12 KiB
phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, key-decisions, requirements-completed, coverage, duration, completed, status
| phase | plan | subsystem | tags | requires | provides | affects | tech-stack | key-files | key-decisions | requirements-completed | coverage | duration | completed | status | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 10-ausschreibungs-radar-foundation-d-e-ingestion | 06 | ui |
|
|
|
|
|
|
|
|
|
3min | 2026-07-21 | 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/SaveSourceConfigPayloadtypes plusfetchSourceConfig()/saveSourceConfig()hittingGET/PUT /modules/tender-radar/source-config, mirroringdkv-api.tsconventions (NEXT_PUBLIC_API_URL,credentials: 'include').SourceConfigForm— loads the singleton config on mount, exposes a numericpollIntervalMininput (client-side clamp 5-1440, mirroring the backendSourceConfigDtobounds) and anisActivetoggle switch (same visual pattern asInboxConfigForm's Aktiv switch), plus read-onlysourceType/lastIngestedDaydisplay 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; nomodule-loader.tswhitelist change needed since the parenttender-radarslug is already whitelisted (Plan 10-02).- Component test (
SourceConfigForm.test.tsx, 4 tests): fetch-on-mount populates the interval input, editing + Speichern callssaveSourceConfigwith the edited{ pollIntervalMin, isActive }payload, and both out-of-bounds directions (below 5, above 1440) are rejected client-side with zerosaveSourceConfigcalls. - Full web Vitest suite green (111/111 across 20 files),
tsc --noEmitclean forapps/web.
Task Commits
Each task committed atomically:
- Task 1: tender-radar-api client + admin source-config settings form -
4360bc0(feat) - 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 acrossit()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 addingmockReset()inafterEach, all four cases passed against the already-correct Task 1 implementation on the very next run. This plan's frontmatter istype: executewith a per-tasktdd="true"flag (not a fulltype: tddplan), 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/SaveSourceConfigPayloadtypes,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 flowapps/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.tsxplaceholder's documented MVP-stub convention (full i18n is CONFIG-03, Phase 14). - No module-loader.ts change —
settings/page.tsxis a standard nested App Router route under the already-whitelistedtender-radarslug; the whitelist gate only applies to the top-level module entry (Plan 10-02), not sub-routes. - Read-only
sourceType/lastIngestedDaydisplay — 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:
afterEachonly calledvi.restoreAllMocks(), which does not clearvi.fn()call history for the module-levelmockFetchSourceConfig/mockSaveSourceConfigmocks (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 capturedsaveSourceConfig(120, true)call and failed. - Fix: Added
mockFetchSourceConfig.mockReset()/mockSaveSourceConfig.mockReset()toafterEach, run beforevi.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-guardedGET/PUT /modules/tender-radar/source-configendpoint 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 theGET /modules/tender-radar/GET /modules/tender-radar/:idread 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