MedInfo Nigeria is a comprehensive healthcare platform built to connect patients with certified doctors, provide free medical information, and facilitate virtual consultations.
This project uses Docker for consistent development environments. All backend services run in isolated containers.
Quick Setup (5 minutes)
git clone <repo-url>
cd medinfo-fullstack
pnpm install
cp apps/backend/.env.example apps/backend/.env
# Configure external services (see below)
docker compose up -d
pnpm db:migrate
pnpm dev:frontend- docs/docker-development.md - Docker setup and workflow
- docs/environment-variables.md - Environment configuration
- docs/external-services.md - External API setup
- docs/troubleshooting.md - Common issues and solutions
- docs/architecture.md - Project architecture and development guidelines
- PostgreSQL 18 - Primary database
- Redis 8 - Cache and job queue (2 instances)
- Backend - Hono.js API server
- Frontend: Next.js 16 (App Router), React 19, TailwindCSS 4, Zustand, TanStack Query
- Backend: Hono.js (Node.js), PostgreSQL, Drizzle ORM, Zod
- @medinfo/db: Database schema and Drizzle configuration
- @medinfo/env: Environment variable validation
- @medinfo/shared: Shared types and validation schemas
- Docker Desktop (recommended) or Docker Engine
- Node.js 18+ (for frontend development)
- pnpm 10.30.3+ (package manager)
git clone <repo-url>
cd medinfo-fullstack
pnpm installcp apps/backend/.env.example apps/backend/.envRequired external services:
- Google OAuth - User authentication
- Cloudinary - File storage
- Zoom API - Video meetings
- Email Service - Appointments (optional)
Quick configuration:
# Edit apps/backend/.env
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
CLOUDINARY_CLOUD_NAME=your-cloudinary-name
CLOUDINARY_API_KEY=your-cloudinary-key
CLOUDINARY_API_SECRET=your-cloudinary-secret
ZOOM_ACCOUNT_ID=your-zoom-account-id
ZOOM_CLIENT_ID=your-zoom-client-id
ZOOM_CLIENT_SECRET=your-zoom-client-secret
# Generate secrets
ACCESS_SECRET=your-access-secret-min-32-chars
REFRESH_SECRET=your-refresh-secret-min-32-charsdocker compose up -dWait 30-60 seconds for services to be healthy:
docker compose ps # Check statuspnpm db:generate
pnpm db:migrate
pnpm db:seed # Optional: seed sample datapnpm dev:frontend- Frontend: http://localhost:3000
- Backend API: http://localhost:8000
- API Documentation: http://localhost:8000/api/docs
The Docker setup includes these services:
| Service | Container | Port | Purpose |
|---|---|---|---|
| PostgreSQL | medinfo-postgres-db |
5432 | Database |
| Redis Cache | medinfo-redis-cache |
6379 | Session storage |
| Redis Queue | medinfo-redis-queue |
6380 | Job processing |
| Backend API | medinfo-backend |
8000 | API server |
# Start all services
docker compose up -d
# Check service health
docker compose ps
# View logs
docker compose logs -f
# Stop all services
docker compose down
# Restart specific service
docker compose restart backend# Start containers (if stopped)
docker compose up -d
# Start frontend
pnpm dev:frontend
# Monitor logs in another terminal
docker compose logs -f backend
# Make code changes (backend hot-reloads, frontend auto-reloads)# Generate and run migrations
pnpm db:generate
pnpm db:migrate
# Seed with sample data
pnpm db:seed
# Open database studio
pnpm db:studio# Access container shell
docker compose exec backend sh
# Connect to database
docker compose exec medinfo-postgres-db psql -U postgres medinfo
# Test Redis
docker compose exec medinfo-redis-cache redis-cli ping# Check port usage
netstat -tulpn | grep ":5432\|:6379\|:6380\|:8000" # Linux
lsof -i :5432 -i :6379 -i :6380 -i :8000 # macOS
netstat -an | findstr ":5432 :6379 :6380 :8000" # Windows- Stop conflicting local services (PostgreSQL, Redis)
- Use alternative ports (edit
docker-compose.yaml) - Remove port exposures (Docker internal only)
You must configure these external services:
Purpose: User authentication with Google accounts Setup: Google Cloud Console β APIs & Services β Credentials
Steps:
- Create new OAuth 2.0 Client ID
- Add
http://localhost:8000/api/v1/auth/google/callbackto authorized redirect URIs - Copy Client ID and Client Secret to
.env
Purpose: File storage for medical documents and profile images Setup: Cloudinary Console β Dashboard
Steps:
- Sign up for free account
- Get Cloud Name, API Key, and API Secret from Dashboard
- Add to
.env
Purpose: Video meeting creation for virtual consultations Setup: Zoom App Marketplace β Build App
Steps:
- Create Server-to-Server OAuth app
- Add necessary scopes (meetings:write, users:read)
- Copy Account ID, Client ID, and Client Secret to
.env
Purpose: Appointment reminders and notifications Recommended: Resend
Steps:
- Create account and generate API key
- Add
RESEND_API_KEYto.env
For detailed setup instructions, see docs/external-services.md.
medinfo-fullstack/
βββ apps/
β βββ backend/ # Hono API Server
β βββ frontend/ # Next.js Application
βββ packages/
β βββ db/ # Database Schema & Migrations
β βββ env/ # Environment Validation
β βββ shared/ # Shared Types & Schemas
βββ docs/ # Documentation
βββ docker-compose.yaml # Docker Development Setup
βββ README.md # This file
# Docker operations
docker compose up -d # Start all services
docker compose down # Stop all services
docker compose logs -f backend # View backend logs
docker compose ps # Check service status
# Database operations
pnpm db:generate # Generate Drizzle schema
pnpm db:migrate # Run migrations
pnpm db:seed # Seed sample data
pnpm db:studio # Open Drizzle Studio
# Development
pnpm dev:frontend # Start frontend (backend runs in Docker)
pnpm dev:docker-db # Start only database services
# Code quality
pnpm lint:eslint # Run ESLint
pnpm lint:format # Format code
pnpm lint:type-check # TypeScript type checking# Check Docker Desktop is running
docker version
# Check port conflicts
netstat -tulpn | grep -E ":(5432|6379|6380|8000)"
# View error logs
docker compose logs# Check database health
docker compose exec medinfo-postgres-db pg_isready
# Test connection
docker compose exec backend node -e "
const { Client } = require('pg');
const client = new Client({ connectionString: process.env.DATABASE_URL_DEV });
client.connect().then(() => console.log('Database connected!')).finally(() => client.end());"# Verify environment variables
docker compose exec backend env | grep -E "(GOOGLE_|CLOUDINARY_|ZOOM_)"
# Check for missing variables in logs
docker compose logs backend | grep "Missing required environment variable"For complete troubleshooting, see docs/troubleshooting.md.
- Docker Desktop installed and running
- Node.js 18+ and pnpm installed
- Environment file configured with external services
- Docker containers started and healthy
- Database migrations applied
- Frontend accessible at http://localhost:3000
- Backend API accessible at http://localhost:8000
- External services connected (OAuth, Cloudinary, Zoom)
- Frontend: http://localhost:3000
- Backend API: http://localhost:8000
- API Documentation: http://localhost:8000/api/docs
- Database Studio:
pnpm db:studio(when services running)
- Fork the repository
- Create a feature branch
- Make your changes
- Run tests and linting
- Submit a pull request
This project is licensed under the MIT License - see the LICENSE file for details.