Build, deploy and configuration

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

capacity-connect/
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 workspace

Docker Compose

infra/docker-compose.yml
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

VariableUsed byMeaning
DATABASE_URLapi, ai-serviceConnection as app_user (RLS applies)
MATCHER_DATABASE_URLapiConnection as the BYPASSRLS matcher role
BETTER_AUTH_SECRETapiSigning secret for Better Auth
AI_PROVIDERapivertex or ollama
VERTEX_PROJECT, VERTEX_LOCATION, VERTEX_MODELapiVertex AI target when AI_PROVIDER=vertex
GOOGLE_APPLICATION_CREDENTIALSapiService account file for Vertex AI
OLLAMA_HOSTapi, ai-serviceBase URL of Ollama, never hardcoded
EMBED_MODELai-servicenomic-embed-text
CHAT_MODELapiQwen3.5 tag used when AI_PROVIDER=ollama
UPLOAD_ROOTapi, ai-serviceVolume mount, for example /data
GOTENBERG_URLapihttp://gotenberg:3000
ALLOWED_ORIGINSapiCORS 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
0 to 6
Courses, enrollment, resources, ingestionhours 6 to 16
6 to 16
Assessments, manual then AIhours 16 to 24
16 to 24
Certificates, competency, dashboardshours 24 to 30
24 to 30
Triage, seed data, rehearsalhours 30 to 36
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.