-
Datenabdeckung: Aktuell
- werden nur EU-weite Oberschwellen-Ausschreibungen aus der zentralen
- DÖE-Quelle erfasst. Unterschwellen-Vergaben einzelner Vergabestellen
- fehlen noch — eine kurze Trefferliste ist daher kein Fehler.
+ {showCoverageNote && (
+
+ Datenabdeckung: Aktuell
+ werden nur EU-weite Oberschwellen-Ausschreibungen aus der zentralen
+ DÖE-Quelle erfasst. Unterschwellen-Vergaben einzelner Vergabestellen
+ fehlen noch — eine kurze Trefferliste ist daher kein Fehler.
+
+ )}
+ {denylistedPortals.length > 0 && (
+
+ Manuell beobachten:{' '}
+ Diese Portale lassen laut ihren Nutzungsbedingungen keinen
+ automatisierten Zugriff zu und müssen daher manuell geprüft werden:{' '}
+ {denylistedPortals.map((p, i) => (
+
+ {i > 0 && ', '}
+
+ {p.portal}
+
+
+ ))}
+ .
+
+ )}
);
}
diff --git a/apps/web/src/lib/tender-radar-api.ts b/apps/web/src/lib/tender-radar-api.ts
index 8237960..3730803 100644
--- a/apps/web/src/lib/tender-radar-api.ts
+++ b/apps/web/src/lib/tender-radar-api.ts
@@ -83,6 +83,21 @@ export interface CoverageResponse {
sources: Array<{ sourcePortal: string; count: number }>;
}
+/**
+ * A single AGB-denylisted portal (UI-06/D-12) — vergabe24/aumass must be
+ * watched manually. `url` is the canonical direct-link, sourced server-side
+ * from `PORTAL_URLS` (source-registry.ts), never hardcoded here.
+ */
+export interface DenylistedPortal {
+ portal: string;
+ url: string;
+}
+
+/** Response shape of GET /modules/tender-radar/denylisted-portals (UI-06/D-12). */
+export interface DenylistedPortalsResponse {
+ portals: DenylistedPortal[];
+}
+
// --- API functions ---
/**
@@ -149,6 +164,20 @@ export async function fetchCoverage(): Promise