From 69601006284ee53e288d8309fd6665a605908b2e Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 5 May 2026 22:57:45 +0200 Subject: [PATCH] docs(legibility): fix three factual errors in ARCHITECTURE.md - Add ANNOTATE_ALL to the Permission enum listing (was missing) - Fix transcription block autosave endpoint: PUT not PATCH, correct path /api/documents/{documentId}/transcription-blocks/{blockId} - Clarify auth injection: hooks.server.ts handleFetch injects the Authorization header, not the SvelteKit action directly Refs #396 Co-Authored-By: Claude Sonnet 4.6 --- docs/ARCHITECTURE.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 660bedaa..abef192b 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -115,7 +115,7 @@ Controller → Service → Repository → DB Controllers never call repositories directly. Services never reach into another domain's repository — they call the other domain's service. This keeps domain boundaries clear and business logic testable without a running database. ### Permission system -Permissions are enforced via `@RequirePermission(Permission.X)` on controller methods, checked at runtime by `PermissionAspect` (Spring AOP). The `Permission` enum defines the available capabilities (`READ_ALL`, `WRITE_ALL`, `ADMIN`, `ADMIN_USER`, `ADMIN_TAG`, `ADMIN_PERMISSION`, `BLOG_WRITE`). This is not Spring Security's `@PreAuthorize` — do not mix the two mechanisms. +Permissions are enforced via `@RequirePermission(Permission.X)` on controller methods, checked at runtime by `PermissionAspect` (Spring AOP). The `Permission` enum defines the available capabilities (`READ_ALL`, `WRITE_ALL`, `ADMIN`, `ADMIN_USER`, `ADMIN_TAG`, `ADMIN_PERMISSION`, `ANNOTATE_ALL`, `BLOG_WRITE`). This is not Spring Security's `@PreAuthorize` — do not mix the two mechanisms. Sessions use a Base64-encoded Basic Auth token stored in an `httpOnly`, `SameSite=strict` cookie (`auth_token`, maxAge=86400 s). CSRF protection is disabled because this cookie configuration structurally prevents cross-origin credential theft. See [docs/security-guide.md](security-guide.md) for the full security reference. @@ -126,7 +126,7 @@ Sessions use a Base64-encoded Basic Auth token stored in an `httpOnly`, `SameSit ### Document upload 1. User submits the edit form (file + metadata) from the browser. -2. SvelteKit server action sends `PUT /api/documents/{id}` as `multipart/form-data` with the `Authorization` header. +2. The SvelteKit server action sends `PUT /api/documents/{id}` as `multipart/form-data`. `hooks.server.ts` (`handleFetch`) transparently injects the `Authorization` header from the `auth_token` cookie — the action itself is unaware of auth. 3. `PermissionAspect` intercepts the controller method, verifies the user has `WRITE_ALL`, and proceeds. 4. `DocumentController` delegates to `DocumentService.updateDocument()`. 5. `DocumentService` resolves the `Person` sender by ID (via `PersonService`), resolves or creates `Tag`s (via `TagService`), then calls `FileService.uploadFile()`. @@ -137,8 +137,8 @@ Sessions use a Base64-encoded Basic Auth token stored in an `httpOnly`, `SameSit ### Transcription block autosave -1. The transcriber pauses typing; the frontend's `useBlockAutoSave` hook fires after a debounce interval. -2. SvelteKit sends `PATCH /api/transcription/blocks/{id}` with the new text and the block's current `version` (optimistic lock). +1. The transcriber pauses typing; the frontend's `useBlockAutoSave` factory fires after a debounce interval. +2. The browser sends `PUT /api/documents/{documentId}/transcription-blocks/{blockId}` with the new text and the block's current `version` (optimistic lock). `hooks.server.ts` (`handleFetch`) injects the `Authorization` header from the cookie. 3. `TranscriptionService.saveBlock()` loads the block, checks the `@Version` field for concurrent edits, updates `block.text` and any `@mention` sidecars, and calls `saveAndFlush`. 4. If a concurrent save collides (version mismatch), the backend returns `409 Conflict`; the frontend's `saveBlockWithConflictRetry` helper re-fetches and retries. 5. On success, `AuditService` logs a `BLOCK_SAVED` event.