Skip to content

Repository Structure

The platform is split across three independently versioned repositories in the workspace, plus external services. There is no single top-level repository that ties them together; each project has its own Git history and release cadence.

DirectoryRole
dps-code-api/Flask API, domain services, SQL migrations, contract tests, deployment documentation
ecc-dps-dashboard/React 19 + TypeScript + Vite dashboard (includes the Training Center)
discord-oauth-proxy/Cloudflare Worker for the Discord OAuth token exchange

dps-code-api/ — the backend

The API repository contains the Flask application, its extracted service modules, the complete SQL migration chain, and the deployment/architecture notes.

Application and routing layer

FileResponsibility
app.pyFlask application factory, route registration, request handling, error handlers, CORS, session interface wiring. The composition/router layer — domain logic lives in the modules below.

Domain services

FileResponsibility
reports_service.pyReport data contract (actions, statuses, patchable fields), the shared report-action domain operations (perform_report_action, conclude_investigation), and the server-side report list.
punishment_service.pyPunishment data contract (statuses, ID format, editable/protected fields), validation helpers, and the punishment list helper.
agents_service.pyAgent data-contract constants (create-required fields, patchable fields, valid ranks).
event_service.pyApplication-level interface for the canonical events stream (record_event, record_report_event); the EVENT_TYPES taxonomy.
admin_service.pyAdmin-domain helpers: session-derived audit identity, health-history recording.
health_service.pyAdmin health payload builder (section statuses from raw rpc_admin_health metrics).
oauth_service.pyDiscord OAuth helpers: token exchange (proxy or direct), return_to validation, Discord JSON requests.
contact_threads.pyContact-message reads and serialization.
action_queue.pyOperator/supervisor action-queue logic: stale requeue, atomic claim, queue listing, Unix timestamp helpers.
discipline_queue.pyDiscipline delivery-queue logic: stale requeue, atomic claim, completion error mapping, delivery list.
training_engine.pyPure scenario-condition evaluation (objectives, evidence unlocks) with no database access.
training_service.pyTraining serializers, role/elapsed-time helpers, and request-scoped training reads.
training_runtime.pyTraining session orchestration: state machine, event recording + Realtime broadcast, session payload/list builders, trainer gates.

Authentication and authorization

