diff --git a/.planning/STATE.md b/.planning/STATE.md index 3effe3f..3293858 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -4,7 +4,7 @@ milestone: v1.1 milestone_name: Backlog & Tech Debt status: planning stopped_at: Completed 07-validation-ux-polish 07-02-PLAN.md -last_updated: "2026-03-31T11:48:24.342Z" +last_updated: "2026-03-31T11:53:18.993Z" last_activity: 2026-03-27 — v1.1 roadmap created, 11 requirements mapped across 3 phases progress: total_phases: 3 diff --git a/.planning/phases/07-validation-ux-polish/07-VERIFICATION.md b/.planning/phases/07-validation-ux-polish/07-VERIFICATION.md new file mode 100644 index 0000000..2084f58 --- /dev/null +++ b/.planning/phases/07-validation-ux-polish/07-VERIFICATION.md @@ -0,0 +1,159 @@ +--- +phase: 07-validation-ux-polish +verified: 2026-03-31T13:55:00Z +status: human_needed +score: 12/12 must-haves verified +re_verification: false +human_verification: + - test: "Inline validation error on Azure account name field" + expected: "Typing 'ABC' then clicking Next shows 'Must be 3–24 lowercase alphanumeric characters' below the field before advancing" + why_human: "Visual rendering and wizard step-gate behavior cannot be confirmed by test assertions alone" + - test: "Inline validation error on S3 region field" + expected: "Typing 'us east 1' then clicking Next shows 'Must be a valid AWS region format (e.g. us-east-1)' inline" + why_human: "Visual placement and UX clarity require a human eye" + - test: "Inline validation error on GCS project_number field" + expected: "Typing 'abc' then clicking Next shows 'Must contain digits only' inline" + why_human: "Visual placement and UX clarity require a human eye" + - test: "Tooltip toggle on SAS URL field" + expected: "Clicking ⓘ next to 'SAS URL' label reveals an explanation panel; clicking again hides it" + why_human: "The human-verify checkpoint in Plan 07-02 was approved (commit 7548c7b) — but that approval is documented in a commit message, not independently verifiable by automated means. A fresh human confirmation closes the loop." + - test: "Tooltip toggle on Access Key field" + expected: "Clicking ⓘ next to 'Access Key' label reveals the unrestricted-access warning panel; clicking again hides it" + why_human: "Same as above — visual confirm of content and toggle" + - test: "Tooltip toggle on SFTP authentication method" + expected: "Clicking ⓘ above the Password/Private Key tabs reveals the auth-method explanation; clicking again hides it" + why_human: "Section-level tooltip — visual placement relative to segmented control needs human confirm" + - test: "Tooltip toggle on OneDrive token field" + expected: "Clicking ⓘ next to 'OAuth Token (JSON)' label reveals the rclone-authorize JSON token explanation; clicking again hides it" + why_human: "Visual confirm of content and toggle" +--- + +# Phase 7: Validation and UX Polish Verification Report + +**Phase Goal:** Add inline field format validation and contextual tooltip help to reduce config errors and support-ticket load. +**Verified:** 2026-03-31T13:55:00Z +**Status:** human_needed +**Re-verification:** No — initial verification + +## Goal Achievement + +### Observable Truths + +| # | Truth | Status | Evidence | +|----|-------|--------|----------| +| 1 | VALID-01 failing tests exist for Azure account name regex rejection and acceptance | VERIFIED | `describe('VALID-01 — format validation')` block in RemoteConfigStep.test.tsx, lines 233–337; 3 Azure tests present | +| 2 | VALID-01 failing tests exist for S3 region regex rejection and acceptance | VERIFIED | S3 region tests at lines 282–309 in test file | +| 3 | VALID-01 failing tests exist for GCS project_number regex rejection and acceptance | VERIFIED | GCS tests at lines 312–336 in test file | +| 4 | UX-01 failing tests exist for ⓘ button presence and tooltip toggle behavior | VERIFIED | `describe('UX-01 — contextual tooltips')` block at lines 339–401; 5 tests present | +| 5 | User entering 'MyStorage' in Azure account name sees an inline error before advancing | VERIFIED | `validate: { regex: /^[a-z0-9]{3,24}$/, message: 'Must be 3–24 lowercase alphanumeric characters...' }` in registry.ts line 33; `buildZodSchema()` chains `.regex()` in index.ts line 18; test passes | +| 6 | User entering 'us east 1' in S3 region field sees an inline error | VERIFIED | `validate: { regex: /^[a-z][a-z0-9-]+[a-z0-9]$/, message: 'Must be a valid AWS region format...' }` in registry.ts line 87; test passes | +| 7 | User entering 'abc' in GCS project_number field sees an inline error | VERIFIED | `validate: { regex: /^\d+$/, message: 'Must contain digits only' }` in registry.ts line 183; test passes | +| 8 | Valid values produce no format error | VERIFIED | Acceptance tests at lines 266, 295, 325 all pass (159/159 full suite) | +| 9 | Empty required fields show 'required' error, not the regex error | VERIFIED | `buildZodSchema()` applies `min(1)` before `regex()` for required fields; order guaranteed by let-schema pattern | +| 10 | User can click ⓘ next to SAS URL / Access Key and read an explanation | VERIFIED | `tooltipText` populated in registry.ts lines 44, 53; AzureAuthToggle reads from BACKEND_REGISTRY and passes to PasswordField (lines 19–20); PasswordField renders ⓘ button + toggle panel | +| 11 | User can click ⓘ on SFTP authentication method section | VERIFIED | SftpAuthToggle.tsx has `showAuthTip` state, ⓘ button with `aria-label="More info about authentication methods"`, conditional explanation panel | +| 12 | User can click ⓘ next to OneDrive token label | VERIFIED | `tooltipText` populated in registry.ts line 147; FieldRenderer passes `tooltipText={field.tooltipText}` to PasswordField for password-type fields | + +**Score:** 12/12 truths verified + +### Required Artifacts + +| Artifact | Expected | Status | Details | +|----------|----------|--------|---------| +| `src/components/wizard/RemoteConfigStep.test.tsx` | Failing test stubs for VALID-01 and UX-01 | VERIFIED | `describe('VALID-01...')` and `describe('UX-01...')` blocks present; 12 tests added (7 VALID-01 + 5 UX-01); all 33 RemoteConfigStep tests pass | +| `src/schemas/registry.ts` | FieldDef with `validate?` and `tooltipText?`; 3 entries with validate rules; tooltipText for sas_url, key, token | VERIFIED | Both optional properties on FieldDef (lines 17–18); validate rules on azureblob.account, s3.region, gcs.project_number; tooltipText on azureblob.sas_url, azureblob.key, onedrive.token | +| `src/schemas/index.ts` | `buildZodSchema()` chains `.regex()` when `field.validate` is present | VERIFIED | `if (field.validate)` block at lines 17–19 chains `(schema as z.ZodString).regex(...)` | +| `src/components/ui/FieldRenderer.tsx` | ⓘ button + tooltip panel for text/select; passes `tooltipText` to PasswordField | VERIFIED | `useState(false)` for `showTooltip`; ⓘ button in both text (line 90) and select (line 48) branches; `tooltipText={field.tooltipText}` passed to PasswordField (line 35) | +| `src/components/ui/PasswordField.tsx` | `tooltipText` prop + `showTooltip` state + ⓘ button + conditional panel | VERIFIED | `tooltipText?: string` in interface (line 11); `showTooltip` state (line 16); ⓘ button (line 23); conditional panel (line 34) | +| `src/components/wizard/AzureAuthToggle.tsx` | Reads `tooltipText` from BACKEND_REGISTRY, passes to PasswordField | VERIFIED | `sasUrlTooltip` and `keyTooltip` lookups via `BACKEND_REGISTRY.azureblob.fields.find(...)` (lines 19–20); both passed as `tooltipText` prop to PasswordField | +| `src/components/wizard/SftpAuthToggle.tsx` | `showAuthTip` state + ⓘ button above segmented control | VERIFIED | `showAuthTip` state (line 17); ⓘ button with `aria-label="More info about authentication methods"` (line 27); conditional explanation panel (line 33) | + +### Key Link Verification + +| From | To | Via | Status | Details | +|------|----|-----|--------|---------| +| `BACKEND_REGISTRY azureblob.account.validate` | `buildZodSchema('azureblob')` | `field.validate` conditional + `(schema as z.ZodString).regex()` | WIRED | index.ts lines 17–19; regex applied and test confirms error message surfaces | +| `BACKEND_REGISTRY s3.region.validate` | `buildZodSchema('s3')` | same pattern | WIRED | registry.ts line 87; test passing | +| `BACKEND_REGISTRY gcs.project_number.validate` | `buildZodSchema('gcs')` | same pattern | WIRED | registry.ts line 183; test passing | +| `BACKEND_REGISTRY azureblob.sas_url.tooltipText` | `AzureAuthToggle → PasswordField tooltipText prop` | `BACKEND_REGISTRY.azureblob.fields.find(f => f.key === 'sas_url')?.tooltipText` | WIRED | AzureAuthToggle.tsx line 19; `tooltipText={sasUrlTooltip}` at line 61 | +| `BACKEND_REGISTRY onedrive.token.tooltipText` | `FieldRenderer ⓘ button rendered` | `field.tooltipText` present → `tooltipText` passed to PasswordField | WIRED | FieldRenderer.tsx line 35; test `renders ⓘ button on OneDrive token field` passes | +| `SftpAuthToggle showAuthTip state` | inline explanation panel | `useState` + `{showAuthTip &&
...}` | WIRED | SftpAuthToggle.tsx line 33; test `renders ⓘ button on SFTP auth method section` passes | + +### Requirements Coverage + +| Requirement | Source Plans | Description | Status | Evidence | +|-------------|-------------|-------------|--------|----------| +| VALID-01 | 07-00, 07-01 | User sees inline validation error on format violations (Azure account, S3 region, GCS project_number) | SATISFIED | validate rules in registry.ts; buildZodSchema chains .regex(); 7 VALID-01 tests pass; TypeScript compiles clean | +| UX-01 | 07-00, 07-02 | User can view contextual tooltip on sensitive/complex fields (SAS token, access key, SFTP auth method, OneDrive token) | SATISFIED | tooltipText in registry; ⓘ buttons in PasswordField/FieldRenderer/SftpAuthToggle; AzureAuthToggle wired; 5 UX-01 tests pass | + +No orphaned requirements — REQUIREMENTS.md maps only VALID-01 and UX-01 to Phase 7, both claimed by plans and verified. + +### Anti-Patterns Found + +| File | Line | Pattern | Severity | Impact | +|------|------|---------|----------|--------| +| `src/components/ui/FieldRenderer.tsx` | 94–98 | Text-branch ⓘ button uses `` for accessible name instead of `aria-label` on the button element directly — unlike the select branch (line 52) which uses `aria-label` | Info | Tests still pass because `sr-only` span content is used by testing-library as the button's accessible name. However the two branches are inconsistent: select uses `aria-label`, text uses `sr-only` span. Not a functional defect but a maintainability inconsistency. | + +No blockers, no stubs, no TODO/FIXME/placeholder comments found in modified files. + +### Human Verification Required + +All automated checks pass (159/159 tests, 0 TypeScript errors). The items below require a human to confirm real-browser behavior, because the human-verify checkpoint documented in Plan 07-02 (commit 7548c7b) was the original approval — this verification independently requests a fresh confirmation. + +#### 1. Inline Validation — Azure Account Name + +**Test:** Open wizard, select Azure Blob Storage. Type `ABC` into Storage Account Name, click Next. +**Expected:** An inline error reading "Must be 3–24 lowercase alphanumeric characters (no hyphens or uppercase)" appears below the field. The wizard does not advance. +**Why human:** Visual placement of error, step-gate behavior. + +#### 2. Inline Validation — S3 Region + +**Test:** Select Amazon S3. Type `us east 1` into Region, click Next. +**Expected:** Inline error reading "Must be a valid AWS region format (e.g. us-east-1)" appears. Wizard does not advance. +**Why human:** Visual placement of error, step-gate behavior. + +#### 3. Inline Validation — GCS Project Number + +**Test:** Select Google Cloud Storage. Type `abc` into Project Number, click Next. +**Expected:** Inline error "Must contain digits only" appears. Wizard does not advance. +**Why human:** Visual placement of error, step-gate behavior. + +#### 4. Tooltip Toggle — SAS URL + +**Test:** Select Azure Blob Storage. Click the ⓘ button next to "SAS URL". +**Expected:** An explanation panel appears below the SAS URL field containing text about Shared Access Signatures. Click ⓘ again — panel disappears. +**Why human:** Visual appearance, tooltip content readability, toggle feel. + +#### 5. Tooltip Toggle — Access Key + +**Test:** In Azure Blob Storage, switch to the "Access Key" tab. Click ⓘ next to "Access Key". +**Expected:** Panel appears with unrestricted-access warning. Click ⓘ again — panel hides. +**Why human:** Visual confirm; the ⓘ button is CSS-hidden until the Access Key tab is active. + +#### 6. Tooltip Toggle — SFTP Authentication Method + +**Test:** Select SFTP. Confirm ⓘ appears above the Password/Private Key tab row (labeled "Authentication Method ⓘ"). Click it. +**Expected:** Explanation panel appears describing password vs key-based auth. Click again — panel hides. +**Why human:** Section-level tooltip placement relative to segmented control. + +#### 7. Tooltip Toggle — OneDrive Token + +**Test:** Select OneDrive. Click ⓘ next to "OAuth Token (JSON)". +**Expected:** Panel appears explaining `rclone authorize "onedrive"` and pasting the JSON blob. Click ⓘ again — panel hides. +**Why human:** Content accuracy and readability of the rclone-specific guidance. + +### Gaps Summary + +No gaps found. All automated evidence confirms the phase goal was achieved: + +- VALID-01: Three backend-specific regex validators wired end-to-end from `BACKEND_REGISTRY` through `buildZodSchema()` to the wizard form; inline error messages match the specified copy; all 7 validation tests pass. +- UX-01: Four tooltip surfaces implemented (SAS URL, Access Key, SFTP auth method, OneDrive token); ⓘ button + toggle panel present in FieldRenderer, PasswordField, AzureAuthToggle, and SftpAuthToggle; all 5 tooltip tests pass. +- Full suite: 159 tests, 0 failures, 0 TypeScript errors. +- All 6 commits documented in summaries confirmed in git history. + +The only outstanding item is fresh human confirmation that the UI behaves correctly in a running browser. The original human-verify checkpoint (Plan 07-02 Task 3) was approved, so this is a confirmation step rather than a discovery step. + +--- + +_Verified: 2026-03-31T13:55:00Z_ +_Verifier: Claude (gsd-verifier)_