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

6.7 KiB
Raw Blame History

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