diff --git a/docs/architecture/c4/l3-frontend-3c-people-stories.puml b/docs/architecture/c4/l3-frontend-3c-people-stories.puml new file mode 100644 index 00000000..49526211 --- /dev/null +++ b/docs/architecture/c4/l3-frontend-3c-people-stories.puml @@ -0,0 +1,32 @@ +@startuml +!include + +title Component Diagram: Web Frontend — People, Stories & Discovery + +Person(user, "User") +Container(backend, "API Backend", "Spring Boot") + +System_Boundary(frontend, "Web Frontend (SvelteKit / SSR)") { + Component(personsPage, "/persons and /persons/[id]", "SvelteKit Routes", "Person directory and detail. Detail: metadata, document list sent/received, correspondents, explicit and inferred family relationships.") + Component(personEdit, "/persons/[id]/edit and /persons/new", "SvelteKit Routes", "Create and edit person forms. Edit: metadata, aliases, explicit relationships. Actions: PUT/POST /api/persons.") + Component(briefwechsel, "/briefwechsel", "SvelteKit Route", "Bilateral conversation timeline. Selects two persons via PersonTypeahead, fetches GET /api/documents/conversation, displays chronological exchange.") + Component(aktivitaeten, "/aktivitaeten", "SvelteKit Route", "Unified activity feed (Chronik). Loader: GET /api/dashboard/activity and GET /api/notifications?read=false.") + Component(geschichten, "/geschichten and /geschichten/[id]", "SvelteKit Routes", "Story list and detail pages. Loader: GET /api/geschichten?status=PUBLISHED.") + Component(geschichtenEdit, "/geschichten/[id]/edit and /geschichten/new", "SvelteKit Routes", "Story editor with rich text, person and document linking. Actions: PUT/POST /api/geschichten. Requires BLOG_WRITE permission.") + Component(stammbaum, "/stammbaum", "SvelteKit Route", "Family tree visualisation. Loader: GET /api/network (nodes + edges). Renders interactive family tree from network graph data.") + Component(profilePage, "/profile", "SvelteKit Route", "Current user profile settings. Loader: GET /api/users/me/notification-preferences. Actions: update name/password and notification preferences.") + Component(userProfile, "/users/[id]", "SvelteKit Route", "Public user profile view. Loader: GET /api/users/{id}.") +} + +Rel(user, personsPage, "Browses family members", "HTTPS / Browser") +Rel(personsPage, backend, "GET /api/persons, GET /api/persons/{id}", "HTTP / JSON") +Rel(personEdit, backend, "GET /api/persons/{id}, PUT /api/persons/{id}, POST /api/persons", "HTTP / JSON") +Rel(briefwechsel, backend, "GET /api/documents/conversation", "HTTP / JSON") +Rel(aktivitaeten, backend, "GET /api/dashboard/activity, GET /api/notifications", "HTTP / JSON") +Rel(geschichten, backend, "GET /api/geschichten", "HTTP / JSON") +Rel(geschichtenEdit, backend, "GET/PUT/POST /api/geschichten", "HTTP / JSON") +Rel(stammbaum, backend, "GET /api/network", "HTTP / JSON") +Rel(profilePage, backend, "GET/PUT /api/users/me, notification-preferences", "HTTP / JSON") +Rel(userProfile, backend, "GET /api/users/{id}", "HTTP / JSON") + +@enduml diff --git a/docs/architecture/c4/l3-frontend-3d-administration.puml b/docs/architecture/c4/l3-frontend-3d-administration.puml new file mode 100644 index 00000000..3f7c89ef --- /dev/null +++ b/docs/architecture/c4/l3-frontend-3d-administration.puml @@ -0,0 +1,27 @@ +@startuml +!include + +title Component Diagram: Web Frontend — Administration & Help + +Person(admin, "Administrator") +Person(user, "User") +Container(backend, "API Backend", "Spring Boot") + +System_Boundary(frontend, "Web Frontend (SvelteKit / SSR)") { + Component(adminUsers, "/admin/users, /admin/users/[id], /admin/users/new, /admin/invites", "SvelteKit Routes", "User directory, create/update/delete users, and manage invite codes. Requires ADMIN_USER permission.") + Component(adminGroups, "/admin/groups, /admin/groups/[id], /admin/groups/new", "SvelteKit Routes", "Permission group management: create/edit groups and their permission sets.") + Component(adminTags, "/admin/tags and /admin/tags/[id]", "SvelteKit Routes", "Tag administration: edit tag hierarchy, merge tags, delete subtrees.") + Component(adminOcr, "/admin/ocr and /admin/ocr/[personId]", "SvelteKit Routes", "Global and per-person OCR configuration. Manages script types and triggers sender model training.") + Component(adminSystem, "/admin/system", "SvelteKit Route", "System status panel. Triggers Excel/ODS mass import (POST /api/admin/trigger-import). Displays import state.") + Component(hilfe, "/hilfe/transkription", "SvelteKit Route", "Static transcription style guide for Kurrent and Sütterlin character recognition. No backend calls.") +} + +Rel(admin, adminUsers, "Manages users and invites", "HTTPS / Browser") +Rel(user, hilfe, "Views transcription style guide", "HTTPS / Browser") +Rel(adminUsers, backend, "GET/POST/DELETE /api/users, POST /api/auth/invite", "HTTP / JSON") +Rel(adminGroups, backend, "GET/POST/PUT/DELETE /api/groups", "HTTP / JSON") +Rel(adminTags, backend, "GET/PUT/DELETE /api/tags", "HTTP / JSON") +Rel(adminOcr, backend, "GET/POST /api/ocr (global config and sender training)", "HTTP / JSON") +Rel(adminSystem, backend, "POST /api/admin/trigger-import, GET /api/admin/import-status", "HTTP / JSON") + +@enduml diff --git a/docs/architecture/c4/seq-auth-flow.puml b/docs/architecture/c4/seq-auth-flow.puml new file mode 100644 index 00000000..bae4a831 --- /dev/null +++ b/docs/architecture/c4/seq-auth-flow.puml @@ -0,0 +1,26 @@ +@startuml +title Authentication Flow + +actor User +participant Browser +participant "Frontend (SvelteKit)" as Frontend +participant "Backend (Spring Boot)" as Backend +participant PostgreSQL as DB + +User -> Browser: Enter email + password +Browser -> Frontend: POST /login (form action) +Frontend -> Frontend: Base64 encode "email:password" +Frontend -> Backend: GET /api/users/me\nAuthorization: Basic +Backend -> Backend: Spring Security parses Basic Auth +Backend -> DB: SELECT user WHERE email=? +DB --> Backend: AppUser + groups + permissions +Backend -> Backend: BCrypt.matches(password, hash) +Backend --> Frontend: 200 OK — UserDTO +Frontend -> Browser: Set-Cookie: auth_token=\n(httpOnly, SameSite=strict, maxAge=86400) +Browser -> Frontend: GET / (next request) +Frontend -> Frontend: hooks.server.ts reads auth_token cookie +Frontend -> Backend: GET /api/users/me\nAuthorization: Basic +Backend --> Frontend: 200 OK — user in event.locals +Frontend --> Browser: Render page with user context + +@enduml diff --git a/docs/architecture/c4/seq-document-upload.puml b/docs/architecture/c4/seq-document-upload.puml new file mode 100644 index 00000000..474d1e8b --- /dev/null +++ b/docs/architecture/c4/seq-document-upload.puml @@ -0,0 +1,32 @@ +@startuml +title Document Upload Flow + +actor User +participant "Frontend (SvelteKit)" as Frontend +participant "Backend (Spring Boot)" as Backend +participant "PermissionAspect (AOP)" as Aspect +participant DocumentService as DocSvc +participant FileService as FileSvc +participant MinIO +participant PostgreSQL as DB + +User -> Frontend: Submit edit form (file + metadata) +Frontend -> Backend: PUT /api/documents/{id}\nmultipart/form-data + Authorization header +Backend -> Aspect: @RequirePermission(WRITE_ALL) check +Aspect -> Aspect: Verify user has WRITE_ALL authority +Aspect --> Backend: Proceed +Backend -> DocSvc: updateDocument(id, dto, file) +DocSvc -> DocSvc: Resolve sender Person by ID +DocSvc -> DocSvc: Resolve/create Tags +DocSvc -> FileSvc: uploadFile(file, filename) +FileSvc -> FileSvc: Generate key: documents/{UUID}_{filename} +FileSvc -> MinIO: PutObject(bucket, key, stream) +MinIO --> FileSvc: Success +FileSvc --> DocSvc: S3 key +DocSvc -> DB: UPDATE documents SET file_path=?, status='UPLOADED', ... +DB --> DocSvc: OK +DocSvc --> Backend: Updated Document entity +Backend --> Frontend: 200 OK — Document JSON +Frontend --> User: Refreshed document view + +@enduml