# Architecture (V1 Baseline) This document describes the current architecture of the personal historical-document transcription system and serves as the V1 technical baseline. ## Architecture Objectives - preserve source material as transcribed text - keep operational complexity low for personal-scale deployment - support asynchronous processing without external queue infrastructure - maintain clear module boundaries for incremental extension ## Runtime Topology V1 runtime is a modular monolith: - one FastAPI + NiceGUI application process - one in-process async worker loop - relational persistence via SQLModel (SQLite baseline) ```mermaid flowchart LR U[Browser User] --> A[FastAPI + NiceGUI App] A --> W[In-process Worker] A --> DB[(SQLite via SQLModel)] W --> P[OpenRouter Provider] W --> DB ``` ## Lifecycle Ownership Application lifespan owns runtime setup/teardown: - configure logging - initialize and dispose DB runtime resources - optional schema bootstrap by environment policy - recover stale processing jobs - start/stop worker consumer lifespan ## Layered Module Structure ### Interface Layer - `src/transcription/ui/**` (NiceGUI pages/components) - `src/transcription/api/**` (FastAPI routes and error handlers) ### Application/Workflow Layer - `src/transcription/services/workflows.py` - `src/transcription/worker.py` Responsibilities: - orchestration and status transitions - retry/timeout behavior - provider call coordination ### Service Layer - `src/transcription/services/*.py` Responsibilities: - CRUD and transactional boundaries - domain-aligned persistence operations ### Infrastructure Layer - `src/transcription/db/**` (runtime/session/bootstrap) - `src/transcription/providers/**` (OpenRouter adapter) ## Processing Workflow 1. User uploads a source file from the UI. 2. App persists `Document`, `Job(queued)`, and `Source`. 3. Worker claims next queued job and marks `processing`. 4. Worker calls provider with prompt + source bytes. 5. On success, app writes immutable `Job.text` and marks `transcribed`. 6. On failure, app writes `Job.error_detail` and marks `failed`. 7. UI exposes job detail, original transcription, and optional revision. ## Domain Ownership Invariants - `Job.text` is immutable original provider output. - `Revision` is optional, user-authored, and linked to `Source`. - `Revision` does not overwrite original job transcription. - Status lifecycle is fixed to: `queued -> processing -> transcribed|failed`. ## Data Model Summary - `Document` has many `Source` and many `Job`. - `Source` belongs to one `Document` and one `Job`. - `Source` has optional `Revision` (`0..1`) enforced by unique `revision.source_id`. ## Simplicity Guardrails (V1) - no external queue/broker required - no search engine required - no distributed worker fleet required - keep provider integration behind adapter boundary ## Extension Path ### V1 (current) - SQLite baseline - OpenRouter provider - in-process worker - optional single revision workflow ### V2 (planned) - PostgreSQL as relational baseline - optional MongoDB adjunct store for scoped use cases - migration-first schema evolution See [ver2/ver2.md](ver2/ver2.md) for roadmap details. ## Test Strategy - unit tests for model/service behaviors - integration tests for upload/workflow reliability - UI integration tests for page/render contracts - external provider tests opt-in via marker/config ## Related References - [index.md](index.md) - [requirements.md](requirements.md) - [schema.md](schema.md) - [error_handling.md](error_handling.md)