# Sprint 9 Implementation Plan — Berichtszentrale (Report Center)

**Date:** 2026-06-15
**Author:** Patrick Plate / Lumen (Architect)
**Status:** Draft v2 (incorporates panel review advisory items)
**Basis:** cannamanage-sprint9-analysis.md
**Sprint Goal:** Complete reporting & documentation module with authority-ready exports

---

## Implementation Phases

Sprint 9 is organized into 6 phases, building from backend infrastructure to frontend polish.

```mermaid
graph LR
    P1[Phase 1: Data Model + Backend Services] --> P2[Phase 2: Report Generators - Financial]
    P2 --> P3[Phase 3: Report Generators - KCanG Compliance]
    P3 --> P4[Phase 4: DSGVO Templates + Verein Reports]
    P4 --> P5[Phase 5: Frontend - Berichtszentrale + Sidebar Reorg]
    P5 --> P6[Phase 6: Compliance Dashboard + Retention + Integration Testing]
```

---

## Phase 1: Data Model & Backend Infrastructure

### Step 1.1 — Database Migrations (V23-V28)

**Files:**
- `cannamanage-api/src/main/resources/db/migration/V23__destruction_records.sql`
- `cannamanage-api/src/main/resources/db/migration/V24__transport_records.sql`
- `cannamanage-api/src/main/resources/db/migration/V25__propagation_sources.sql`
- `cannamanage-api/src/main/resources/db/migration/V26__prevention_activities.sql`
- `cannamanage-api/src/main/resources/db/migration/V27__generated_reports.sql`
- `cannamanage-api/src/main/resources/db/migration/V28__compliance_deadlines.sql`
- `cannamanage-api/src/main/resources/db/migration/V29__distribution_thc_cbd.sql`

**V29 specifically:**
```sql
ALTER TABLE distributions ADD COLUMN IF NOT EXISTS thc_percentage NUMERIC(4,2);
ALTER TABLE distributions ADD COLUMN IF NOT EXISTS cbd_percentage NUMERIC(4,2);
ALTER TABLE distributions ADD COLUMN IF NOT EXISTS strain_name VARCHAR(200);
```

### Step 1.2 — JPA Entities

**New entities:**
- `de.cannamanage.domain.entity.DestructionRecord`
- `de.cannamanage.domain.entity.TransportRecord`
- `de.cannamanage.domain.entity.PropagationSource`
- `de.cannamanage.domain.entity.PreventionActivity`
- `de.cannamanage.domain.entity.GeneratedReport`
- `de.cannamanage.domain.entity.ComplianceDeadline`

**Modified entities:**
- `Distribution` — add `thcPercentage`, `cbdPercentage`, `strainName` fields

### Step 1.3 — Repositories

- `DestructionRecordRepository`
- `TransportRecordRepository`
- `PropagationSourceRepository`
- `PreventionActivityRepository`
- `GeneratedReportRepository`
- `ComplianceDeadlineRepository`

Each with standard tenant-scoped queries + date range filters.

### Step 1.4 — Base Report Service Infrastructure

**New file:** `cannamanage-service/src/main/java/de/cannamanage/service/report/ReportGenerator.java`

```java
/**
 * Base interface for all report generators.
 * Standardizes the contract across 18+ report types.
 * Each implementation handles one ReportType.
 */
public interface ReportGenerator<T extends ReportParameters> {
    ReportType getType();
    byte[] generatePdf(T params);
    default byte[] generateCsv(T params) {
        throw new UnsupportedOperationException("CSV not supported for " + getType());
    }
    default byte[] generateJson(T params) {
        throw new UnsupportedOperationException("JSON not supported for " + getType());
    }
    Set<ExportFormat> supportedFormats();
}
```

**New file:** `cannamanage-service/src/main/java/de/cannamanage/service/ReportGeneratorService.java`

