Files
transcription/docs/api_qa.md
T

6.0 KiB

API Questions & Answers

Question

what is v4_documents.py?

Response

v4_documents.py is the new additive V4 API router I added in Phase 4.

What it does:

  • Defines V4 endpoints under /api/v4 for registry-driven document/relationship workflows.
  • Exposes read endpoints for catalogs:
    • GET /api/v4/document-types
    • GET /api/v4/person-roles
  • Exposes write endpoints for code-or-id updates:
    • PUT /api/v4/documents/{document_id}/type
    • POST /api/v4/documents/{document_id}/people
    • PATCH /api/v4/document-people/{document_person_id}
    • DELETE /api/v4/document-people/{document_person_id}
  • Uses DocumentService methods as the backend (no direct DB access in the route layer).
  • Returns typed request/response models for backward-compatible, additive API evolution.

It is registered in app.py, so it is live when the app starts.

If you want, I can walk endpoint-by-endpoint with examples of request/response payloads.


Question

Please do

Response

Absolutely. Here is a quick endpoint-by-endpoint walkthrough of v4_documents.py, with practical request/response examples.

What This Router Is

  • Prefix: /api/v4
  • Purpose: additive V4 contract for:
  1. Registry catalogs (document types, person roles)
  2. Role-aware document-person linking
  3. Code-or-id document type assignment
  • It delegates to DocumentService and does not access DB sessions directly in route handlers.

Dependency Wiring

  • Route dependency: get_document_service in v4_documents.py
  • Behavior:
  1. Uses app.state.services.documents when running in the app lifecycle
  2. Falls back to a direct DocumentService() instance if needed (useful in isolated tests)

1) List Document Types

  • Endpoint: GET /api/v4/document-types
  • Query param: active_only=true by default
  • Backing service call: list_document_types(active_only=...)
  • Response shape: [ { "id": "uuid", "code": "letter", "label": "Letter", "is_active": true, "sort_order": 0 } ]

2) List Person Roles

  • Endpoint: GET /api/v4/person-roles
  • Query param: active_only=true by default
  • Backing service call: list_person_roles(active_only=...)
  • Response shape: [ { "id": "uuid", "code": "author", "label": "Author", "is_active": true } ]

3) Set Document Type (By Id Or Code)

  • Endpoint: PUT /api/v4/documents/{document_id}/type
  • Body options:
  1. document_type_id
  2. document_type_code
  • Rule: provide one selector, not both
  • Example request: { "document_type_code": "record" }
  • Example response: { "document_id": "uuid", "document_type_id": "uuid", "document_type_code": "record" }

4) List Document-Person Links For A Document

  • Endpoint: GET /api/v4/documents/{document_id}/people
  • Backing service call: list_document_people(document_id=...)
  • Example response: { "document_id": "uuid", "links": [ { "id": "uuid", "document_id": "uuid", "person_id": "uuid", "role_id": "uuid", "role_code": "author", "person_name": "Zenna Cochran" } ] }

5) Add A Document-Person Link

  • Endpoint: POST /api/v4/documents/{document_id}/people
  • Body fields:
  1. person_id required
  2. role_id optional
  3. role_code optional
  • If duplicate document/person/role link is attempted, returns conflict envelope via shared error handlers.
  • Example request: { "person_id": "uuid", "role_code": "mentioned" }
  • Example success response: { "id": "uuid", "document_id": "uuid", "person_id": "uuid", "role_id": "uuid", "role_code": "mentioned", "person_name": "Ada Lovelace" }

6) Update Link Role

  • Endpoint: PATCH /api/v4/document-people/{document_person_id}
  • Body options:
  1. role_id
  2. role_code
  • Rule: provide one selector, not both
  • Example request: { "role_code": "recipient" }
  • Example response: { "id": "uuid", "document_id": "uuid", "person_id": "uuid", "role_id": "uuid", "role_code": "recipient", "person_name": "Ada Lovelace" }

7) Delete Link

  • Endpoint: DELETE /api/v4/document-people/{document_person_id}
  • Response: HTTP 204 No Content

Error Behavior

  • Uses shared registration in errors.py
  • So AppError categories map to consistent envelope + status codes:
  1. validation_error -> 400
  2. not_found_error -> 404
  3. conflict_error -> 409
  4. internal_unexpected_error -> 500

Where It Gets Mounted

  • Included in app factory at app.py
  • That makes all /api/v4 endpoints available during normal app startup.

If you want, next I can generate a compact curl-style smoke checklist for all 7 endpoints so you can test them in under 2 minutes.


Question

Should there be one of these for people, jobs, and sources too?

Response

Short answer: yes, but not all at once.

Given your V4 scope, the strongest split is:

  1. Keep v4_documents.py for document-centric workflows
    This file already owns:
  • document type catalog/use
  • document-person role links
  • document-level relationship mutations
  1. Add a V4 people router next
    Recommended new file:
  • src/transcription/api/v4_people.py

Why:

  • You likely need person-centric queries and updates that are not naturally document-scoped
  • It keeps API boundaries clearer as UI grows
  1. Do not rush a separate jobs/sources V4 router unless contracts are diverging
    For now, jobs and sources are still tightly tied to the existing transcription pipeline behavior. A new v4_jobs or v4_sources router is useful only when you need genuinely new contract shape, such as:
  • job lifecycle contract changes
  • source revision/audit contract changes
  • new pagination/filtering semantics incompatible with current endpoints

Practical rule of thumb:

  1. New router if the domain has new V4 semantics and independent lifecycle
  2. Keep existing router if only additive fields are needed

Suggested target structure:

  1. v4_documents.py
  2. src/transcription/api/v4_people.py
  3. optional later: src/transcription/api/v4_jobs.py
  4. optional later: src/transcription/api/v4_sources.py

If you want, I can scaffold v4_people next with additive endpoints that mirror your current service capabilities and keep error envelope behavior consistent.