Skip to content

Repository Map ​

GitHub Repositories ​

RepositoryGitHub URLPurpose
c2fit-app-frontendOpen GitHub repository ↗Flutter mobile app — patient-facing assessment flow.
c2fit-bffOpen GitHub repository ↗Go backend-for-frontend: first-party auth/user/bundle/journey/streak API + reverse proxy to Assessment/Result/Speech services.
c2fit-assessment-resultOpen GitHub repository ↗Go monorepo containing two independently-deployed services: Assessment Service (cmd/assessment) and Result Service (cmd/result), plus a published pkg/model Go client submodule.
c2fit-assessment-dashboardOpen GitHub repository ↗Deprecated/unsupported. React + Vite + SQLite local tool (package.json name: dm_question_maker) for authoring/importing/exporting question pools and assessment paths. Not a deployed service — no .github/workflows/, no .env, no API calls found in src/.

CI/CD Trigger ​

RepositoryBranchTriggerEnvironment
c2fit-bffdevpush → build + deployDev (c2fit-bff-dev ECS service)
c2fit-bffmainpush → build + push to ECR onlyDeploy job is conditioned on dev only. For prod/study, the built image lands in ECR but rolling it out to the running ECS service is a separate manual step in the AWS console — not automated. Same for c2fit-assessment-result.
c2fit-bffdev / mainpull_requestRuns acceptance + unit tests only (acceptance_test.yml)
c2fit-assessment-resultdevpush → build + deploy both servicesDev (c2fit-assessment-dev, c2fit-result-dev ECS services)
c2fit-app-frontendn/a (manual dispatch)workflow_dispatchCreates study/production tags, deploys dev/study builds to Firebase App Distribution, and uploads production Android builds to Google Play. Production iOS is built and uploaded locally through Xcode.

Release promotion for the two Go backends is tag-based, not branch-based: c2fit-bff/tag-version.yml and c2fit-assessment-result/tag-version.yml are manual workflow_dispatch workflows that create a Git tag and retag an existing ECR image ({commit-sha} → {version}) — they do not rebuild from source.

c2fit-app-frontend ​

Flutter mobile app. Feature-based Clean Architecture, 37 feature modules under lib/feature/{name}/ (up to 4 layers: data/, domain/, presentation/, util/). State management: june (no BLoC/Provider/Riverpod, no DI container). Full internal documentation already exists at c2fit-app-frontend/docs/ (16 files) — see that repo's docs/README.md as the entry point; not duplicated here.

Important areas:

PathPurpose
lib/feature/{name}/37 feature modules (login, register, streak, journey, result, the 6 assessments, etc.)
lib/feature/api/network/api_service.dartDio-based ApiService — Sentry, cache interceptor, X-C2Fit-Frontend-Version header
lib/feature/router/constant.dartNamed route table (appRouter) + C2FitRoute enum
lib/feature/error/util/common_error_handler.dart401 refresh+retry, timeout, 5xx handling
docs/Existing deep documentation set (architecture, modules catalog, per-assessment detail, build/release)
android/fastlane/Fastfile, ios/fastlane/FastfileFastlane lanes for dev/study Firebase App Distribution and the production Google Play upload
generate_env.shWrites .env from 8 positional args at build time

Common commands (see CLAUDE.md for the full list):

CommandPurpose
fvm flutter run --flavor releaseDevRun locally against the dev flavor (Flutter pinned to 3.38.5 via .fvmrc)
make run_lintfvm flutter analyze
make run_unit_testfvm flutter test test/
make run_integration_testRequires a simulator already booted
make generate_mockRegenerate Mockito mocks after interface changes
make start_mock_serverWireMock via docker-compose --env-file .env.test up -d

Environment variables (.env.template, all optional/commented placeholders — one .env shared across all 3 flavors):

  • BASE_URL, TRANSCRIBE_SOCKET_URL
  • PRINT_DETAILED_STACKTRACE
  • IOS_VERSION_S3_URL, ANDROID_VERSION_S3_URL (S3-hosted app-version-control JSON)
  • SENTRY_ENVIRONMENT, SENTRY_DSN, SENTRY_RELEASE
  • SMARTLOOK_PROJECT_KEY

Per-flavor identity (not env vars — separate config files): google-services.json / GoogleService-Info.plist under android/app/src/{flavor}/ and ios/Config/{flavor}/.

c2fit-bff ​