```java
@Service
public class ReportGeneratorService {
    // Central orchestrator — delegates to typed ReportGenerator implementations
    // Auto-discovers all ReportGenerator beans via Spring injection
    // Handles: format dispatch, audit logging, document storage
    // Rate-limited: max 5 generations per minute per tenant (via @RateLimiter)
    
    private final Map<ReportType, ReportGenerator<?>> generators;
    
    public ReportGeneratorService(List<ReportGenerator<?>> allGenerators) {
        this.generators = allGenerators.stream()
            .collect(Collectors.toMap(ReportGenerator::getType, Function.identity()));
    }
    
    @RateLimiter(name = "reportGeneration", fallbackMethod = "rateLimitFallback")
    public GeneratedReport generateReport(ReportType type, ReportParameters params);
    public byte[] exportAsPdf(ReportType type, ReportParameters params);
    public byte[] exportAsCsv(ReportType type, ReportParameters params);
    public byte[] exportAsJson(ReportType type, ReportParameters params);
    
    private GeneratedReport rateLimitFallback(ReportType type, ReportParameters params, Exception ex) {
        throw new TooManyRequestsException("Report generation rate limit exceeded. Max 5 per minute.");
    }
}
```

> **Advisory implementation (v2):** The `ReportGenerator<T>` interface provides a standardized contract across all 18+ report generators. This enables consistent error handling, format negotiation, and future plugin extensibility without requiring every generator to implement all formats. Rate limiting (max 5/min/tenant) is enforced at the orchestrator level via Resilience4j `@RateLimiter`.

**New file:** `cannamanage-service/src/main/java/de/cannamanage/service/RetentionService.java`

```java
@Service
public class RetentionService {
    // Scheduled daily: checks retention periods
    // Flags records approaching end-of-retention
    // Never auto-deletes — requires admin confirmation
    
    @Scheduled(cron = "0 0 2 * * *") // 2 AM daily
    public void checkRetentionPeriods();
    public List<RetentionAlert> getPendingAlerts(UUID tenantId);
}
```

### Step 1.5 — REST Controllers for New Entities

- `DestructionRecordController` — CRUD + PDF generation
- `TransportRecordController` — CRUD + certificate generation
- `PropagationSourceController` — CRUD
- `PreventionActivityController` — CRUD
- `ComplianceDeadlineController` — CRUD + status updates
- `ReportController` (enhanced) — all report generation endpoints

### Step 1.6 — Enums

**New enums in `cannamanage-domain`:**
- `ReportType` — `ANNUAL_AUTHORITY`, `DISTRIBUTION_LOG`, `STOCK_INVENTORY`, `DESTRUCTION_PROTOCOL`, `CULTIVATION_REPORT`, `TRANSPORT_CERTIFICATE`, `FULL_AUTHORITY_EXPORT`, `EUR`, `ANNUAL_FINANCIAL`, `KASSENBUCH_EXPORT`, `FEE_CONFIRMATION`, `MEMBER_LIST_REGISTRY`, `BOARD_CHANGE_NOTICE`, `ANNUAL_BOARD_REPORT`, `VVT`, `TOM`, `DSFA`, `DELETION_CONCEPT`, `BREACH_NOTIFICATION`
- `DestructionMethod` — `INCINERATION`, `COMPOSTING`, `CHEMICAL`, `OTHER`
- `TransportStatus` — `PLANNED`, `AUTHORITY_NOTIFIED`, `IN_TRANSIT`, `COMPLETED`
- `ComplianceArea` — `KCANG`, `FINANCE`, `DSGVO`, `VEREIN`
- `ComplianceStatus` — `GREEN`, `YELLOW`, `RED`
- `RetentionCategory` — `KCANG_5Y`, `AO_6Y`, `AO_8Y`, `AO_10Y`, `INDEFINITE`

---

## Phase 2: Financial Report Generators

### Step 2.1 — EÜR (Einnahmen-Überschuss-Rechnung) Generator

**File:** `cannamanage-service/src/main/java/de/cannamanage/service/report/EurReportGenerator.java`

Logic:
1. Query all `financial_transactions` for the selected calendar year
2. Group into Einnahmen (INCOME transactions) and Ausgaben (EXPENSE transactions)
3. Sub-group by `expense_category` / income source
4. Calculate: Total income, total expenses, Überschuss/Fehlbetrag
5. Include: Opening balance (Jan 1) and closing balance (Dec 31)
6. Generate PDF in standard EÜR format (Anlage EÜR compatible structure)
7. Generate CSV with semicolons, ISO-8859-1, German decimal format

