Complete DVD-WP-0002 main codebase TDD kickoff
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s

This commit is contained in:
tegwick 2026-07-08 15:21:17 +02:00
parent 945460b84e
commit 11b862588f
12 changed files with 135 additions and 5 deletions

View file

@ -6,12 +6,16 @@
## Dev Commands
```bash
# Production codebase (src/)
python3 -m venv .venv && .venv/bin/pip install -e ".[dev]"
.venv/bin/pytest -q tests/unit
.venv/bin/pytest -q tests/acceptance # routing-rules tests fail until implemented
# Orient on architecture and migration plan
cat INTENT.md
cat docs/WORKPLAN_MainCodebase_Integration.md
ls docs/architecture/adr/
# Prototype smoke (chatgpt5 — most complete)
# Prototype reference (chatgpt5)
cd prototype-chatgpt5 && pip install -e . && pytest -q
# After workplan edits

View file

@ -28,7 +28,8 @@ direkt-vermittlung-de exists to provide the capability described in INTENT.md.
## Current State
- Pre-production: three parallel prototypes (chatgpt5, geminiNbt3pro, grok4.1) exist under /prototype-*; no unified /src codebase yet. Architecture is documented via 8 ADRs and a migration workplan, but the target production codebase has not been started.
- `/src` production skeleton started (`dvd.domain`, `dvd.adapters.routing`); unit tests green; routing-rules acceptance tests red (TDD).
- Prototypes remain under `/prototype-*` as reference; migration tracked in `docs/WORKPLAN_MainCodebase_Integration.md`.
## Getting Oriented

25
pyproject.toml Normal file
View file

@ -0,0 +1,25 @@
[project]
name = "direkt-vermittlung-de"
version = "0.1.0"
description = "DirektVermittlungDe production backend"
requires-python = ">=3.11"
dependencies = [
"pydantic>=2.7.0",
]
[project.optional-dependencies]
dev = [
"pytest>=8.0.0",
"pytest-asyncio>=0.23.0",
]
[tool.pytest.ini_options]
asyncio_mode = "auto"
testpaths = ["tests"]
[build-system]
requires = ["setuptools>=68"]
build-backend = "setuptools.build_meta"
[tool.setuptools.packages.find]
where = ["src"]

1
src/dvd/__init__.py Normal file
View file

@ -0,0 +1 @@
"""DirektVermittlungDe production codebase."""

View file

View file

@ -0,0 +1,11 @@
"""Metadata-only routing adapter (split-payload model)."""
from __future__ import annotations
from dvd.domain.models import DocumentMetadata
async def route_document(meta: DocumentMetadata) -> str:
"""Route using plaintext metadata only — never inspect encrypted payload."""
if meta.doc_type.upper() == "NOTICE":
return f"{meta.authority_id}-NoticeTeam"
return f"{meta.authority_id}-DefaultTeam"

View file

@ -0,0 +1,8 @@
"""Future routing-rules table adapter (not yet implemented)."""
from __future__ import annotations
from dvd.domain.models import DocumentMetadata
async def route_document_with_rules(meta: DocumentMetadata) -> str:
raise NotImplementedError("Authority routing rules table not implemented yet")

View file

28
src/dvd/domain/models.py Normal file
View file

@ -0,0 +1,28 @@
"""Domain models for split-payload document intake (ADR-001)."""
from __future__ import annotations
from datetime import datetime
from pydantic import BaseModel, Field
class DocumentMetadata(BaseModel):
"""Plaintext routing metadata — backend routes on this only."""
authority_id: str = Field(..., max_length=50, alias="authorityId")
reference_number: str = Field(..., max_length=50, alias="referenceNumber")
doc_type: str = Field(..., max_length=50, alias="docType")
issued_at: datetime = Field(..., alias="issuedAt")
model_config = {"populate_by_name": True}
class DocumentCreateRequest(BaseModel):
metadata: DocumentMetadata
encrypted_payload: str = Field(
...,
description="Base64-encoded opaque blob; routing layer must not decode",
alias="encryptedPayload",
)
model_config = {"populate_by_name": True}

View file

@ -0,0 +1,20 @@
"""Acceptance tests for future routing-rules table (TDD red phase)."""
from datetime import UTC, datetime
import pytest
from dvd.domain.models import DocumentMetadata
@pytest.mark.asyncio
async def test_route_by_reference_prefix_from_rules_table() -> None:
"""ADR-001 follow-on: authority-specific rules should override doc_type defaults."""
meta = DocumentMetadata(
authorityId="DE-BY-001",
referenceNumber="FIN-2026-001",
docType="APPLICATION",
issuedAt=datetime(2026, 1, 15, tzinfo=UTC),
)
from dvd.adapters.routing_rules import route_document_with_rules
assert await route_document_with_rules(meta) == "DE-BY-001-FinanceTeam"

View file

@ -0,0 +1,28 @@
from datetime import UTC, datetime
import pytest
from dvd.adapters.routing import route_document
from dvd.domain.models import DocumentMetadata
@pytest.mark.asyncio
async def test_route_notice_to_notice_team() -> None:
meta = DocumentMetadata(
authorityId="DE-BY-001",
referenceNumber="AZ-123",
docType="NOTICE",
issuedAt=datetime(2026, 1, 15, tzinfo=UTC),
)
assert await route_document(meta) == "DE-BY-001-NoticeTeam"
@pytest.mark.asyncio
async def test_route_default_team_for_other_doc_types() -> None:
meta = DocumentMetadata(
authorityId="DE-BY-001",
referenceNumber="AZ-456",
docType="APPLICATION",
issuedAt=datetime(2026, 1, 15, tzinfo=UTC),
)
assert await route_document(meta) == "DE-BY-001-DefaultTeam"

View file

@ -4,11 +4,12 @@ type: workplan
title: "Main codebase TDD integration kickoff"
domain: government
repo: direkt-vermittlung-de
status: ready
status: finished
owner: codex
topic_slug: personhood
created: "2026-07-08"
updated: "2026-07-08"
state_hub_workstream_id: "dde8f640-0bf7-4258-bb88-3be3f408e63f"
---
# Main codebase TDD integration kickoff
@ -19,8 +20,11 @@ Start unified `/src` production codebase with ADR-governed TDD interfaces, conso
```task
id: DVD-WP-0002-T01
status: todo
status: done
priority: high
state_hub_task_id: "90d0ab6a-6c86-4025-b8bf-2f63e3cd8cc3"
```
Result 2026-07-08: Created src/dvd domain+routing; pyproject.toml; unit tests pass; acceptance routing-rules test fails (TDD red).
Create `/src` skeleton, port split-payload routing interfaces from chatgpt5 prototype, and add first failing acceptance tests per docs/WORKPLAN_MainCodebase_Integration.md.