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

2.9 KiB

quick_id, slug, date, status, relates_to, closes_todo, commits
quick_id slug date status relates_to closes_todo commits
260811-j04 doe-tender-links-point-to-the-api-instea 2026-08-11 complete tender-radar 2026-08-05-ausschreibungsportal-falsche-url
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.