# newnol/retain-pdf-en architecture

> Architecture diagram of the GitHub repository newnol/retain-pdf-en, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-28). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/newnol/retain-pdf-en
- Repository: https://github.com/newnol/retain-pdf-en

## Overview

RetainPDF is a full-stack tool for translating PDFs while preserving page layout, including scanned documents and complex inline formulas. Its main workflow is upload, job creation, OCR and document normalization, translation, layout reconstruction and PDF rendering, then artifact download or reading. The graph also includes job monitoring and diagnostics, OCR provider integrations, and artifact storage. README capabilities inform the end-to-end pipeline; sampled source confirms frontend job/upload behavior and artifact handling, but does not expose every backend or Python call, so uncertain links are omitted.

Main entry points: [`backend/rust_api/src/job_runner/mod.rs`](https://github.com/newnol/retain-pdf-en/blob/main/backend/rust_api/src/job_runner/mod.rs) (Job runner), [`backend/rust_api/src/routes/jobs/mod.rs`](https://github.com/newnol/retain-pdf-en/blob/main/backend/rust_api/src/routes/jobs/mod.rs) (Job endpoints), [`frontend/src/js/main.js`](https://github.com/newnol/retain-pdf-en/blob/main/frontend/src/js/main.js) (Web application), [`backend/rust_api/src/job_runner/ocr_flow/mod.rs`](https://github.com/newnol/retain-pdf-en/blob/main/backend/rust_api/src/job_runner/ocr_flow/mod.rs) (OCR processing)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_frontend["User interface"]
  node_frontend_app["Web application<br/>[main.js]"]
  node_upload_ui["Upload controls<br/>[controller.js]"]
  node_workflow_ui["Workflow actions<br/>[controller.js]"]
  node_job_ui["Job monitoring<br/>[controller.js]"]
  node_job_explorer["Job history<br/>[controller.js]"]
  node_reader["PDF reader<br/>[controller.js]"]
end

subgraph group_api["Rust API"]
  node_api["Rust API<br/>[router.rs]"]
  node_upload_route["Upload endpoint<br/>[uploads.rs]"]
  node_job_routes["Job endpoints<br/>[mod.rs]"]
  node_job_creation["Job creation<br/>[creation.rs]"]
  node_job_runner["Job runner<br/>[mod.rs]"]
  node_ocr_flow["OCR processing<br/>[mod.rs]"]
  node_translation_flow["Translation processing"]
  node_render_flow["Render processing<br/>[render_flow.rs]"]
  node_artifact_service["Artifact delivery<br/>[mod.rs]"]
end

subgraph group_pipeline["Document pipeline"]
  node_ocr_adapters["OCR normalization"]
  node_book_pipeline["Document workflow<br/>[book_pipeline.py]"]
  node_rendering["PDF reconstruction"]
end

subgraph group_integrations["External services"]
  node_ocr_services["OCR providers<br/>[catalog.rs]"]
  node_ocr_vendor{{"OCR services"}}
  node_translation_service{{"Translation service"}}
end

subgraph group_storage["Job data"]
  node_job_database[("Job records<br/>[db.rs]")]
  node_job_artifacts["Job artifacts<br/>[storage_paths.rs]"]
end

node_user(("PDF user"))

node_user -->|"uses"| node_frontend_app
node_frontend_app -->|"mounts"| node_upload_ui
node_frontend_app -->|"mounts"| node_workflow_ui
node_frontend_app -->|"mounts"| node_job_ui
node_frontend_app -->|"mounts"| node_job_explorer
node_frontend_app -->|"opens"| node_reader
node_upload_ui -->|"uploads PDF"| node_upload_route
node_workflow_ui -->|"submits job"| node_job_routes
node_job_ui -->|"polls and controls"| node_job_routes
node_job_explorer -->|"lists jobs"| node_job_routes
node_reader -->|"loads PDF"| node_artifact_service
node_api -->|"routes requests"| node_upload_route
node_api -->|"routes requests"| node_job_routes
node_job_routes -->|"creates jobs"| node_job_creation
node_job_creation -->|"launches jobs"| node_job_runner
node_job_runner -->|"runs OCR stage"| node_ocr_flow
node_job_runner -->|"runs translation stage"| node_translation_flow
node_job_runner -->|"runs render stage"| node_render_flow
node_ocr_flow -->|"selects provider"| node_ocr_services
node_ocr_services -.->|"sends OCR requests"| node_ocr_vendor
node_ocr_flow -->|"normalizes OCR"| node_ocr_adapters
node_job_runner -->|"invokes workflow"| node_book_pipeline
node_book_pipeline -.->|"requests translation"| node_translation_service
node_book_pipeline -->|"reconstructs pages"| node_rendering
node_job_routes -->|"reads and writes"| node_job_database
node_job_runner -->|"updates job state"| node_job_database
node_job_runner -->|"writes outputs"| node_job_artifacts
node_artifact_service -->|"reads files"| node_job_artifacts
node_job_routes -->|"serves downloads"| node_artifact_service

click node_frontend_app "https://github.com/newnol/retain-pdf-en/blob/main/frontend/src/js/main.js"
click node_upload_ui "https://github.com/newnol/retain-pdf-en/blob/main/frontend/src/js/features/upload/controller.js"
click node_workflow_ui "https://github.com/newnol/retain-pdf-en/blob/main/frontend/src/js/features/app-actions/controller.js"
click node_job_ui "https://github.com/newnol/retain-pdf-en/blob/main/frontend/src/js/features/job-runtime/controller.js"
click node_job_explorer "https://github.com/newnol/retain-pdf-en/blob/main/frontend/src/js/features/recent-jobs/controller.js"
click node_reader "https://github.com/newnol/retain-pdf-en/blob/main/frontend/src/js/features/reader-dialog/controller.js"
click node_api "https://github.com/newnol/retain-pdf-en/blob/main/backend/rust_api/src/app/router.rs"
click node_upload_route "https://github.com/newnol/retain-pdf-en/blob/main/backend/rust_api/src/routes/uploads.rs"
click node_job_routes "https://github.com/newnol/retain-pdf-en/blob/main/backend/rust_api/src/routes/jobs/mod.rs"
click node_job_creation "https://github.com/newnol/retain-pdf-en/blob/main/backend/rust_api/src/services/jobs/creation.rs"
click node_job_runner "https://github.com/newnol/retain-pdf-en/blob/main/backend/rust_api/src/job_runner/mod.rs"
click node_ocr_flow "https://github.com/newnol/retain-pdf-en/blob/main/backend/rust_api/src/job_runner/ocr_flow/mod.rs"
click node_translation_flow "https://github.com/newnol/retain-pdf-en/blob/main/backend/rust_api/src/job_runner/translation_flow.rs"
click node_render_flow "https://github.com/newnol/retain-pdf-en/blob/main/backend/rust_api/src/job_runner/render_flow.rs"
click node_ocr_adapters "https://github.com/newnol/retain-pdf-en/blob/main/backend/scripts/services/document_schema/normalize_pipeline.py"
click node_book_pipeline "https://github.com/newnol/retain-pdf-en/blob/main/backend/scripts/runtime/pipeline/book_pipeline.py"
click node_rendering "https://github.com/newnol/retain-pdf-en/blob/main/backend/scripts/services/rendering/render_only_pipeline.py"
click node_ocr_services "https://github.com/newnol/retain-pdf-en/blob/main/backend/rust_api/src/ocr_provider/catalog.rs"
click node_job_database "https://github.com/newnol/retain-pdf-en/blob/main/backend/rust_api/src/db.rs"
click node_job_artifacts "https://github.com/newnol/retain-pdf-en/blob/main/backend/rust_api/src/storage_paths.rs"
click node_artifact_service "https://github.com/newnol/retain-pdf-en/blob/main/backend/rust_api/src/services/artifacts/mod.rs"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_frontend_app,node_upload_ui,node_workflow_ui,node_job_ui,node_job_explorer,node_reader,node_user toneBlue
class node_api,node_upload_route,node_job_routes,node_job_creation,node_job_runner,node_ocr_flow,node_translation_flow,node_render_flow,node_artifact_service toneAmber
class node_ocr_adapters,node_book_pipeline,node_rendering toneMint
class node_ocr_services,node_ocr_vendor,node_translation_service toneRose
class node_job_database,node_job_artifacts toneIndigo
```

## Components

### User interface

- [Web application](https://github.com/newnol/retain-pdf-en/blob/main/frontend/src/js/main.js): `frontend/src/js/main.js`
- [Upload controls](https://github.com/newnol/retain-pdf-en/blob/main/frontend/src/js/features/upload/controller.js): `frontend/src/js/features/upload/controller.js`
- [Workflow actions](https://github.com/newnol/retain-pdf-en/blob/main/frontend/src/js/features/app-actions/controller.js): `frontend/src/js/features/app-actions/controller.js`
- [Job monitoring](https://github.com/newnol/retain-pdf-en/blob/main/frontend/src/js/features/job-runtime/controller.js): `frontend/src/js/features/job-runtime/controller.js`
- [Job history](https://github.com/newnol/retain-pdf-en/blob/main/frontend/src/js/features/recent-jobs/controller.js): `frontend/src/js/features/recent-jobs/controller.js`
- [PDF reader](https://github.com/newnol/retain-pdf-en/blob/main/frontend/src/js/features/reader-dialog/controller.js): `frontend/src/js/features/reader-dialog/controller.js`

### Rust API

- [Rust API](https://github.com/newnol/retain-pdf-en/blob/main/backend/rust_api/src/app/router.rs): `backend/rust_api/src/app/router.rs`
- [Upload endpoint](https://github.com/newnol/retain-pdf-en/blob/main/backend/rust_api/src/routes/uploads.rs): `backend/rust_api/src/routes/uploads.rs`
- [Job endpoints](https://github.com/newnol/retain-pdf-en/blob/main/backend/rust_api/src/routes/jobs/mod.rs): `backend/rust_api/src/routes/jobs/mod.rs`
- [Job creation](https://github.com/newnol/retain-pdf-en/blob/main/backend/rust_api/src/services/jobs/creation.rs): `backend/rust_api/src/services/jobs/creation.rs`
- [Job runner](https://github.com/newnol/retain-pdf-en/blob/main/backend/rust_api/src/job_runner/mod.rs): `backend/rust_api/src/job_runner/mod.rs`
- [OCR processing](https://github.com/newnol/retain-pdf-en/blob/main/backend/rust_api/src/job_runner/ocr_flow/mod.rs): `backend/rust_api/src/job_runner/ocr_flow/mod.rs`
- [Translation processing](https://github.com/newnol/retain-pdf-en/blob/main/backend/rust_api/src/job_runner/translation_flow.rs): `backend/rust_api/src/job_runner/translation_flow.rs`
- [Render processing](https://github.com/newnol/retain-pdf-en/blob/main/backend/rust_api/src/job_runner/render_flow.rs): `backend/rust_api/src/job_runner/render_flow.rs`
- [Artifact delivery](https://github.com/newnol/retain-pdf-en/blob/main/backend/rust_api/src/services/artifacts/mod.rs): `backend/rust_api/src/services/artifacts/mod.rs`

### Document pipeline

- [OCR normalization](https://github.com/newnol/retain-pdf-en/blob/main/backend/scripts/services/document_schema/normalize_pipeline.py): `backend/scripts/services/document_schema/normalize_pipeline.py`
- [Document workflow](https://github.com/newnol/retain-pdf-en/blob/main/backend/scripts/runtime/pipeline/book_pipeline.py): `backend/scripts/runtime/pipeline/book_pipeline.py`
- [PDF reconstruction](https://github.com/newnol/retain-pdf-en/blob/main/backend/scripts/services/rendering/render_only_pipeline.py): `backend/scripts/services/rendering/render_only_pipeline.py`

### External services

- [OCR providers](https://github.com/newnol/retain-pdf-en/blob/main/backend/rust_api/src/ocr_provider/catalog.rs): `backend/rust_api/src/ocr_provider/catalog.rs`
- **OCR services**
- **Translation service**

### Job data

- [Job records](https://github.com/newnol/retain-pdf-en/blob/main/backend/rust_api/src/db.rs): `backend/rust_api/src/db.rs`
- [Job artifacts](https://github.com/newnol/retain-pdf-en/blob/main/backend/rust_api/src/storage_paths.rs): `backend/rust_api/src/storage_paths.rs`

### Other components

- **PDF user**

## Connections

- PDF user → Web application: uses
- Web application → Upload controls: mounts
- Web application → Workflow actions: mounts
- Web application → Job monitoring: mounts
- Web application → Job history: mounts
- Web application → PDF reader: opens
- Upload controls → Upload endpoint: uploads PDF
- Workflow actions → Job endpoints: submits job
- Job monitoring → Job endpoints: polls and controls
- Job history → Job endpoints: lists jobs
- PDF reader → Artifact delivery: loads PDF
- Rust API → Upload endpoint: routes requests
- Rust API → Job endpoints: routes requests
- Job endpoints → Job creation: creates jobs
- Job creation → Job runner: launches jobs
- Job runner → OCR processing: runs OCR stage
- Job runner → Translation processing: runs translation stage
- Job runner → Render processing: runs render stage
- OCR processing → OCR providers: selects provider
- OCR providers → OCR services: sends OCR requests
- OCR processing → OCR normalization: normalizes OCR
- Job runner → Document workflow: invokes workflow
- Document workflow → Translation service: requests translation
- Document workflow → PDF reconstruction: reconstructs pages
- Job endpoints → Job records: reads and writes
- Job runner → Job records: updates job state
- Job runner → Job artifacts: writes outputs
- Artifact delivery → Job artifacts: reads files
- Job endpoints → Artifact delivery: serves downloads
