From 9387fcc17b5737bdb09258edeb6d763282acdd3e Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 6 May 2026 21:25:53 +0200 Subject: [PATCH] docs(c4): add L3 backend 3a security and 3b document management --- .../c4/l3-backend-3a-security.puml | 21 ++++++++++ .../c4/l3-backend-3b-document-management.puml | 40 +++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 docs/architecture/c4/l3-backend-3a-security.puml create mode 100644 docs/architecture/c4/l3-backend-3b-document-management.puml diff --git a/docs/architecture/c4/l3-backend-3a-security.puml b/docs/architecture/c4/l3-backend-3a-security.puml new file mode 100644 index 00000000..33e41dc9 --- /dev/null +++ b/docs/architecture/c4/l3-backend-3a-security.puml @@ -0,0 +1,21 @@ +@startuml +!include + +title Component Diagram: API Backend — Security & Authentication + +Container(frontend, "Web Frontend", "SvelteKit") +ContainerDb(db, "PostgreSQL", "PostgreSQL 16") + +System_Boundary(backend, "API Backend (Spring Boot)") { + Component(secFilter, "Security Filter Chain", "Spring Security", "Enforces authentication on all requests. Parses Basic Auth header and constructs an Authentication token; delegates credential validation to DaoAuthenticationProvider via BCrypt. Permits password-reset, invite, and register endpoints without authentication.") + Component(permAspect, "PermissionAspect", "Spring AOP", "Intercepts methods annotated with @RequirePermission. Checks user's granted authorities against the required permission. Throws 401/403 if denied.") + Component(secConf, "SecurityConfig", "Spring @Configuration", "Configures filter chain: all routes require authentication, CSRF disabled, BCrypt password encoder, DaoAuthenticationProvider with CustomUserDetailsService.") + Component(userDetails, "CustomUserDetailsService", "Spring Security UserDetailsService", "Loads AppUser by email from DB. Converts group permissions to Spring GrantedAuthority objects. Logs unknown permissions.") +} + +Rel(frontend, secFilter, "All requests", "HTTP / Basic Auth header") +Rel(secFilter, permAspect, "Authenticated requests reach guarded service methods") +Rel(secConf, userDetails, "Wires as UserDetailsService") +Rel(userDetails, db, "Loads user by email", "JDBC") + +@enduml diff --git a/docs/architecture/c4/l3-backend-3b-document-management.puml b/docs/architecture/c4/l3-backend-3b-document-management.puml new file mode 100644 index 00000000..1b68dbeb --- /dev/null +++ b/docs/architecture/c4/l3-backend-3b-document-management.puml @@ -0,0 +1,40 @@ +@startuml +!include + +title Component Diagram: API Backend — Document Management & Import + +Container(frontend, "Web Frontend", "SvelteKit") +ContainerDb(db, "PostgreSQL", "PostgreSQL 16") +ContainerDb(minio, "Object Storage", "MinIO (S3-compatible)") + +System_Boundary(backend, "API Backend (Spring Boot)") { + Component(docCtrl, "DocumentController", "Spring MVC — /api/documents", "CRUD for documents: search, get by ID, update metadata, upload/download file, conversation thread, and batch metadata updates.") + Component(adminCtrl, "AdminController", "Spring MVC — /api/admin", "Triggers asynchronous Excel/ODS mass import (requires ADMIN permission). Reports import state (IDLE/RUNNING/DONE/FAILED).") + Component(docSvc, "DocumentService", "Spring Service", "Core document business logic: store, update, search. Resolves persons and tags, delegates file I/O to FileService, builds dynamic JPA Specifications, and integrates with audit logging.") + Component(fileSvc, "FileService", "Spring Service", "Wraps AWS SDK v2 S3Client. Uploads files with UUID-keyed paths, computes SHA-256 hash, downloads with content-type detection, and generates presigned URLs for OCR access.") + Component(massImport, "MassImportService", "Spring Service — @Async", "Reads Excel/ODS files from /import mount. Tracks import state (IDLE/RUNNING/DONE/FAILED) and delegates to ExcelService. Returns immediately; processing runs asynchronously.") + Component(excelSvc, "ExcelService", "Spring Service", "Parses Excel/ODS workbooks (Apache POI). Column indices configurable via application.properties. Creates/updates document records per row.") + Component(minioConf, "MinioConfig", "Spring @Configuration", "Creates the S3Client and S3Presigner beans with path-style access for MinIO. Validates MinIO connectivity on startup.") + Component(docRepo, "DocumentRepository", "Spring Data JPA", "Queries documents with Specification-based dynamic search, bidirectional conversation thread queries, full-text search with ranking and match highlighting, and transcription pipeline queue projections.") + Component(docSpec, "DocumentSpecifications", "JPA Criteria API", "Factory for composable predicates: hasText (full-text), hasSender, hasReceiver, isBetween (date range), hasTags (subquery AND/OR logic).") +} + +Component(personSvc, "PersonService", "Spring Service", "See diagram 3e. Called by DocumentService to resolve sender / receiver persons by ID.") +Component(tagSvc, "TagService", "Spring Service", "See diagram 3d. Called by DocumentService to find or create tags by name.") + +Rel(frontend, docCtrl, "Document requests", "HTTP / JSON") +Rel(frontend, adminCtrl, "Trigger import", "HTTP / JSON") +Rel(docCtrl, docSvc, "Delegates to") +Rel(adminCtrl, massImport, "Triggers") +Rel(docSvc, fileSvc, "Upload / download files") +Rel(docSvc, docRepo, "Reads / writes documents") +Rel(docSvc, docSpec, "Builds search predicates") +Rel(docSvc, personSvc, "Resolves sender / receivers") +Rel(docSvc, tagSvc, "Finds or creates tags") +Rel(massImport, excelSvc, "Parses Excel/ODS file") +Rel(excelSvc, docSvc, "Creates / updates documents") +Rel(minioConf, fileSvc, "Provides S3Client and S3Presigner beans") +Rel(fileSvc, minio, "PUT / GET / presigned URL objects", "S3 API / HTTP") +Rel(docRepo, db, "SQL queries", "JDBC") + +@enduml