**PDF Structure:**
```
EINNAHMEN-ÜBERSCHUSS-RECHNUNG
Kalenderjahr: 2025
Verein: Grüner Daumen e.V.

I. EINNAHMEN
   Mitgliedsbeiträge ................ 54.000,00 €
   Sonstige Einnahmen ............... 2.400,00 €
   ─────────────────────────────────────────────
   Summe Einnahmen .................. 56.400,00 €

II. AUSGABEN
   Miete/Pacht ...................... 18.000,00 €
   Strom/Energie .................... 4.800,00 €
   Cannabis-Anbaumaterial ........... 12.000,00 €
   Verwaltung ....................... 3.600,00 €
   Versicherungen ................... 2.400,00 €
   Sonstige Ausgaben ................ 5.200,00 €
   ─────────────────────────────────────────────
   Summe Ausgaben ................... 46.000,00 €

III. ERGEBNIS
   Überschuss ....................... 10.400,00 €
```

### Step 2.2 — Enhanced Kassenbuch Export

**File:** `cannamanage-service/src/main/java/de/cannamanage/service/report/KassenbuchExportGenerator.java`

Enhance existing Kassenbuch with:
- DATEV-compatible CSV format (optional export)
- GoBD-compliant: immutable entries, sequential numbering, no gaps
- Period selection (monthly, quarterly, annual)
- Running balance per entry
- Category totals at bottom

### Step 2.3 — Beitragsbescheinigung (Fee Confirmation per Member)

**File:** `cannamanage-service/src/main/java/de/cannamanage/service/report/FeeConfirmationGenerator.java`

- Per-member annual PDF: confirms total fees paid in calendar year
- Letterhead with club name, address, Vereinsregisternummer
- Suitable for member's tax records (Sonderausgaben)
- Batch generation: one click → all active members get a PDF

### Step 2.4 — Jahresabschluss Enhancement

Enhance existing Sprint 8 annual report with:
- Comparison to previous year (if data exists)
- Category-wise breakdown with percentages
- Chart data (for frontend visualization)
- Kassenprüfer-ready format (signature lines)

---

## Phase 3: KCanG Compliance Report Generators

### Step 3.1 — Annual Authority Report (§26 Abs. 3 KCanG)

**File:** `cannamanage-service/src/main/java/de/cannamanage/service/report/AnnualAuthorityReportGenerator.java`

**THE most important report.** Due January 31 each year.

Logic:
1. Query all harvests (from grow module) in calendar year → sum by strain + THC/CBD
2. Query all distributions in calendar year → sum by strain + THC/CBD
3. Query all destruction records in calendar year → sum by strain + THC/CBD
4. Query stock snapshot as of Dec 31 → by strain + THC/CBD
5. Validate: cultivated - distributed - destroyed ≈ stock change (flag discrepancies)
6. Format into authority-mandated structure

**Output format (PDF + JSON):**
```json
{
  "anbauvereinigung": { "name": "...", "erlaubnisnummer": "...", "anschrift": "..." },
  "berichtszeitraum": { "von": "2025-01-01", "bis": "2025-12-31" },
  "angebaute_mengen": [
    { "sorte": "Amnesia Haze", "menge_gramm": 5000, "thc_prozent": 18.5, "cbd_prozent": 0.8 }
  ],
  "weitergegebene_mengen": [...],
  "vernichtete_mengen": [...],
  "bestand_jahresende": [...]
}
```

### Step 3.2 — Distribution Log (§26 Abs. 1 Nr. 5)

**File:** `cannamanage-service/src/main/java/de/cannamanage/service/report/DistributionLogGenerator.java`

- Date-range selectable log of all distributions
- Per entry: Datum, Mitglied (Name, Vorname, Geburtsjahr), Menge (g), THC%, Sorte
- Summary: total grams, unique members, average per member
- Flags any quota violations (>25g/day, >50g/month, >30g/month for 18-21, >10% THC for 18-21)
- PDF + CSV export

### Step 3.3 — Stock Inventory Report (§26 Abs. 1 Nr. 2)

**File:** `cannamanage-service/src/main/java/de/cannamanage/service/report/StockInventoryReportGenerator.java`

- Point-in-time snapshot of all cannabis + propagation material on premises
- By strain: grams available, THC%, CBD%, harvest date
- Propagation material: count by type (seeds, clones, cuttings)
- Includes stock movements for selected period (in/out/destroyed)

### Step 3.4 — Destruction Protocol (§26 Abs. 1 Nr. 4)

