docs(legibility): fix three factual errors in ARCHITECTURE.md
Some checks failed
CI / OCR Service Tests (pull_request) Successful in 32s
CI / Backend Unit Tests (pull_request) Failing after 3m21s
CI / Unit & Component Tests (push) Failing after 3m6s
CI / Backend Unit Tests (push) Failing after 3m21s
CI / OCR Service Tests (push) Successful in 30s
CI / Unit & Component Tests (pull_request) Failing after 3m24s

- 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 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-05-05 22:57:45 +02:00
parent dc6910a31e
commit 6960100628

View File

@@ -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.