738513a3ba
- Updated environment variables in .env.example for production setup. - Changed project references from MedAssist to MedAssist-ng in documentation and code. - Adjusted Docker configurations for new image names and ports. - Removed deprecated push-images.sh script and added docker-compose.dev.yml for development. - Updated translation files to reflect new project name. - Ensured all email notifications and headers reflect the new branding.
3.5 KiB
3.5 KiB
MedAssist-ng - AI Coding Instructions
Architecture Overview
MedAssist-ng is a medication tracking and planning app with a monorepo structure:
- Backend: Fastify 5 + TypeScript + SQLite (Drizzle ORM) at
backend/ - Frontend: React 18 + Vite + TypeScript at
frontend/ - Database: SQLite with migrations in
backend/src/db/migrations/ - Deployment: Docker Compose with separate dev containers
Data Flow
Frontend (React) → /api/* proxy → Backend (Fastify) → SQLite
↓ (Vite rewrites /api to /)
The Vite proxy at frontend/vite.config.ts rewrites /api/* to / - so frontend calls /api/medications but backend route is just /medications.
Development Commands
# Start dev environment (preferred)
docker compose -f docker-compose.dev.yml up
# Or run services separately:
cd backend && npm run dev # tsx watch on port 3000
cd frontend && npm run dev # Vite on port 5173
# Production
docker compose up -d
# Database migrations
cd backend && npm run migrate
Key Patterns
Backend Routes (backend/src/routes/)
- Routes register directly on app without
/apiprefix - Use Fastify's type-safe body/params:
app.put<{ Body: MyType }>() - Settings: notification config → JSON file (
data/notification-settings.json), SMTP →.env
Frontend (frontend/src/App.tsx)
- Single-file React app with all components and state
- Uses React Router for navigation (
/dashboard,/medications,/planner,/settings) - API calls use
/api/prefix (proxied by Vite) - Medication scheduling logic with "slices" (usage patterns)
Database Schema (backend/src/db/schema.ts)
medications: tracks count, strips, pack inventory, usage schedules as JSONusers,refreshTokens: JWT auth with rotating refresh tokenssettings: legacy table (SMTP now from.env, notifications from JSON file)
Settings Architecture
SMTP config: .env file (read-only in UI, loaded via env_file in docker-compose)
Notifications: data/notification-settings.json (editable via UI)
Conventions
- TypeScript: Strict mode, ESM modules (
"type": "module") - Styling: CSS custom properties in
frontend/src/styles.css, dark/light theme viadata-theme - API responses: Return objects directly, Fastify serializes to JSON
- Environment: Copy
.env.example→.env, secrets must be 10+ chars
⚠️ Database Migrations (CRITICAL)
When adding/modifying database columns, ALWAYS:
- Update schema:
backend/src/db/schema.ts - Create migration file:
backend/src/db/migrations/XXXX_description.sql-- Example: Adding a new column ALTER TABLE medications ADD COLUMN new_column TEXT; - Update journal:
backend/src/db/migrations/meta/_journal.json{ "idx": X, "version": 1, "when": TIMESTAMP, "tag": "XXXX_description", "breakpoint": false }
Why this matters: The dev database might get updated manually, but production will break without proper migration files. This causes SQLITE_ERROR: no such column errors in prod.
Migration naming: 0001_add_strips.sql, 0002_pack_inventory.sql, 0003_add_image_url.sql
File Locations
| Purpose | Location |
|---|---|
| Backend entry | backend/src/index.ts |
| Database schema | backend/src/db/schema.ts |
| Migrations | backend/src/db/migrations/*.sql |
| Frontend app | frontend/src/App.tsx |
| Styles | frontend/src/styles.css |
| Docker prod | docker-compose.yml |
| Docker dev | docker-compose.dev.yml |
| Env template | .env.example |