**File:** `cannamanage-service/src/main/java/de/cannamanage/service/report/DestructionProtocolGenerator.java`

- Official Vernichtungsprotokoll PDF
- Per destruction event: date, batch, strain, grams, method, reason, witness
- Dual signature lines (destroying person + witness)
- Sequential protocol number
- Cumulative annual destruction total

### Step 3.5 — Cultivation Report (§26 Abs. 1 Nr. 3)

**File:** `cannamanage-service/src/main/java/de/cannamanage/service/report/CultivationReportGenerator.java`

- Harvest data from grow module
- Per harvest: strain, grams harvested, THC%, CBD%, harvest date, grow cycle ID
- Annual total by strain
- Growth cycle overview (planted → harvested → distributed/destroyed)

### Step 3.6 — Transport Certificate (§22 Abs. 4 KCanG)

**File:** `cannamanage-service/src/main/java/de/cannamanage/service/report/TransportCertificateGenerator.java`

Per §22(4), the certificate must contain:
1. Name und Anschrift des Sitzes der Anbauvereinigung
2. Datum des Transports
3. Start- und Zieladresse des Transports
4. Mengen in Gramm und Sorten des transportierten Cannabis
5. Name und Kontaktdaten der zuständigen Behörde

Generate as a single-page PDF, suitable for printing and carrying during transport.

### Step 3.7 — Full Authority Export (§26 Abs. 2 + §27)

**File:** `cannamanage-service/src/main/java/de/cannamanage/service/report/FullAuthorityExportGenerator.java`

The "panic button" — generates EVERYTHING the authority needs in one package:
1. All distribution records (complete §26(1) Nr. 5 data)
2. Stock movement history
3. All destruction records
4. All cultivation records
5. All transport records
6. Propagation material sources
7. Member register (name + birth year only, per DSGVO minimization)

**Security:** Requires re-authentication (password re-entry) before generation. This is a high-sensitivity operation containing all member distribution histories (Art. 9 DSGVO health data). The confirmation dialog includes a mandatory reason field for the audit trail.

> **Advisory implementation (v2):** Re-authentication gate added per Security Expert recommendation. The endpoint requires a fresh authentication token (max 30 seconds old) obtained via `POST /api/auth/reconfirm` before the export can proceed.

**Output:** ZIP file — **streamed** (not buffered in memory):
- Uses `StreamingResponseBody` to write ZIP entries directly to the HTTP response
- For clubs with 5+ years and 500 members, exports can reach 50MB+
- Streaming avoids `OutOfMemoryError` on the server

> **Advisory implementation (v2):** Streaming ZIP generation per Architecture Expert recommendation. Uses `ZipOutputStream` wrapping `ServletOutputStream` directly — entries are written sequentially without buffering the entire archive in heap memory.

**ZIP contents:**
- `README.txt` — explains contents and legal basis
- `distributions.json` + `distributions.csv`
- `stock.json`
- `destructions.json`
- `cultivation.json`
- `transports.json`
- `members.json` (anonymized: name + birth year only)
- `summary.pdf` — human-readable overview

### Step 3.8 — Distribution Info Sheet (§21 Abs. 2 KCanG)

**File:** `cannamanage-service/src/main/java/de/cannamanage/service/report/DistributionInfoSheetGenerator.java`

Printable info sheet that must be handed out at every distribution:
- Weight in grams
- Harvest date
- Best-before date
- Strain name
- Average THC%
- Average CBD%
- Health warnings (§21(3) — standardized text)

Generate as small PDF (A5 or 1/3 A4) — can be batch-printed.

---

## Phase 4: DSGVO Templates & Verein Administrative Reports

### Step 4.1 — Verarbeitungsverzeichnis (VVT) Generator

**File:** `cannamanage-service/src/main/java/de/cannamanage/service/report/VvtGenerator.java`

Pre-filled template for Anbauvereinigungen:
- 8 standard processing activities pre-defined (member mgmt, distributions, finance, video, etc.)
- Club-specific data filled in (name, address, DPO name if applicable)
- Output: PDF (A4, multi-page table format per Art. 30 requirements)

### Step 4.2 — TOM (Technisch-Organisatorische Maßnahmen) Document

**File:** `cannamanage-service/src/main/java/de/cannamanage/service/report/TomGenerator.java`