Go, Gin + Uber Fx. Two roles: first-party API (auth, user, bundle, journey, streak — MongoDB + Redis) and reverse-proxy/gateway (/assessment-service/*, /result-service/*, /ws/v1/speech). Also imports c2fit-assessment-result's published pkg/model Go client directly for typed calls. README is stale (describes a Go 1.20 / older boilerplate layout that doesn't match the actual internal/app/bff + internal/pkg structure) — do not trust it for architecture.

Important areas:

PathPurpose
cmd/bff/main.goEntry point, Fx wiring (API server + cron jobs)
config/bff/{config.go,config.yml}Typed config struct + defaults, Viper-based
internal/app/bff/router/Route registration by domain (auth, journey, bundle, streak, user, report, admin, assessment-service proxy, result-service proxy, ws, health)
internal/app/bff/service/Business logic per domain
internal/app/bff/reverse-proxy/Generic HTTP + WebSocket reverse proxy handlers
internal/pkg/repository/, internal/pkg/entity/Mongo repositories/entities: Auth, User, Bundle, Journey, Streak, File, Session, Notification, AppVersion
acceptance_tests/Ginkgo black-box tests (currently cover Digit Span Speak and Drawing Memory submission flows)
seed/bundle.jsMongo seed script

Common commands (Makefile targets — these load .env via include .env/export, so prefer them over raw go run):

CommandPurpose
make go-runRun locally
make docker-runRun via docker compose up --build -d
make go-unitUnit tests (as run in CI)
make go-acceptanceAcceptance tests (spins up test-mongo/test-redis/test-wiremock, seeds Mongo, then runs)
make go-integration / make docker-integrationIntegration tests against docker-compose.test.yml
make seed-mongoRun seed/migrate.sh
make mock-genRegenerate mockgen mocks for repositories/engines

Environment variables (.env.template, names only):

REDIS_ENDPOINT, SYSTEM_API_ACCESS_KEY*, MONGODB_CONNECTION_STRING, MONGODB_DATABASE_NAME, MONGODB_TIMEOUT*, APP_NAME, APP_SECRET_KEY, AWS_REGION, AWS_ACCESS_KEY, AWS_SECRET_KEY, AWS_S3_BUCKET_NAME, AWS_CLOUDWATCH_NAMESPACE*, AWS_COGNITO_CLIENT_ID, AWS_COGNITO_CLIENT_SECRET, AWS_COGNITO_USER_POOL_ID, AWS_COGNITO_JWKS_URL, AWS_COGNITO_DOMAIN, DEPLOYMENT_ENVIRONMENT, JWT_ACCESS_SECRET*, JWT_REFRESH_SECRET* (commented out — Cognito/JWKS is the live auth path), ASSESSMENT_SERVICE_BASE_URL, RESULT_SERVICE_BASE_URL, SPEECH_SERVICE_BASE_URL, GITHUB_TOKEN* (build-time, private Go module access), TESTING_ACCEPTANCE_USER_EMAIL*, TESTING_ACCEPTANCE_USER_PASSWORD* (* = commented/optional in the template).

Values are managed through .env locally and (per CI) AWS Secrets Manager/GitHub Actions secrets in deployed environments — never documented here.

c2fit-assessment-result ​

Go monorepo, two independently deployed services sharing one module and one MongoDB database (assessment-result):

  • Assessment Service — cmd/assessment, config config/assessment/, default port 8081. Config only wires App, LogSetting, MongoDB, Deployment — Redis/AWS/Cognito/Cloudwatch are present in code but commented out (not in use).
  • Result Service — cmd/result, config config/result/, default port 8082. Config additionally wires AWS (region/keys/s3_bucket_name), Google (Speech-to-Text credentials — legacy/alternate path), ASRService (global-asr-service base URL — the active ASR path).
  • cmd/export — a standalone one-off CLI script (not a deployed service) that connects directly to both this DB and c2fit-bff's Mongo DB to export a user's journey + results; hardcodes target user/time range, meant to be edited ad hoc.

Important areas:

PathPurpose
cmd/assessment/, cmd/result/Two service entry points
internal/app/{assessment,result}/router/Gin route trees (/api, /internal, /health per service)
internal/app/{assessment,result}/service/JourneyPathService/QuestionService (assessment), JourneyService/ResultService (result)
internal/pkg/entity/Mongo document models — one file per task type + BaseResult, AssessmentPath, BaseQuestionPool
internal/pkg/engine/Scoring engines (one per task type) + journey-path generation — the real business-rule core
internal/pkg/repository/Mongo repositories, one pair (question/result) per task type + assessment_path_repo.go, file_repo.go (S3)
pkg/model/ (separately versioned Go submodule, own go.mod)request/response/payload/enum/errors + client/ — typed HTTP clients (AssessmentClient, ResultClient) consumed by c2fit-bff
docs/api/Postman + Bruno API collections for both services — closest thing to authoritative API docs (no docs/*.md exists)
acceptance-tests/Ginkgo suite booting both services in-process; Digit Span Speak test currently XDescribe'd (disabled)

Common commands (Makefile targets — these load result.env via include result.env/export, so prefer them over raw go run):

CommandPurpose
make go-run-assessment / make go-run-resultRun either service locally
make docker-run-assessment / make docker-run-resultRun either service via Docker
make go-unitUnit tests
make go-acceptanceSpin up mongo + wiremock via docker-compose, seed Mongo, run acceptance Ginkgo tests
make seed-mongoSeed Mongo
make mock-genRegenerate mockgen mocks

Environment variables (names only — shared vars in both .env.template files, service-specific ones noted):

  • Shared: MONGODB_CONNECTION_STRING, MONGODB_DATABASE_NAME, MONGODB_TIMEOUT*, APP_NAME, DEPLOYMENT_ENVIRONMENT, GITHUB_TOKEN (build-time). Commented/inactive in both templates: REDIS_ENDPOINT, SYSTEM_API_ACCESS_KEY, CLOUDWATCH_NAMESPACE, AWS_REGION/AWS_ACCESS_KEY/AWS_SECRET_KEY, AWS_COGNITO_*, JWT_ACCESS_SECRET/JWT_REFRESH_SECRET.
  • Result Service only (result.env.template, active): GOOGLE_CREDENTIALS_JSON, GOOGLE_SPEECH_TO_TEXT_RECOGNIZER; commented: AI_CONTROLLER_SERVICE_BASE_URL (legacy, superseded by global-asr-service). ASR base URL and S3 bucket name are set via config/result/config.yml defaults, not the env template.
  • Ports: 8081 (assessment), 8082 (result) — set in config.yml, not env vars.

Auth model differs from c2fit-bff: no Cognito/JWT wiring is active here — both services read a c2fit-user-id header (+ optional c2fit-user-age) via C2fitUserContextMiddleware, applied to the /api/v1 groups. The /internal/v1/* groups have no user-context middleware — intended for trusted service-to-service callers (i.e. the BFF, or the two services calling each other via pkg/model/client).

c2fit-assessment-dashboard ​

Deprecated/unsupported. Local content-authoring tool, not part of the deployed system. React 19 + Vite + Mantine UI + better-sqlite3 (local SQLite DB, no backend calls found). Components: AddQuestion, EditQuestion, AddAssessmentPath, EditAssessmentPath, ImportAssessmentPath/ExportAssessmentPath, ImportPage/ExportPage, Dashboard, AssessmentPathDashboard. Used to author question pools and assessment paths locally and export them; the exported JSON is manually copied into c2fit-assessment-result/seed/*.js, then applied to MongoDB via the manual seed/migrate.sh migration script — no live DB link or automated pipeline between the two repos. No .github/workflows/, no .env/.env.template — this tool is not deployed or CI-tested.

Cross-Repo Integration ​

FlowRepositories Involved
Loginc2fit-app-frontend → c2fit-bff (POST /api/v1/auth/login/email)
Journey lifecycle (start/next/state/restart/skip-task)c2fit-app-frontend → c2fit-bff first-party /api/v1/journey/* — owned by the BFF itself against Mongo/Redis, not proxied
Result submission / fetchc2fit-app-frontend → c2fit-bff (/result-service/* proxy) → c2fit-assessment-result Result Service
Digit Span Speak scoringc2fit-assessment-result Result Service → global-asr-service (external internal ASR microservice, same platform DTM's docs reference)
Assessment content / journey-path generationc2fit-app-frontend (JourneyAssessmentService.getQuestionInfo) → c2fit-bff (/assessment-service/api/v1/question/info proxy) → c2fit-assessment-result Assessment Service
Real-time speech (transcription during recording)c2fit-app-frontend → c2fit-bff WebSocket proxy (/ws/v1/speech) → speech service (SPEECH_SERVICE_BASE_URL)
Typed cross-service clientc2fit-bff imports c2fit-assessment-result's published pkg/model Go module directly (aClient.NewAssessmentClient, aClient.NewResultClient) — a compile-time dependency, not just an HTTP proxy relationship
Question/path content authoringc2fit-assessment-dashboard (local tool, deprecated) → export JSON → manually copied into c2fit-assessment-result/seed/*.js → manual mongosh migration (seed/migrate.sh) — no live DB link or automated pipeline

Documentation Sources ​