42 lines
3.6 KiB
Markdown
42 lines
3.6 KiB
Markdown
# v1.1 Ausschreibungs-Radar — Milestone Audit
|
||
|
||
**Milestone:** v1.1 (Phasen 10–14)
|
||
**Audited:** 2026-07-24
|
||
**Verdict:** GAPS — 1 neuer Blocker, 1 Warnung, 2 akzeptierte Deferrals
|
||
|
||
## Phasen-Verifikationen (aggregiert)
|
||
|
||
| Phase | Status | Score |
|
||
|-------|--------|-------|
|
||
| 10 Foundation & DÖE | passed | 5/5 |
|
||
| 11 Filter/UI/Saved Searches | passed | 5/5 |
|
||
| 12 Notifications | passed | 4/4 |
|
||
| 13 Scraping-Adapter + Dedup | gaps_found | 3/4 (Truth 3 Dedup dormant, Option C) |
|
||
| 14 RSS/E-Mail/Rollout | human_needed | 4/5 (EWS-Live-Test offen) |
|
||
|
||
Alle 24 Requirements sind in REQUIREMENTS.md als `[x]` markiert. Der Integrations-Checker bestätigt: die Ingestion-Pipeline aller 5 Quellen ist verdrahtet (Registry → pollDueSources → Normalizer → Tender), Filter/UI/Notifications/Denylist/i18n sind end-to-end verbunden. ABER:
|
||
|
||
## BLOCKER — NetServer/cosinex-Adapter haben keinen Aktivierungspfad
|
||
|
||
**Betroffene REQ-IDs: INGEST-02, INGEST-03, CONFIG-02 (teilweise)**
|
||
|
||
- `ai-netserver` und `cosinex-dtvp` `TenderSourcePollConfig`-Zeilen werden mit `isActive: false` geseedet, Kommentar „activation deferred to Phase 14 UI".
|
||
- Aber Phase 14 hat diese UI nie geliefert: `SourceConfigDto` (`dto/source-config.dto.ts`) hat KEIN `sourceType`-Feld; `GET/PUT /modules/tender-radar/source-config` (`tenders.controller.ts:43,190-215`) ist auf `DOE_SOURCE_TYPE = 'doe-opendata'` hartverdrahtet. `SourceConfigForm.tsx` spricht denselben Single-Source-Endpoint an.
|
||
- Es existiert KEINE Route/Service-Methode/UI, die `isActive` für `ai-netserver`/`cosinex-dtvp` umschalten kann.
|
||
- Netto: Die in Phase 13 gebauten, getesteten, registrierten Adapter (INGEST-02/03) sind produktiv unerreichbar — sie bleiben für immer `isActive:false` (außer manuellem DB-Write). Widerspricht Phase-13-Kriterien 1/2 und CONFIG-02 („Admin verwaltet Quellen-Poll-Konfiguration").
|
||
|
||
**Fix (klein):** `SourceConfigDto`/Endpoint auf beliebigen `sourceType` generalisieren (nicht nur DÖE) + `SourceConfigForm` alle pollbaren Quellen auflisten und togglebar machen. Denylist-Gate bleibt (vergabe24/aumass werden ohnehin nicht registriert).
|
||
|
||
## WARNUNG — Scheduler-Cron hängt allein am DÖE-Config
|
||
|
||
`TenderSchedulerService.onApplicationBootstrap()` (`tender-scheduler.service.ts:73-89`) registriert den einen globalen Cron NUR, wenn `doe-opendata` aktiv ist; die admin `source-config` PUT-Route ruft `stopJob()`, wenn DÖE deaktiviert wird. Da dieser eine Cron via `pollDueSources()` ALLE aktiven Quellen fächert, würde ein Deaktivieren von DÖE still auch RSS + E-Mail-Ingestion abschalten. Architektur-Schuld (Phase-13/14-Fan-out auf Phase-10-Single-Source-Scheduler gesetzt, ohne die Bootstrap/Stop-Bedingung auf „irgendeine aktive Quelle" umzustellen). Nicht user-facing im Normalfall (DÖE ist active-by-default, kein Toggle für die anderen exponiert) → WARNUNG, nicht Blocker.
|
||
|
||
## Akzeptierte Deferrals (keine neuen Findings)
|
||
|
||
1. **SCHEMA-03 Cross-Source-Fingerprint-Dedup dormant** — `dedupActive = activePortalCount >= 2`; Fingerprint-CPV-Asymmetrie (Option C, 13-VERIFICATION.md). Hinweis: durch den Blocker oben verschärft — mit inaktiven NetServer/cosinex sind praktisch nur DÖE+RSS aktiv, echte Cross-Source-Overlaps bleiben unwahrscheinlich.
|
||
2. **14-03 EWS/Exchange-Live-Test** — braucht echtes Postfach, vom User bewusst vertagt.
|
||
|
||
## Empfehlung
|
||
|
||
Den Blocker (Quellen-Aktivierungs-UI) vor dem formalen v1.1-Abschluss schließen — er ist klein und macht INGEST-02/03 + CONFIG-02 erst wirklich wahr. Die Scheduler-Warnung optional gleich mitnehmen. EWS-Test + Dedup-dormant bleiben legitime „braucht-Live-Daten"-Deferrals nach v1.2.
|