Files
direkt-vermittlung-de/CLAUDE.md

361 lines
12 KiB
Markdown

# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
**DirektVermittlungDe (DVD)** is a document-centric communication platform between citizens and German authorities. It eliminates the "phone hunt" by:
1. Citizens upload a document or provide an *Aktenzeichen* (reference number)
2. The system auto-routes to the responsible unit
3. Opens an interaction thread for direct clarification
## Current Development Status
**⚠️ IMPORTANT**: This repository is currently in transition from prototype phase to main production codebase.
- **Current State**: Three prototype implementations (chatgpt5, geminiNbt3pro, grok4.1) in `/prototype-*` directories
- **Target State**: Unified production codebase in `/src` with TDD-driven development
- **Active Workplan**: See `docs/WORKPLAN_MainCodebase_Integration.md` for detailed migration plan
**When working on this codebase:**
- Check the workplan to understand which phase we're in
- Follow TDD practices: write tests first, then implementation
- Reference ADRs for architectural decisions (see below)
- New code goes in `/src`, not prototypes
## Repository Structure (Target State)
```
/
├── docs/
│ ├── architecture/
│ │ ├── adr/ # Individual ADR files (0001-*.md)
│ │ │ ├── 0001-split-payload-model.md
│ │ │ ├── 0002-stateless-authentication.md
│ │ │ └── ...
│ │ ├── architecture-overview.md
│ │ └── design-patterns.md
│ ├── api/
│ │ ├── openapi.yaml
│ │ └── api-scenarios.md
│ ├── development/
│ │ ├── testing-strategy.md
│ │ ├── agentic-coding-guide.md
│ │ └── setup-guide.md
│ └── WORKPLAN_MainCodebase_Integration.md
├── src/
│ ├── domain/ # Pure business logic (TDD tested)
│ ├── adapters/ # External integrations (mocked in tests)
│ ├── service/ # Application services (TDD tested)
│ ├── api/ # FastAPI routes (integration tested)
│ └── workers/ # Background jobs
├── tests/
│ ├── unit/ # TDD unit tests
│ ├── integration/ # Integration tests
│ └── fixtures/ # Test data and mocks
├── scripts/ # Utility scripts
├── prototype-*/ # ARCHIVED prototypes (reference only)
├── pyproject.toml # Dependencies & tool config
└── pytest.ini # Test configuration
```
## Development Commands
### Setup and Run (Main Codebase)
```bash
# Install dependencies (from repo root)
pip install -e ".[dev]"
# Initialize database metadata
python -m scripts.init_db
# Run development server
uvicorn src.main:app --reload
# View API docs
# http://localhost:8000/docs
```
### Testing (TDD Workflow)
```bash
# Run all tests
pytest
# Run with coverage report
pytest --cov=src --cov-report=html
# Run only unit tests
pytest tests/unit/
# Run only integration tests
pytest tests/integration/
# Run specific test file
pytest tests/unit/domain/test_document_metadata.py -v
# Watch mode (requires pytest-watch)
ptw
```
### Code Quality
```bash
# Lint and format with ruff
ruff check src/ tests/
ruff format src/ tests/
# Type checking with mypy
mypy src/
# Run pre-commit hooks manually
pre-commit run --all-files
```
## Key Architectural Patterns
### 1. Split-Payload Model (ADR-001)
**Critical**: Documents use a split design to enable both encryption and routing:
- **metadata** (plaintext JSON): authorityId, referenceNumber, docType, issuedAt
- **encryptedPayload** (encrypted blob): actual PDF/scan content
The backend can route based on metadata without decrypting the payload. This is the core architectural constraint.
When working with documents:
- NEVER attempt to decrypt `encryptedPayload` in the main service
- The backend treats encrypted content as opaque
- Routing logic operates only on metadata fields
### 2. Hybrid Concurrency Pattern (ADR-007)
Python's GIL requires careful concurrency handling:
- **I/O operations** (DB, network): Use native `async`/`await`
- **CPU operations** (crypto, PDF): Offload to `ProcessPoolExecutor`
Example pattern:
```python
cpu_pool = ProcessPoolExecutor(max_workers=4)
async def handler():
# I/O: async/await
data = await db.fetch()
# CPU: executor
loop = asyncio.get_running_loop()
result = await loop.run_in_executor(cpu_pool, heavy_function, data)
```
### 3. Cursor-Based Pagination (ADR-003)
For message threads, use cursor-based pagination (timestamp) instead of offset-based:
- Ensures consistent performance regardless of thread length
- Prevents duplicate/missing messages during real-time updates
- Target: <300ms response time (NFR-1)
### 4. Async Export Pattern (ADR-004)
Data exports use async request-reply:
1. POST `/exports` → 202 Accepted + jobId
2. Background worker processes via message queue
3. Client polls status endpoint or receives webhook
### 5. Stateless Authentication (ADR-002)
OAuth2/JWT with scopes:
- `citizen:write`: Document submission, thread creation
- `official:read`: View assigned cases
- `official:write`: Respond to inquiries
JWTs enable horizontal scaling without session affinity.
### 6. GDPR-Compliant Retention (ADR-006)
Documents have `retention_date` field:
- Default: `closedAt + gracePeriod`
- Personal archive: `null` or extended date
- Automated cleanup via TTL engine
## API Structure
The API follows document-centric REST hierarchy:
- `/documents` - Root envelope (FR-1: Document intake)
- `/documents/{id}/threads` - Sub-resource for communication (FR-3)
- `/threads/{threadId}/messages` - Message exchange
- `/exports` - Async data export for authority systems (FR-7)
## Critical Domain Models
Located in `src/domain/models.py` (target) or `prototype-chatgpt5/src/app/domain/models.py` (reference):
**Enums:**
- **ThreadType**: TEXT_CHAT, CALLBACK_REQUEST, APPOINTMENT
- **SenderRole**: CITIZEN, OFFICIAL, SYSTEM
- **ExportJobStatus**: QUEUED, RUNNING, COMPLETED, FAILED
**Core Models:**
- **DocumentMetadata**: authorityId, referenceNumber, docType, issuedAt
- Validation: authorityId (1-50 chars), referenceNumber required
- **DocumentCreateRequest**: metadata, encryptedPayload (base64)
- **DocumentCreatedResponse**: id, status, assignedUnit
- **ThreadCreateRequest**: type, initialMessage, preferredTimeSlot
- **MessageDto**: id, senderRole, content (encrypted), timestamp
## Performance Targets (NFR)
- Core operations: <300ms response time
- Document upload routing: <500ms
- Concurrent sessions: 10k+ per region
- Availability: ≥99.5%
## Security Constraints
- E2E encryption required for sensitive data (NFR-5)
- Backend cannot decrypt document payloads
- Least-privilege access via OAuth scopes (NFR-6)
- No PII in plaintext application logs
## TDD Development Workflow
**CRITICAL**: This project follows a strict Test-Driven Development approach.
### The Red-Green-Refactor Cycle
1. **RED**: Write a failing test that defines desired behavior
2. **GREEN**: Write minimal code to make the test pass
3. **REFACTOR**: Improve code while keeping tests green
### Example TDD Workflow
```python
# Step 1: Write failing test (tests/unit/domain/test_document_metadata.py)
def test_document_metadata_validates_authority_id():
with pytest.raises(ValidationError):
DocumentMetadata(
authorityId="", # Empty should fail
referenceNumber="123/456",
docType="NOTICE",
issuedAt=datetime.now()
)
# Step 2: Run test (it fails)
# $ pytest tests/unit/domain/test_document_metadata.py
# Step 3: Implement validation (src/domain/models.py)
class DocumentMetadata(BaseModel):
authorityId: str = Field(..., min_length=1, max_length=50)
# ... rest of fields
# Step 4: Run test again (it passes)
# Step 5: Refactor if needed, ensure tests still pass
```
### Agentic TDD Pattern
When asking Claude to implement features, use this pattern:
```
"Write a test for [feature] that verifies [specific behavior].
Use pytest and follow the pattern in tests/unit/[module]/.
Reference ADR-[number] for architectural constraints."
```
Example:
```
"Write a test for document routing that verifies documents with docType='NOTICE'
are routed to the NoticeTeam. Mock the routing adapter using the protocol defined
in src/adapters/protocols.py. Follow ADR-0001 split-payload constraints."
```
See `docs/development/agentic-coding-guide.md` for comprehensive examples.
## Documentation References
### Architecture & Decisions
- **Workplan**: `docs/WORKPLAN_MainCodebase_Integration.md` - Current migration plan
- **ADRs**: `docs/architecture/adr/` - Individual decision records
- `0001-split-payload-model.md` - Core constraint: metadata vs encrypted payload
- `0002-stateless-authentication.md` - OAuth2/JWT architecture
- `0003-cursor-based-pagination.md` - Performance-optimized pagination
- `0004-async-export-workflow.md` - Background job pattern
- `0005-rest-resource-structure.md` - API design hierarchy
- `0006-gdpr-retention-model.md` - Data lifecycle management
- `0007-hybrid-concurrency-pattern.md` - Python GIL mitigation
- `0008-agentic-tdd-workflow.md` - LLM-driven development process
- **Overview**: `docs/architecture/architecture-overview.md` - System design
- **Patterns**: `docs/architecture/design-patterns.md` - Common patterns
### API Documentation
- **OpenAPI**: `docs/api/openapi.yaml` - Full API specification
- **Scenarios**: `docs/api/api-scenarios.md` - Real-world usage examples
### Development Guides
- **Testing**: `docs/development/testing-strategy.md` - TDD practices
- **Agentic Coding**: `docs/development/agentic-coding-guide.md` - AI-assisted development
- **Setup**: `docs/development/setup-guide.md` - Environment setup
### Legacy (Prototypes)
- `prototype-chatgpt5/README.md` - Reference implementation (ARCHIVED)
- `docs/decisions.md` - Original ADRs (DEPRECATED, see /docs/architecture/adr/)
## Database Schema
Key tables (PostgreSQL):
- **documents**: id, reference_number, authority_id, status, storage_path, retention_date
- **threads**: id, document_id, type, assigned_official_id, last_activity_at
- **messages**: id, thread_id, sender_role, content_blob, created_at
Indexes:
- `idx_docs_authority` on documents(authority_id, status)
- `idx_msgs_thread_time` on messages(thread_id, created_at DESC)
## Technology Stack
- **Language**: Python 3.11+
- **Framework**: FastAPI + Uvicorn
- **ORM**: SQLAlchemy (async)
- **Database**: PostgreSQL 15+
- **Blob Storage**: S3-compatible (MinIO/AWS S3)
- **Task Queue**: ARQ (Redis-based, async) or Celery
- **Auth**: OAuth2/JWT (stateless)
- **Testing**: pytest + pytest-asyncio + pytest-cov
- **Linting**: ruff (fast, replaces flake8/isort/pyupgrade)
- **Type Checking**: mypy (strict mode)
- **CI/CD**: GitHub Actions
## Workplan & Phase Tracking
**Active Workplan**: `docs/WORKPLAN_MainCodebase_Integration.md`
### Current Phase Status
To check which phase we're in:
1. Open `docs/WORKPLAN_MainCodebase_Integration.md`
2. Look for checked `[x]` items in each phase section
3. Focus development on uncompleted `[ ]` items in the current phase
### How to Contribute
**Before implementing any feature:**
1. Check if it's in the current phase of the workplan
2. Read the relevant ADR(s) in `docs/architecture/adr/`
3. Write tests first (TDD approach)
4. Implement to make tests pass
5. Ensure all quality gates pass (pytest, mypy, ruff)
**When adding new architectural decisions:**
1. Create a new ADR file in `docs/architecture/adr/`
2. Use the template in `0000-template.md`
3. Number sequentially (next available number)
4. Update the ADR index in `docs/architecture/adr/README.md`
## Common Gotchas
1. **Stream large files**: Use `aiobotocore` to stream uploads to S3, don't load entire payloads into memory
2. **ProcessPoolExecutor**: CPU-heavy operations MUST be offloaded to avoid blocking the event loop
3. **Metadata separation**: The routing engine needs plaintext metadata - design API contracts accordingly
4. **Retention dates**: Always set `retention_date` on document creation for GDPR compliance
5. **Cursor pagination**: Use timestamp-based cursors for message history, not offset-based