document_card.v1 row in
context.document_cards. The app had no read door for that row, so the Document Page could
not render the card as soon as it landed. This Story adds the read-only route and stops there.
The new app API endpoint is GET /app/documents/{doc_id}/document-card. It mirrors the
sibling GET /app/documents/{doc_id}/insight-brief route:
@router.get(
"/{doc_id}/document-card",
response_model=DocumentCard,
responses=AUTH_NOT_FOUND_VALIDATION_SERVER_RESPONSES,
)
async def get_document_card(...):
return await read_document_card(db, document_id=doc_id)
DocumentCard from src.shared.context_contracts. It does not redefine the card,
rename fields, or touch the Bug-2451 kind tolerance rules.
src/shared/context/card_read.py performs one firm-scoped read from
context.document_cards:
SELECT card
FROM context.document_cards
WHERE document_id = :document_id
The app route receives an AppDbDep session, so PostgreSQL RLS supplies the firm boundary,
exactly like the insight-brief read door. A missing row raises
PramaanNotFoundError with code pramaan.context.document_card_not_found, so a
not-yet-generated card returns a clean 404 rather than a 500 or empty payload.
| Surface | Result |
|---|---|
openapi/app-api.json |
Adds appGetDocumentCard with a DocumentCard 200 response and canonical error envelopes. |
openapi/permission-map.json |
Maps appGetDocumentCard to matters:read. |
openapi/admin-api.json |
No change; this is an app API route only. |
| Check | What it proves |
|---|---|
tests/contract/test_app_documents_openapi.py |
The generated schema exposes /document-card, operation id
appGetDocumentCard, DocumentCard response model, and
ErrorResponse 404 envelope. |
tests/integration/test_app_document_card_route.py |
DB-backed route coverage: no-card 404, stored card round-trip through the contract, and cross-firm 404 through RLS. |
scripts/generate_openapi.py and scripts/gen_permissions.py |
Regenerate producer snapshots for the new route and permission surface. |
Story-2456 walkthrough for pramaan-functions. Issue:
pramaan-spec#2456.