Server Guides
Server Overview
The Hikma Health Server is a full-stack TypeScript application that serves as the backbone of the entire EHR platform. It combines both the API backend (for mobile applications) and the admin web interface into a single unified application, designed for offline-first operation in low-resource settings.
What Does the Server Do?
The server's main responsibilities include:
- Authentication & Authorization: Secure user management and access control
- Database Management: All data operations through a type-safe query builder
- API Endpoints: RESTful API for mobile applications to sync data
- Admin Web Interface: Browser-based portal for system administration
- Data Synchronization: Handles offline-first sync from mobile devices
- Patient Records: Manages patient information, visits, and medical history
- Forms Management: Dynamic medical forms that can be customized
- Reports & Analytics: Data export and reporting capabilities
Technology Stack
The server is built with modern web technologies optimized for reliability and performance:
Core Framework
- Runtime: Node.js 22.14+
- Language: TypeScript - Type-safe JavaScript
- Framework: TanStack Start - React-based full-stack framework
- Build Tool: Vite - Fast build and hot module replacement
Database & Queries
- Database: PostgreSQL - Reliable relational database
- Query Builder: Kysely - Type-safe SQL query builder
- Migrations: SQL-based schema migrations in the
db/directory
Frontend (Admin Portal)
- UI Framework: React with TypeScript
- Styling: Tailwind CSS 4.0 - Utility-first CSS
- Components: Radix UI + shadcn/ui
- Forms: TanStack Form with React Hook Form
- Routing: TanStack Router - Type-safe file-based routing
State Management
- Client State: TanStack Store
- State Machines: XState
- Data Caching: TanStack Query (React Query)
Development & Testing
- Testing: Vitest for unit tests, Playwright for E2E
- Linting & Formatting: Biome - Fast linter and formatter
- Type Checking: TypeScript strict mode
- Monitoring: Sentry for error tracking
Package Management
- Package Manager: pnpm - Fast, disk-efficient package manager
Architecture
The server uses a modern full-stack architecture where the frontend and backend are tightly integrated:
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā Hikma Health Server ā
ā (Single Unified Application) ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤
ā ā
ā āāāāāāāāāāāāāāā āāāāāāāāāāāāāāā ā
ā ā Admin UI ā ā API Routes ā ā
ā ā (Browser) ā ā (Mobile) ā ā
ā āāāāāāāā¬āāāāāāā āāāāāāāā¬āāāāāāā ā
ā ā ā ā
ā āāāāāāāāāāāā¬āāāāāāāāāāā ā
ā ā ā
ā āāāāāāāāāāāā¼āāāāāāāāāāā ā
ā ā Business Logic ā ā
ā ā & Middleware ā ā
ā āāāāāāāāāāāā¬āāāāāāāāāāā ā
ā ā ā
ā āāāāāāāāāāāā¼āāāāāāāāāāā ā
ā ā Kysely Query ā ā
ā ā Builder Layer ā ā
ā āāāāāāāāāāāā¬āāāāāāāāāāā ā
āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāāāāāāāāā
ā
āāāāāāāāāāāā¼āāāāāāāāāāā
ā PostgreSQL ā
ā Database ā
āāāāāāāāāāāāāāāāāāāāāāā
Project Structure
Understanding the project structure helps you navigate and modify the codebase:
hikma-health-server/
āāā db/ # Database migrations (SQL files)
ā āāā 001_initial.sql
ā āāā 002_add_feature.sql
ā
āāā src/
ā āāā app/ # Application-level layouts & components
ā āāā components/ # Reusable UI components (shadcn/ui)
ā āāā data/ # Data fetching & caching logic
ā āāā db/ # Database connection & utilities
ā āāā hooks/ # Custom React hooks
ā āāā integrations/ # Third-party service integrations
ā āāā lib/ # Utility functions & helpers
ā āāā middleware/ # Server middleware (auth, etc.)
ā āāā models/ # TypeScript data models & types
ā āāā routes/ # File-based routing (API + pages)
ā āāā stores/ # State management stores
ā āāā env.ts # Environment variable validation
ā āāā router.tsx # Router configuration
ā āāā styles.css # Global styles
ā
āāā tests/ # Unit test files
āāā e2e/ # End-to-end test files
āāā scripts/ # Utility scripts
āāā public/ # Static assets
ā
āāā .env # Environment variables (DO NOT COMMIT)
āāā package.json # Dependencies & scripts
āāā tsconfig.json # TypeScript configuration
āāā vite.config.ts # Build configuration
Key Directories Explained
src/routes/: File-based routing powered by TanStack Router. Each file represents a route in the application (both API endpoints and UI pages).src/components/: Reusable UI components built with Radix UI and styled with Tailwind CSS.src/db/: Database connection setup, query builders, and Kysely configuration.db/: SQL migration files that define the database schema evolution.src/models/: TypeScript types and interfaces for data structures (patients, visits, forms, etc.).src/middleware/: Server middleware for authentication, authorization, error handling, etc.
Environment Variables
The server uses environment variables for configuration. Create a .env file in the root directory:
Required Variables
# Database connection string
DATABASE_URL=postgresql://username:password@host:port/database
# Example for local development
DATABASE_URL=postgresql://hikma_health:hikma_health@localhost:5432/hikma_health
Optional Variables
# Node environment (development, production, test)
NODE_ENV=development
# Server port (default: 3000)
PORT=3000
# Sentry DSN for error monitoring (production)
SENTRY_DSN=your-sentry-dsn-here
# JWT secret for authentication
JWT_SECRET=your-secret-key-here
# Session configuration
SESSION_SECRET=your-session-secret-here
Security Best Practices
- NEVER commit the
.envfile to version control (it's in.gitignore) - Use strong, unique values for all secrets
- Rotate secrets regularly
- Use different
.envfiles for development, staging, and production - In production, use environment variables provided by your hosting platform (e.g., Render, DigitalOcean)
Database Management
Migrations
The server uses SQL-based migrations stored in the db/ directory. Migrations are numbered and run in order.
Running Migrations
# Run all pending migrations
pnpm run migrate:latest
# Rollback last migration
pnpm run migrate:down
# Create a new migration
# Create a new file in db/ directory with the next number
# Example: db/003_add_new_table.sql
Migration Best Practices
- Always test migrations locally before deploying
- Migrations should be reversible when possible
- Use transactions to ensure atomicity
- Include both
upanddownmigrations - Document complex migrations with comments
Query Builder (Kysely)
The server uses Kysely for type-safe database queries:
// Example: Fetching patients
const patients = await db
.selectFrom('patients')
.selectAll()
.where('clinic_id', '=', clinicId)
.execute()
// Example: Creating a visit
const visit = await db
.insertInto('visits')
.values({
patient_id: patientId,
clinic_id: clinicId,
provider_id: providerId,
visit_date: new Date(),
})
.returningAll()
.executeTakeFirstOrThrow()
Benefits of Kysely:
- Full TypeScript type safety
- Auto-completion for table names and columns
- Compile-time error checking
- No ORM overhead - just SQL
- Easy to debug - see the actual SQL being generated
Development Workflow
Running Locally
# Install dependencies
pnpm install
# Set up environment variables
cp .env.example .env
# Edit .env with your database credentials
# Run migrations
pnpm run migrate:latest
# Start development server (with hot reload)
pnpm dev
The application will be available at http://localhost:3000
Available Commands
| Command | Description |
|---|---|
pnpm dev | Start development server on port 3000 |
pnpm build | Build for production |
pnpm start | Run production server (with migrations) |
pnpm test | Run unit tests |
pnpm test:watch | Run tests in watch mode |
pnpm test:e2e | Run end-to-end tests |
pnpm db:migrate | Run database migrations |
pnpm format | Format code with Biome |
pnpm lint | Lint code with Biome |
pnpm check | Run format + lint checks |
Testing
The server includes comprehensive testing:
Unit Tests (Vitest):
# Run all tests
pnpm test
# Run tests in watch mode
pnpm test:watch
# Run tests with coverage
pnpm test:coverage
E2E Tests (Playwright):
# Run E2E tests
pnpm test:e2e
# Run E2E tests with UI
pnpm test:e2e:ui
API Routes
The API provides endpoints for the mobile application to sync data. All API routes are in the src/routes/api/ directory.
Authentication
All API requests (except login) require authentication via JWT tokens or session cookies.
Common Endpoints
POST /api/login- User authenticationGET /api/patients- List patientsPOST /api/patients- Create new patientGET /api/patients/:id- Get patient detailsPOST /api/visits- Record a visitGET /api/forms- Get available formsPOST /api/sync- Sync offline data
Sync Mechanism
The server handles offline-first synchronization from mobile devices:
- Mobile app collects data offline
- When online, app sends batch sync request
- Server validates and processes each item
- Conflicts are resolved based on timestamps
- Server responds with sync status and any server updates
- Mobile app updates local database
Admin Web Interface
The admin interface is served at the same URL as the API. It provides:
- Dashboard: Overview of system status and recent activity
- Patient Management: Search, view, and edit patient records
- User Management: Create and manage clinician accounts
- Forms Editor: Create and customize medical forms
- Reports: Generate and export data reports
- Settings: Configure system settings
- QR Code Generator: Create QR codes for mobile app activation
Deployment
Quick Deploy
Use the one-click deploy buttons for easy deployment:
Manual Deployment
For other platforms:
- Ensure Node.js 22.14+ is available
- Set environment variables (especially
DATABASE_URL) - Install dependencies:
pnpm install - Build the application:
pnpm build - Run migrations and start:
pnpm start
Production Considerations
- Use a production-grade PostgreSQL database
- Enable SSL/TLS for database connections
- Set up regular database backups
- Configure monitoring and error tracking (Sentry)
- Use environment variables for all secrets
- Set up health check endpoints
- Configure proper CORS policies
- Enable rate limiting for API endpoints
Monitoring & Debugging
Logging
The server includes structured logging for debugging:
console.log('Patient created:', { patientId, clinicId })
console.error('Failed to sync visit:', error)
In production, logs are available through your hosting provider's dashboard.
Error Tracking
Configure Sentry for automatic error tracking:
SENTRY_DSN=your-sentry-dsn
Sentry will capture and report:
- Unhandled exceptions
- API errors
- Frontend errors
- Performance issues
Health Checks
The server exposes health check endpoints:
GET /health- Basic health checkGET /health/db- Database connectivity check
Migration from Python Version
If you're migrating from the old Python/Flask backend:
Key Differences
| Aspect | Old (Python) | New (TypeScript) |
|---|---|---|
| Language | Python 3.10 | TypeScript (Node.js 22+) |
| Framework | Flask | TanStack Start |
| Admin | Separate Next.js app | Integrated in same app |
| ORM | psycopg2 | Kysely query builder |
| Port | 8000 | 3000 |
| Migrations | Flask-Migrate | SQL files |
| Testing | pytest | Vitest + Playwright |
Migration Steps
- Deploy the new server using your existing database
- The application will automatically run migrations
- Update mobile app QR codes to point to new URL
- Test all functionality
- Retire old Python backend and admin deployments
Your data remains safe - the new system uses the same PostgreSQL database and migrates the schema automatically.
Contributing
To contribute to the server:
- Fork the repository
- Create a feature branch
- Make your changes
- Run tests:
pnpm test && pnpm test:e2e - Run checks:
pnpm check - Submit a pull request
See the CONTRIBUTING.md for detailed guidelines.
Further Reading
- Architecture Guide - Understand the full system architecture
- Deployment Guide - Deploy your own instance
- Customization - Customize forms and workflows
- API Documentation - Detailed API endpoint documentation
- Security Best Practices - Secure your deployment