feat(14-05): add tenderRadar i18n namespace (DE + EN) with key-parity guard

Introduces the tenderRadar top-level namespace in de.json/en.json covering
page, results, filter (incl. Bundesland/CPV division labels), savedSearch,
detail, coverage, settings, sourceConfig, rssFeeds and emailAlerts groups.
EN translations authored with consistent Vergabe-domain terminology
(Ausschreibung->tender, Vergabestelle->contracting authority, Frist->
deadline, Auftragswert->estimated value). tenderRadar-parity.spec.ts
enforces recursively-flattened de/en key-set equality so no follow-up edit
can silently add a string to only one locale.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-23 14:07:41 +02:00
parent a4889f8399
commit d73171b052
3 changed files with 565 additions and 0 deletions
+253
View File
@@ -571,5 +571,258 @@
"wrongPassword": "Falsches Passwort. PFX/P12-Datei konnte nicht entschluesselt werden.",
"unknownFormat": "Unbekanntes Format. Die Datei konnte nicht als Zertifikat erkannt werden."
}
},
"tenderRadar": {
"page": {
"title": "Ausschreibungs-Radar",
"loading": "Lädt…"
},
"results": {
"colTitle": "Titel",
"colBuyer": "Auftraggeber",
"colDeadline": "Frist",
"colValue": "Wert",
"colPublished": "Veröffentlicht",
"colTriage": "Triage",
"noValue": "keine Wertangabe",
"error": "Ausschreibungen konnten nicht geladen werden.",
"emptyTitle": "Keine Ausschreibungen gefunden.",
"emptyBody": "Passen Sie die Filter an oder deaktivieren Sie „nur noch offene\".",
"markUnread": "Als ungelesen markieren",
"markRead": "Als gelesen markieren",
"readLabel": "Gelesen",
"unreadLabel": "Ungelesen",
"removeFavorite": "Favorit entfernen",
"setFavorite": "Favorit setzen",
"favoriteOn": "★ Favorit",
"favoriteOff": "☆ Favorit",
"showingRange": "Zeige {from}–{to} von {total}",
"prevPage": "← Zurück",
"nextPage": "Weiter →"
},
"filter": {
"sortPublished": "Veröffentlichungsdatum",
"sortDeadline": "Abgabefrist",
"sortValue": "Auftragswert",
"searchLabel": "Suche",
"searchPlaceholder": "Titel oder Auftraggeber…",
"sortLabel": "Sortierung",
"openOnlyLabel": "Nur noch offene",
"favOnlyLabel": "Nur Favoriten/Merkliste",
"deadlineFromLabel": "Abgabefrist von",
"deadlineToLabel": "Abgabefrist bis",
"plzLabel": "PLZ",
"plzPlaceholder": "z. B. 10",
"bundeslandLabel": "Bundesland",
"bundeslandAll": "Alle Bundesländer",
"cpvLabel": "Branche (CPV)",
"cpvPlaceholder": "z. B. Bau, IT, Gesundheit…",
"cpvRemoveAria": "Division {code} entfernen",
"valueMinLabel": "Auftragswert von (€)",
"valueMinPlaceholder": "min.",
"valueMaxLabel": "Auftragswert bis (€)",
"valueMaxPlaceholder": "max.",
"includeNullValueLabel": "Ohne Wertangabe einschließen",
"bundeslandOptions": {
"DE1": "Baden-Württemberg",
"DE2": "Bayern",
"DE3": "Berlin",
"DE4": "Brandenburg",
"DE5": "Bremen",
"DE6": "Hamburg",
"DE7": "Hessen",
"DE8": "Mecklenburg-Vorpommern",
"DE9": "Niedersachsen",
"DEA": "Nordrhein-Westfalen",
"DEB": "Rheinland-Pfalz",
"DEC": "Saarland",
"DED": "Sachsen",
"DEE": "Sachsen-Anhalt",
"DEF": "Schleswig-Holstein",
"DEG": "Thüringen"
},
"cpvDivisions": {
"03": "Landwirtschaftliche, fischereiwirtschaftliche, forstwirtschaftliche und verwandte Erzeugnisse",
"09": "Mineralölerzeugnisse, Brennstoffe, Elektrizität und andere Energiequellen",
"14": "Bergbauerzeugnisse, Grundstoffe und verwandte Erzeugnisse",
"15": "Nahrungsmittel, Getränke, Tabak und verwandte Erzeugnisse",
"16": "Land- und forstwirtschaftliche Maschinen",
"18": "Bekleidung, Schuhe, Reiseartikel und Zubehör",
"19": "Leder- und Textilwaren, Kunststoff- und Gummierzeugnisse",
"22": "Druckerzeugnisse und verwandte Erzeugnisse",
"24": "Chemische Erzeugnisse",
"30": "Büromaschinen, Datenverarbeitungsgeräte, -ausrüstung und -material, ausgenommen Möbel und Softwarepakete",
"31": "Elektrische Maschinen, Geräte, Ausrüstungen und Verbrauchsartikel; Beleuchtung",
"32": "Rundfunk-, Fernseh-, Kommunikations-, Telekommunikations- und verwandte Geräte",
"33": "Medizinische Apparate, pharmazeutische Erzeugnisse und Körperpflegeprodukte",
"34": "Transportausrüstung und Transportzubehör",
"35": "Sicherheits-, Feuerlösch-, Polizei- und Verteidigungsausrüstung",
"37": "Musikinstrumente, Sportartikel, Spiele, Spielzeug, Kunsthandwerk, Kunstmaterial und Zubehör",
"38": "Laborgeräte, optische und Präzisionsgeräte (ausgenommen Gläser)",
"39": "Möbel (einschließlich Büromöbel), Einrichtungsgegenstände, Haushaltsgeräte (ausgenommen Beleuchtung) und Reinigungsmittel",
"41": "Gesammeltes und gereinigtes Wasser",
"42": "Industriemaschinen",
"43": "Maschinen für Bergbau, Steinbruch, Bauwesen",
"44": "Baustoffe und zugehörige Artikel",
"45": "Bauarbeiten",
"48": "Softwarepaket und Informationssysteme",
"50": "Reparatur- und Wartungsdienste",
"51": "Installationsdienste (ausgenommen Software)",
"55": "Beherbergungs-, Gaststätten- und Handelsdienstleistungen",
"60": "Transportdienstleistungen (ohne Abfalltransport)",
"63": "Neben- und Hilfstätigkeiten im Verkehr; Reisebüros",
"64": "Post- und Telekommunikationsdienste",
"65": "Versorgungsbetriebe",
"66": "Finanz- und Versicherungsdienstleistungen",
"70": "Dienstleistungen im Zusammenhang mit Immobilien",
"71": "Architektur-, Bau-, Ingenieur- und Prüfdienste",
"72": "IT-Dienste: Beratung, Software-Entwicklung, Internet und Hilfestellung",
"73": "Forschungs- und Entwicklungsdienste sowie zugehörige Beratung",
"75": "Öffentliche Verwaltung, Verteidigung und Sozialversicherung",
"76": "Dienstleistungen im Zusammenhang mit der Öl- und Gasindustrie",
"77": "Landwirtschaftliche, forstwirtschaftliche, gartenbauliche Dienste, Aquakultur und Imkerei",
"79": "Unternehmensbezogene Dienstleistungen: Recht, Marketing, Consulting, Personal, Druck und Sicherheit",
"80": "Dienstleistungen des Bildungswesens und der Ausbildung",
"85": "Dienste im Gesundheits- und Sozialwesen",
"90": "Abwasser- und Abfallbeseitigung, Reinigung und Umweltschutzdienste",
"92": "Dienstleistungen der Freizeitgestaltung, der Kultur und des Sports",
"98": "Sonstige Gemeinschafts-, Sozial- und Individualdienstleistungen"
}
},
"savedSearch": {
"title": "Suchprofile",
"saveAsLabel": "Aktuelle Filter speichern als",
"namePlaceholder": "Name des Suchprofils…",
"save": "Speichern",
"cancel": "Abbrechen",
"loading": "Lädt…",
"empty": "Noch keine Suchprofile gespeichert.",
"loadTitle": "Suchprofil laden",
"instantAlertTitle": "Sofort-Alert per E-Mail bei neuen Treffern dieses Profils",
"instantAlertLabel": "Sofort-Alert",
"instantAlertAria": "Sofort-Alert für {name}",
"renameTitle": "Umbenennen",
"renameAria": "{name} umbenennen",
"renameConfirmAria": "{name} umbenennen bestätigen",
"renameCancelAria": "Umbenennen abbrechen",
"deleteTitle": "Löschen",
"deleteAria": "{name} löschen",
"errorLoad": "Suchprofile konnten nicht geladen werden.",
"errorSave": "Suchprofil konnte nicht gespeichert werden.",
"errorRename": "Suchprofil konnte nicht umbenannt werden.",
"errorDelete": "Suchprofil konnte nicht gelöscht werden.",
"errorToggleAlert": "Sofort-Alert konnte nicht umgeschaltet werden."
},
"detail": {
"dialogAria": "Ausschreibungsdetails",
"title": "Ausschreibungsdetails",
"close": "Schließen",
"loading": "Lädt…",
"error": "Ausschreibung konnte nicht geladen werden.",
"fieldTitle": "Titel",
"fieldBuyer": "Auftraggeber",
"fieldRegion": "Region / PLZ / Bundesland",
"fieldCpv": "CPV-Codes",
"noCpv": "keine CPV-Codes angegeben",
"fieldDeadline": "Abgabefrist",
"noDeadline": "keine Frist angegeben",
"fieldValue": "Geschätzter Auftragswert",
"noValue": "keine Wertangabe",
"fieldProcedureType": "Verfahrensart",
"fieldStatus": "Status",
"fieldPublished": "Veröffentlicht",
"mirrorNotice": "Vergabeunterlagen werden nicht lokal gespiegelt — der folgende Link führt direkt zum Original auf dem Quellportal.",
"sourceLink": "{portal}: Zur Ausschreibung auf dem Quellportal →",
"noSourceLink": "{portal}: Kein Quell-Link verfügbar.",
"sourceLinkFallback": "Zur Ausschreibung auf dem Quellportal →",
"noSourceLinkFallback": "Kein Quell-Link verfügbar."
},
"coverage": {
"label": "Datenabdeckung:",
"text": "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.",
"denylistLabel": "Manuell beobachten:",
"denylistText": "Diese Portale lassen laut ihren Nutzungsbedingungen keinen automatisierten Zugriff zu und müssen daher manuell geprüft werden:"
},
"settings": {
"title": "Ausschreibungs-Radar — Einstellungen",
"rssSectionTitle": "RSS-Feeds",
"rssSectionBody": "Öffentliche, plattformweite RSS-Quellen (z. B. service.bund.de oder eine subreport-elvis-Kommunalfeed) — gilt für alle Mandanten gleich, nicht pro Mandant konfigurierbar.",
"emailSectionTitle": "E-Mail-Alerts",
"emailSectionBody": "Postfach, in das Vergabeportale Ihre Benachrichtigungsmails schicken — pro Mandant konfigurierbar, getrennt vom DKV-Rechnungspostfach. Aus diesen Mails erkannte Ausschreibungen sind nur für Ihren Mandanten sichtbar.",
"notificationsSectionTitle": "Benachrichtigungen",
"digestIntervalLabel": "Digest-Intervall",
"digestDaily": "Täglich",
"digestWeekly": "Wöchentlich",
"digestOff": "Aus",
"digestHelp": "Fasst neue Treffer aus Ihren Suchprofilen in einer täglichen oder wöchentlichen Sammel-Mail zusammen. „Aus\" deaktiviert den Digest — Sofort-Alerts pro Suchprofil bleiben unabhängig davon nutzbar.",
"saveSuccess": "Einstellung gespeichert.",
"errorLoad": "Benachrichtigungseinstellung konnte nicht geladen werden",
"errorSave": "Benachrichtigungseinstellung konnte nicht gespeichert werden"
},
"sourceConfig": {
"errorLoad": "Konfiguration konnte nicht geladen werden",
"errorSave": "Einstellungen konnten nicht gespeichert werden",
"validationError": "Intervall muss zwischen {min} und {max} Minuten liegen.",
"sourceLabel": "Quelle",
"lastIngestedLabel": "Zuletzt erfasster Tag",
"neverIngested": "Noch keine Erfassung",
"pollIntervalLabel": "Abrufintervall (Minuten) *",
"minutesSuffix": "Min.",
"pollIntervalHelp": "Cron-Taktfrequenz ({min}–{max} Min.) — der eigentliche DÖE-Abruf ist zusätzlich über den Tages-Cursor gedrosselt.",
"activeLabel": "Aktiv",
"saving": "Speichert...",
"save": "Speichern",
"saveSuccess": "Einstellungen gespeichert."
},
"rssFeeds": {
"errorLoad": "RSS-Feeds konnten nicht geladen werden",
"errorAdd": "RSS-Feed konnte nicht gespeichert werden",
"errorRemove": "RSS-Feed konnte nicht entfernt werden",
"validationRequired": "URL und Bezeichnung sind erforderlich.",
"empty": "Noch keine RSS-Feeds hinterlegt.",
"activeLabel": "aktiv",
"inactiveLabel": "inaktiv",
"removeAria": "RSS-Feed \"{label}\" entfernen",
"removing": "Entfernt...",
"remove": "Entfernen",
"urlLabel": "Feed-URL *",
"urlPlaceholder": "https://www.service.bund.de/.../RSSGenerator_Ausschreibungen.xml",
"labelLabel": "Bezeichnung *",
"labelPlaceholder": "z. B. service-bund",
"adding": "Wird hinzugefügt...",
"add": "Feed hinzufügen"
},
"emailAlerts": {
"notSaved": "Noch nicht gespeichert — Postfach-Konfiguration ausfüllen und speichern.",
"protocolLabel": "Protokoll *",
"protocolImap": "IMAP",
"protocolExchange": "Exchange",
"hostLabelExchange": "EWS-Endpunkt-URL",
"hostLabelImap": "IMAP-Server",
"hostPlaceholderExchange": "https://mail.firma.de/EWS/Exchange.asmx",
"hostPlaceholderImap": "imap.firma.de",
"portLabel": "Port *",
"encryptionLabel": "Verschlüsselung *",
"encryptionNone": "Keine",
"encryptionStarttls": "STARTTLS",
"encryptionSslTls": "SSL-TLS",
"folderLabel": "Ordner",
"folderPlaceholderExchange": "Inbox",
"folderPlaceholderImap": "INBOX",
"domainLabel": "Windows-Domäne",
"domainPlaceholder": "CONTOSO",
"senderFilterLabel": "Absenderfilter",
"senderFilterPlaceholder": "alerts@vergabeportal.de",
"usernameLabel": "Benutzername",
"passwordLabel": "Passwort",
"passwordPlaceholder": "••••••••",
"showPassword": "Passwort anzeigen",
"hidePassword": "Passwort verbergen",
"activeLabel": "Aktiv",
"saving": "Wird gespeichert...",
"save": "Speichern",
"saveSuccess": "Einstellungen gespeichert.",
"errorSave": "Einstellungen konnten nicht gespeichert werden"
}
}
}