Files
direkt-vermittlung-de/docs/decisions.md

125 lines
6.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Decision Log: DirektVermittlungDe
**Status:** Approved
**Date:** 2025-12-01
**Context:** [DvdArchitektur.txt], [Introduction.txt]
Here is the formal **Decision Log** for the DirektVermittlungDe (DVD) project. This document captures the critical architectural choices, the options considered, and the rationale based on the provided requirements and constraints.
# Decision Log: DirektVermittlungDe
**Status:** Approved
**Date:** 2025-12-01
**Context:** [DvdArchitektur.txt], [Introduction.txt]
---
## ADR-001: Separation of Metadata and Content Payload
**Context:**
[cite_start]The system requires an automated **Routing-Engine** to assign documents to the correct authority[cite: 4]. [cite_start]However, strict **End-to-End Encryption (E2E)** is required for sensitive data in transport and rest[cite: 23]. The server cannot route what it cannot read.
**Decision:**
We will implement a **Split-Payload Model**:
1. [cite_start]**Metadata (Plaintext):** A defined set of non-sensitive routing criteria (e.g., Authority ID, Reference/Aktenzeichen, Document Type) is sent as unencrypted JSON (over TLS)[cite: 3].
2. [cite_start]**Payload (Encrypted):** The actual PDF document and sensitive message content are encrypted on the client side and stored as opaque blobs[cite: 23, 42].
**Rationale:**
* [cite_start]**Compliance:** Satisfies NFR-5 (Privacy/Encryption) while enabling FR-2 (Auto-routing)[cite: 4, 23].
* [cite_start]**Performance:** The Routing Engine operates on lightweight JSON metadata (< 500ms target) without needing to decrypt/encrypt heavy files[cite: 20].
[Image of end to end encryption architecture]
---
## ADR-002: Stateless Authentication via OAuth2/JWT
**Context:**
[cite_start]The system must support **10k+ concurrent sessions** per region [cite: 20] [cite_start]and allow horizontal scaling (TC-2)[cite: 40]. Traditional server-side sessions (sticky sessions) would hinder scalability.
**Decision:**
Use **OAuth2 with OpenID Connect (OIDC)** and stateless **JWTs (JSON Web Tokens)** for session handling.
* **Citizens:** Authenticate via BundID/eID.
* [cite_start]**Officials:** Authenticate via Authority SSO (SAML/OIDC integration)[cite: 35].
**Rationale:**
* [cite_start]**Scalability:** Allows the backend to be purely stateless; any instance can service any request (TC-2)[cite: 40].
* [cite_start]**Security:** Scopes (e.g., `citizen:write`, `official:read`) map directly to the least-privilege NFR-6[cite: 24].
---
## ADR-003: Pagination Strategy for Interaction Threads
**Context:**
Interaction threads (FR-3) can grow long over time. [cite_start]The NFR-1 target is a response time of **< 300ms** for core operations[cite: 19]. Standard "Page/Offset" pagination degrades in performance as datasets grow (Offset Drifting) and handles real-time updates poorly.
**Decision:**
* **Cursor-based Pagination:** Used for `InteractionThreads` (chat history). The cursor will be the `timestamp` of the message.
* [cite_start]**Offset-based Pagination:** Retained for the **Officials Case List/Inbox** (FR-1.2), where users expect to "jump to page 2"[cite: 13].
**Rationale:**
* [cite_start]**Performance:** Cursor seeking is O(1) complexity, ensuring the 300ms SLA is met regardless of thread length[cite: 19].
* [cite_start]**Usability:** Prevents "missing messages" or duplicates if new messages arrive while a user is scrolling (essential for chat)[cite: 8].
---
## ADR-004: Asynchronous Processing for Data Exports
**Context:**
[cite_start]Authorities need to export data (PDFs + History) to their eAkte systems (FR-7)[cite: 11]. Generating these packages is resource-intensive and unpredictable in duration, which risks timing out a synchronous HTTP request.
**Decision:**
Implement the **Asynchronous Request-Reply Pattern**.
1. Client POSTs to `/exports` and receives `202 Accepted` + `Job-ID`.
2. [cite_start]Background workers (via Message Queue) process the PDF assembly[cite: 43].
3. Client polls for completion or receives a webhook.
**Rationale:**
* [cite_start]**Resilience:** Prevents blocking the main API threads, protecting the availability goal of ≥ 99.5%[cite: 25].
* **User Experience:** Provides immediate feedback to the official instead of a loading spinner that might freeze.
---
## ADR-005: Resource Naming and Structure
**Context:**
[cite_start]The API must be intuitive ("Clean API") and extensible[cite: 17]. The domain model includes "Documents", "Threads", and "Routing".
**Decision:**
Adopt a **Document-Centric REST hierarchy**:
* [cite_start]Root: `/documents` (The core "Envelope")[cite: 2].
* [cite_start]Sub-resource: `/documents/{id}/threads` (The communication context)[cite: 6].
* [cite_start]**Strict Nouns:** Use `/documents` instead of `/uploadDocument`[cite: 44].
**Rationale:**
* [cite_start]**Alignment:** Matches the architectural definition of DVD being "belegorientiert" (document-driven), not just a generic chat app[cite: 17].
* **Extensibility:** Allows adding new sub-resources (e.g., `/documents/{id}/audit-log` or `/documents/{id}/appeals`) without breaking the root model.
---
## ADR-006: Data Retention & Deletion
**Context:**
[cite_start]Standard behavior requires data deletion after the case is closed (FR-6)[cite: 9]. [cite_start]However, users can opt for a "Personal Archive"[cite: 10, 15].
**Decision:**
Implement a **TTL (Time-To-Live) Engine** on the database rows.
* **Default:** `deletionDate` = `closedAt` + `gracePeriod`.
* **Archive Option:** If `personalArchive` is active, `deletionDate` is set to `null` or an extended timestamp.
**Rationale:**
* [cite_start]**GDPR Compliance:** Ensures Privacy-by-Design (NFR-4) by automating the "Right to Erasure" / data economy principles[cite: 21].
* **Automation:** Reduces administrative overhead for cleanup.
## ADR-007: Python & ProcessPoolExecutor for Backend Services
**Context:**
The implementation team utilizes Agentic Coding (LLM-driven TDD). While Go/Java offers native concurrency, Python provides superior velocity with LLMs. However, Python's GIL risks blocking the event loop during CPU-intensive tasks (Encryption, PDF merging).
**Decision:**
Implement the Service Layer in **Python (FastAPI)** with a strict **Hybrid Concurrency Pattern**:
1. **I/O (DB/Network):** Native `async`/`await`.
2. **CPU (Crypto/PDF):** Must be offloaded to a `ProcessPoolExecutor`.
**Rationale:**
* **Velocity:** Maximizes the efficiency of AI coding assistants (Claude/GPT).
* **Performance:** `ProcessPoolExecutor` bypasses the GIL, ensuring the main loop remains non-blocking for the 10k concurrent connections.
* **Ecosystem:** Access to superior Python-based libraries for potential future AI features (classification/extraction).
xxx