--- created: 2026-08-11 completed: 2026-08-12 title: Ausschreibungs-Radar — Einstellungsseite mischt Administration und persoenliche Einstellung area: tender-radar severity: minor trigger: wenn das Modul das erste Mal von normalen Nutzern verwendet wird, nicht nur von Admins files: - apps/web/src/app/(portal)/modules/tender-radar/settings/page.tsx - apps/web/src/app/(portal)/settings/general/account - apps/api/src/tenders/tenders.controller.ts resolution_commits: - 05b1d29 - 55ceb24 - adb72f6 - 9616155 - 7dee116 - 4100bb5 - 150046e --- ## Problem `/modules/tender-radar/settings` traegt vier Abschnitte, die drei verschiedenen Zustaendigkeiten gehoeren: | Abschnitt | Gehoert | |---|---| | Quelle (Abrufintervall, Aktiv) | Plattform-Administration | | RSS-Feeds | Plattform-Administration (ausdruecklich fuer alle Mandanten gleich) | | E-Mail-Alerts (Postfach) | Mandanten-Administration | | **Benachrichtigungen (Digest-Intervall)** | **dem einzelnen Nutzer** | Das Digest-Intervall ist die einzige persoenliche Einstellung auf der Seite — `TenderNotificationPref` haengt an `userId`, nicht am Mandanten (NOTIFY-01/D-03). Sie steht als letzter Abschnitt unter drei Bloecken, die ein normaler Nutzer weder aendern darf noch braucht. Wer nur seinen Digest auf woechentlich stellen will, scrollt an Abrufintervallen, Feed-URLs und Postfach-Zugangsdaten vorbei. **Kein Berechtigungsloch:** die zugehoerigen API-Endpunkte (`source-config`, `rss-feeds`, Postfach) sind serverseitig mit `@Roles(ADMIN, SUPER_ADMIN)` abgesichert (`tenders.controller.ts`). Ein normaler Nutzer kann dort also nichts verstellen — er sieht die Bedienelemente aber und laeuft beim Speichern in eine Fehlermeldung, weil die Seite selbst keine Rollenpruefung hat. Aufgefallen am 2026-08-11 beim Erklaeren des Moduls: der User fragte, wo man die Benachrichtigungsfrequenz einstellt, und die ehrliche Antwort war "ganz unten auf der Admin-Seite". ## Solution Richtung, nicht beschlossen — der zweite Punkt ist eine Produktfrage: 1. **Die Admin-Abschnitte hinter eine Rollenpruefung legen**, damit ein normaler Nutzer sie gar nicht erst sieht. Kleinster sinnvoller Schritt, loest den Fehlermeldungs-Fall und den groessten Teil der Verwirrung. 2. **Wohin gehoert die persoenliche Einstellung?** Es gibt bereits `/settings/general/account` fuer nutzereigene Einstellungen. Drei Varianten: - Digest-Intervall dorthin verschieben — konsequent, aber modulfremde Einstellungen in einer allgemeinen Seite sammeln sich mit jedem weiteren Modul an. - Im Modul lassen, aber sichtbar abgetrennt und oberhalb der Admin-Bloecke. - Eine eigene, nutzerseitige Modulseite ("Meine Benachrichtigungen") getrennt von der Admin-Seite. Die Antwort betrifft nicht nur dieses Modul: DKV-Fleet hat dieselbe Bauform (`modules/dkv-fleet/settings`), und jedes kuenftige Modul mit persoenlichen Einstellungen wird die Frage erneut stellen. Sinnvollerweise einmal grundsaetzlich entscheiden statt pro Modul. ## Resolution (2026-08-12) Beim Durchsprechen dieses Zettels mit dem User stellte sich heraus, dass die urspruengliche Diagnose zu eng war — nicht nur das Digest-Intervall gehoerte dem einzelnen Nutzer, auch das Postfach und die RSS-Feeds waren inhaltlich falsch zugeschnitten ("Wenn Person A ihre Ausschreibungen auf kontoa@mail.de und Person B von kontob@mail.de holt, macht eine gemeinsame Einstellung keinen Sinn"). Der User hat festgehalten, dass seine urspruengliche Zustimmung zur gemeinsamen Konfiguration auf einer missverstaendlichen Erklaerung meinerseits beruhte — keine Meinungsaenderung, eine Korrektur. Daraus wurde Phase 17 mit drei Plaenen statt einer kleinen Rollenpruefung: **Zwei Entscheidungen, die der User im Gespraech getroffen hat:** - **Eigene Quellen je Nutzer.** `TenderEmailConfig` wechselt von `tenantId @unique` auf `userId @unique` (D-01), `TenderRssFeedSource` bekommt ein nullable `userId` — plattformweite Feeds (der seit Phase 14 aktive service.bund.de-Feed) bleiben fuer alle bestehen, jeder Nutzer kann zusaetzlich eigene Feeds anlegen (D-02). Umgesetzt in 05b1d29/55ceb24 (Plan 17-01) und adb72f6/9616155/7dee116 (Plan 17-02). - **Trefferliste bleibt plattform-global (D-05, harte Grenze).** Explizit gegengefragt und bestaetigt: "Reicht dir 'jeder speist seine eigenen Quellen ein, gesehen wird alles gemeinsam'?" → "Ja, plane". `Tender` bleibt ohne `tenantId`/RLS — geaendert wird nur, WER Quellen einspeist, nicht WER Treffer sieht. Was ueber das Postfach oder einen Feed von Nutzer A hereinkommt, steht danach auch in der Trefferliste von Nutzer B desselben Mandanten. Diese Konsequenz benennt die Oberflaeche jetzt ehrlich (`mySources.intro`, `mySources.platformFeedsNote`). **Offener Punkt 4 (wohin mit den nutzereigenen Abschnitten) ist damit ebenfalls beantwortet:** eine eigene, nutzerseitige Modulseite (`/modules/tender-radar/my-sources`, "Meine Quellen") statt einer Erweiterung von `/settings/general/account` — modulspezifische Einstellungen bleiben beim Modul statt sich auf einer allgemeinen Seite anzusammeln. Das ist ab jetzt die Bauform, an der sich DKV-Fleet und kuenftige Module mit persoenlichen Einstellungen orientieren. **Offener Punkt 5 (Rollenpruefung) schliesst Plan 17-03** (4100bb5, 150046e): `/modules/tender-radar/settings` traegt nur noch, was tatsaechlich Plattform-Administration ist — Abrufintervall und plattformweite RSS-Feeds — und prueft die Rolle aus dem Anmelde-Speicher rein zur Anzeige (die verbindliche Pruefung bleibt serverseitig, `@UseModule('tender-radar')` + Inline-Rollencheck fuer `scope: 'platform'`, T-17-08). Ein normaler Nutzer sieht dort keine Bedienelemente mehr, die beim Speichern in eine Fehlermeldung liefen — genau der urspruengliche Anlass dieses Zettels. Postfach, eigene Feeds und Benachrichtigungsintervall leben jetzt vollstaendig auf "Meine Quellen"; das Zahnrad auf der Modulseite fuehrt jeden Nutzer dorthin. **Nicht ausgefuehrt:** die Browser-Gegenprobe aus den `human-check`-Schritten der Plaene 17-01 bis 17-03 (kein Browser-Tool in den jeweiligen Sitzungen verfuegbar) — festgehalten in WINDOWS.md (#7 und Folge-Eintraege), vor `/gsd-ship` nachzuholen.