Checklist-style PDF with:
- Zutrittskontrolle (physical access)
- Zugangskontrolle (system access — passwords, 2FA)
- Zugriffskontrolle (data access — roles, permissions)
- Trennungskontrolle (purpose limitation)
- Pseudonymisierung/Verschlüsselung
- Verfügbarkeit und Belastbarkeit (backups, disaster recovery)
- Verfahren zur regelmäßigen Überprüfung

Pre-filled with what CannaManage provides (encryption, role-based access, audit log, etc.).

### Step 4.3 — DSFA (Datenschutz-Folgenabschätzung) Template

**File:** `cannamanage-service/src/main/java/de/cannamanage/service/report/DsfaGenerator.java`

Required because cannabis distribution data = health-related data (Art. 9 DSGVO).

Structure:
1. Beschreibung der Verarbeitung (automated from VVT)
2. Bewertung der Notwendigkeit (pre-filled: §26 KCanG mandates the processing)
3. Risikobewertung (template with common risks pre-identified)
4. Abhilfemaßnahmen (auto-filled from TOM document)

### Step 4.4 — Löschkonzept (Deletion Concept)

**File:** `cannamanage-service/src/main/java/de/cannamanage/service/report/DeletionConceptGenerator.java`

Documents when each category of data is deleted:
- Maps data categories → retention periods → deletion triggers
- References §26(2) KCanG (5 years), §147 AO (6/8/10 years)
- Describes the automated retention checking (RetentionService)
- Lists manual review process

### Step 4.4b — Breach Notification Template (Art. 33/34 DSGVO) — **P1**

**File:** `cannamanage-service/src/main/java/de/cannamanage/service/report/BreachNotificationGenerator.java`

> **Advisory implementation (v2):** Elevated from P2 to P1 per Risk/Compliance Expert recommendation. Cannabis distribution data is Art. 9 DSGVO health data — a breach could cause significant harm (employment discrimination, social stigma). Having the template ready before an incident occurs is critical.

Pre-filled breach notification PDF with:
- Art. 33 fields: nature of breach, categories of data subjects affected, approximate number, DPO contact, likely consequences, measures taken
- Art. 34 fields: communication to affected data subjects (plain language)
- Auto-fills club details, DPO info, and data category descriptions from VVT
- Checklist: 72-hour notification deadline reminder, authority contact details
- Editable fields for incident-specific details (what happened, when discovered)

**Priority justification:** A cannabis club experiencing a data breach has 72 hours to notify the Landesdatenschutzbehörde. Without a pre-prepared template, clubs will scramble under pressure and risk non-compliance with Art. 33(1) DSGVO. Given the sensitivity of cannabis health data, this is P1.

### Step 4.5 — Mitgliederliste für Vereinsregister

**File:** `cannamanage-service/src/main/java/de/cannamanage/service/report/MemberListRegistryGenerator.java`

Formatted per BGB requirements for Vereinsregister:
- Minimal data: Name, Vorname, Anschrift, Eintrittsdatum
- Sorted alphabetically
- Includes total count and date of generation
- Footer: "Erstellt gemäß §67 BGB"

### Step 4.6 — Vorstandsänderung-Meldung (Board Change Template)

**File:** `cannamanage-service/src/main/java/de/cannamanage/service/report/BoardChangeNoticeGenerator.java`

Template for notifying Registergericht of board changes:
- Old board composition
- New board composition (from board_members table)
- Date of election (from assembly records)
- Reference to MV protocol
- Signature line for new Vorstand

### Step 4.7 — Jahresbericht des Vorstands (Annual Board Report)

**File:** `cannamanage-service/src/main/java/de/cannamanage/service/report/AnnualBoardReportGenerator.java`

Combines multiple data sources into a report the Vorstand presents to members at the annual MV:
- Member statistics (new, left, total)
- Financial summary (from EÜR)
- Compliance status (KCanG obligations met)
- Key activities (from prevention log, assemblies held, etc.)
- Outlook/plans (editable text section)

---

## Phase 5: Frontend — Berichtszentrale & Sidebar Reorganization

### Step 5.1 — Sidebar Reorganization

**Modified file:** `cannamanage-frontend/src/data/navigations.ts`

Replace flat list with grouped, collapsible sections:

