docs(c4): add L3 backend 3e persons, 3f OCR, 3g supporting domains
This commit is contained in:
30
docs/architecture/c4/l3-backend-3e-persons.puml
Normal file
30
docs/architecture/c4/l3-backend-3e-persons.puml
Normal file
@@ -0,0 +1,30 @@
|
||||
@startuml
|
||||
!include <C4/C4_Component>
|
||||
|
||||
title Component Diagram: API Backend — Persons & Family Graph
|
||||
|
||||
Container(frontend, "Web Frontend", "SvelteKit")
|
||||
ContainerDb(db, "PostgreSQL", "PostgreSQL 16")
|
||||
|
||||
System_Boundary(backend, "API Backend (Spring Boot)") {
|
||||
Component(personCtrl, "PersonController", "Spring MVC — /api/persons", "Lists and searches family members. Returns documents sent by or received by a person, correspondent suggestions, and person summary with document counts.")
|
||||
Component(relCtrl, "RelationshipController", "Spring MVC — /api/network, /api/persons/{id}/relationships", "CRUD for explicit person relationships and the full family network graph (nodes + edges) used by the Stammbaum view.")
|
||||
Component(personSvc, "PersonService", "Spring Service", "Person CRUD, alias management, and merge operations (reassigns all document sender/receiver references before deleting duplicate persons).")
|
||||
Component(relSvc, "RelationshipService", "Spring Service", "Manages explicit directional family relationships (PARENT_OF, SPOUSE_OF, SIBLING_OF, etc.) with optional date ranges and notes.")
|
||||
Component(relInference, "RelationshipInferenceService", "Spring Service", "Computes transitive family relationships from explicit edges to infer grandparent/grandchild, aunt/uncle, and other extended-family links for the network graph.")
|
||||
Component(personRepo, "PersonRepository", "Spring Data JPA", "Queries persons with name search (including aliases), correspondent discovery, person summaries with document counts, and merge/reassignment helpers.")
|
||||
Component(relRepo, "PersonRelationshipRepository", "Spring Data JPA", "Reads and writes PersonRelationship records. Supports lookup by person ID, by relation type, and existence checks for deduplication.")
|
||||
}
|
||||
|
||||
Rel(frontend, personCtrl, "Person requests", "HTTP / JSON")
|
||||
Rel(frontend, relCtrl, "Relationship and graph requests", "HTTP / JSON")
|
||||
Rel(personCtrl, personSvc, "Delegates to")
|
||||
Rel(relCtrl, relSvc, "Delegates to")
|
||||
Rel(relCtrl, relInference, "Queries inferred graph")
|
||||
Rel(personSvc, personRepo, "Reads / writes persons")
|
||||
Rel(relSvc, relRepo, "Reads / writes relationships")
|
||||
Rel(relInference, relRepo, "Reads relationships for inference")
|
||||
Rel(personRepo, db, "SQL queries", "JDBC")
|
||||
Rel(relRepo, db, "SQL queries", "JDBC")
|
||||
|
||||
@enduml
|
||||
41
docs/architecture/c4/l3-backend-3f-ocr.puml
Normal file
41
docs/architecture/c4/l3-backend-3f-ocr.puml
Normal file
@@ -0,0 +1,41 @@
|
||||
@startuml
|
||||
!include <C4/C4_Component>
|
||||
|
||||
title Component Diagram: API Backend — OCR Orchestration
|
||||
|
||||
Container(frontend, "Web Frontend", "SvelteKit")
|
||||
ContainerDb(db, "PostgreSQL", "PostgreSQL 16")
|
||||
ContainerDb(minio, "Object Storage", "MinIO (S3-compatible)")
|
||||
Container(ocrPy, "OCR Service", "Python FastAPI")
|
||||
|
||||
System_Boundary(backend, "API Backend (Spring Boot)") {
|
||||
Component(ocrCtrl, "OcrController", "Spring MVC — /api/ocr", "REST entry point: trigger single or batch OCR jobs, stream progress via SSE, query job status, and manage training runs and per-sender models.")
|
||||
Component(ocrSvc, "OcrService", "Spring Service", "Creates OcrJob and OcrJobDocument records, checks Python service health, and delegates async execution to OcrAsyncRunner.")
|
||||
Component(ocrBatch, "OcrBatchService", "Spring Service", "Orchestrates multi-document OCR jobs, iterating documents and delegating each to OcrAsyncRunner.")
|
||||
Component(ocrAsync, "OcrAsyncRunner", "Spring Component — @Async", "Async worker that streams OCR results from Python page by page, persists transcription blocks and annotations via domain services, and emits progress via SSE.")
|
||||
Component(ocrClient, "RestClientOcrClient", "Spring Component", "HTTP client wrapping the Python service: POST /ocr/stream (NDJSON), /train, /segtrain, and /train-sender. Falls back from streaming to batch on 404.")
|
||||
Component(ocrTraining, "OcrTrainingService", "Spring Service", "Orchestrates model training: exports training data as ZIP, calls Python /train or /segtrain, persists training metrics in OcrTrainingRunRepository.")
|
||||
Component(ocrJobRepo, "OcrJobRepository, OcrJobDocumentRepository", "Spring Data JPA", "Reads and writes OcrJob and OcrJobDocument records. Tracks job status (RUNNING/DONE/FAILED), per-document progress, page counts, and error messages.")
|
||||
}
|
||||
|
||||
Component(transcriptionSvc, "TranscriptionService", "Spring Service", "See diagram 3c. Called by OcrAsyncRunner to persist transcription blocks per page.")
|
||||
Component(annotationSvc, "AnnotationService", "Spring Service", "See diagram 3c. Called by OcrAsyncRunner to persist OCR-generated annotation regions per page.")
|
||||
|
||||
Rel(frontend, ocrCtrl, "OCR trigger, status, and progress requests", "HTTP / JSON / SSE")
|
||||
Rel(ocrCtrl, ocrSvc, "Single-document jobs")
|
||||
Rel(ocrCtrl, ocrBatch, "Batch jobs")
|
||||
Rel(ocrCtrl, ocrTraining, "Training runs")
|
||||
Rel(ocrSvc, ocrAsync, "Delegates async execution")
|
||||
Rel(ocrBatch, ocrAsync, "Delegates async execution")
|
||||
Rel(ocrAsync, ocrClient, "Streams OCR results page by page", "HTTP / NDJSON")
|
||||
Rel(ocrTraining, ocrClient, "Sends training data ZIP", "HTTP / multipart")
|
||||
Rel(ocrClient, ocrPy, "POST /ocr/stream, /train, /segtrain, /train-sender", "HTTP / REST")
|
||||
Rel(ocrAsync, transcriptionSvc, "Saves transcription blocks per page")
|
||||
Rel(ocrAsync, annotationSvc, "Saves annotation regions per page")
|
||||
Rel(ocrAsync, ocrJobRepo, "Reads / writes OCR job state")
|
||||
Rel(ocrJobRepo, db, "SQL queries", "JDBC")
|
||||
Rel(ocrAsync, minio, "Generates presigned URLs for PDF fetch", "S3 API")
|
||||
Rel(ocrPy, minio, "Fetches PDF via presigned URL", "HTTP / S3 presigned")
|
||||
Rel(ocrTraining, db, "Persists training run metrics", "JDBC")
|
||||
|
||||
@enduml
|
||||
46
docs/architecture/c4/l3-backend-3g-supporting.puml
Normal file
46
docs/architecture/c4/l3-backend-3g-supporting.puml
Normal file
@@ -0,0 +1,46 @@
|
||||
@startuml
|
||||
!include <C4/C4_Component>
|
||||
|
||||
title Component Diagram: API Backend — Supporting Domains
|
||||
|
||||
Container(frontend, "Web Frontend", "SvelteKit")
|
||||
ContainerDb(db, "PostgreSQL", "PostgreSQL 16")
|
||||
|
||||
System_Boundary(backend, "API Backend (Spring Boot)") {
|
||||
Component(auditSvc, "AuditService", "Spring Service — @Async", "Writes audit log entries asynchronously via a dedicated TaskExecutor, with transaction-aware logging to prevent deadlocks on concurrent saves.")
|
||||
Component(auditQuery, "AuditLogQueryService", "Spring Service", "Queries audit logs for activity feeds, pulse stats, recent contributors, and per-document history. Facade over AuditLogRepository.")
|
||||
Component(dashCtrl, "DashboardController", "Spring MVC — /api/dashboard", "REST endpoints for the user dashboard: recent document resume (/resume), weekly transcription pulse stats (/pulse), and activity feed (/activity) with kind filtering and pagination.")
|
||||
Component(statsCtrl, "StatsController", "Spring MVC — /api/stats", "Returns aggregate counts (total persons, total documents) for the UI stats bar.")
|
||||
Component(statsSvc, "StatsService", "Spring Service", "Queries aggregate counts: total persons and total documents.")
|
||||
Component(dashSvc, "DashboardService", "Spring Service", "Assembles the user dashboard: recent document resume (calls DocumentService + TranscriptionService), weekly transcription pulse stats, and activity feed with contributor avatars.")
|
||||
Component(notifCtrl, "NotificationController", "Spring MVC — /api/notifications", "REST and SSE endpoints for notification stream, history with filtering, read/unread state, and per-user preference management.")
|
||||
Component(notifSvc, "NotificationService", "Spring Service", "Creates REPLY and MENTION notifications, optionally sends email, marks as read, and pushes events to connected clients via SseEmitterRegistry.")
|
||||
Component(sseRegistry, "SseEmitterRegistry", "Spring Component", "In-memory ConcurrentHashMap of Spring SseEmitter instances per user. Handles registration, deregistration, and JSON event broadcasts.")
|
||||
Component(geschCtrl, "GeschichteController", "Spring MVC — /api/geschichten", "CRUD for publishable stories that link persons and documents. Requires BLOG_WRITE permission for write operations.")
|
||||
Component(geschSvc, "GeschichteService", "Spring Service", "Manages story lifecycle (DRAFT → PUBLISHED with timestamp). Sanitizes HTML body with an allowlist policy.")
|
||||
Component(exHandler, "GlobalExceptionHandler", "Spring @RestControllerAdvice", "Converts DomainException, validation errors, and generic exceptions to ErrorResponse JSON with machine-readable ErrorCode and HTTP status.")
|
||||
}
|
||||
|
||||
Component(documentSvc, "DocumentService", "Spring Service", "See diagram 3b. Called by DashboardService to fetch document titles and resume data.")
|
||||
Component(transcriptionSvc, "TranscriptionService", "Spring Service", "See diagram 3c. Called by DashboardService to fetch transcription block progress for resume.")
|
||||
|
||||
Rel(frontend, dashCtrl, "Dashboard requests", "HTTP / JSON")
|
||||
Rel(frontend, statsCtrl, "GET /api/stats", "HTTP / JSON")
|
||||
Rel(frontend, notifCtrl, "Notification stream and history", "HTTP / JSON / SSE")
|
||||
Rel(frontend, geschCtrl, "Story requests", "HTTP / JSON")
|
||||
Rel(dashCtrl, dashSvc, "Delegates to")
|
||||
Rel(statsCtrl, statsSvc, "Delegates to")
|
||||
Rel(statsSvc, db, "Reads aggregate counts", "JDBC")
|
||||
Rel(dashSvc, auditQuery, "Fetches activity feed and pulse stats")
|
||||
Rel(dashSvc, documentSvc, "Fetches document titles and resume data")
|
||||
Rel(dashSvc, transcriptionSvc, "Fetches transcription block progress for resume")
|
||||
Rel(notifCtrl, notifSvc, "Delegates to")
|
||||
Rel(notifCtrl, sseRegistry, "Registers client SSE connection")
|
||||
Rel(notifSvc, sseRegistry, "Broadcasts events to connected clients")
|
||||
Rel(geschCtrl, geschSvc, "Delegates to")
|
||||
Rel(auditSvc, db, "Writes audit_log", "JDBC")
|
||||
Rel(auditQuery, db, "Reads audit_log", "JDBC")
|
||||
Rel(notifSvc, db, "Reads / writes notifications", "JDBC")
|
||||
Rel(geschSvc, db, "Reads / writes geschichten", "JDBC")
|
||||
|
||||
@enduml
|
||||
Reference in New Issue
Block a user