docs(17-03): complete UI-Aufteilung Meine Quellen vs. Administration plan
This commit is contained in:
@@ -55,6 +55,16 @@
|
|||||||
- [x] **CONFIG-02**: Admin verwaltet Quellen-Poll-Konfiguration sowie das E-Mail-Ingestion-Postfach pro Mandant (Zugangsdaten verschlüsselt gespeichert).
|
- [x] **CONFIG-02**: Admin verwaltet Quellen-Poll-Konfiguration sowie das E-Mail-Ingestion-Postfach pro Mandant (Zugangsdaten verschlüsselt gespeichert).
|
||||||
- [x] **CONFIG-03**: Die gesamte Modul-UI ist mehrsprachig (Deutsch + Englisch, i18n).
|
- [x] **CONFIG-03**: Die gesamte Modul-UI ist mehrsprachig (Deutsch + Englisch, i18n).
|
||||||
|
|
||||||
|
### SRC — Eigene Ausschreibungs-Quellen je Nutzer
|
||||||
|
|
||||||
|
**Hinzugefügt 2026-08-12** — aus dem Backlog-Punkt `2026-08-11-tender-radar-einstellungen-mischen-rollen.md` und `.planning/phases/17-eigene-ausschreibungs-quellen-je-nutzer/17-CONTEXT.md` abgeleitet, neue modul-lokale Kategorie.
|
||||||
|
|
||||||
|
- [x] **SRC-01**: Jeder Nutzer bindet sein eigenes Alert-Postfach an; ein Mandant kann mehrere Postfächer haben (D-01).
|
||||||
|
- [x] **SRC-02**: RSS-Feeds haben einen Besitzer; Feeds ohne Besitzer bleiben plattformweit und von der Administration gepflegt (D-02).
|
||||||
|
- [x] **SRC-03**: Der zeitgesteuerte Abruf holt weiterhin alle Quellen in einem Durchlauf; eine kaputte Quelle blockiert die anderen nicht.
|
||||||
|
- [x] **SRC-04**: Nutzereigene Einstellungen (Postfach, eigene Feeds, Digest-Intervall) liegen auf einer eigenen, für jeden Modulnutzer erreichbaren Seite (D-04).
|
||||||
|
- [x] **SRC-05**: Die verbleibenden Administrationseinstellungen sind für normale Nutzer nicht sichtbar; die Rollenprüfung greift in der Oberfläche wie in der API (D-03).
|
||||||
|
|
||||||
## v1.2 Requirements
|
## v1.2 Requirements
|
||||||
|
|
||||||
**Milestone:** v1.2 Plattform-Berechtigungen — Modulzugriff nicht mehr nur pro Mandant, sondern zusätzlich pro Gruppe und pro Benutzer.
|
**Milestone:** v1.2 Plattform-Berechtigungen — Modulzugriff nicht mehr nur pro Mandant, sondern zusätzlich pro Gruppe und pro Benutzer.
|
||||||
@@ -121,6 +131,11 @@
|
|||||||
| CONFIG-02 | Phase 14 | Complete |
|
| CONFIG-02 | Phase 14 | Complete |
|
||||||
| CONFIG-03 | Phase 14 | Complete |
|
| CONFIG-03 | Phase 14 | Complete |
|
||||||
| UI-06 | Phase 14 | Complete |
|
| UI-06 | Phase 14 | Complete |
|
||||||
|
| SRC-01 | Phase 17 | Complete |
|
||||||
|
| SRC-02 | Phase 17 | Complete |
|
||||||
|
| SRC-03 | Phase 17 | Complete |
|
||||||
|
| SRC-04 | Phase 17 | Complete |
|
||||||
|
| SRC-05 | Phase 17 | Complete |
|
||||||
|
|
||||||
| PERM-01 | Phase 15 | Complete |
|
| PERM-01 | Phase 15 | Complete |
|
||||||
| PERM-02 | Phase 16 | Complete |
|
| PERM-02 | Phase 16 | Complete |
|
||||||
@@ -130,4 +145,4 @@
|
|||||||
| PERM-06 | Phase 15 | Pending |
|
| PERM-06 | Phase 15 | Pending |
|
||||||
| PERM-07 | Phase 15 | Complete |
|
| PERM-07 | Phase 15 | Complete |
|
||||||
|
|
||||||
**Coverage:** 29/29 v1.1 requirements mapped — no orphans. 7/7 v1.2 requirements mapped: PERM-01/03/04/05/06/07 auf Phase 15, PERM-02 auf Phase 16 (umgehängt 2026-08-06).
|
**Coverage:** 34/34 v1.1 requirements mapped (29 aus Phase 10–14 + SRC-01..05 aus Phase 17, nachträglich am 2026-08-12 ergänzt — die Kategorie fehlte in dieser Datei, obwohl 17-01/17-02 sie bereits in ihren SUMMARY-Frontmattern als erledigt führten) — no orphans. 7/7 v1.2 requirements mapped: PERM-01/03/04/05/06/07 auf Phase 15, PERM-02 auf Phase 16 (umgehängt 2026-08-06).
|
||||||
|
|||||||
@@ -609,7 +609,7 @@ Phases execute in numeric order: 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10
|
|||||||
| 14. RSS, Email-Alert Ingestion & Module Rollout | 5/5 | In Progress| |
|
| 14. RSS, Email-Alert Ingestion & Module Rollout | 5/5 | In Progress| |
|
||||||
| 15. Modul-Berechtigungen: Gruppen & User-Grants | 8/8 | Complete | 2026-08-04 (Bericht 15-04 am 2026-08-11 nachgezogen) |
|
| 15. Modul-Berechtigungen: Gruppen & User-Grants | 8/8 | Complete | 2026-08-04 (Bericht 15-04 am 2026-08-11 nachgezogen) |
|
||||||
| 16. AD-Gruppen-Synchronisation | 5/5 | Complete | 2026-08-11 |
|
| 16. AD-Gruppen-Synchronisation | 5/5 | Complete | 2026-08-11 |
|
||||||
| 17. Eigene Ausschreibungs-Quellen je Nutzer | 2/3 | In Progress| |
|
| 17. Eigene Ausschreibungs-Quellen je Nutzer | 3/3 | In Progress| |
|
||||||
|
|
||||||
### Phase 17: Eigene Ausschreibungs-Quellen je Nutzer
|
### Phase 17: Eigene Ausschreibungs-Quellen je Nutzer
|
||||||
|
|
||||||
@@ -628,7 +628,7 @@ Phases execute in numeric order: 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10
|
|||||||
- **SRC-05**: Die verbleibenden Administrationseinstellungen sind fuer normale Nutzer nicht sichtbar; die Rollenpruefung greift in der Oberflaeche wie in der API (D-03).
|
- **SRC-05**: Die verbleibenden Administrationseinstellungen sind fuer normale Nutzer nicht sichtbar; die Rollenpruefung greift in der Oberflaeche wie in der API (D-03).
|
||||||
|
|
||||||
**Depends on:** Phase 16
|
**Depends on:** Phase 16
|
||||||
**Plans:** 2/3 plans executed
|
**Plans:** 3/3 plans executed
|
||||||
|
|
||||||
**Success Criteria** (what must be TRUE):
|
**Success Criteria** (what must be TRUE):
|
||||||
|
|
||||||
@@ -644,4 +644,4 @@ Plans (Wellenstruktur — streng nacheinander, alle drei fassen Schema, Controll
|
|||||||
|
|
||||||
- [x] 17-01-PLAN.md (Welle 1) — Alert-Postfach wechselt vom Mandanten zum Nutzer: Schema, handgeschriebene Migration mit Besitzer-Zuordnung, Dienst und Endpunkt, erste Fassung der Seite "Meine Quellen". Enthaelt den Entscheidungspunkt fuer beide Datenbank-Umbauten der Phase.
|
- [x] 17-01-PLAN.md (Welle 1) — Alert-Postfach wechselt vom Mandanten zum Nutzer: Schema, handgeschriebene Migration mit Besitzer-Zuordnung, Dienst und Endpunkt, erste Fassung der Seite "Meine Quellen". Enthaelt den Entscheidungspunkt fuer beide Datenbank-Umbauten der Phase.
|
||||||
- [x] 17-02-PLAN.md (Welle 2, nach 17-01) — RSS-Feeds bekommen einen Besitzer: Schema und Migration, Besitzerlogik, Schutz gegen fremdes Loeschen, Mengenbegrenzung, Herkunftsmarkierung im Abruf, angepasste Startbestueckung.
|
- [x] 17-02-PLAN.md (Welle 2, nach 17-01) — RSS-Feeds bekommen einen Besitzer: Schema und Migration, Besitzerlogik, Schutz gegen fremdes Loeschen, Mengenbegrenzung, Herkunftsmarkierung im Abruf, angepasste Startbestueckung.
|
||||||
- [ ] 17-03-PLAN.md (Welle 3, nach 17-01 und 17-02) — Oberflaeche nach Zustaendigkeit trennen: "Meine Quellen" vollstaendig, Administrationsseite reduziert und rollengeprueft, Zahnrad umgehaengt, Beschriftungen in beiden Sprachen, Backlog-Punkt geschlossen.
|
- [x] 17-03-PLAN.md (Welle 3, nach 17-01 und 17-02) — Oberflaeche nach Zustaendigkeit trennen: "Meine Quellen" vollstaendig, Administrationsseite reduziert und rollengeprueft, Zahnrad umgehaengt, Beschriftungen in beiden Sprachen, Backlog-Punkt geschlossen.
|
||||||
|
|||||||
+14
-9
@@ -4,16 +4,16 @@ milestone: v1.1
|
|||||||
milestone_name: Ausschreibungs-Radar
|
milestone_name: Ausschreibungs-Radar
|
||||||
current_phase: 17
|
current_phase: 17
|
||||||
current_phase_name: eigene-ausschreibungs-quellen-je-nutzer
|
current_phase_name: eigene-ausschreibungs-quellen-je-nutzer
|
||||||
status: executing
|
status: verifying
|
||||||
stopped_at: "17-02 abgeschlossen: RSS-Feeds bekommen einen Besitzer (D-02), Migration lokal angewendet (alpha noch nicht ausgerollt), Loeschschutz+Obergrenze+D-06-Tagging getestet. Naechster Schritt: Plan 17-03 (UI-Aufteilung)."
|
stopped_at: "17-03 abgeschlossen: UI-Aufteilung Meine Quellen vs. Administration, Backlog-Punkt geschlossen. Phase 17 vollstaendig — bereit fuer /gsd-ship (Browser-Gegenprobe aller drei Plaene und Testserver-Rollout stehen als offene Punkte in WINDOWS.md)."
|
||||||
last_updated: "2026-08-12T09:48:46.242Z"
|
last_updated: "2026-08-12T10:06:09.773Z"
|
||||||
last_activity: 2026-08-12
|
last_activity: 2026-08-12
|
||||||
last_activity_desc: Phase 17 execution started
|
last_activity_desc: Phase 17 execution started
|
||||||
progress:
|
progress:
|
||||||
total_phases: 17
|
total_phases: 17
|
||||||
completed_phases: 15
|
completed_phases: 16
|
||||||
total_plans: 83
|
total_plans: 83
|
||||||
completed_plans: 81
|
completed_plans: 82
|
||||||
---
|
---
|
||||||
|
|
||||||
# Project State
|
# Project State
|
||||||
@@ -29,7 +29,7 @@ See: .planning/PROJECT.md (updated 2026-07-17)
|
|||||||
|
|
||||||
Phase: 17 (eigene-ausschreibungs-quellen-je-nutzer) — EXECUTING
|
Phase: 17 (eigene-ausschreibungs-quellen-je-nutzer) — EXECUTING
|
||||||
Plan: 3 of 3
|
Plan: 3 of 3
|
||||||
Status: Ready to execute
|
Status: Phase complete — ready for verification
|
||||||
uebersprungen (kein AD-Schreibzugriff, Entscheidung des Users 2026-08-11).
|
uebersprungen (kein AD-Schreibzugriff, Entscheidung des Users 2026-08-11).
|
||||||
UAT-Test 2 hat einen kritischen Fehler in der Loescherkennung aufgedeckt, der
|
UAT-Test 2 hat einen kritischen Fehler in der Loescherkennung aufgedeckt, der
|
||||||
beim ersten echten Sync alle AD-gebundenen Gruppen entfernt haette — behoben in
|
beim ersten echten Sync alle AD-gebundenen Gruppen entfernt haette — behoben in
|
||||||
@@ -37,7 +37,7 @@ beim ersten echten Sync alle AD-gebundenen Gruppen entfernt haette — behoben i
|
|||||||
dokumentiert in 16-VERIFICATION.md.
|
dokumentiert in 16-VERIFICATION.md.
|
||||||
Last activity: 2026-08-12 — Phase 17 execution started
|
Last activity: 2026-08-12 — Phase 17 execution started
|
||||||
|
|
||||||
Progress: [██████████] 98%
|
Progress: [██████████] 99%
|
||||||
|
|
||||||
## Performance Metrics
|
## Performance Metrics
|
||||||
|
|
||||||
@@ -119,6 +119,7 @@ Progress: [██████████] 98%
|
|||||||
| Phase 16 P05 | 6min | 2 tasks | 4 files |
|
| Phase 16 P05 | 6min | 2 tasks | 4 files |
|
||||||
| Phase 17 P01 | 76min | 3 tasks | 12 files |
|
| Phase 17 P01 | 76min | 3 tasks | 12 files |
|
||||||
| Phase 17 P02 | 58min | 3 tasks | 14 files |
|
| Phase 17 P02 | 58min | 3 tasks | 14 files |
|
||||||
|
| Phase 17 P03 | 62min | 3 tasks | 13 files |
|
||||||
|
|
||||||
## Accumulated Context
|
## Accumulated Context
|
||||||
|
|
||||||
@@ -288,6 +289,10 @@ Recent decisions affecting current work:
|
|||||||
- [Phase ?]: [17-02]: Startbestueckung (tenders.module.ts) vorgezogen aus Task 3 nach Task 1 (Rule 3) - find-then-create statt upsert-on-url, Prismas Compound-Unique-Typ verlangt userId als Pflicht-String
|
- [Phase ?]: [17-02]: Startbestueckung (tenders.module.ts) vorgezogen aus Task 3 nach Task 1 (Rule 3) - find-then-create statt upsert-on-url, Prismas Compound-Unique-Typ verlangt userId als Pflicht-String
|
||||||
- [Phase ?]: [17-02]: seedServiceBundRssFeed() aus TendersModule.onModuleInit extrahiert (tenders.seed.ts), damit die Bestueckungs-Idempotenz echten Produktivcode testet
|
- [Phase ?]: [17-02]: seedServiceBundRssFeed() aus TendersModule.onModuleInit extrahiert (tenders.seed.ts), damit die Bestueckungs-Idempotenz echten Produktivcode testet
|
||||||
- [Phase ?]: [17-02]: DELETE /rss-feeds/:feedId von @Roles auf @UseModule umgestellt - Besitzpruefung im Dienst ersetzt die Rollenpruefung vollstaendig (T-17-07)
|
- [Phase ?]: [17-02]: DELETE /rss-feeds/:feedId von @Roles auf @UseModule umgestellt - Besitzpruefung im Dienst ersetzt die Rollenpruefung vollstaendig (T-17-07)
|
||||||
|
- [Phase ?]: [17-03]: RssFeedListForm scope-Prop (personal/platform) bedient beide Seiten; Berechtigung entscheidet der Server (T-17-08)
|
||||||
|
- [Phase ?]: [17-03]: createRssFeed-Antwort traegt kein isPlatformWide (nur GET mappt es) — Komponente leitet es lokal aus dem verwendeten scope ab (Rule 1)
|
||||||
|
- [Phase ?]: [17-03]: Anzeige-Rollenpruefung auf settings/page.tsx ueber useAuthStore (unbekannt/erlaubt/verweigert); verbindliche Pruefung bleibt serverseitig
|
||||||
|
- [Phase ?]: [17-03]: REQUIREMENTS.md SRC-01..05 nachtraeglich ergaenzt — Luecke aus 17-01/17-02, dort schon in SUMMARY-Frontmatter gefuehrt
|
||||||
|
|
||||||
### Pending Todos
|
### Pending Todos
|
||||||
|
|
||||||
@@ -336,7 +341,7 @@ Items acknowledged and carried forward from previous milestone close:
|
|||||||
|
|
||||||
## Session Continuity
|
## Session Continuity
|
||||||
|
|
||||||
Last session: 2026-08-12T09:48:46.207Z
|
Last session: 2026-08-12T10:06:09.739Z
|
||||||
Stopped at: 17-02 abgeschlossen: RSS-Feeds bekommen einen Besitzer (D-02), Migration lokal angewendet (alpha noch nicht ausgerollt), Loeschschutz+Obergrenze+D-06-Tagging getestet. Naechster Schritt: Plan 17-03 (UI-Aufteilung).
|
Stopped at: 17-03 abgeschlossen: UI-Aufteilung Meine Quellen vs. Administration, Backlog-Punkt geschlossen. Phase 17 vollstaendig — bereit fuer /gsd-ship (Browser-Gegenprobe aller drei Plaene und Testserver-Rollout stehen als offene Punkte in WINDOWS.md).
|
||||||
Resume file: None
|
Resume file: None
|
||||||
Last activity: 2026-07-14 - Built LDAP per-user exclude/denylist filter (9d1323f), migration applied on live DB, verified via Playwright: sync deactivated 4 excluded service accounts (administrator/krbtgt/guest/dns-ldap), 2 real LDAP users stay active, 0 wrongly created
|
Last activity: 2026-07-14 - Built LDAP per-user exclude/denylist filter (9d1323f), migration applied on live DB, verified via Playwright: sync deactivated 4 excluded service accounts (administrator/krbtgt/guest/dns-ldap), 2 real LDAP users stay active, 0 wrongly created
|
||||||
|
|||||||
+29
-3
@@ -1,10 +1,10 @@
|
|||||||
---
|
---
|
||||||
schema_version: 1
|
schema_version: 1
|
||||||
open_count: 7
|
open_count: 9
|
||||||
waived_count: 0
|
waived_count: 0
|
||||||
fixed_count: 0
|
fixed_count: 0
|
||||||
total_count: 7
|
total_count: 9
|
||||||
last_updated: 2026-08-12T09:24:35.289Z
|
last_updated: 2026-08-12T10:02:49.291Z
|
||||||
---
|
---
|
||||||
|
|
||||||
# Broken Windows Ledger
|
# Broken Windows Ledger
|
||||||
@@ -22,6 +22,8 @@ last_updated: 2026-08-12T09:24:35.289Z
|
|||||||
| 5 | 16 | unrun-verify | .planning/phases/16-ad-gruppen-synchronisation/16-04-PLAN.md | | Manueller Browser-Durchklick aus dem Plan-Verification-Block (drei GroupFormModal-Zustaende: Anlegen mit Hinweis-Link, lokale Gruppe umbenennen, importierte Gruppe mit gesperrtem Namen + internem Namen speichern; Namensanzeige mit Tooltip in der Liste nach dem Speichern) nicht ausgefuehrt — kein Browser-Tool in dieser Session verfuegbar. | open | | 2026-08-06T14:31:14.336Z | |
|
| 5 | 16 | unrun-verify | .planning/phases/16-ad-gruppen-synchronisation/16-04-PLAN.md | | Manueller Browser-Durchklick aus dem Plan-Verification-Block (drei GroupFormModal-Zustaende: Anlegen mit Hinweis-Link, lokale Gruppe umbenennen, importierte Gruppe mit gesperrtem Namen + internem Namen speichern; Namensanzeige mit Tooltip in der Liste nach dem Speichern) nicht ausgefuehrt — kein Browser-Tool in dieser Session verfuegbar. | open | | 2026-08-06T14:31:14.336Z | |
|
||||||
| 6 | 16 | unrun-verify | .planning/phases/16-ad-gruppen-synchronisation/16-05-PLAN.md | | 16-05 <verification> Manuell nachzuholen (Browser): Sync ausloesen und pruefen, dass alle drei Zahlenzeilen erscheinen; Lauf mit verschobener Standardmarkierung provozieren und Amber-Zeile pruefen; Freigabe-Matrix-Spaltensuche unter beiden Namen probieren - nicht ausgefuehrt, kein Browser-Tool in dieser Session verfuegbar. | open | | 2026-08-06T14:39:03.905Z | |
|
| 6 | 16 | unrun-verify | .planning/phases/16-ad-gruppen-synchronisation/16-05-PLAN.md | | 16-05 <verification> Manuell nachzuholen (Browser): Sync ausloesen und pruefen, dass alle drei Zahlenzeilen erscheinen; Lauf mit verschobener Standardmarkierung provozieren und Amber-Zeile pruefen; Freigabe-Matrix-Spaltensuche unter beiden Namen probieren - nicht ausgefuehrt, kein Browser-Tool in dieser Session verfuegbar. | open | | 2026-08-06T14:39:03.905Z | |
|
||||||
| 7 | 17 | unrun-verify | .planning/phases/17-eigene-ausschreibungs-quellen-je-nutzer/17-01-PLAN.md | | 17-01 Task 2 human-check: Browser-Gegenprobe (normaler Nutzer oeffnet /modules/tender-radar/my-sources, speichert Postfach, zweites Konto desselben Mandanten sieht leeres Formular) nicht ausgefuehrt — kein Browser-Tool in dieser Session verfuegbar. Automatisierte Pruefungen (prisma validate/migrate status, Index-Liste, beide Typpruefungen, 335/335 src/tenders-Tests) sind gelaufen und gruen. | open | | 2026-08-12T09:24:35.289Z | |
|
| 7 | 17 | unrun-verify | .planning/phases/17-eigene-ausschreibungs-quellen-je-nutzer/17-01-PLAN.md | | 17-01 Task 2 human-check: Browser-Gegenprobe (normaler Nutzer oeffnet /modules/tender-radar/my-sources, speichert Postfach, zweites Konto desselben Mandanten sieht leeres Formular) nicht ausgefuehrt — kein Browser-Tool in dieser Session verfuegbar. Automatisierte Pruefungen (prisma validate/migrate status, Index-Liste, beide Typpruefungen, 335/335 src/tenders-Tests) sind gelaufen und gruen. | open | | 2026-08-12T09:24:35.289Z | |
|
||||||
|
| 8 | 17 | unrun-verify | apps/web/src/app/(portal)/modules/tender-radar/my-sources/page.tsx | | Browser-Gegenprobe Plan 17-03 Task 1 (Tracer-Feedback-Gate): Meine Quellen mit drei Abschnitten, neu angelegter eigener Feed sofort sichtbar, plattformweiter Feed ohne Entfernen-Knopf, Digest-Intervall speichert nach Reload — kein Browser-Tool in dieser Sitzung verfuegbar | open | | 2026-08-12T10:02:49.122Z | |
|
||||||
|
| 9 | 17 | unrun-verify | apps/web/src/app/(portal)/modules/tender-radar/settings/page.tsx | | Browser-Gegenprobe Plan 17-03 Task 2: USER-Konto sieht keine Bedienelemente auf /settings (nur Hinweis+Verweis), ADMIN-Konto sieht Abrufintervall+plattformweite Feeds ohne Postfach/Benachrichtigung, Zahnrad fuehrt in beiden Faellen nach Meine Quellen — kein Browser-Tool in dieser Sitzung verfuegbar | open | | 2026-08-12T10:02:49.291Z | |
|
||||||
|
|
||||||
````json
|
````json
|
||||||
[
|
[
|
||||||
@@ -108,6 +110,30 @@ last_updated: 2026-08-12T09:24:35.289Z
|
|||||||
"reason": "",
|
"reason": "",
|
||||||
"recorded_at": "2026-08-12T09:24:35.289Z",
|
"recorded_at": "2026-08-12T09:24:35.289Z",
|
||||||
"resolved_at": null
|
"resolved_at": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 8,
|
||||||
|
"kind": "unrun-verify",
|
||||||
|
"phase": "17",
|
||||||
|
"file": "apps/web/src/app/(portal)/modules/tender-radar/my-sources/page.tsx",
|
||||||
|
"line": null,
|
||||||
|
"description": "Browser-Gegenprobe Plan 17-03 Task 1 (Tracer-Feedback-Gate): Meine Quellen mit drei Abschnitten, neu angelegter eigener Feed sofort sichtbar, plattformweiter Feed ohne Entfernen-Knopf, Digest-Intervall speichert nach Reload — kein Browser-Tool in dieser Sitzung verfuegbar",
|
||||||
|
"status": "open",
|
||||||
|
"reason": "",
|
||||||
|
"recorded_at": "2026-08-12T10:02:49.122Z",
|
||||||
|
"resolved_at": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 9,
|
||||||
|
"kind": "unrun-verify",
|
||||||
|
"phase": "17",
|
||||||
|
"file": "apps/web/src/app/(portal)/modules/tender-radar/settings/page.tsx",
|
||||||
|
"line": null,
|
||||||
|
"description": "Browser-Gegenprobe Plan 17-03 Task 2: USER-Konto sieht keine Bedienelemente auf /settings (nur Hinweis+Verweis), ADMIN-Konto sieht Abrufintervall+plattformweite Feeds ohne Postfach/Benachrichtigung, Zahnrad fuehrt in beiden Faellen nach Meine Quellen — kein Browser-Tool in dieser Sitzung verfuegbar",
|
||||||
|
"status": "open",
|
||||||
|
"reason": "",
|
||||||
|
"recorded_at": "2026-08-12T10:02:49.291Z",
|
||||||
|
"resolved_at": null
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
````
|
````
|
||||||
|
|||||||
@@ -0,0 +1,203 @@
|
|||||||
|
---
|
||||||
|
phase: 17-eigene-ausschreibungs-quellen-je-nutzer
|
||||||
|
plan: 03
|
||||||
|
subsystem: ui
|
||||||
|
tags: [nextjs, next-intl, zustand, vitest, testing-library]
|
||||||
|
|
||||||
|
# Dependency graph
|
||||||
|
requires:
|
||||||
|
- phase: 17-01
|
||||||
|
provides: "TenderEmailConfig per-user, /modules/tender-radar/my-sources (Seite mit Postfach-Abschnitt)"
|
||||||
|
- phase: 17-02
|
||||||
|
provides: "RssFeedSource.isPlatformWide-Vertrag (GET/POST /rss-feeds, scope-Wunsch, Besitz-basierter Loeschschutz)"
|
||||||
|
provides:
|
||||||
|
- "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)"
|
||||||
|
affects: [dkv-fleet-settings-restructuring, future-per-user-module-settings]
|
||||||
|
|
||||||
|
# Actuals (#2632)
|
||||||
|
actuals:
|
||||||
|
tokens: 18180
|
||||||
|
tasks: 3
|
||||||
|
commits: 3
|
||||||
|
|
||||||
|
tech-stack:
|
||||||
|
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)"
|
||||||
|
|
||||||
|
key-files:
|
||||||
|
created:
|
||||||
|
- "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"
|
||||||
|
modified:
|
||||||
|
- 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
|
||||||
|
|
||||||
|
key-decisions:
|
||||||
|
- "[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"
|
||||||
|
|
||||||
|
requirements-completed: [SRC-04, SRC-05]
|
||||||
|
|
||||||
|
coverage:
|
||||||
|
- id: D1
|
||||||
|
description: "\"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"
|
||||||
|
requirement: "SRC-04"
|
||||||
|
verification:
|
||||||
|
- kind: unit
|
||||||
|
ref: "apps/web/src/app/(portal)/modules/tender-radar/my-sources/my-sources.test.tsx (5 Tests)"
|
||||||
|
status: pass
|
||||||
|
- kind: unit
|
||||||
|
ref: "apps/web/src/app/(portal)/modules/tender-radar/settings/components/RssFeedListForm.test.tsx (scope=personal-Block, 6 Tests inkl. Mischliste mit/ohne Entfernen-Knopf)"
|
||||||
|
status: pass
|
||||||
|
human_judgment: false
|
||||||
|
- id: D2
|
||||||
|
description: "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"
|
||||||
|
requirement: "SRC-05"
|
||||||
|
verification:
|
||||||
|
- kind: unit
|
||||||
|
ref: "apps/web/src/app/(portal)/modules/tender-radar/settings/settings-roles.test.tsx (5 Tests: USER/ADMIN/SUPER_ADMIN/unbekannt/entfernte Ueberschriften)"
|
||||||
|
status: pass
|
||||||
|
- kind: unit
|
||||||
|
ref: "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)"
|
||||||
|
status: pass
|
||||||
|
human_judgment: false
|
||||||
|
- id: D3
|
||||||
|
description: "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"
|
||||||
|
requirement: "SRC-04"
|
||||||
|
verification: []
|
||||||
|
human_judgment: true
|
||||||
|
rationale: "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: D4
|
||||||
|
description: "Alle neuen Beschriftungen liegen in Deutsch und Englisch vor; keine mehr verwendete Beschriftung bleibt verwaist"
|
||||||
|
requirement: "SRC-04"
|
||||||
|
verification:
|
||||||
|
- kind: unit
|
||||||
|
ref: "Node-Skript-Schluesselvergleich beider Sprachdateien (in allen drei Task-<verify>-Bloecken gelaufen)"
|
||||||
|
status: pass
|
||||||
|
human_judgment: false
|
||||||
|
|
||||||
|
duration: 62min
|
||||||
|
completed: 2026-08-12
|
||||||
|
status: 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
|
||||||
|
- `createRssFeed`s 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*
|
||||||
Reference in New Issue
Block a user