Codebase overview¶
Architecture¶
- Monolith: Django serves both HTML templates (Tailwind + Alpine.js + htmx) and a DRF REST API
- URL pattern: Most views scoped under
/a/<org_slug>/viaOrganizationMiddleware - API versioning:
AcceptHeaderVersioningwith versions1.0and2.0 - Background tasks: Celery with Redis broker; beat scheduler uses DB
- Feature flags: django-waffle with a custom
Flagmodel. Flag names inflags/flag_names.py, switch names inflags/switch_names.py— see Terminology below - Audit trail: django-pghistory stores
username+user_emailin context (survives user deletion). Readdocs/audit-history.mdbefore tracking a model or reading its events - Database: PostgreSQL + PostGIS.
ATOMIC_REQUESTS = True(all requests are transactions) - Deployment: Kamal (Docker-based) + Ansible on EC2. See
deploy/README.md
Key directories¶
commcare_connect/
opportunity/ # Core domain: opportunities, visits, payments (largest app)
organization/ # Org management, membership roles
program/ # Program management, linking orgs/opportunities
users/ # Custom User model, ConnectID links
audit/ # Audit reports: CHC indicators, sampling, review workflow
commcarehq/ # CommCare HQ server integration
connect_id_client/ # HTTP client for ConnectID service
form_receiver/ # Receives xforms from CommCare HQ
commcarehq_provider/ # OAuth provider: HQ as an identity provider
ocs_provider/ # Open Chat Studio integration
data_export/ # CSV/streaming exports over OAuth token scopes
microplanning/ # Work areas, coverage tracking, maps (Mapbox)
reports/ # KPI and admin reports
flags/ # Waffle feature flag/switch name constants
health/ # /up liveness probe, token-gated /status/ dependency checks (see its README)
multidb/ # Secondary DB support + logical replication
deid/ # SQL generator for de-identifying a DB copy; only in INSTALLED_APPS under local.py
web/ # Context processors, shared template tags
prelogin/ # Public marketing pages
utils/ # BaseModel, middleware, caching, permissions
config/
settings/ # base.py, local.py, test.py; deploy_base.py shared by staging.py + production.py
api_router.py # DRF API URL routing
celery_app.py # Celery config
urls.py # Root URL config
Terminology¶
Some words mean several unrelated things here. Work out which one you are in before searching.
"flag" — four separate concepts:
- Waffle flags: per-request/per-user feature toggles. Names in
flags/flag_names.py, checked withflag_is_active(request, NAME), backed by the customFlagmodel inflags/models.py. - Waffle switches: global on/off toggles. Names in
flags/switch_names.py, checked withswitch_is_active(NAME). - Visit validation flags: why a
UserVisitwas flagged for review (duplicate,gps, …). Defined inutils/flags.py(Flags,FlagDescription,FlagLabels), stored onUserVisit.flaggedandUserVisit.flag_reason. - Verification flag config: which validation flags an opportunity applies —
OpportunityVerificationFlagsandDeliverUnitFlagRulesinopportunity/models/verification.py.
"worker" — there is no Worker model. A worker is a User reached through an OpportunityAccess, and WorkerPageView, the Worker*Table classes and the worker templates all resolve to that pair. Nothing on User marks someone as a worker: org staff have a UserOrganizationMembership, workers have an OpportunityAccess. Worker-scoped URLs pass ?user=<User.user_id> — the UUID, not the PK.