docs(07): capture phase context
This commit is contained in:
@@ -0,0 +1,101 @@
|
|||||||
|
# Phase 7: Validation & UX Polish - Context
|
||||||
|
|
||||||
|
**Gathered:** 2026-03-31
|
||||||
|
**Status:** Ready for planning
|
||||||
|
|
||||||
|
<domain>
|
||||||
|
## Phase Boundary
|
||||||
|
|
||||||
|
Add format validation to specific credential fields (inline error on bad format) and clickable contextual tooltips to sensitive or confusing fields in RemoteConfigStep. Does not add new backends or change existing required/optional field logic.
|
||||||
|
|
||||||
|
</domain>
|
||||||
|
|
||||||
|
<decisions>
|
||||||
|
## Implementation Decisions
|
||||||
|
|
||||||
|
### Validation scope
|
||||||
|
- **Azure account name** (`account` field, azureblob): 3–24 lowercase alphanumeric characters — validate with regex
|
||||||
|
- **S3 region** (`region` field, s3): valid AWS region format (lowercase letters, digits, hyphens, e.g. `us-east-1`) — validate with regex
|
||||||
|
- **GCS project number** (`project_number` field, gcs): digits only — validate with regex
|
||||||
|
- **S3-compatible endpoint**: non-empty only (existing required behavior) — no URL format validation
|
||||||
|
- **S3-compatible region**: skip — optional field, no universal format rule across providers
|
||||||
|
- No other backends/fields need format validation beyond what already exists
|
||||||
|
|
||||||
|
### Validation rule location
|
||||||
|
- Add a `validate?: { regex: RegExp; message: string }` property to `FieldDef` in `src/schemas/registry.ts`
|
||||||
|
- `buildZodSchema()` in `src/schemas/index.ts` reads `field.validate` and adds `.regex(...)` to the Zod string — keeps the registry as single source of truth
|
||||||
|
- Registry entries for the 3 validated fields get their `validate` rule inline
|
||||||
|
|
||||||
|
### Tooltip trigger
|
||||||
|
- **ⓘ icon** (info icon) placed next to the field label — click/tap toggles explanation
|
||||||
|
- Inline reveal: explanation expands directly below the field input, pushing content down
|
||||||
|
- Toggle state is local to the field component (no global state needed)
|
||||||
|
- Tooltip stays visible until ⓘ is clicked again (not dismissed on blur)
|
||||||
|
|
||||||
|
### Tooltip data location
|
||||||
|
- Add a new optional `tooltipText?: string` field to the `FieldDef` interface
|
||||||
|
- `helpText` remains unchanged (brief hint, always visible below the field)
|
||||||
|
- `tooltipText` is the longer plain-language explanation shown on ⓘ click — only fields that need a tooltip get this field populated
|
||||||
|
- `FieldRenderer` and `PasswordField` render the ⓘ icon + inline expand when `tooltipText` is present
|
||||||
|
|
||||||
|
### Fields that get tooltips
|
||||||
|
Per roadmap requirements (VALID-01 / UX-01 success criteria):
|
||||||
|
- **azureblob `sas_url`**: explain SAS URL vs access key — a SAS URL bundles endpoint + time-limited token, scoped to containers; access key is the full account credential
|
||||||
|
- **azureblob `key`** (access key): explain it's the full storage account key — different from SAS, full access
|
||||||
|
- **sftp** auth method (password vs key): explain the difference between password auth and key-based auth — SftpAuthToggle UI needs an ⓘ on the tab labels or above the toggle
|
||||||
|
- **onedrive `token`**: explain what the JSON token is and how to obtain it via `rclone authorize "onedrive"`
|
||||||
|
|
||||||
|
### Claude's Discretion
|
||||||
|
- Exact Tailwind styling of the ⓘ icon and inline tooltip panel
|
||||||
|
- Whether SftpAuthToggle gets its ⓘ on the tab label or as a standalone line above the tabs
|
||||||
|
- ⓘ icon source (Heroicons, inline SVG, or text character)
|
||||||
|
- Exact wording of tooltip content (stay close to existing helpText tone)
|
||||||
|
|
||||||
|
</decisions>
|
||||||
|
|
||||||
|
<code_context>
|
||||||
|
## Existing Code Insights
|
||||||
|
|
||||||
|
### Reusable Assets
|
||||||
|
- `FieldDef` interface (`src/schemas/registry.ts`): add `validate?: { regex: RegExp; message: string }` and `tooltipText?: string` — minimal interface extension
|
||||||
|
- `buildZodSchema()` (`src/schemas/index.ts`): reads `field.required` to pick `.min(1)` — extend to also read `field.validate?.regex` and chain `.regex(regex, message)`
|
||||||
|
- `FieldRenderer` (`src/components/ui/FieldRenderer.tsx`): already renders `helpText` and `error` — add ⓘ icon + conditional inline tooltip panel alongside label
|
||||||
|
- `PasswordField` (`src/components/ui/PasswordField.tsx`): password fields also need the ⓘ icon treatment for sas_url, key, onedrive token
|
||||||
|
- `SftpAuthToggle` (`src/components/wizard/SftpAuthToggle.tsx`): manages pass/key_pem tab — needs an ⓘ for the auth method concept (tab-level, not field-level)
|
||||||
|
|
||||||
|
### Established Patterns
|
||||||
|
- Error display: errors shown only after first submit, then live (`mode: 'onSubmit', reValidateMode: 'onChange'` already set in RemoteConfigStep — no change needed)
|
||||||
|
- helpText rendered as `<p className="text-xs text-gray-500">` below field — tooltip panel should use a similar small-text style, perhaps a different color (e.g., blue-tinted)
|
||||||
|
- CSS-hidden toggle pattern used in AzureAuthToggle/SftpAuthToggle — can use same `div.hidden`/`div.block` for tooltip visibility
|
||||||
|
|
||||||
|
### Integration Points
|
||||||
|
- `src/schemas/registry.ts`: `FieldDef` interface + registry entries for azureblob.account, s3.region, gcs.project_number (add `validate`), and sas_url/key/sftp-auth/onedrive-token (add `tooltipText`)
|
||||||
|
- `src/schemas/index.ts`: `buildZodSchema()` — read `field.validate` and apply regex
|
||||||
|
- `src/components/ui/FieldRenderer.tsx`: add ⓘ icon + inline tooltip to text and select renderers
|
||||||
|
- `src/components/ui/PasswordField.tsx`: add ⓘ icon + inline tooltip to password renderer
|
||||||
|
- `src/components/wizard/SftpAuthToggle.tsx`: add ⓘ near the auth method tabs
|
||||||
|
|
||||||
|
</code_context>
|
||||||
|
|
||||||
|
<specifics>
|
||||||
|
## Specific Ideas
|
||||||
|
|
||||||
|
- Tooltip expand is local React state (useState per field) — no external state or store involvement
|
||||||
|
- The ⓘ icon appears inline with the label text: `Storage Account Name ⓘ` — clicking ⓘ expands an explanation block below the input
|
||||||
|
- Validation regex for Azure account: `/^[a-z0-9]{3,24}$/`
|
||||||
|
- Validation regex for S3 region: `/^[a-z][a-z0-9-]+[a-z0-9]$/` (AWS region format)
|
||||||
|
- Validation regex for GCS project number: `/^\d+$/`
|
||||||
|
|
||||||
|
</specifics>
|
||||||
|
|
||||||
|
<deferred>
|
||||||
|
## Deferred Ideas
|
||||||
|
|
||||||
|
None — discussion stayed within phase scope.
|
||||||
|
|
||||||
|
</deferred>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Phase: 07-validation-ux-polish*
|
||||||
|
*Context gathered: 2026-03-31*
|
||||||
Reference in New Issue
Block a user