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>
This commit is contained in:
+2
-1
@@ -8,7 +8,7 @@ status: complete
|
|||||||
stopped_at: Phase 16 abgeschlossen — UAT durchgefuehrt, kritischer Sweep-Fehler gefunden und behoben (260811-f9i), Rest-Annahme A1 bewusst als offen akzeptiert
|
stopped_at: Phase 16 abgeschlossen — UAT durchgefuehrt, kritischer Sweep-Fehler gefunden und behoben (260811-f9i), Rest-Annahme A1 bewusst als offen akzeptiert
|
||||||
last_updated: "2026-08-11T09:25:00.000Z"
|
last_updated: "2026-08-11T09:25:00.000Z"
|
||||||
last_activity: 2026-08-11
|
last_activity: 2026-08-11
|
||||||
last_activity_desc: Phase 16 UAT abgeschlossen; objectGUID-Existenzpruefung repariert
|
last_activity_desc: DOE-Bekanntmachungslinks repariert (260811-j04)
|
||||||
progress:
|
progress:
|
||||||
total_phases: 16
|
total_phases: 16
|
||||||
completed_phases: 15
|
completed_phases: 15
|
||||||
@@ -309,6 +309,7 @@ None yet.
|
|||||||
| 260728-lih | LDAP: Sync strikt selektiv (leere Auswahl = No-Op statt Voll-Import) + Auto-Sync-Default aus (syncIntervalMin 60→0) | 2026-07-28 | c54e424,57bc7f9,63a07ab | [260728-lih-ldap-sync-selektiv-und-auto-sync-default](.planning/quick/260728-lih-ldap-sync-selektiv-und-auto-sync-default/) |
|
| 260728-lih | LDAP: Sync strikt selektiv (leere Auswahl = No-Op statt Voll-Import) + Auto-Sync-Default aus (syncIntervalMin 60→0) | 2026-07-28 | c54e424,57bc7f9,63a07ab | [260728-lih-ldap-sync-selektiv-und-auto-sync-default](.planning/quick/260728-lih-ldap-sync-selektiv-und-auto-sync-default/) |
|
||||||
| 260729-d3k | LDAP: Multi-Base-DN und Base-DN als Sync-Scope (statt leerer Gruppenfilter = No-Op) | 2026-07-29 | 5cbd530,96be7e1 | [260729-d3k-ldap-multi-base-dn-und-base-dn-als-scope](.planning/quick/260729-d3k-ldap-multi-base-dn-und-base-dn-als-scope/) |
|
| 260729-d3k | LDAP: Multi-Base-DN und Base-DN als Sync-Scope (statt leerer Gruppenfilter = No-Op) | 2026-07-29 | 5cbd530,96be7e1 | [260729-d3k-ldap-multi-base-dn-und-base-dn-als-scope](.planning/quick/260729-d3k-ldap-multi-base-dn-und-base-dn-als-scope/) |
|
||||||
| 260805-d0r | Benutzer-Detail zeigte Gruppenmitgliedschaften aus Freigaben statt aus Mitgliedschaften — GET /module-grants/users/:userId liefert jetzt { groups, modules }, Chips mit Herkunfts-Badge; im Browser gegengeprüft: Mitgliedschaft bleibt sichtbar, auch wenn die Gruppe kein Modul freigibt | 2026-08-05 | ecadf69,f8ff74b,8ce3748 | [260805-d0r-benutzer-detail-zeigt-gruppenmitgliedsch](.planning/quick/260805-d0r-benutzer-detail-zeigt-gruppenmitgliedsch/) |
|
| 260805-d0r | Benutzer-Detail zeigte Gruppenmitgliedschaften aus Freigaben statt aus Mitgliedschaften — GET /module-grants/users/:userId liefert jetzt { groups, modules }, Chips mit Herkunfts-Badge; im Browser gegengeprüft: Mitgliedschaft bleibt sichtbar, auch wenn die Gruppe kein Modul freigibt | 2026-08-05 | ecadf69,f8ff74b,8ce3748 | [260805-d0r-benutzer-detail-zeigt-gruppenmitgliedsch](.planning/quick/260805-d0r-benutzer-detail-zeigt-gruppenmitgliedsch/) |
|
||||||
|
| 260811-j04 | DOE-Ausschreibungen verlinkten auf die API (rohes JSON) statt auf die Bekanntmachung — betraf Trefferliste, Detailansicht und Alarm-Mails. Adapter baut die URL jetzt aus der Bekanntmachungsnummer, Migration schreibt 2846 bestehende Zeilen in Tender und TenderSource um. Zielseite im Browser fuer beide Kennungsformen verifiziert (numerisch und UUID) — ein HTTP-Statuscheck taugt dort nicht, die Seite antwortet auf jede Kennung mit 200 | 2026-08-11 | ecf7872 | [260811-j04-doe-tender-links-point-to-the-api-instea](.planning/quick/260811-j04-doe-tender-links-point-to-the-api-instea/) |
|
||||||
| 260811-f9i | KRITISCH: objectGUID-Existenzpruefung fand nie etwas — der Filter wurde als `\xx`-escapter String gebaut, ldapts wandelt das nicht in Rohbytes; beide Suchen (Base-DNs und WR-03-Fallback) teilten ihn, also haette der erste echte Sync JEDE AD-gebundene Gruppe samt Mitgliedschaften und Modulfreigaben geloescht. Jetzt EqualityFilter ueber den rohen Buffer, `escapeLdapFilterBuffer()` entfernt. Read-only am echten AD gemessen (escapter String 0 Treffer, EqualityFilter 1 korrekter Treffer); Regressionstests gegengeprueft (alter Code = 8 rote Tests) | 2026-08-11 | d2019dc | [260811-f9i-fix-objectguid-existence-sweep-to-use-eq](.planning/quick/260811-f9i-fix-objectguid-existence-sweep-to-use-eq/) |
|
| 260811-f9i | KRITISCH: objectGUID-Existenzpruefung fand nie etwas — der Filter wurde als `\xx`-escapter String gebaut, ldapts wandelt das nicht in Rohbytes; beide Suchen (Base-DNs und WR-03-Fallback) teilten ihn, also haette der erste echte Sync JEDE AD-gebundene Gruppe samt Mitgliedschaften und Modulfreigaben geloescht. Jetzt EqualityFilter ueber den rohen Buffer, `escapeLdapFilterBuffer()` entfernt. Read-only am echten AD gemessen (escapter String 0 Treffer, EqualityFilter 1 korrekter Treffer); Regressionstests gegengeprueft (alter Code = 8 rote Tests) | 2026-08-11 | d2019dc | [260811-f9i-fix-objectguid-existence-sweep-to-use-eq](.planning/quick/260811-f9i-fix-objectguid-existence-sweep-to-use-eq/) |
|
||||||
| 260805-fok | Standardgruppe bei Mandanten-Anlage + Startup-Reparatur — GroupsService.ensureDefaultGroup(tenantId) mit D-13-Waechter (null Gruppen, nicht fehlende Markierung), verdrahtet in TenantService.create und AdminSeedService.ensureDefaultGroupsForAllTenants; schliesst die Migrations-Backfill-Luecke auf frischen Installationen (Testserver: tenants=1 users=4 groups=0) | 2026-08-05 | 9d1254c,0d7d8a5 | [260805-fok-standardgruppe-bei-mandanten-anlage-und-](.planning/quick/260805-fok-standardgruppe-bei-mandanten-anlage-und-/) |
|
| 260805-fok | Standardgruppe bei Mandanten-Anlage + Startup-Reparatur — GroupsService.ensureDefaultGroup(tenantId) mit D-13-Waechter (null Gruppen, nicht fehlende Markierung), verdrahtet in TenantService.create und AdminSeedService.ensureDefaultGroupsForAllTenants; schliesst die Migrations-Backfill-Luecke auf frischen Installationen (Testserver: tenants=1 users=4 groups=0) | 2026-08-05 | 9d1254c,0d7d8a5 | [260805-fok-standardgruppe-bei-mandanten-anlage-und-](.planning/quick/260805-fok-standardgruppe-bei-mandanten-anlage-und-/) |
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
---
|
||||||
|
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.
|
||||||
+6
@@ -1,5 +1,11 @@
|
|||||||
---
|
---
|
||||||
created: 2026-08-05
|
created: 2026-08-05
|
||||||
|
resolved: 2026-08-11
|
||||||
|
resolution: |
|
||||||
|
Behoben in Quick-Task 260811-j04, Commit ecf7872. Der User hat sich fuer die
|
||||||
|
Bekanntmachungsseite entschieden (nicht fuer den Link auf das ausschreibende
|
||||||
|
Portal). Adapter baut die URL jetzt aus der Bekanntmachungsnummer, Migration
|
||||||
|
20260811120000_doe_notice_url_backfill schreibt die 2846 bestehenden Zeilen um.
|
||||||
title: DÖE-Ausschreibungen verlinken auf die API statt auf die Bekanntmachungsseite
|
title: DÖE-Ausschreibungen verlinken auf die API statt auf die Bekanntmachungsseite
|
||||||
area: tender-radar
|
area: tender-radar
|
||||||
severity: major
|
severity: major
|
||||||
Reference in New Issue
Block a user