FileResponsibility
authz.pyRank/clearance constants, API-key verification, browser-session agent resolution, permission checks, supervisor/reassign/Director gates, admin allowlist gate (require_admin).
oauth_service.pyOAuth flow helpers used by the /auth/* routes.

Database access

FileResponsibility
db_access.pyThe request-scoped supabase proxy, canonical table-name constants, low-level readers (db_get_*), Discord profile normalization/serialization, report/agent/punishment serializers, and identifier scrubbing.
environment.pyEnvironment configuration (production/demo), per-request environment resolution, environment-bound session cookies, request-scoped Supabase clients, optional HMAC ingress verification.
migrations/The ordered SQL migration chain (000034) — schema, RPCs, grants, RLS, triggers. See Migrations.
apply_rpc_migrations.pyMigration application helper: reads a connection string from db.url (or DB_URL), applies the chosen SQL files in order, and records them in schema_migrations.
demo_seed.pyCanonical fictional demo dataset and fail-closed demo reset tooling (demo environment only).

Integrations

FileResponsibility
erlc_relay.pyER:LC (Roblox game server) API client: relay selection, failover ordering, per-relay circuit breaker, player lookup.
cloudflare/ingress_worker.jsTrusted-ingress Worker: strips client-supplied environment headers and (when enabled) signs the HMAC ingress assertion.
discord-oauth-proxy/ (separate directory)The OAuth token-exchange Worker.
tools/erlc_relay/The local residential egress relay implementation used to reach the ER:LC API.

Supporting modules

FileResponsibility
request_limits.pyRequest body-size cap, report-ID validation, search-length bounds.
health_service.pyAdmin health formatting (see above).
*_tests.pyExecutable contract suites (see Testing).
ENVIRONMENT_DEPLOYMENT.mdProduction/demo environment isolation and deployment notes.
TRAINING_DEPLOYMENT.mdTraining Center deployment guide.
DB_OWNER_CONTRACTS.mdDatabase/RPC owner contracts for the hardening pass (actor identity, atomic transitions).
AUDIT_LOG_FINDINGS.mdAudit-log review findings that drove migrations 032–034.

ecc-dps-dashboard/ — the frontend

PathResponsibility
src/main.tsxEntry point: mounts App in StrictMode.
src/App.tsxRoute tree for the normal dashboard; selects the Training Center when the hostname is training.* or the path begins /training.
src/pages/Page components: Dashboard, Dockets, DocketDetail, Evidence, Analytics, Agents, Agentdetail, Queue, AuditLog, Punishments, PunishmentDetail, Admin, Settings, Login.
src/components/Shared components: AppLayout (sidebar/topbar), DiscordProfileCard/DiscordProfileModal, GlobalSearch, NotificationCenter, SensitiveField, AdminConfirmDialog, DataState, OverlayPortal.
src/lib/api/The API client and typed endpoint wrappers: client.ts (fetch + ApiError), auth.ts, reports.ts, agents.ts, admin.ts, punishments.ts, types.ts.
src/lib/Shared utilities: urlSafety.ts (URL sanitization), theme.tsx, toast.tsx, prefs.ts, format.ts, usePageTitle.ts, environment.ts, search/.
src/auth/AuthProvider.tsxSession state, permission flags, admin capabilities, sign-out.
src/training/The Training Center: TrainingApp.tsx (routes), TrainingRoleGate.tsx (role-branching shell), realtime.ts (Realtime hook), api.ts, types.ts, pages, and the TraineeInvestigation / TrainerControlCenter components.
tests/smoke/Playwright production smoke suites.
playwright/Config, global setup, session capture, and E2E/diagnostic scripts.
vite.config.tsVite config incl. the /api dev proxy and @/ alias.
tsconfig*.jsonTypeScript project configs.
DEMO_ENVIRONMENT.mdDemo environment runbook for the frontend.

discord-oauth-proxy/ — the OAuth Worker

PathResponsibility
src/index.jsCloudflare Worker: authenticates callers with X-Worker-Secret, forwards the authorization-code grant to Discord's token endpoint, returns the token response. Moves the outbound exchange off Render's shared IP.
wrangler.tomlWorker configuration (name, entrypoint, observability).

External dependencies

  • Supabase — PostgreSQL database, Realtime, and the PostgREST API surface used by the supabase Python client.
  • Render — hosts the Flask API.
  • Cloudflare Pages — hosts the dashboard bundle (and the docs site).
  • Cloudflare Workers — the OAuth proxy and the optional ingress Worker.
  • Discord (OAuth + BotGhost bot) — identity provider and the bot integration.
  • ER:LC API — Roblox game-server data used by the bot via the relay.

Where functionality lives — quick map

"Where do I find…"Location
Report lifecycle rulesreports_service.py + rpc_report_action in migrations 006/018/019/033/034
Investigation begin/concludereports_service.perform_report_action / conclude_investigation
Punishment recordspunishment_service.py + rpc_punishment_* in migration 029
Discipline delivery queuediscipline_queue.py + migration 030/031
Event taxonomyevent_service.EVENT_TYPES + migration 033
Permission policyauthz.CLEARANCE_POLICY + /auth/me
Admin gatesauthz.require_admin + admin_users (migration 009)
Training enginetraining_engine.py
Training runtimetraining_runtime.py
Realtime broadcasttraining_runtime._rt_broadcast + ecc-dps-dashboard/src/training/realtime.ts
URL sanitizationdb_access._validate_http_url + ecc-dps-dashboard/src/lib/urlSafety.ts