generated from john/python-template
5.0 KiB
5.0 KiB
System Architecture (Version 4)
This document defines the current V4 architecture baseline.
Architecture Objectives
- Preserve durable archival records for Documents, Sources, People, and processing runs.
- Execute page transcription asynchronously with bounded worker behavior.
- Preserve append-only machine-attempt evidence with request/response provenance.
- Keep UI, API, service, persistence, and provider boundaries explicit and testable.
Technical Stack
- Runtime: Python 3.12+
- Web application: FastAPI + NiceGUI
- Persistence: SQLModel / SQLAlchemy (SQLite-first, PostgreSQL-compatible model design)
- Validation and settings: Pydantic V2 + pydantic-settings
- Concurrency: asyncio worker loop
- Provider integration: OpenRouter adapter behind provider interface
- Quality and tests: Ruff, ty, pytest, pytest-asyncio
Runtime Topology
flowchart LR
U[Browser User] --> A[FastAPI + NiceGUI App]
A --> W[Asyncio Worker]
A --> DB[(SQLite/PostgreSQL Model)]
W --> P[Provider Adapter]
W --> DB
Layered Boundaries
Interface Layer
src/transcription/ui/**src/transcription/api/**
Responsibilities:
- Route registration, page orchestration, presentation adapters.
- Structured user messaging through shared error presenter.
- No direct persistence access from pages/components.
Service and Orchestration Layer
src/transcription/services/documents.pysrc/transcription/services/people.pysrc/transcription/services/jobs.pysrc/transcription/services/sources.pysrc/transcription/services/evidence.pysrc/transcription/services/store.pysrc/transcription/services/workflows.py
Responsibilities:
- Aggregate ownership and invariants.
- Transaction-aware write helpers.
- Cross-service workflows in orchestration modules (
store.py,workflows.py).
Persistence Layer
src/transcription/db/**
Responsibilities:
- SQLModel definitions, async session/engine runtime, registry bootstrap.
- Loader helpers that enforce explicit eager loading with
lazy="raise"relationships.
Provider Layer
src/transcription/providers/**
Responsibilities:
- Provider API encapsulation.
- Request manifest and transport evidence capture.
- Normalized transcription result contract.
Core Domain Model
Documentowns archival metadata and links toSource,Job, andDocumentPerson.Sourceis a document page/file record with selected machine projection and human revision.Jobis an aggregate processing run with status and frozen prompt/runtime settings.JobSourceis queue/membership state for one(job, source)pair.ExecutionAttemptis append-only evidence for each provider call.DocumentTypeandPersonRoleare UUID-backed registries with optional protectedsemantic_key.
Processing and Evidence Workflow
- User creates/updates Document metadata and linked People atomically through workflow orchestration.
- User creates a Job by uploading one or more Source files or by retranscribing an existing Source.
- Source files are validated and stored; orientation normalization may be applied at ingest, and stored bytes become the canonical processing bytes.
- Worker claims queued Job, transitions to
processing, and processes pending pages in deterministic order. - Each provider call writes one immutable
ExecutionAttemptwith:- request manifest + hash
- transport evidence (when response exists)
- SDK snapshot and normalized metadata
- outcome, timing, and error details when applicable
JobSourcestatus is updated as queue/projection state;Source.raw_transcriptionis set on first successful attempt and can be explicitly re-pointed by candidate promotion.- Job terminal status resolves to
transcribed,partial_success, orfailed.
Status Semantics
- Job statuses:
queued,processing,transcribed,completed,partial_success,failed- Operational success path currently resolves to
transcribed. completedremains a recognized legacy-compatible status value.
- Operational success path currently resolves to
- JobSource statuses:
pending,transcribed,failed,cancelled
Security and Path Handling Boundaries
- Print media delivery uses record-validated API route:
src/transcription/api/v4_print.py
- General UI media links resolve through:
src/transcription/ui/components/media_urls.py
- Local filesystem paths must never be accepted from user input as trusted media routes.
Concurrency and Reliability Principles
- Worker loop reuses service bundle/provider resources for pooled calls.
- Provider-call timeout is explicit and bounded.
- Non-retriable worker-loop faults are surfaced and stop loop spin.
- Per-page outcomes are durably persisted before processing next page.