docs(c4): document timeline density widget across backend+frontend (#385)

- l3-backend-3b: extend DocumentController description to include the
  per-month density aggregation endpoint.
- l3-frontend-3b: add /documents/+page.ts (client-side gated loader) and
  TimelineDensityFilter component, plus relationships to the density
  endpoint and the search dashboard.

Per Markus' follow-up §5: both diagrams are mandatory before merge.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-05-07 22:17:29 +02:00
parent 6786c0112d
commit e8fb8150b7
2 changed files with 6 additions and 1 deletions

View File

@@ -8,7 +8,7 @@ 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(docCtrl, "DocumentController", "Spring MVC — /api/documents", "CRUD for documents: search, get by ID, update metadata, upload/download file, conversation thread, batch metadata updates, and per-month density aggregation for the timeline filter widget.")
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.")

View File

@@ -8,6 +8,8 @@ Container(backend, "API Backend", "Spring Boot")
System_Boundary(frontend, "Web Frontend (SvelteKit / SSR)") {
Component(homePage, "/ (Home / Search)", "SvelteKit Route", "Loader: parses URL params (q, from, to, senderId, receiverId, tags), fetches /api/documents/search and /api/persons. Renders search form with full-text, date range, sender/receiver typeahead, and tag filters.")
Component(docsListPageTs, "/documents/+page.ts", "SvelteKit Client Loader", "Client-side load gated by matchMedia('(min-width: 640px)') and ?view query. Fetches /api/documents/density only on tablet/desktop and outside calendar view; degrades to empty buckets on network failure.")
Component(timelineFilter, "TimelineDensityFilter.svelte", "Svelte Component", "Per-month density bars above the document list. Click selects a single month, emits onchange({from, to}) using YYYY-MM-DD boundaries. Hidden on mobile and in calendar view.")
Component(docDetail, "/documents/[id]", "SvelteKit Route", "Loader: GET /api/documents/{id}. Page: metadata panel, inline file viewer, transcription editor, annotation layer, and comment thread.")
Component(docEdit, "/documents/[id]/edit", "SvelteKit Route", "Edit form with PersonTypeahead, TagInput, date/location fields. Form action: PUT /api/documents/{id}.")
Component(docNew, "/documents/new", "SvelteKit Route", "Upload form for a new document. Loader: GET /api/persons. Form action: POST /api/documents with multipart file.")
@@ -21,6 +23,9 @@ System_Boundary(frontend, "Web Frontend (SvelteKit / SSR)") {
Rel(user, homePage, "Searches and browses", "HTTPS / Browser")
Rel(homePage, backend, "GET /api/documents/search, GET /api/persons", "HTTP / JSON")
Rel(docsListPageTs, backend, "GET /api/documents/density (tablet/desktop only)", "HTTP / JSON")
Rel(homePage, timelineFilter, "Mounts above the result list")
Rel(docsListPageTs, timelineFilter, "Provides density / minDate / maxDate props")
Rel(docDetail, backend, "GET /api/documents/{id}, GET /api/documents/{id}/file", "HTTP / JSON + Binary")
Rel(docEdit, backend, "PUT /api/documents/{id}", "HTTP / Multipart")
Rel(docNew, backend, "GET /api/persons, POST /api/documents", "HTTP / JSON + Multipart")