Files
tessera-ctl/.planning/quick/260811-j04-doe-tender-links-point-to-the-api-instea/SUMMARY.md
T
schalli 637866b9f2
Tessera CI/CD / Lint & Type Check (push) Successful in 44s
Tessera CI/CD / Tests (push) Successful in 54s
Tessera CI/CD / Build & Publish Images (push) Successful in 28s
docs: close the DOE notice-link backlog item
Records the user's choice between the two candidate link targets (the notice
page on oeffentlichevergabe.de, not the awarding portal's own page), what was
checked before touching the adapter, and the trap in verifying it: the target
is a single-page app that answers 200 with an identical shell for any id, so
only rendered content proves the link works.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 13:45:44 +02:00

65 lines
2.9 KiB
Markdown

---
quick_id: 260811-j04
slug: doe-tender-links-point-to-the-api-instea
date: 2026-08-11
status: complete
relates_to: tender-radar
closes_todo: 2026-08-05-ausschreibungsportal-falsche-url
commits:
- ecf7872 fix(tenders): link DOE notices to the notice page, not the API
---
# Summary: DÖE-Ausschreibungen verlinken auf die Bekanntmachungsseite
## Entscheidung des Users
Von den beiden möglichen Zielen — Bekanntmachungsseite auf oeffentlichevergabe.de
oder Link auf das ausschreibende Portal selbst (`tender.documents[0].url`) — hat
der User am 2026-08-11 die **Bekanntmachungsseite** gewählt.
## Was gemacht wurde
`doe-opendata.adapter.ts` baut `sourceUrl` jetzt über die neue Funktion
`buildDoeNoticeUrl()` aus der Bekanntmachungsnummer, statt `ocdsDocument.uri`
durchzureichen. Die Nummer liegt ohnehin schon als `sourceNoticeId` im Datensatz,
es braucht also keinen zweiten Abruf.
Dazu die Migration `20260811120000_doe_notice_url_backfill`, die die bereits
importierten Zeilen umschreibt — in `Tender` und in `TenderSource`, weil die
Detailansicht die Quell-Links zusammengeführter Ausschreibungen einzeln auflistet.
## Was vorher geprüft wurde
- **Ist `ocdsDocument.uri` anderswo als Kennung in Gebrauch?** Nein — die einzige
Verwendung im gesamten Code war genau diese eine Zeile.
- **Ist die Nummer in der API-URL dieselbe wie `releases[0].id`?** Ja, live gegen
den Feed geprüft. Der eine auffällige Datensatz in der Datenbank
(`sourceNoticeId` 25671684, URL auf 25671680) stammt nicht aus einer
Feld-Verwechslung, sondern aus der Dedup-Zusammenführung zweier echter,
gleichnamiger Bekanntmachungen ("Bauleistungen"). Nach dem Backfill folgt die
URL der Kennung der Zeile und ist damit in sich stimmig.
- **Funktioniert die Zielseite für beide Kennungsformen?** Ja, im Browser
verifiziert: numerisch (25673764 → "Feuerwehr-Gerätehaus Miehlen
Fliesenarbeiten") und als UUID (7085ba12-… → "Holzfassade").
- **Reicht ein HTTP-Statuscheck?** Nein, und das ist die Falle an dieser Stelle:
die Zielseite ist eine Single-Page-App und antwortet auf JEDE Kennung mit 200
und identischen 1309 Bytes, auch auf `NONSENSE123`. Nur der gerenderte Inhalt
beweist etwas.
- **Wie viele Zeilen betrifft der Nachlauf?** Read-only auf alpha gezählt: 2846
DÖE-Zeilen betroffen, 0 fallen durch die Kennungsprüfung.
## Verifikation
- `pnpm --filter @tessera/api test` — 575 Tests grün (41 Dateien)
- `npx tsc --noEmit` — sauber
- Neue Tests: der Adapter setzt für jeden Datensatz die Bekanntmachungs-URL und
nie mehr `/api/notices/`; `buildDoeNoticeUrl()` escapet die Kennung; das
Migrations-SQL fasst beide Tabellen an, ist idempotent und rührt andere Portale
nicht an.
## Offen
Der Nachlauf läuft erst beim nächsten Deploy an, weil Migrationen beim
Containerstart ausgeführt werden. Danach im Browser gegenprüfen, dass ein
Treffer aus der Liste auf der Bekanntmachung landet.