Story 1997: the Brief read DTO
pramaan-docs ADR-153 makes the boundary simple: Vega proposes facts, canonical tables own facts. This endpoint gives the Brief page one payload that keeps those authorities visible instead of merging them into one misleading blob.
The endpoint
GET /app/matters/{matter_id}/brief (matter_id = firm-local matter number)
200 {
"frame": current matter_frames version or null,
"locks": field locks + whole-frame freeze,
"canonical": parties, forum, case ref, value, outcome,
"clock": matter status + live proceeding stages
}
404 pramaan.matter.not_found // unknown OR cross-firm matter
What landed where
| Piece | Reason |
|---|---|
src/domains/matter_frame/dtos.py |
Defines the authority-labeled response: frame is proposed or counsel-authored, canonical is canonical truth, locks are live pin state, and clock comes from runtime tables. |
src/domains/matter_frame/service.py |
Assembles the Brief with fixed reads: matter anchor, current frame, locks, participants, Main proceeding forum, and live proceeding stages. It reuses the cached RLS app context when present and falls back to the session GUC for worker-style sessions. |
src/app_api/router_matters.py |
Adds GET /app/matters/{matter_id}/brief with an explicit response_model and canonical auth/not-found/error responses. |
tests/integration/test_app_matter_brief.py |
Exercises the real ASGI route against the isolated Postgres test DB, including empty first-run state, populated assembly, DTO round-trip, cross-firm 404, and bounded query budget. |
openapi/app-api.json |
Regenerated producer contract for the app mirror. |
Authority Labels
The response does not ask the frontend to infer legal authority from
position. The canonical.authority field is always
canonical. Agent-produced frames are labeled
proposed; counsel-authored frame versions are labeled
counsel. The raw envelope.frame,
envelope.resolution, and envelope.provenance
compartments are passed through as stored, so the read side does not
invent reconciliation state.
First Run
A matter with no
business.matter_frames row is a valid first
state. The endpoint returns frame: null, empty locks, and the
canonical/clock facts that already exist. It does not 404 a real matter
just because Vega has not produced a frame yet.
Verification
make test-db-reset && make test-db set -a; source .env.test-db; set +a; uv run pytest tests/integration/test_app_matter_brief.py -q uv run ruff check src/app_api/router_matters.py src/domains/matter_frame/service.py src/domains/matter_frame/dtos.py tests/integration/test_app_matter_brief.py make openapi