7.7 KiB
phase, plan, subsystem, tags, dependency_graph, tech_stack, key_files, decisions, metrics
| phase | plan | subsystem | tags | dependency_graph | tech_stack | key_files | decisions | metrics | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 07-dkv-fleet-module | 06 | dkv-smtp-settings-ui |
|
|
|
|
|
|
Phase 07 Plan 06: SMTP Settings UI (Surface C) — Summary
Settings API client (settings-api.ts) and SMTP configuration UI delivered: Surface C form (SmtpSettingsForm) with show/hide password toggle, connection-test feedback with 6-second auto-clear, and the /settings/general/smtp route. SettingsSidebar extended with an "Allgemein" category linking to the SMTP page — placed above the existing Dashboard section. DKV-05 UI complete. 5 Vitest tests covering load, save, test success/failure, and password toggle pass after TDD RED→GREEN cycle.
Tasks Completed
| Task | Name | Commit | Key Files |
|---|---|---|---|
| 1 (RED) | Failing SMTP settings form tests | a96d79a |
smtp-settings.test.tsx |
| 1 (GREEN) | settings-api client + SmtpSettingsForm + SMTP page | fd2dda6 |
settings-api.ts, smtp-settings-form.tsx, smtp/page.tsx, de.json, en.json |
| 2 | Extend SettingsSidebar with Allgemein > SMTP | 75aec38 |
settings-sidebar.tsx |
Architecture Notes
Test Feedback Auto-Clear
The testFeedback state is set to { type: 'loading', message } immediately on test click, then updated to success/error after testSmtp() resolves. A setTimeout(() => setTestFeedback(null), 6000) auto-clears the feedback. The timer handle is stored in a useRef so it can be:
- Cancelled on re-click (prevents stale clear from a previous click)
- Cleaned up on unmount via a
useEffectreturn function
Password Never Pre-Filled (T-07-17)
fetchSmtp() returns SmtpConfig with hasPassword: boolean but no password value. The form always initializes password: ''. On load success, password stays ''. The password is only included in saveSmtp / testSmtp payloads when form.password !== '' (user has typed something).
SettingsSidebar Extension
The new "Allgemein" section is inserted before the existing <div className="p-4"> Dashboard category block. It uses the identical link class string (bg-sidebar-accent text-sidebar-accent-foreground font-medium for active, text-sidebar-foreground hover:bg-muted for inactive) and the same aria-current="page" pattern. The isActive helper's pathname.startsWith branch handles /settings/general/smtp automatically.
TDD Gate Compliance
- RED gate commit:
a96d79a✓ (test(07-06): add failing SMTP settings form tests) - GREEN gate commit:
fd2dda6✓ (feat(07-06): settings-api client + SmtpSettingsForm + SMTP page) - Tests: 5/5 passed ✓
Deviations from Plan
Auto-fixed Issues
1. [Rule 1 - Bug] Required-field asterisks in label text broke getByLabelText
- Found during: Task 1 GREEN phase (first test run — 2/5 tests failed)
- Issue: Initial form implementation used
{t('smtp.host')} *inside<label>text.getByLabelText('Host')failed because the label's accessible text was "Host *" (exact match required by testing-library). Thearia-hidden="true"approach on the*span also failed — @testing-library includesaria-hiddenchild text in label text content computation. - Fix: Removed asterisks from label text entirely. Required fields use the
requiredattribute on inputs for HTML5 native validation. The plan's UI-SPEC uses*as a visual convention; the semanticrequiredattribute is the correct mechanism. - Files modified: smtp-settings-form.tsx
- Commit:
fd2dda6(included in GREEN task commit)
2. [Rule 2 - Missing] i18n keys for password toggle and test feedback not in original spec
- Found during: Task 1 implementation
- Issue: The UI-SPEC
settings.smtp.*namespace defined 10 keys. The form additionally needsshowPassword,hidePassword,testTesting,testSuccess,testFailedfor the toggle button aria-labels and test feedback strings. - Fix: Added 5 new keys to
settings.smtpin both de.json and en.json. Values follow the established German copy from the UI-SPEC copywriting contract. - Files modified: apps/web/src/messages/de.json, apps/web/src/messages/en.json
- Commit:
fd2dda6
Verification Results
pnpm --filter @tessera/web exec tsc --noEmit -p tsconfig.jsonexits 0: PASSpnpm --filter @tessera/web test -- --run smtp-settings: 5/5 passedgrep -q "credentials: 'include'"settings-api.ts: PASSgrep -q "smtp/test"settings-api.ts: PASSgrep -q "categoryGeneral"settings-sidebar.tsx: PASSgrep -q "/settings/general/smtp"settings-sidebar.tsx: PASSgrep -q "categorySmtp"settings-sidebar.tsx: PASS- All 4 created files present on disk: PASS
- settings-sidebar.tsx modified: PASS
Known Stubs
None. settings-api.ts targets real /settings/smtp endpoints from Plan 03 (SettingsController). SmtpSettingsForm is fully wired to fetchSmtp/saveSmtp/testSmtp. The SMTP page renders the form directly. No placeholder values or TODO items.
Threat Flags
None. All STRIDE threats from the plan's threat register are mitigated:
- T-07-17:
SmtpConfigexposes onlyhasPassword; password state always''; password sent only when typed;credentials: 'include'on all API calls - T-07-18: Backend
@Roles(Role.ADMIN, Role.SUPER_ADMIN)on /settings/smtp endpoints (Plan 03) is authoritative; frontend cannot bypass - T-07-19: All backend strings rendered via React text nodes; no
dangerouslySetInnerHTMLin any new component