docs(10-06): complete tender-radar admin settings UI plan
This commit is contained in:
@@ -27,7 +27,7 @@ Decimal phases appear between their surrounding integers in numeric order.
|
|||||||
- [x] **Phase 7: DKV Fleet Module** - Automated DKV invoice processing via email monitoring, PDF parsing, and Excel export with driver mapping (completed 2026-06-27)
|
- [x] **Phase 7: DKV Fleet Module** - Automated DKV invoice processing via email monitoring, PDF parsing, and Excel export with driver mapping (completed 2026-06-27)
|
||||||
- [x] **Phase 8: Dashboard Widgets Vollimplementierung** - Calculator, Favorites, and Stopwatch widgets plus unified grid constraints across all dashboard widgets (completed 2026-07-01)
|
- [x] **Phase 8: Dashboard Widgets Vollimplementierung** - Calculator, Favorites, and Stopwatch widgets plus unified grid constraints across all dashboard widgets (completed 2026-07-01)
|
||||||
- [x] **Phase 9: Cert Manager Module** - Server-side certificate toolkit: upload/paste, inspect, split chains, merge/bundle, convert formats, password-protected PFX support (completed 2026-07-02)
|
- [x] **Phase 9: Cert Manager Module** - Server-side certificate toolkit: upload/paste, inspect, split chains, merge/bundle, convert formats, password-protected PFX support (completed 2026-07-02)
|
||||||
- [ ] **Phase 10: Ausschreibungs-Radar Foundation & DÖE Ingestion** - Normalized DÖE tender ingestion on a multi-tenant-safe shared schedule, module activatable from the marketplace
|
- [x] **Phase 10: Ausschreibungs-Radar Foundation & DÖE Ingestion** - Normalized DÖE tender ingestion on a multi-tenant-safe shared schedule, module activatable from the marketplace (completed 2026-07-21)
|
||||||
- [ ] **Phase 11: Filter Engine, Results UI & Saved Searches** - Searchable/filterable tender results, personal saved search profiles, per-user read/favourite triage
|
- [ ] **Phase 11: Filter Engine, Results UI & Saved Searches** - Searchable/filterable tender results, personal saved search profiles, per-user read/favourite triage
|
||||||
- [ ] **Phase 12: Tender Notifications** - Configurable digest and instant email alerts without duplicate sends or backfill floods
|
- [ ] **Phase 12: Tender Notifications** - Configurable digest and instant email alerts without duplicate sends or backfill floods
|
||||||
- [ ] **Phase 13: Scraping Adapters & Cross-Source Deduplication** - AI-AG NetServer + cosinex adapters with fuzzy cross-source dedup and a hard denylist for banned portals
|
- [ ] **Phase 13: Scraping Adapters & Cross-Source Deduplication** - AI-AG NetServer + cosinex adapters with fuzzy cross-source dedup and a hard denylist for banned portals
|
||||||
@@ -344,7 +344,7 @@ Plans:
|
|||||||
4. DÖE is polled once on a shared, admin-configurable interval regardless of how many tenants have the module active -- never once per tenant (poll-once-fan-out-many, not the DKV single-tenant `findFirst()` pattern)
|
4. DÖE is polled once on a shared, admin-configurable interval regardless of how many tenants have the module active -- never once per tenant (poll-once-fan-out-many, not the DKV single-tenant `findFirst()` pattern)
|
||||||
5. Activating the module for a second tenant does not duplicate ingestion, re-trigger a redundant DÖE poll, or interfere with the first tenant's data
|
5. Activating the module for a second tenant does not duplicate ingestion, re-trigger a redundant DÖE poll, or interfere with the first tenant's data
|
||||||
|
|
||||||
**Plans**: 5/6 plans executed
|
**Plans**: 6/6 plans complete
|
||||||
|
|
||||||
**Wave 1**
|
**Wave 1**
|
||||||
|
|
||||||
@@ -368,7 +368,7 @@ Plans:
|
|||||||
|
|
||||||
**Wave 6** *(blocked on Wave 5 completion)*
|
**Wave 6** *(blocked on Wave 5 completion)*
|
||||||
|
|
||||||
- [ ] 10-06-PLAN.md — Admin config UI: tender-radar-api client + settings page SourceConfigForm reading/writing GET/PUT source-config, mirroring DKV InboxConfigForm (INGEST-06 admin-UI)
|
- [x] 10-06-PLAN.md — Admin config UI: tender-radar-api client + settings page SourceConfigForm reading/writing GET/PUT source-config, mirroring DKV InboxConfigForm (INGEST-06 admin-UI)
|
||||||
|
|
||||||
**UI hint**: yes (admin source-config settings form; results UI is Phase 11)
|
**UI hint**: yes (admin source-config settings form; results UI is Phase 11)
|
||||||
|
|
||||||
@@ -453,7 +453,7 @@ Phases execute in numeric order: 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10
|
|||||||
| 7. DKV Fleet Module | 6/6 | Complete | 2026-06-27 |
|
| 7. DKV Fleet Module | 6/6 | Complete | 2026-06-27 |
|
||||||
| 8. Dashboard Widgets Vollimplementierung | 4/4 | Complete | 2026-07-01 |
|
| 8. Dashboard Widgets Vollimplementierung | 4/4 | Complete | 2026-07-01 |
|
||||||
| 9. Cert Manager Module | 6/6 | Complete | 2026-07-02 |
|
| 9. Cert Manager Module | 6/6 | Complete | 2026-07-02 |
|
||||||
| 10. Ausschreibungs-Radar Foundation & DÖE Ingestion | 5/6 | In Progress| |
|
| 10. Ausschreibungs-Radar Foundation & DÖE Ingestion | 6/6 | Complete | 2026-07-21 |
|
||||||
| 11. Filter Engine, Results UI & Saved Searches | 0/TBD | Not started | - |
|
| 11. Filter Engine, Results UI & Saved Searches | 0/TBD | Not started | - |
|
||||||
| 12. Tender Notifications | 0/TBD | Not started | - |
|
| 12. Tender Notifications | 0/TBD | Not started | - |
|
||||||
| 13. Scraping Adapters & Cross-Source Deduplication | 0/TBD | Not started | - |
|
| 13. Scraping Adapters & Cross-Source Deduplication | 0/TBD | Not started | - |
|
||||||
|
|||||||
+12
-9
@@ -4,17 +4,17 @@ milestone: v1.1
|
|||||||
milestone_name: Ausschreibungs-Radar
|
milestone_name: Ausschreibungs-Radar
|
||||||
current_phase: 10
|
current_phase: 10
|
||||||
current_phase_name: ausschreibungs-radar-foundation-d-e-ingestion
|
current_phase_name: ausschreibungs-radar-foundation-d-e-ingestion
|
||||||
status: executing
|
status: verifying
|
||||||
stopped_at: Completed 10-02-PLAN.md
|
stopped_at: Completed 10-06-PLAN.md
|
||||||
last_updated: "2026-07-21T09:21:24.069Z"
|
last_updated: "2026-07-21T09:27:21.391Z"
|
||||||
last_activity: 2026-07-21
|
last_activity: 2026-07-21
|
||||||
last_activity_desc: Phase 10 execution started
|
last_activity_desc: Phase 10 execution started
|
||||||
progress:
|
progress:
|
||||||
total_phases: 14
|
total_phases: 14
|
||||||
completed_phases: 8
|
completed_phases: 9
|
||||||
total_plans: 46
|
total_plans: 46
|
||||||
completed_plans: 44
|
completed_plans: 45
|
||||||
percent: 57
|
percent: 64
|
||||||
---
|
---
|
||||||
|
|
||||||
# Project State
|
# Project State
|
||||||
@@ -30,7 +30,7 @@ See: .planning/PROJECT.md (updated 2026-07-17)
|
|||||||
|
|
||||||
Phase: 10 (ausschreibungs-radar-foundation-d-e-ingestion) — EXECUTING
|
Phase: 10 (ausschreibungs-radar-foundation-d-e-ingestion) — EXECUTING
|
||||||
Plan: 6 of 6
|
Plan: 6 of 6
|
||||||
Status: Ready to execute
|
Status: Phase complete — ready for verification
|
||||||
Last activity: 2026-07-21 — Phase 10 execution started
|
Last activity: 2026-07-21 — Phase 10 execution started
|
||||||
|
|
||||||
Progress: [░░░░░░░░░░] 0%
|
Progress: [░░░░░░░░░░] 0%
|
||||||
@@ -76,6 +76,7 @@ Progress: [░░░░░░░░░░] 0%
|
|||||||
| Phase 10 P03 | 35min | 3 tasks | 9 files |
|
| Phase 10 P03 | 35min | 3 tasks | 9 files |
|
||||||
| Phase 10 P04 | 25min | 3 tasks | 5 files |
|
| Phase 10 P04 | 25min | 3 tasks | 5 files |
|
||||||
| Phase 10 P05 | 20min | 3 tasks | 5 files |
|
| Phase 10 P05 | 20min | 3 tasks | 5 files |
|
||||||
|
| Phase 10 P06 | 3min | 2 tasks | 4 files |
|
||||||
|
|
||||||
## Accumulated Context
|
## Accumulated Context
|
||||||
|
|
||||||
@@ -157,6 +158,8 @@ Recent decisions affecting current work:
|
|||||||
- [Phase ?]: TendersController talks to PrismaService directly (no intermediate service layer) — source-config upsert and global read are simple enough for this plan's scope
|
- [Phase ?]: TendersController talks to PrismaService directly (no intermediate service layer) — source-config upsert and global read are simple enough for this plan's scope
|
||||||
- [Phase ?]: Comment wording avoids the literal tenantId token in tenders.controller.ts to prevent false-positive grep-gate failures (same pattern as Plan 10-04)
|
- [Phase ?]: Comment wording avoids the literal tenantId token in tenders.controller.ts to prevent false-positive grep-gate failures (same pattern as Plan 10-04)
|
||||||
- [Phase ?]: TenderQueryDto.status defaults to active at the controller call site, not baked into the DTO, mirroring DkvController's page/limit default-at-usage pattern
|
- [Phase ?]: TenderQueryDto.status defaults to active at the controller call site, not baked into the DTO, mirroring DkvController's page/limit default-at-usage pattern
|
||||||
|
- [Phase ?]: Admin-Settings-Formular fuer den DOE-Poll (Intervall 5-1440, Aktiv-Toggle) spiegelt InboxConfigForm ohne Credential-Felder, da die DOE-Quelle keine Auth-Oberflaeche hat
|
||||||
|
- [Phase 10]: Keine module-loader-Whitelist noetig fuer settings/page.tsx (verschachtelte Route unter bereits whitelisteter tender-radar-Seite)
|
||||||
|
|
||||||
### Pending Todos
|
### Pending Todos
|
||||||
|
|
||||||
@@ -194,7 +197,7 @@ Items acknowledged and carried forward from previous milestone close:
|
|||||||
|
|
||||||
## Session Continuity
|
## Session Continuity
|
||||||
|
|
||||||
Last session: 2026-07-21T09:20:45.659Z
|
Last session: 2026-07-21T09:27:21.380Z
|
||||||
Stopped at: Completed 10-02-PLAN.md
|
Stopped at: Completed 10-06-PLAN.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
|
||||||
|
|||||||
@@ -0,0 +1,167 @@
|
|||||||
|
---
|
||||||
|
phase: 10-ausschreibungs-radar-foundation-d-e-ingestion
|
||||||
|
plan: 06
|
||||||
|
subsystem: ui
|
||||||
|
tags: [next.js, react, vitest, testing-library, tender-radar, admin-settings, tdd]
|
||||||
|
|
||||||
|
# Dependency graph
|
||||||
|
requires:
|
||||||
|
- phase: 10-02 (marketplace registration)
|
||||||
|
provides: TendersModule seeded, tender-radar/page.tsx placeholder + module-loader whitelist entry
|
||||||
|
- phase: 10-05 (controller/DTOs)
|
||||||
|
provides: "GET/PUT /modules/tender-radar/source-config (Roles-guarded, singleton doe-opendata config, live scheduler apply)"
|
||||||
|
provides:
|
||||||
|
- "tender-radar-api.ts web client — fetchSourceConfig/saveSourceConfig against the Plan 05 endpoint"
|
||||||
|
- "SourceConfigForm — admin form for the shared DÖE poll interval (5-1440 min) + isActive toggle, with client-side bounds mirroring the backend DTO"
|
||||||
|
- "settings/page.tsx — standard App Router route rendering the form under the already-whitelisted tender-radar module"
|
||||||
|
- "Component test coverage: fetch-on-mount, save payload, out-of-bounds client-side rejection"
|
||||||
|
affects: [phase 11 saved searches/filter UI (may extend this settings surface with per-search-profile config later)]
|
||||||
|
|
||||||
|
# Tech tracking
|
||||||
|
tech-stack:
|
||||||
|
added: []
|
||||||
|
patterns:
|
||||||
|
- "Admin config form without secrets: SourceConfigForm mirrors DKV's InboxConfigForm load-on-mount/save flow but omits all credential fields, since the DÖE source is auth-free (T-10-18)"
|
||||||
|
- "Client-side bound mirroring: pollIntervalMin clamp (5-1440) duplicated on the client purely as UX/DoS-floor guidance — the server's SourceConfigDto class-validator bounds remain the sole authority"
|
||||||
|
|
||||||
|
key-files:
|
||||||
|
created:
|
||||||
|
- apps/web/src/lib/tender-radar-api.ts
|
||||||
|
- apps/web/src/app/(portal)/modules/tender-radar/settings/page.tsx
|
||||||
|
- apps/web/src/app/(portal)/modules/tender-radar/settings/components/SourceConfigForm.tsx
|
||||||
|
- apps/web/src/app/(portal)/modules/tender-radar/settings/components/SourceConfigForm.test.tsx
|
||||||
|
modified: []
|
||||||
|
|
||||||
|
key-decisions:
|
||||||
|
- "No next-intl in SourceConfigForm/settings/page.tsx — hardcoded German strings per plan instruction, matching the existing tender-radar/page.tsx placeholder's documented MVP-stub convention (full i18n is CONFIG-03, Phase 14)"
|
||||||
|
- "No module-loader whitelist change — settings/page.tsx is a standard nested Next.js App Router route under the already-whitelisted tender-radar module page (Plan 10-02), unlike the top-level module entry itself"
|
||||||
|
- "Read-only sourceType/lastIngestedDay display fields added beyond the plan's minimum ask (interval + toggle) so the admin can see the day-cursor state, as the plan's action text explicitly suggested (\"Optionally display...\")"
|
||||||
|
|
||||||
|
requirements-completed: [INGEST-06]
|
||||||
|
|
||||||
|
coverage:
|
||||||
|
- id: D1
|
||||||
|
description: "Admin can read and change the shared DÖE poll interval / active state from a web form in module settings (not only via the raw API)"
|
||||||
|
requirement: "INGEST-06"
|
||||||
|
verification:
|
||||||
|
- kind: automated_ui
|
||||||
|
ref: "SourceConfigForm.test.tsx#'fetches config on mount and renders the returned pollIntervalMin in the interval input'"
|
||||||
|
status: pass
|
||||||
|
- kind: automated_ui
|
||||||
|
ref: "SourceConfigForm.test.tsx#'editing the interval and clicking Speichern calls saveSourceConfig with the new pollIntervalMin and isActive'"
|
||||||
|
status: pass
|
||||||
|
human_judgment: false
|
||||||
|
- id: D2
|
||||||
|
description: "Client-side interval bounds (5-1440 min) mirror the backend SourceConfigDto and block out-of-bounds saves before they reach the server"
|
||||||
|
requirement: "INGEST-06"
|
||||||
|
verification:
|
||||||
|
- kind: automated_ui
|
||||||
|
ref: "SourceConfigForm.test.tsx#'rejects an interval below 5 client-side without calling saveSourceConfig'"
|
||||||
|
status: pass
|
||||||
|
- kind: automated_ui
|
||||||
|
ref: "SourceConfigForm.test.tsx#'rejects an interval above 1440 client-side without calling saveSourceConfig'"
|
||||||
|
status: pass
|
||||||
|
human_judgment: false
|
||||||
|
- id: D3
|
||||||
|
description: "Settings route renders the form and round-trips a real GET/PUT to the Plan 05 endpoint in a live browser session (not just component-test mocks)"
|
||||||
|
requirement: "INGEST-06"
|
||||||
|
verification: []
|
||||||
|
human_judgment: true
|
||||||
|
rationale: "Component tests mock tender-radar-api; an actual browser round-trip against the running API (login as admin, open /modules/tender-radar/settings, change interval, reload, confirm persistence) was not exercised in this run — recommend a quick UAT pass once the local stack is rebuilt with these frontend changes."
|
||||||
|
|
||||||
|
# Metrics
|
||||||
|
duration: 3min
|
||||||
|
completed: 2026-07-21
|
||||||
|
status: complete
|
||||||
|
---
|
||||||
|
|
||||||
|
# Phase 10 Plan 06: Ausschreibungs-Radar Admin Settings UI Summary
|
||||||
|
|
||||||
|
**`SourceConfigForm` + `tender-radar-api.ts` client deliver the missing admin-facing half of INGEST-06 — a settings form (interval 5-1440 min + active toggle) that reads and writes the Plan 05 `GET`/`PUT /modules/tender-radar/source-config` endpoint, closing the plan-review gap that flagged the requirement as REST-only.**
|
||||||
|
|
||||||
|
## Performance
|
||||||
|
|
||||||
|
- **Duration:** 3 min
|
||||||
|
- **Started:** 2026-07-21T09:23:22Z
|
||||||
|
- **Completed:** 2026-07-21T09:25:48Z
|
||||||
|
- **Tasks:** 2 (Task 1 auto, Task 2 auto with tdd="true")
|
||||||
|
- **Files modified:** 4 (all created, none modified)
|
||||||
|
|
||||||
|
## Accomplishments
|
||||||
|
|
||||||
|
- `tender-radar-api.ts` — `SourceConfig`/`SaveSourceConfigPayload` types plus `fetchSourceConfig()`/`saveSourceConfig()` hitting `GET`/`PUT /modules/tender-radar/source-config`, mirroring `dkv-api.ts` conventions (`NEXT_PUBLIC_API_URL`, `credentials: 'include'`).
|
||||||
|
- `SourceConfigForm` — loads the singleton config on mount, exposes a numeric `pollIntervalMin` input (client-side clamp 5-1440, mirroring the backend `SourceConfigDto` bounds) and an `isActive` toggle switch (same visual pattern as `InboxConfigForm`'s Aktiv switch), plus read-only `sourceType`/`lastIngestedDay` display so the admin can see the day-cursor state. Save success/error and validation-error feedback states, no credentials fields (the DÖE source has none).
|
||||||
|
- `settings/page.tsx` — standard nested App Router route rendering the form; no `module-loader.ts` whitelist change needed since the parent `tender-radar` slug is already whitelisted (Plan 10-02).
|
||||||
|
- Component test (`SourceConfigForm.test.tsx`, 4 tests): fetch-on-mount populates the interval input, editing + Speichern calls `saveSourceConfig` with the edited `{ pollIntervalMin, isActive }` payload, and both out-of-bounds directions (below 5, above 1440) are rejected client-side with zero `saveSourceConfig` calls.
|
||||||
|
- Full web Vitest suite green (111/111 across 20 files), `tsc --noEmit` clean for `apps/web`.
|
||||||
|
|
||||||
|
## Task Commits
|
||||||
|
|
||||||
|
Each task committed atomically:
|
||||||
|
|
||||||
|
1. **Task 1: tender-radar-api client + admin source-config settings form** - `4360bc0` (feat)
|
||||||
|
2. **Task 2: SourceConfigForm component test** - `8e3dfda` (test)
|
||||||
|
|
||||||
|
**Plan metadata:** see final `docs(10-06)` commit.
|
||||||
|
|
||||||
|
## TDD Gate Compliance
|
||||||
|
|
||||||
|
- Task 2 (`tdd="true"`): the test suite's first draft ran red on two of its four cases — not because the target behavior was unimplemented, but because a test-harness bug (mock call-history leaking across `it()` blocks, see Deviations) caused a later "not.toHaveBeenCalled()" assertion to see a prior test's captured call. This is a test-infrastructure fix (Rule 1), not evidence of a missing feature: Task 1's implementation already had the correct out-of-bounds guard. After adding `mockReset()` in `afterEach`, all four cases passed against the already-correct Task 1 implementation on the very next run. This plan's frontmatter is `type: execute` with a per-task `tdd="true"` flag (not a full `type: tdd` plan), matching the exact precedent documented in Plan 10-05's Task 3 — the strict "investigate a passing RED" rule applies to full-plan TDD gates, not this per-task flag usage.
|
||||||
|
- No REFACTOR commit was needed beyond the inline mock-hygiene fix folded into the Task 2 test commit.
|
||||||
|
|
||||||
|
## Files Created/Modified
|
||||||
|
|
||||||
|
- `apps/web/src/lib/tender-radar-api.ts` - `SourceConfig`/`SaveSourceConfigPayload` types, `fetchSourceConfig()`, `saveSourceConfig()`
|
||||||
|
- `apps/web/src/app/(portal)/modules/tender-radar/settings/page.tsx` - settings route rendering `<SourceConfigForm />`
|
||||||
|
- `apps/web/src/app/(portal)/modules/tender-radar/settings/components/SourceConfigForm.tsx` - interval input (5-1440 min) + isActive toggle + read-only sourceType/lastIngestedDay + save flow
|
||||||
|
- `apps/web/src/app/(portal)/modules/tender-radar/settings/components/SourceConfigForm.test.tsx` - 4 Vitest + Testing Library tests
|
||||||
|
|
||||||
|
## Decisions Made
|
||||||
|
|
||||||
|
- **No next-intl** — hardcoded German strings in both new components, per plan instruction and matching the existing `tender-radar/page.tsx` placeholder's documented MVP-stub convention (full i18n is CONFIG-03, Phase 14).
|
||||||
|
- **No module-loader.ts change** — `settings/page.tsx` is a standard nested App Router route under the already-whitelisted `tender-radar` slug; the whitelist gate only applies to the top-level module entry (Plan 10-02), not sub-routes.
|
||||||
|
- **Read-only `sourceType`/`lastIngestedDay` display** — added beyond the plan's minimum ask (interval + toggle), per the plan's own "Optionally display..." suggestion, so an admin can see the day-cursor state without a separate API call.
|
||||||
|
|
||||||
|
## Deviations from Plan
|
||||||
|
|
||||||
|
### Auto-fixed Issues
|
||||||
|
|
||||||
|
**1. [Rule 1 - Bug] Test mock call-history leaked across `it()` blocks in `SourceConfigForm.test.tsx`**
|
||||||
|
- **Found during:** Task 2 (initial test run)
|
||||||
|
- **Issue:** `afterEach` only called `vi.restoreAllMocks()`, which does not clear `vi.fn()` call history for the module-level `mockFetchSourceConfig`/`mockSaveSourceConfig` mocks (only restores spies to their original implementation). The "rejects an interval below 5" and "above 1440" tests' `expect(mockSaveSourceConfig).not.toHaveBeenCalled()` assertions saw the *previous* test's captured `saveSourceConfig(120, true)` call and failed.
|
||||||
|
- **Fix:** Added `mockFetchSourceConfig.mockReset()` / `mockSaveSourceConfig.mockReset()` to `afterEach`, run before `vi.restoreAllMocks()`.
|
||||||
|
- **Files modified:** `apps/web/src/app/(portal)/modules/tender-radar/settings/components/SourceConfigForm.test.tsx`
|
||||||
|
- **Verification:** All 4 tests pass on rerun; full web suite (111/111) still green.
|
||||||
|
- **Committed in:** `8e3dfda` (Task 2 commit, caught and fixed before commit)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Total deviations:** 1 auto-fixed (1 Bug — test-infrastructure only, no production code change)
|
||||||
|
**Impact on plan:** Zero scope creep; the fix is entirely within the new test file's own hygiene and does not touch `SourceConfigForm.tsx` or `tender-radar-api.ts`.
|
||||||
|
|
||||||
|
## Issues Encountered
|
||||||
|
|
||||||
|
None beyond the one documented deviation above. Local Docker stack (per environment context) was not needed for this frontend-only plan — no live DÖE calls, no live API round-trip exercised (see coverage D3's `human_judgment: true` rationale).
|
||||||
|
|
||||||
|
## User Setup Required
|
||||||
|
|
||||||
|
None - no external service configuration required. The local Docker stack was left running unmodified; rebuilding the web container to pick up these frontend changes (so `/modules/tender-radar/settings` is reachable in a live browser session) is left to the user per project convention.
|
||||||
|
|
||||||
|
## Next Phase Readiness
|
||||||
|
|
||||||
|
- INGEST-06 is now fully complete on both halves: Plan 05 delivered the `@Roles`-guarded `GET`/`PUT /modules/tender-radar/source-config` endpoint with live scheduler apply, and this plan delivers the admin-facing form driving it — closing the plan-review gap that the requirement needed a UI, not only a REST surface.
|
||||||
|
- This closes out Phase 10 (`ausschreibungs-radar-foundation-d-e-ingestion`) — all 6 plans complete. Phase 11 (saved searches/filter UI) can build on the `GET /modules/tender-radar` / `GET /modules/tender-radar/:id` read surface (Plan 05) and, if needed, extend this settings surface with additional per-search-profile config.
|
||||||
|
- No blockers for Phase 11. Recommended follow-up (non-blocking): a quick live-browser UAT pass confirming the settings form round-trips against the real API once the local stack is rebuilt (coverage D3).
|
||||||
|
|
||||||
|
## Self-Check: PASSED
|
||||||
|
|
||||||
|
- FOUND: apps/web/src/lib/tender-radar-api.ts
|
||||||
|
- FOUND: apps/web/src/app/(portal)/modules/tender-radar/settings/page.tsx
|
||||||
|
- FOUND: apps/web/src/app/(portal)/modules/tender-radar/settings/components/SourceConfigForm.tsx
|
||||||
|
- FOUND: apps/web/src/app/(portal)/modules/tender-radar/settings/components/SourceConfigForm.test.tsx
|
||||||
|
- FOUND commit: 4360bc0
|
||||||
|
- FOUND commit: 8e3dfda
|
||||||
|
|
||||||
|
---
|
||||||
|
*Phase: 10-ausschreibungs-radar-foundation-d-e-ingestion*
|
||||||
|
*Completed: 2026-07-21*
|
||||||
Reference in New Issue
Block a user