Files
tessera-ctl/.planning/phases/10-ausschreibungs-radar-foundation-d-e-ingestion/.continue-here.md
T

74 lines
5.5 KiB
Markdown

---
context: phase
phase: 10-ausschreibungs-radar-foundation-d-e-ingestion
task: null
total_tasks: 16
status: code_complete_uat_pending
last_updated: 2026-07-21T09:34:48.800Z
---
# Phase 10 — Ausschreibungs-Radar Foundation & DÖE Ingestion
_No blocking anti-patterns were discovered this session. Execution was clean._
## Critical Anti-Patterns
| Pattern | Description | Severity | Prevention Mechanism |
|---------|-------------|----------|---------------------|
| Stale live container masks completion | Code + migration + tests are complete and green, but the running `tessera-ctl-api-1` container is on the pre-Phase-10 image, so nobody has observed the boot-seed or a live HTTP request against the new routes. This is why verification is `human_needed`, NOT a code defect. | advisory | Rebuild the container (`docker compose up -d --build api web`) before treating a "green tests" state as user-visible done. |
<current_state>
Phase 10 is code-complete: all 6 plans executed, 22 commits on `main`. Full monorepo test suite green (API 74/74, Web 111/111), `tsc --noEmit` clean for both apps. Independent goal-backward verification (`10-VERIFICATION.md`) confirmed 5/5 must-haves at the code/DB/test level. Verification status is `human_needed` — the only open item is a live UAT run after a Docker rebuild.
</current_state>
<completed_work>
- Plan 10-01: Prisma `Tender` + `TenderSourcePollConfig` (global, no tenantId/RLS) + migration APPLIED to local DB — SCHEMA-01. Commit 6cfda90.
- Plan 10-02: Marketplace self-seed `tender-radar` + web module-loader whitelist + placeholder page — CONFIG-01. Commit f80d491.
- Plan 10-03: `DoeOpenDataAdapter` + `TenderNormalizerService` (TDD, real DÖE fixtures, D-02 positive tag-match filter, zip-bomb guard T-10-07) — INGEST-01, SCHEMA-01. Commit 7610778.
- Plan 10-04: `TenderIngestionService` + `TenderSchedulerService` (day-cursor, single global cron, contentHash upsert-update, 90-day retention with null-deadline exemption, two-tenant safety test) — SCHEMA-02, INGEST-06. Commit 9227cc9.
- Plan 10-05: `TendersController` (global read, ModuleGuard-gated) + admin `GET/PUT /modules/tender-radar/source-config` (live-applies interval to scheduler) — INGEST-06. Commit 6d63022.
- Plan 10-06: Admin config UI (`tender-radar-api.ts` client + `SourceConfigForm.tsx` + `settings/page.tsx`) — INGEST-06 admin-facing. Commit 4f3c6cf.
</completed_work>
<remaining_work>
Code: none. Pending human UAT (after Docker rebuild), all from `10-VERIFICATION.md`:
- UAT-1: activate "Ausschreibungs-Radar" for a tenant from the marketplace, confirm the module page loads.
- UAT-2: settings form — change interval / toggle isActive, save → GET/PUT source-config roundtrip works.
- UAT-3: after rebuild, `TenderSourcePollConfig` has 1 row (boot-seed fired).
</remaining_work>
<decisions_made>
- DÖE is a daily-batch export ZIP (not a paginated feed); today/future days return HTTP 400 → scheduler uses a day-cursor, not a since-timestamp. The admin-configurable hourly poll mostly no-ops by design.
- Parse eForms-DE XML as primary (OCDS drops tenderPeriod/value for Unterschwelle notices); OCDS only for ocid/party resolution.
- `Tender` + `TenderSourcePollConfig` are platform-global: no tenantId, no forTenant()/RLS (D-03) — verified in the live schema.
- Single global cron, `findUnique` on fixed sourceType, no `activeTenantId`/`findFirst` (poll-once-fan-out-many, not the DKV single-tenant pattern). Two-tenant test proves 0 extra DÖE calls / cron jobs / rows on 2nd activation.
- adm-zip approved via the supply-chain human-verify checkpoint (cthackers/adm-zip, MIT, since 2012; RESEARCH `[SUS]` flag was a too-new heuristic false positive).
</decisions_made>
<blockers>
- Live container stale: `tessera-ctl-api-1` runs the pre-Phase-10 image. Resolve with `docker compose up -d --build api web`. Not a code defect.
</blockers>
## Required Reading (in order)
1. `.planning/phases/10-ausschreibungs-radar-foundation-d-e-ingestion/10-VERIFICATION.md` — the 3 structured human-verification items + per-criterion findings.
2. `.planning/phases/10-ausschreibungs-radar-foundation-d-e-ingestion/10-RESEARCH.md` — the live-verified DÖE API contract (daily-batch ZIP, day-cursor, eForms-primary).
3. Memory `project_local_db_migrations` — how to reach the local dev DB (no host port; use db container IP).
## Infrastructure State
- Local Docker stack STARTED this session (was down 2 days after a reboot). `db` + `api` up.
- `api` container is on the OLD image — needs rebuild to run Phase 10 code.
- DB migrations applied from host (tender-radar + an older LDAP migration never run locally). `prisma migrate status` = up to date.
- DB reachable only via container IP (no host port): `postgresql://tessera:tessera_dev@172.19.0.2:5432/tessera` (IP ephemeral).
- Boundary: the no-docker-rebuild rule in memory is about the TEST SERVER (192.168.13.12); the local dev machine is fine to rebuild.
<context>
The phase went cleanly through the full GSD pipeline this session: research → validation strategy → pattern map → plan (5) → checker (1 blocker: missing admin config UI) → replan (+Plan 06) → verification passed → execute all 6 waves sequentially on main (worktrees auto-degraded, origin/HEAD unresolved) → goal-backward verify. The only reason this isn't marked fully Complete is the stale live container — everything else is proven.
</context>
<next_action>
Start with: `docker compose up -d --build api web`, then run the 3 UAT checks in `10-VERIFICATION.md`. If green, proceed to `/gsd-discuss-phase 11` (Filter Engine, Results UI & Saved Searches).
</next_action>