Delivery
Build, deploy and configuration
The repository layout, the Docker Compose services, every environment variable, the Postgres roles, and the build order for the 36-hour finale. Nothing here changes the design; it makes the design runnable.
Repository
apps/
admin-console/ Vite multi-page + React Router, Admin portal
portal/ Vite multi-page + React Router, Trainer and Trainee, role-branched
mobile/ Flutter (go_router, dio)
services/
api/ Express REST API, middleware chain, handlers
ai-service/ Python: extraction, chunking, embedding, workers
pdf-service/ thin wrapper around Gotenberg
packages/
db/ Drizzle schema, migrations, sql/ (RLS, indexes)
ui/ shared component set
types/ shared TS types
infra/
docker-compose.yml
nginx/ per-section try_files, rate limits
cron/ snapshot.sh, restore-check.sh
turbo.json pnpm + Turborepo workspaceDocker Compose
services:
nginx: { image: nginx:stable, ports: ["80:80", "443:443"], depends_on: [api] }
api: { build: ./services/api, env_file: .env, volumes: ["appdata:/data"],
depends_on: [postgres, gotenberg] }
ai-service: { build: ./services/ai-service, env_file: .env, volumes: ["appdata:/data:ro"],
depends_on: [postgres] }
gotenberg: { image: gotenberg/gotenberg:8 } # no ports: internal network only
postgres: { image: pgvector/pgvector:pg17, volumes: ["pgdata:/var/lib/postgresql/data"] }
# Ollama runs on the host to use the GPU: OLLAMA_HOST=http://host.docker.internal:11434
volumes: { appdata: {}, pgdata: {} }Environment variables
| Variable | Used by | Meaning |
|---|---|---|
DATABASE_URL | api, ai-service | Connection as app_user (RLS applies) |
MATCHER_DATABASE_URL | api | Connection as the BYPASSRLS matcher role |
BETTER_AUTH_SECRET | api | Signing secret for Better Auth |
AI_PROVIDER | api | vertex or ollama |
VERTEX_PROJECT, VERTEX_LOCATION, VERTEX_MODEL | api | Vertex AI target when AI_PROVIDER=vertex |
GOOGLE_APPLICATION_CREDENTIALS | api | Service account file for Vertex AI |
OLLAMA_HOST | api, ai-service | Base URL of Ollama, never hardcoded |
EMBED_MODEL | ai-service | nomic-embed-text |
CHAT_MODEL | api | Qwen3.5 tag used when AI_PROVIDER=ollama |
UPLOAD_ROOT | api, ai-service | Volume mount, for example /data |
GOTENBERG_URL | api | http://gotenberg:3000 |
ALLOWED_ORIGINS | api | CORS origins |
Build order
The grand finale is one continuous 36-hour build. Bars are to scale. The last six hours are reserved for hardening and rehearsal, with no new features.
Environment, auth, approvalshours 0 to 6
Courses, enrollment, resources, ingestionhours 6 to 16
Assessments, manual then AIhours 16 to 24
Certificates, competency, dashboardshours 24 to 30
Triage, seed data, rehearsalhours 30 to 36
0h6h12h18h24h30h36h
Index after load
Create the ivfflat index after content is loaded so it trains on real rows.
Model ready
ollama pull nomic-embed-text runs once per host before first use.
Capacity Connect · Team Syntax Squad · SIH 2026 · PS 26075Code samples are implementation sketches.