```typescript
export const navigationsData: NavigationType[] = [
  {
    title: "Betrieb",
    icon: "Leaf",
    items: [
      { title: "Dashboard", href: "/dashboard", iconName: "LayoutDashboard" },
      { title: "Mitglieder", href: "/members", iconName: "Users" },
      { title: "Ausgabe", href: "/distributions", iconName: "Leaf" },
      { title: "Lager", href: "/stock", iconName: "Package" },
      { title: "Anbau", href: "/grow", iconName: "Sprout" },
    ],
  },
  {
    title: "Kommunikation",
    icon: "MessageCircle",
    items: [
      { title: "Schwarzes Brett", href: "/info-board", iconName: "Megaphone" },
      { title: "Kalender", href: "/calendar", iconName: "Calendar" },
      { title: "Forum", href: "/forum", iconName: "MessageSquare" },
    ],
  },
  {
    title: "Verwaltung",
    icon: "Building",
    items: [
      { title: "Finanzen", href: "/finance", iconName: "Wallet" },
      { title: "Versammlungen", href: "/assemblies", iconName: "Gavel" },
      { title: "Dokumente", href: "/documents", iconName: "FileArchive" },
      { title: "Vorstand", href: "/board", iconName: "Shield" },
      { title: "Personal", href: "/settings/staff", iconName: "UserCog" },
    ],
  },
  {
    title: "Compliance",
    icon: "ShieldCheck",
    items: [
      { title: "Berichtszentrale", href: "/reports", iconName: "FileBarChart" },
      { title: "Protokoll", href: "/audit-log", iconName: "ScrollText" },
      { title: "Einstellungen", href: "/settings", iconName: "Settings" },
    ],
  },
]
```

**Modified component:** Sidebar must support collapsible groups with section headers and icons.

### Step 5.2 — Berichtszentrale Page (Report Center)

**New page:** `cannamanage-frontend/src/app/(app)/reports/page.tsx` (replaces existing basic reports page)

Layout:
- Top: Compliance status cards (4 cards: KCanG 🟢/🟡/🔴, Finanzen, DSGVO, Verein)
- Middle: Upcoming deadlines list (next 90 days)
- Bottom: Report categories as card grid with accordion sub-items

**Empty-state handling (new clubs):**

> **Advisory implementation (v2):** Per UX Expert recommendation — when a club first accesses the Berichtszentrale with no reports generated yet, all compliance indicators will be 🔴 RED. To prevent this from being demoralizing, display a "Compliance Setup" guided callout instead of raw red indicators.

When `generated_reports` is empty for this tenant:
- Show a "Erste Schritte" banner with 4-step setup guide:
  1. "VVT erstellen" → links to DSGVO tab
  2. "Jahresbericht konfigurieren" → links to KCanG tab
  3. "Kassenbuch einrichten" → links to Finance tab
  4. "Fristen prüfen" → links to deadlines view
- Compliance cards show "Einrichtung erforderlich" (setup required) in neutral gray instead of alarming red
- After first report is generated in any category, switch to normal traffic-light indicators
- Dismissible: admin can click "Verstanden, Dashboard anzeigen" to skip directly to normal view

Each report card shows:
- Report name
- Last generated date (or "Noch nie erstellt")
- Legal basis reference
- [Generate PDF] [Generate CSV] [Generate JSON] buttons (as applicable)
- [View History] link

### Step 5.3 — Report Category Pages

**New pages:**
- `/reports/finance` — Financial reports tab
- `/reports/compliance` — KCanG reports tab
- `/reports/verein` — Administrative reports tab
- `/reports/dsgvo` — Data protection reports tab

Each with:
- List of available reports in that category
- Generation form (date range, parameters)
- Preview before download
- Download history table

### Step 5.4 — Destruction Record Management

**New pages:**
- `/stock/destructions` — List all destruction records
- `/stock/destructions/new` — Record a new destruction event

Form fields: Batch selection, grams destroyed, propagation count, method, reason, witness name, date.

### Step 5.5 — Transport Record Management

**New pages:**
- `/transports` (or nested under operations)
- `/transports/new` — Plan a new transport (with authority notification reminder)
- `/transports/[id]/certificate` — View/download transport certificate

### Step 5.6 — Prevention Activity Log

**New page:**
- `/board/prevention` — Prevention officer activity log

List of activities + "Add Activity" form. Shows training certificate info.

### Step 5.7 — Report Services (Frontend)

