Every mapped table resolves a retention policy; a report-only job runs over all of them and logs "N records to purge". ARCH §6.4; NIST AU-11, SI-12; source RFP C.5.7.42. - framework/retention.py: RetentionPolicy (data class, disposal, period, anchor column, cadence, approved, authority), run_retention(), and a `python -m ypms.framework.retention` entrypoint. Phase 0 never mutates data: interim-period rows are counted (interim_eligible), approved-period rows are counted (to_purge), nothing is purged. One retention_run audit row per run. - retention_classes.py: PIA §9 data classes at their interim periods, all approved=False pending YPMS-POAM-054. Classes without a PIA basis (hosts, operational logs, accounts, consent-derived) are unset and logged by name with their governing POA&M item. Vendored framework tables are mapped by table name so vendored files stay unchanged. - stub_models.py + migration 0004: id + mixin models for the 26 stub entities so each can carry a policy. Migration uses a literal table list. - ypms/models.py: single import-all module used by Alembic env, the job, and the test fixtures. - Drift guard: test upgrades a scratch SQLite DB to head and compares to Base.metadata. Found pre-existing drift in 0002 (named unique constraints duplicating the unique indexes on roles.code, users.username, users.email); allow-listed, follow-up noted in PHASE0_STATUS. 156 tests passing; ruff + mypy clean. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
YPMS — Youth Program Management System
DC Department of Employment Services / Office of Youth Programs — in-house build replacing seven legacy tools (MBSYEP intake, TMS timekeeping, PF3 admin, manual payroll scripts, MicroStrategy, and two supporting apps) with a single Python / FastAPI / Postgres system on Azure Government.
Status: Pre-development. Phase 0 (foundations) in flight.
System owner + ISSO + AO: Chris Tonjes, DOES CIO.
Full context: OVERVIEW.md, ARCHITECTURE.md, PHASE0_PLAN.md.
Quickstart (local)
Requires Docker Desktop (or equivalent). Ports 8000 (app), 5433 (Postgres), 8081 (Adminer) must be free.
cp .env.example .env
docker compose up --build
App at http://localhost:8000. OpenAPI docs at http://localhost:8000/docs.
curl http://localhost:8000/healthz # → {"status":"ok"}
curl http://localhost:8000/readyz # → {"status":"ok"} once db is up
Adminer (DB explorer) at http://localhost:8081. Connect with:
- System: PostgreSQL
- Server:
db - Username / Password / Database:
ypms/ypms/ypms
Stop with Ctrl+C; wipe local DB with docker compose down -v.
Tests
Local (no Docker required for the tests):
python -m venv .venv && source .venv/bin/activate
pip install -e '.[dev]'
pytest
Coverage:
pytest --cov=src/ypms --cov-report=term-missing
Tests use SQLite in-memory for speed. Postgres-specific behaviour gets its own Postgres-only fixture when a migration or query needs it (see ARCHITECTURE.md §4.8).
Repo shape
Full tree in ARCHITECTURE.md §5.1. High points:
src/ypms/main.py— FastAPI factorysrc/ypms/settings.py— pydantic-settings configsrc/ypms/db.py— SQLAlchemy engine, session,Basesrc/ypms/logging.py— structlog + sensitive-field sanitizersrc/ypms/middleware.py— request idsrc/ypms/framework/— vendored from OWC, milestone 0.2src/ypms/security/— auth + RBAC + column encryption, milestones 0.3–0.4src/ypms/youth/— Registrant entity (vertical slice), milestone 0.5- Other entity packages — 501 stubs, milestone 0.6
migrations/— Alembic, immutable-once-mergedtests/— pytest, SQLite by default
Adding an entity
Once the framework lands in milestone 0.2, adding a new entity follows the OWC add-entity pattern (model → schemas → router → main.py registration → migration → permissions seed entry → test → coverage doc). Full instructions land here at milestone 0.2 completion.
Contributing
See CONTRIBUTING.md for the hard rules. Highlights: migrations are immutable once merged, every state-mutating route emits an audit row, framework/security modules must not carry domain logic, no --no-verify or # type: ignore without a written reason.
Compliance
SYSTEM_SECURITY_PLAN.mdv0.3 — NIST 800-53 Moderate SSPNIST_800_53_CONTROL_MAPPING.mdv0.2 — full control-family mapPRIVACY_IMPACT_ASSESSMENT.mdv0.1 — PIA covering minors, SSN, banking, FERPA, CFSAPOAM.mdv0.1 — POA&M with 62 items and 2 closures as of 2026-09-30
License / usage
Internal DOES system. Not for external distribution.