generated from coulomb/repo-seed
125 lines
6.7 KiB
Markdown
125 lines
6.7 KiB
Markdown
# 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 **Official’s 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 |