**New file:** `cannamanage-frontend/src/services/report-center.ts`

```typescript
// Report generation triggers
export function useGenerateReport(type: ReportType, params: ReportParams)
export function useReportHistory(type?: ReportType)
export function useComplianceStatus()
export function useUpcomingDeadlines()
export function useDestructionRecords()
export function useTransportRecords()
export function usePreventionActivities()
```

### Step 5.8 — i18n Additions

**Modified files:**
- `cannamanage-frontend/messages/de.json` — all new report names, categories, form labels
- `cannamanage-frontend/messages/en.json` — English translations

---

## Phase 6: Compliance Dashboard + Retention + Integration

### Step 6.1 — Compliance Status Service (Backend)

**File:** `cannamanage-service/src/main/java/de/cannamanage/service/ComplianceDashboardService.java`

Calculates real-time compliance status per area:

```java
public ComplianceStatus getOverallStatus(UUID tenantId) {
    // KCanG: Check if annual report was submitted, distribution records complete
    // Finance: Check if EÜR generated for last fiscal year
    // DSGVO: Check if VVT exists and is recent
    // Verein: Check board term expiry, next MV date
    
    // Yellow = deadline within 30 days or data gaps
    // Red = deadline passed or critical gaps
    // Green = everything current
}
```

### Step 6.2 — Deadline Seeding + Scheduler

**File:** `cannamanage-service/src/main/java/de/cannamanage/service/ComplianceDeadlineScheduler.java`

On tenant creation (or first report center access):
- Seed standard annual deadlines (Jan 31 authority report, MV, EÜR)
- Daily scheduler checks for approaching deadlines → creates notifications
- Auto-rolls annual deadlines to next year after completion

### Step 6.3 — Retention Service Implementation

Implements the daily retention check:
- Queries all data categories
- Compares creation date against retention period rules
- Creates admin notification when data approaches end-of-retention
- Provides "Löschprotokoll" (deletion log) export

### Step 6.4 — API Endpoint Summary

New REST endpoints:

```
# Destruction Records
POST   /api/destructions
GET    /api/destructions
GET    /api/destructions/{id}
GET    /api/destructions/{id}/pdf

# Transport Records
POST   /api/transports
GET    /api/transports
GET    /api/transports/{id}
GET    /api/transports/{id}/certificate/pdf
POST   /api/transports/{id}/notify-authority

# Propagation Sources
POST   /api/propagation-sources
GET    /api/propagation-sources
DELETE /api/propagation-sources/{id}

# Prevention Activities
POST   /api/prevention-activities
GET    /api/prevention-activities
DELETE /api/prevention-activities/{id}

# Report Center
POST   /api/reports/generate          (body: {type, params})
GET    /api/reports/history
GET    /api/reports/{id}/download

# Specific Report Generators
GET    /api/reports/eur/pdf?year=2025
GET    /api/reports/eur/csv?year=2025
GET    /api/reports/authority-annual/pdf?year=2025
GET    /api/reports/authority-annual/json?year=2025
GET    /api/reports/distribution-log/pdf?from=&to=
GET    /api/reports/distribution-log/csv?from=&to=
GET    /api/reports/stock-inventory/pdf?date=
GET    /api/reports/destruction-protocol/pdf?from=&to=
GET    /api/reports/cultivation/pdf?year=
GET    /api/reports/transport-certificate/{id}/pdf
GET    /api/reports/authority-export/zip?from=&to=
GET    /api/reports/member-list-registry/pdf
GET    /api/reports/board-change-notice/pdf
GET    /api/reports/annual-board-report/pdf?year=
GET    /api/reports/vvt/pdf
GET    /api/reports/tom/pdf
GET    /api/reports/dsfa/pdf
GET    /api/reports/deletion-concept/pdf
GET    /api/reports/fee-confirmation/pdf?memberId=&year=
GET    /api/reports/fee-confirmation/batch/zip?year=
GET    /api/reports/info-sheet/{distributionId}/pdf

# Compliance Dashboard
GET    /api/compliance/status
GET    /api/compliance/deadlines
PUT    /api/compliance/deadlines/{id}/complete
```

### Step 6.5 — Integration Testing

