Files
tessera-ctl/.planning/phases/17-eigene-ausschreibungs-quellen-je-nutzer/17-03-SUMMARY.md
T
schalli 4453e86626
Tessera CI/CD / Lint & Type Check (push) Successful in 46s
Tessera CI/CD / Tests (push) Successful in 53s
Tessera CI/CD / Build & Publish Images (push) Successful in 1m58s
docs(17-03): complete UI-Aufteilung Meine Quellen vs. Administration plan
2026-08-12 12:06:31 +02:00

16 KiB
Raw Blame History

phase, plan, subsystem, tags, requires, provides, affects, actuals, tech-stack, key-files, key-decisions, requirements-completed, coverage, duration, completed, status
phase plan subsystem tags requires provides affects actuals tech-stack key-files key-decisions requirements-completed coverage duration completed status
17-eigene-ausschreibungs-quellen-je-nutzer 03 ui
nextjs
next-intl
zustand
vitest
testing-library
phase provides
17-01 TenderEmailConfig per-user, /modules/tender-radar/my-sources (Seite mit Postfach-Abschnitt)
phase provides
17-02 RssFeedSource.isPlatformWide-Vertrag (GET/POST /rss-feeds, scope-Wunsch, Besitz-basierter Loeschschutz)
my-sources/page.tsx vollstaendig: Postfach + eigene Feeds + Digest-Intervall auf einer Seite
RssFeedListForm mit scope-Prop (personal/platform) — eine Komponente fuer beide Seiten
DigestIntervalForm als eigenstaendige Komponente (aus settings/page.tsx herausgeloest)
settings/page.tsx auf reine Administration reduziert, Anzeige-Rollenpruefung ueber useAuthStore
Zahnrad auf der Modulseite fuehrt zu /my-sources statt /settings
REQUIREMENTS.md SRC-01..05 Sektion + Traceability (fehlte bisher trotz Nutzung in 17-01/17-02-SUMMARY)
dkv-fleet-settings-restructuring
future-per-user-module-settings
tokens tasks commits
18180 3 3
added patterns
Eine Formkomponente mit einem scope-Prop (personal/platform) statt zwei fast identischer Komponenten — der Server entscheidet ueber Berechtigung, das Prop entscheidet nur ueber Darstellung und den scope-Wunsch im Request
Anzeige-Rollenpruefung ueber useAuthStore in der Seite selbst (drei Zustaende: unbekannt/Platzhalter, erlaubt/Inhalt, verweigert/Hinweis+Verweis) statt eines Guards oder Redirects — verbindliche Pruefung bleibt serverseitig
Verhaltensunveraendertes Herausloesen einer Komponente aus einer Seite ohne neue i18n-Schluessel, wenn nur der Ort wechselt, nicht das Verhalten (DigestIntervalForm)
created modified
apps/web/src/app/(portal)/modules/tender-radar/settings/components/DigestIntervalForm.tsx
apps/web/src/app/(portal)/modules/tender-radar/my-sources/my-sources.test.tsx
apps/web/src/app/(portal)/modules/tender-radar/settings/settings-roles.test.tsx
apps/web/src/lib/tender-radar-api.ts
apps/web/src/app/(portal)/modules/tender-radar/settings/components/RssFeedListForm.tsx
apps/web/src/app/(portal)/modules/tender-radar/settings/components/RssFeedListForm.test.tsx
apps/web/src/app/(portal)/modules/tender-radar/my-sources/page.tsx
apps/web/src/app/(portal)/modules/tender-radar/settings/page.tsx
apps/web/src/app/(portal)/modules/tender-radar/page.tsx
apps/web/src/messages/de.json
apps/web/src/messages/en.json
.planning/REQUIREMENTS.md
[Rule 3] settings/page.tsx auf RssFeedListForm scope="platform" vorgezogen bereits in Task 1, statt erst in Task 2 — Task 1s eigener Type-Check-Verify verlangt eine kompilierbare RssFeedListForm-Prop-Signatur ueber das ganze Projekt hinweg, gleiches Muster wie in 17-01/17-02
[Rule 1] createRssFeed()-Antwort traegt kein isPlatformWide (nur GET /rss-feeds mappt es serverseitig, T-17-12) — RssFeedListForm setzt das Feld nach dem Anlegen lokal aus dem verwendeten scope, sonst waere ein frisch angelegter plattformweiter Feed bis zum naechsten Neuladen aus seiner eigenen Liste verschwunden
page.settingsTitle bleibt bestehen und wird als Verweistext auf der Nutzerseite fuer Administratoren wiederverwendet (Task 1/2), statt eines separaten neuen Schluessels — neuer Schluessel page.mySourcesTitle nur fuer das umgehaengte Zahnrad
REQUIREMENTS.md um die SRC-01..05-Sektion und Traceability-Zeilen ergaenzt — Luecke aus Plan 17-01/17-02 (dort bereits requirements-completed im SUMMARY-Frontmatter gefuehrt, aber nie in REQUIREMENTS.md selbst nachgezogen), gehoert inhaltlich zum Requirements-Traceability-Schritt dieses Plans
SRC-04
SRC-05
id description requirement verification human_judgment
D1 "Meine Quellen" traegt alle drei nutzereigenen Abschnitte (Postfach, eigene Feeds, Benachrichtigung) auf einer Seite; ein neu angelegter eigener Feed erscheint sofort in der eigenen Liste; plattformweite Feeds erscheinen darunter als nicht bedienbare Aufzaehlung mit Administrations-Hinweis SRC-04
kind ref status
unit apps/web/src/app/(portal)/modules/tender-radar/my-sources/my-sources.test.tsx (5 Tests) pass
kind ref status
unit apps/web/src/app/(portal)/modules/tender-radar/settings/components/RssFeedListForm.test.tsx (scope=personal-Block, 6 Tests inkl. Mischliste mit/ohne Entfernen-Knopf) pass
false
id description requirement verification human_judgment
D2 Die Administrationsseite zeigt nur noch Abrufintervall und plattformweite Feeds; ein Konto ohne ADMIN/SUPER_ADMIN-Rolle sieht dort keine Bedienelemente mehr, sondern Hinweis + Verweis auf "Meine Quellen"; waehrend die Rolle noch unbekannt ist, erscheint weder das eine noch das andere SRC-05
kind ref status
unit apps/web/src/app/(portal)/modules/tender-radar/settings/settings-roles.test.tsx (5 Tests: USER/ADMIN/SUPER_ADMIN/unbekannt/entfernte Ueberschriften) pass
kind ref status
unit apps/web/src/app/(portal)/modules/tender-radar/settings/components/RssFeedListForm.test.tsx (scope=platform-Block, 2 Tests: eigene Feeds tauchen dort nicht auf, scope-Parameter im Request) pass
false
id description requirement verification human_judgment rationale
D3 Das Zahnrad auf der Modulseite fuehrt jeden Nutzer nach /my-sources statt zur admin-only Administrationsseite; Administratoren erreichen die Administrationsseite von dort mit einem Klick SRC-04
true Browser-Gegenprobe (Klick auf das Zahnrad, Navigationsziel im echten Router pruefen) nicht ausgefuehrt — kein Browser-Tool in dieser Session verfuegbar (WINDOWS.md #8/#9). Der Link selbst ist per Testing-Library gegen den gerenderten href geprueft (my-sources.test.tsx, settings-roles.test.tsx), nicht aber die tatsaechliche Client-seitige Navigation im Next.js-Router.
id description requirement verification human_judgment
D4 Alle neuen Beschriftungen liegen in Deutsch und Englisch vor; keine mehr verwendete Beschriftung bleibt verwaist SRC-04
kind ref status
unit Node-Skript-Schluesselvergleich beider Sprachdateien (in allen drei Task-<verify>-Bloecken gelaufen) pass
false
62min 2026-08-12 complete

Phase 17 Plan 03: UI-Aufteilung — "Meine Quellen" vs. Administration Summary

Ausschreibungs-Radar-Oberflaeche in zwei Seiten getrennt: "Meine Quellen" traegt jetzt Postfach, eigene RSS-Feeds und Digest-Intervall auf einer Seite fuer jeden Modulnutzer, die Administrationsseite schrumpft auf Abrufintervall und plattformweite Feeds mit einer Anzeige-Rollenpruefung — der urspruengliche Anlass des Backlog-Punkts ist damit geschlossen.

Performance

  • Duration: 62 min
  • Started: 2026-08-12T09:58:00Z
  • Completed: 2026-08-12T11:00:00Z
  • Tasks: 3
  • Files modified: 13 (3 neu, 10 geaendert) + Backlog-Punkt verschoben + REQUIREMENTS.md ergaenzt

Accomplishments

  • RssFeedSource bekommt das serverseitig gelieferte isPlatformWide-Kennzeichen, createRssFeed einen scope-Parameter (personal/platform, Vorgabe personal) — der Server entscheidet ueber Berechtigung (T-17-08), das Frontend nur ueber Darstellung
  • RssFeedListForm bedient jetzt beide Seiten ueber ein scope-Prop: scope="personal" zeigt die eigenen Feeds editierbar und plattformweite darunter als schlichte, nicht bedienbare Liste mit Administrations-Hinweis; scope="platform" zeigt nur plattformweite Feeds editierbar, eigene Feeds tauchen dort gar nicht auf
  • DigestIntervalForm unveraendert aus settings/page.tsx herausgeloest — dieselbe Logik, dieselben Beschriftungen, jetzt eine eigenstaendige Komponente, die beide Seiten nutzen
  • /modules/tender-radar/my-sources traegt jetzt alle drei nutzereigenen Abschnitte (Postfach, eigene Feeds, Benachrichtigung) auf einer Seite; Administratoren sehen zusaetzlich einen Verweis auf die Administrationsseite
  • /modules/tender-radar/settings zeigt nur noch Abrufintervall und plattformweite Feeds; eine Anzeige-Rollenpruefung ueber den vorhandenen Anmelde-Speicher blendet die Bedienelemente fuer Konten ohne ADMIN/SUPER_ADMIN-Rolle aus (Hinweis + Verweis auf "Meine Quellen" stattdessen) — die verbindliche Pruefung bleibt serverseitig unveraendert
  • Das Zahnrad auf der Modulseite fuehrt jetzt zu "Meine Quellen" statt zur Administrationsseite
  • Backlog-Punkt 2026-08-11-tender-radar-einstellungen-mischen-rollen.md nach todos/completed/ verschoben, mit Resolution-Abschnitt, der beide vom User im Gespraech getroffenen Entscheidungen (eigene Quellen je Nutzer, Trefferliste bleibt plattform-global) und die Antwort auf den offenen Punkt 4 (eigene nutzerseitige Modulseite als Vorbild fuer DKV-Fleet und kuenftige Module) dokumentiert
  • REQUIREMENTS.md um die SRC-01..05-Sektion und Traceability-Zeilen ergaenzt (Luecke aus 17-01/17-02 geschlossen)

Task Commits

Jede Aufgabe wurde einzeln committet:

  1. Task 1: "Meine Quellen" wird vollstaendig — Postfach, eigene Feeds, Benachrichtigung — 4100bb5 (feat)
  2. Task 2: Die Administrationsseite schrumpft auf das, was Administration ist — 150046e (feat)
  3. Task 3: Tests fuer beide Seiten und der Backlog-Punkt wird zugemacht — 809afbc (test)

Plan metadata: wird mit diesem SUMMARY committet (docs)

Files Created/Modified

  • apps/web/src/lib/tender-radar-api.ts — RssFeedSource.isPlatformWide, createRssFeed(payload, scope)
  • apps/web/src/app/(portal)/modules/tender-radar/settings/components/RssFeedListForm.tsx — scope-Prop, editierbare/nicht-editierbare Teillisten, lokale isPlatformWide-Ableitung nach dem Anlegen
  • apps/web/src/app/(portal)/modules/tender-radar/settings/components/RssFeedListForm.test.tsx — auf scope umgestellt, Mischlisten-Faelle fuer beide Scopes ergaenzt
  • apps/web/src/app/(portal)/modules/tender-radar/settings/components/DigestIntervalForm.tsx — neu, unveraendert aus settings/page.tsx herausgeloest
  • apps/web/src/app/(portal)/modules/tender-radar/my-sources/page.tsx — Abschnitte "Meine Feeds" und "Benachrichtigung" ergaenzt, Verweis auf Administrationsseite fuer ADMIN/SUPER_ADMIN
  • apps/web/src/app/(portal)/modules/tender-radar/my-sources/my-sources.test.tsx — neu, 5 Tests
  • apps/web/src/app/(portal)/modules/tender-radar/settings/page.tsx — Postfach-/Benachrichtigungsabschnitt entfernt, Anzeige-Rollenpruefung ueber useAuthStore
  • apps/web/src/app/(portal)/modules/tender-radar/settings/settings-roles.test.tsx — neu, 5 Tests
  • apps/web/src/app/(portal)/modules/tender-radar/page.tsx — Zahnrad zeigt auf /my-sources, neue Beschriftung
  • apps/web/src/messages/de.json, apps/web/src/messages/en.json — neue mySources.*/settings.*/page.mySourcesTitle-Schluessel, drei verwaiste settings.*-Schluessel entfernt
  • .planning/todos/completed/2026-08-11-tender-radar-einstellungen-mischen-rollen.md — verschoben, mit Resolution-Abschnitt
  • .planning/REQUIREMENTS.md — SRC-01..05-Sektion + Traceability ergaenzt

Decisions Made

  • settings/page.tsx bereits in Task 1 auf RssFeedListForm scope="platform" vorgezogen (Rule 3), volle Rollenpruefung + Abschnittsreduktion folgte in Task 2
  • createRssFeeds Antwort traegt kein isPlatformWide — Komponente leitet es lokal aus dem verwendeten scope ab (Rule 1, sonst verschwaende ein frisch angelegter plattformweiter Feed bis zum Neuladen)
  • page.settingsTitle bleibt bestehen und dient jetzt als Verweistext auf der Nutzerseite; neuer Schluessel page.mySourcesTitle nur fuer das umgehaengte Zahnrad
  • REQUIREMENTS.md um SRC-01..05 ergaenzt (gehoert zum Requirements-Traceability-Schritt dieses Plans, schliesst eine Luecke aus 17-01/17-02)

Deviations from Plan

Auto-fixed Issues

1. [Rule 3 - Blocking] settings/page.tsx auf RssFeedListForm scope="platform" vorgezogen aus Task 2 nach Task 1

  • Found during: Task 1 (Type-Check nach Aenderung der RssFeedListForm-Prop-Signatur)
  • Issue: Task 1s eigener Verify verlangt einen fehlerfreien projektweiten Type-Check; settings/page.tsx (Task 2s Datei) rief <RssFeedListForm /> noch ohne das neue Pflicht-Prop scope auf
  • Fix: Minimale Ergaenzung scope="platform" an der bestehenden Aufrufstelle — die vollstaendige Umgestaltung der Seite (Rollenpruefung, Abschnittsreduktion) blieb Task 2 vorbehalten
  • Files modified: apps/web/src/app/(portal)/modules/tender-radar/settings/page.tsx
  • Verification: pnpm --filter @tessera/web type-check fehlerfrei ab Task 1
  • Committed in: 4100bb5 (Task 1 commit)

2. [Rule 1 - Bug] RssFeedListForm leitet isPlatformWide nach dem Anlegen lokal ab

  • Found during: Task 1 (beim Entwurf von handleAdd fuer beide Scopes)
  • Issue: POST /rss-feeds mappt isPlatformWide nicht (nur GET /rss-feeds tut das serverseitig, T-17-12) — ein frisch angelegter Eintrag haette das Feld undefined, wodurch ein neu angelegter plattformweiter Feed (scope="platform") faelschlich aus der eigenen editierbaren Liste gefallen waere, bis zum naechsten Neuladen
  • Fix: Nach erfolgreichem createRssFeed(...) wird isPlatformWide clientseitig aus dem verwendeten scope gesetzt (scope === 'platform'), statt sich auf ein vom Server nicht geliefertes Feld zu verlassen
  • Files modified: apps/web/src/app/(portal)/modules/tender-radar/settings/components/RssFeedListForm.tsx
  • Verification: RssFeedListForm.test.tsx deckt beide Scopes explizit ab ("die neue Feed landet sofort in der editierbaren Liste, mit funktionierendem Entfernen-Knopf")
  • Committed in: 4100bb5 (Task 1 commit)

Total deviations: 2 auto-fixed (1× Rule 3 Kompilierfaehigkeit, 1× Rule 1 Bugfix) Impact on plan: Beide Anpassungen waren fuer die Korrektheit der eigentlichen Plan-Aenderung zwingend notwendig. Kein Scope Creep — Deviation 1 ist eine minimale Vorziehung der ohnehin geplanten Aenderung, Deviation 2 behebt eine waehrend der Implementierung entdeckte Inkonsistenz zwischen POST- und GET-Antwortform derselben Ressource.

Issues Encountered

  • REQUIREMENTS.md enthielt keine SRC-Kategorie, obwohl 17-01/17-02-SUMMARY bereits requirements-completed: [SRC-01, SRC-03] bzw. [SRC-02, SRC-03] fuehrten — die Datei war seit dem Anlegen von Phase 17 nie nachgezogen worden (nur ROADMAP.md hatte die SRC-Beschreibungen). Ergaenzt als Teil des Requirements-Traceability-Schritts dieses Plans, keine separate Aenderung noetig.

User Setup Required

None — keine externe Dienstkonfiguration erforderlich.

Next Phase Readiness

  • Phase 17 ist inhaltlich abgeschlossen: alle drei Plaene liefern D-01 bis D-05 vollstaendig, der Backlog-Punkt ist geschlossen, SRC-01..05 sind erledigt
  • Web 205/205 Tests gruen, API src/tenders 362/362 gruen, beide Typpruefungen (API + Web) fehlerfrei
  • Offen: die Browser-Gegenprobe aus den human-check-Schritten aller drei Plaene (17-01 bis 17-03) — kein Browser-Tool in den jeweiligen Sitzungen verfuegbar, festgehalten in WINDOWS.md (#7, #8, #9), vor /gsd-ship nachzuholen
  • Offen: Rollout beider Migrationen (17-01, 17-02) auf dem Testserver (192.168.13.12) bleibt bewusst Nutzeraktion (Projektregel: kein docker compose pull/up/rebuild durch Claude auf dem Testserver)

Self-Check: PASSED

Alle im SUMMARY genannten Dateien existieren auf der Festplatte; alle drei Task-Commit-Hashes (4100bb5, 150046e, 809afbc) sind im Git-Log auffindbar.


Phase: 17-eigene-ausschreibungs-quellen-je-nutzer Completed: 2026-08-12