- Test each report generator with realistic data
- Verify PDF output quality (correct German formatting, legal references)
- Verify CSV encoding (ISO-8859-1, semicolons, decimal comma)
- Verify JSON schema for authority export
- Test retention service with date manipulation
- Test compliance status calculation edge cases
- E2E: Generate report from frontend → download → verify contents

### Step 6.6 — Seed Data Enhancement

Extend existing seed data with:
- Sample destruction records
- Sample transport records
- Sample propagation sources
- Prevention activities
- Pre-seeded compliance deadlines for demo
- THC/CBD percentages on existing distribution seeds

---

## Technical Decisions

| Decision | Choice | Rationale |
|----------|--------|-----------|
| PDF library | Reuse existing OpenPDF | Proven in Sprint 5+8, already in dependencies |
| CSV encoding | ISO-8859-1 + semicolons | German DATEV standard, accountants expect this |
| CSV injection prevention | Prefix dangerous cells with single quote | Cells starting with `=`, `+`, `-`, `@` get `'` prefix to prevent Excel formula injection |
| JSON schema | Custom (no standard exists) | KCanG is too new for an official schema — we define it |
| ZIP generation | `java.util.zip.ZipOutputStream` via `StreamingResponseBody` | Standard library, streamed to avoid OOM on large exports |
| Report storage | Database record + file in documents module | Reuse existing document storage from Sprint 8 |
| Retention checking | Spring `@Scheduled` | Simple, already used for payment reminders |
| Rate limiting | Resilience4j `@RateLimiter` — 5 reports/min/tenant | Prevents DoS via report generation spam (CPU-intensive PDF rendering) |
| Authority export auth | Re-authentication required (password re-entry) | High-sensitivity: contains all member health data |
| Sidebar state | LocalStorage for collapsed/expanded | No backend needed, instant UX |
| Report preview | Server-side rendered HTML → PDF | Same template for preview and final PDF |
| Empty-state UX | Guided setup banner for new clubs | Prevents demoralizing all-red compliance dashboard on first access |

> **Advisory implementations (v2):** CSV injection prevention, rate limiting, re-authentication gate, streaming ZIP, and empty-state UX all added per panel review recommendations.

---

## File Count Estimate

| Phase | New Backend Files | New Frontend Files | Modified Files |
|-------|------------------|--------------------|----------------|
| Phase 1 | ~18 (entities, repos, controllers, enums) | 0 | 3 (Distribution entity, pom.xml) |
| Phase 2 | ~5 (report generators) | 0 | 1 (existing ReportService) |
| Phase 3 | ~9 (report generators) | 0 | 0 |
| Phase 4 | ~8 (report generators) | 0 | 0 |
| Phase 5 | 0 | ~20 (pages, components, services) | 5 (sidebar, navigations, i18n) |
| Phase 6 | ~4 (services, schedulers) | ~3 (dashboard components) | 2 (seed data) |
| **Total** | **~44** | **~23** | **~11** |

---

## Dependencies & Risks

| Risk | Probability | Impact | Mitigation |
|------|-------------|--------|------------|
| Authority report format changes | Low (KCanG is new) | Medium | JSON export is flexible, PDF regenerable |
| DSGVO template incomplete | Medium | Low | Templates are editable, clubs can customize |
| PDF formatting issues with German umlauts | Low | Low | OpenPDF handles UTF-8, already proven |
| Retention period legal ambiguity (§26 "5 Jahre" — from when?) | Medium | Medium | Conservative: 5 years from record creation + admin review |
| Large data export performance | Low | Medium | Stream responses, chunked ZIP generation |
| Sidebar reorg breaks existing bookmarks | Low | Low | URL paths stay the same, only visual grouping changes |

---

## Success Criteria

1. ✅ All P0 reports generate valid PDFs with correct German formatting
2. ✅ Authority annual report (§26(3)) produces complete, accurate data
3. ✅ Full authority export generates machine-readable JSON bundle
4. ✅ EÜR matches standard format for Finanzamt submission
5. ✅ Sidebar is grouped and collapsible with no functionality loss
6. ✅ Compliance dashboard shows correct status for all 4 areas
7. ✅ Retention service identifies records approaching end-of-life
8. ✅ All exports respect DSGVO data minimization (birth year, not full DOB in authority exports)
9. ✅ CSV exports use correct encoding (ISO-8859-1) and delimiter (semicolons)
10. ✅ Report history tracks what was generated when and by whom
