diff --git a/.planning/MILESTONES.md b/.planning/MILESTONES.md index b3da87b..9e424f7 100644 --- a/.planning/MILESTONES.md +++ b/.planning/MILESTONES.md @@ -23,3 +23,23 @@ --- +## v1.1 Backlog & Tech Debt (Shipped: 2026-03-31) + +**Phases completed:** 3 phases, 11 plans +**Timeline:** 2026-03-30 → 2026-03-31 (2 days) +**Stats:** 47 files changed, +7,311 / -210 lines + +**Key accomplishments:** +1. Registry-driven architecture — BACKEND_REGISTRY enriched with `displayName`, `description`, `fields`; BackendSelectionStep fully data-driven via `Object.entries()` +2. 4 new cloud backends — OneDrive, SFTP (password + key auth), GCS, and Backblaze B2 added end-to-end through registry, schema, and UI +3. SftpAuthToggle component — CSS-hidden toggle for SFTP auth method (password vs SSH key), following AzureAuthToggle pattern +4. RemoteConfigStep extended for all 7 backends — registry-loop renders all fields; SFTP has dedicated branch +5. Inline field validation — `FieldDef.validate` regex rules on 3 fields; wired via `buildZodSchema().regex()` +6. Contextual tooltips (UX-01) — `FieldDef.tooltipText` rendered via ⓘ button across all field types + +**Tech debt carried forward:** +- 7 browser UI verifications pending (confirmatory, not discovery) +- FieldRenderer aria inconsistency between text-branch and select-branch (cosmetic) +- Phase 7 Nyquist compliance partial + +--- diff --git a/.planning/PROJECT.md b/.planning/PROJECT.md index 48e1b44..918a514 100644 --- a/.planning/PROJECT.md +++ b/.planning/PROJECT.md @@ -2,44 +2,31 @@ ## What This Is -Ready2Blob is a pure-frontend web app that helps IT professionals deploy rclone onto end-user Windows PCs. A step-by-step wizard collects backend credentials (Azure Blob, S3, S3-compatible) and deployment preferences, then generates rclone config files and PowerShell scripts ready to push via Intune or any RMM tool — all client-side, no server required. +Ready2Blob is a pure-frontend web app that helps IT professionals deploy rclone onto end-user Windows PCs. A step-by-step wizard collects backend credentials (Azure Blob, S3, S3-compatible, OneDrive, SFTP, Google Cloud Storage, Backblaze B2) and deployment preferences, then generates rclone config files and PowerShell scripts ready to push via Intune or any RMM tool — all client-side, no server required. ## Core Value An IT pro can go from zero to a deployable rclone setup in minutes — without needing to know rclone's config syntax or PowerShell deployment conventions. -## Requirements +## Current State -### Validated +**Shipped:** v1.1 — 2026-03-31 +**Backends:** 7 (Azure Blob, S3, S3-compatible, OneDrive, SFTP, GCS, Backblaze B2) +**Tech stack:** Vite 6, React 18, TypeScript 5, Tailwind v4, react-hook-form 7, Zod 4, Vitest 4, JSZip +**Test coverage:** 159 tests across all test files — all GREEN +**Total milestones:** 2 shipped (v1.0 + v1.1), 7 phases, 29 plans -- ✓ Multi-step wizard guides user through rclone backend selection and configuration — v1.0 -- ✓ Supports Azure Blob, S3, and S3-compatible backends — v1.0 -- ✓ Generates a valid rclone.conf file with live preview — v1.0 -- ✓ Generates PowerShell deployment script for MS Intune (Intune install + detection scripts) — v1.0 -- ✓ Generates PowerShell deployment script for RMM tools (generic SYSTEM-context) — v1.0 -- ✓ User can download each output file individually or as a ZIP bundle — v1.0 -- ✓ Includes rclone installation step in scripts (toggleable) — v1.0 -- ✓ All config generation runs client-side (no backend, static site) — v1.0 -- ✓ Security warning gate before any download — v1.0 -- ✓ Wizard state never written to localStorage or sessionStorage — v1.0 +## Next Milestone Goals -### Active +*(Not yet defined — run `/gsd:new-milestone` to start next milestone)* -**Milestone: v1.1 — Backlog & Tech Debt** +## Constraints -*Tech debt:* -- [ ] `scriptTargets` filtering: only render output blocks for selected Intune/RMM targets (TD-1) -- [ ] ReviewStep Back button (UX consistency with other steps — TD-2) -- [ ] Backend list in BackendSelectionStep driven by BACKEND_REGISTRY keys (maintainability — TD-4) -- [ ] `BackendFormValues` dead export removal from src/schemas/index.ts -- [ ] `act()` warnings fixed in BackendSelectionStep tests +- **Architecture**: Pure static frontend — no backend, no server required +- **Target OS**: Windows endpoints only (scripts are PowerShell) +- **Secrets**: Plain text in generated files — UI must display a clear security warning before download -*Backlog features:* -- [ ] Additional backends: OneDrive, SFTP, Google Cloud Storage, Backblaze B2 -- [ ] Field-level format validation per backend (Azure account name format, S3 region codes) -- [ ] Explanatory tooltips on sensitive fields (SAS token vs access key, region codes) - -### Out of Scope +## Out of Scope - User accounts / saved templates — no backend, no persistence - Server-side generation — everything runs in the browser @@ -48,24 +35,8 @@ An IT pro can go from zero to a deployable rclone setup in minutes — without n - Non-Windows targets — scripts target Windows endpoints only - Auto-push to Intune via Graph API — requires Azure AD app registration, massive scope increase - Config credential encryption — rclone encrypted configs require interactive unlock, incompatible with unattended deployment - -## Context - -**Shipped:** v1.0 — 2026-03-26/27, 2 days, 4 phases, 18 plans, ~2,746 LOC TypeScript/TSX -**Tech stack:** Vite 6, React 18, TypeScript 5, Tailwind v4, react-hook-form 7, Zod 4, Vitest 4, JSZip -**Test coverage:** 98 tests across 12 test files — all GREEN - -**Known issues / tech debt:** -- `scriptTargets` disconnect: user can deselect Intune or RMM in DeploymentStep but all blocks still appear in ReviewStep -- ReviewStep lacks a Back button; users navigate back via StepIndicator breadcrumb only -- BackendSelectionStep BACKENDS constant is hardcoded — adding to BACKEND_REGISTRY does not auto-surface in UI -- 6 browser verifications still pending (live preview reactivity, real file writes, ZIP content, clipboard, DevTools storage check) - -## Constraints - -- **Architecture**: Pure static frontend — no backend, no server required -- **Target OS**: Windows endpoints only (scripts are PowerShell) -- **Secrets**: Plain text in generated files — UI must display a clear security warning before download +- Multiple remotes in one config — significant wizard UX complexity, defer to v2 +- OAuth flow in browser (OneDrive) — requires backend proxy; paste pre-obtained token instead ## Key Decisions @@ -75,26 +46,33 @@ An IT pro can go from zero to a deployable rclone setup in minutes — without n | BACKEND_REGISTRY as single source of truth | Drives form rendering, Zod schemas, and config generation from one definition | ✓ Good — zero duplication across phases | | useReducer + Context API (no external state lib) | Zero dependencies, sufficient for 4-step wizard | ✓ Good — kept bundle lean | | Wave 0 TDD (stubs RED before implementation) | Forces API contract before code, catches integration mismatches early | ✓ Good — caught several issues upfront | -| Support all rclone backends (not Azure-only) | Broader utility despite "Blob" in project name | ✓ Good — S3-compatible covers Wasabi/MinIO/R2 | +| Support all rclone backends (not Azure-only) | Broader utility despite "Blob" in project name | ✓ Good — 7 backends and growing | | Optional rclone install in scripts | Different orgs have different baseline images | ✓ Good — no friction for orgs that pre-install | | Tailwind v4 via @tailwindcss/vite plugin | No postcss.config.js, no tailwind.config.js needed | ✓ Good — cleaner config | | Zod v4 + @hookform/resolvers v5 together | v5 resolvers required for Zod v4 compatibility | ✓ Good — noted for future upgrades | -| AzureAuthToggle uses CSS hidden (not conditional render) | Preserves both sas_url and key in react-hook-form state when toggling | ✓ Good — avoids field reset on toggle | -| scriptTargets defaults to both ['intune','rmm'] | Users deselect rather than discover — less friction | — Pending (deferred filtering to v1.1) | -| BACKEND_REGISTRY keys not wired to UI list | Hardcoded BACKENDS constant in BackendSelectionStep | ⚠️ Revisit — maintainability gap for v1.1 | +| AzureAuthToggle / SftpAuthToggle CSS hidden pattern | Preserves both auth fields in react-hook-form state when toggling | ✓ Good — avoids field reset on toggle | +| FieldDef.validate + tooltipText extension | Additive interface change, non-breaking to existing backends | ✓ Good — clean composition | +| Registry-loop rendering in RemoteConfigStep | Three-branch ternary (azureblob/sftp/else) — custom logic minimal | ✓ Good — scales with new backends | -## Current Milestone: v1.1 Backlog & Tech Debt +
+Previous milestone context (v1.0 → v1.1) -**Goal:** Ship all deferred tech debt and backlog features from v1.0 — no new functionality. +**v1.0 shipped:** 2026-03-27, 4 phases, 18 plans, ~2,746 LOC +**v1.1 shipped:** 2026-03-31, 3 phases, 11 plans, +7,311 lines -**Target features:** -- scriptTargets filtering in ReviewStep -- ReviewStep Back button -- BackendSelectionStep driven by BACKEND_REGISTRY -- Dead export + test warning cleanup -- 4 additional backends (OneDrive, SFTP, GCS, Backblaze B2) -- Field-level format validation per backend -- Explanatory tooltips on sensitive fields +**v1.0 tech debt resolved in v1.1:** +- scriptTargets filtering in ReviewStep (TECH-01) +- ReviewStep Back button (TECH-02) +- Registry-driven BackendSelectionStep (TECH-03) +- Dead export removal (TECH-04) +- act() warnings fix (TECH-05) + +**v1.1 remaining tech debt:** +- 7 browser UI verifications pending (confirmatory) +- FieldRenderer aria inconsistency (cosmetic) +- Phase 7 Nyquist compliance partial + +
--- -*Last updated: 2026-03-27 after v1.1 milestone started* +*Last updated: 2026-03-31 after v1.1 milestone completed* diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md deleted file mode 100644 index 25ebe9e..0000000 --- a/.planning/REQUIREMENTS.md +++ /dev/null @@ -1,68 +0,0 @@ -# Requirements: Ready2Blob - -**Defined:** 2026-03-30 -**Core Value:** An IT pro can go from zero to a deployable rclone setup in minutes — without needing to know rclone's config syntax or PowerShell deployment conventions. - -## v1.1 Requirements - -### Tech Debt - -- [x] **TECH-01**: User sees only the script output blocks matching their selected deployment targets (Intune and/or RMM) in ReviewStep -- [x] **TECH-02**: User can navigate back from ReviewStep using an explicit Back button -- [x] **TECH-03**: Backend list in BackendSelectionStep is automatically derived from BACKEND_REGISTRY keys (no hardcoded list) -- [x] **TECH-04**: Dead `BackendFormValues` export is removed from `src/schemas/index.ts` -- [x] **TECH-05**: BackendSelectionStep test suite runs without `act()` warnings - -### Backends - -- [x] **BACK-01**: User can configure an OneDrive remote (with OAuth token paste input and guidance) -- [x] **BACK-02**: User can configure an SFTP remote (host, user, password or key-based auth) -- [x] **BACK-03**: User can configure a Google Cloud Storage remote -- [x] **BACK-04**: User can configure a Backblaze B2 remote - -### Validation - -- [x] **VALID-01**: User sees inline validation error when a field value violates backend-specific format rules (Azure account name: 3–24 lowercase alphanumeric; S3 region: valid format; etc.) - -### UX - -- [x] **UX-01**: User can view a contextual tooltip on sensitive or complex fields (SAS token vs. access key, region codes, SFTP auth method, OneDrive token) - -## Future Requirements - -*(None identified — all backlog items are in scope for v1.1)* - -## Out of Scope - -| Feature | Reason | -|---------|--------| -| Multiple remotes in one config | Significant wizard UX complexity — defer to v2 | -| OAuth flow in browser (OneDrive) | Requires backend proxy; paste pre-obtained token instead | -| Test connection / credential validation | Requires backend proxy (CORS blocks direct cloud API calls) | -| RMM-named script variants | Generic SYSTEM-context script covers all RMM platforms | -| Save/load configurations | localStorage = credentials in browser storage = security risk | - -## Traceability - -| Requirement | Phase | Status | -|-------------|-------|--------| -| TECH-01 | Phase 5 | Complete | -| TECH-02 | Phase 5 | Complete | -| TECH-03 | Phase 5 | Complete | -| TECH-04 | Phase 5 | Complete | -| TECH-05 | Phase 5 | Complete | -| BACK-01 | Phase 6 | Complete | -| BACK-02 | Phase 6 | Complete | -| BACK-03 | Phase 6 | Complete | -| BACK-04 | Phase 6 | Complete | -| VALID-01 | Phase 7 | Complete | -| UX-01 | Phase 7 | Complete | - -**Coverage:** -- v1.1 requirements: 11 total -- Mapped to phases: 11 -- Unmapped: 0 ✓ - ---- -*Requirements defined: 2026-03-30* -*Last updated: 2026-03-27 after roadmap creation — all 11 requirements mapped* diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 4d9e90b..4e4b823 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -3,7 +3,7 @@ ## Milestones - ✅ **v1.0 MVP** — Phases 1–4 (shipped 2026-03-27) -- 🚧 **v1.1 Backlog & Tech Debt** — Phases 5–7 (in progress) +- ✅ **v1.1 Backlog & Tech Debt** — Phases 5–7 (shipped 2026-03-31) ## Phases @@ -19,67 +19,16 @@ Full phase details: [.planning/milestones/v1.0-ROADMAP.md](milestones/v1.0-ROADM -### 🚧 v1.1 Backlog & Tech Debt (In Progress) +
+✅ v1.1 Backlog & Tech Debt (Phases 5–7) — SHIPPED 2026-03-31 -**Milestone Goal:** Ship all deferred tech debt and backlog features from v1.0 — scriptTargets filtering, UX consistency fixes, registry-driven backend list, 4 new backends, field validation, and contextual tooltips. +- [x] Phase 5: Tech Debt (4/4 plans) — completed 2026-03-30 +- [x] Phase 6: New Backends (4/4 plans) — completed 2026-03-31 +- [x] Phase 7: Validation & UX Polish (3/3 plans) — completed 2026-03-31 -- [x] **Phase 5: Tech Debt** - Fix all deferred v1.0 issues (scriptTargets filtering, Back button, registry-driven UI, dead export, test warnings) (completed 2026-03-30) -- [x] **Phase 6: New Backends** - Add OneDrive, SFTP, Google Cloud Storage, and Backblaze B2 to the backend registry and wizard (completed 2026-03-31) -- [x] **Phase 7: Validation & UX Polish** - Add field-level format validation and contextual tooltips across all backends (completed 2026-03-31) +Full phase details: [.planning/milestones/v1.1-ROADMAP.md](milestones/v1.1-ROADMAP.md) -## Phase Details - -### Phase 5: Tech Debt -**Goal**: The wizard behaves consistently and the codebase is clean — no visual noise from deselected script targets, ReviewStep has a Back button, BackendSelectionStep is driven by the registry, and dead code is removed -**Depends on**: Phase 4 (v1.0 complete) -**Requirements**: TECH-01, TECH-02, TECH-03, TECH-04, TECH-05 -**Success Criteria** (what must be TRUE): - 1. User who deselected RMM in DeploymentStep sees only the Intune output block in ReviewStep (and vice versa) - 2. User can click a Back button on ReviewStep to return to DeploymentStep without losing any form data - 3. Adding a new entry to BACKEND_REGISTRY automatically surfaces that backend in the BackendSelectionStep UI with no other code changes - 4. BackendSelectionStep test suite runs with zero `act()` warnings in the Vitest output - 5. `BackendFormValues` export is absent from `src/schemas/index.ts` and no TypeScript errors arise -**Plans**: 4 plans - -Plans: -- [ ] 05-00-PLAN.md — Wave 0 TDD stubs: ReviewStep filtering + Back button failing tests, registry.test.ts .fields prep -- [ ] 05-01-PLAN.md — Registry enrichment (TECH-03) + consumers update + dead export removal (TECH-04) -- [ ] 05-02-PLAN.md — ReviewStep scriptTargets filtering + Back button (TECH-01, TECH-02) -- [ ] 05-03-PLAN.md — act() warnings fix: userEvent migration + vi.useFakeTimers (TECH-05) - -### Phase 6: New Backends -**Goal**: IT pros can configure OneDrive, SFTP, Google Cloud Storage, and Backblaze B2 remotes through the same wizard flow, with appropriate guidance for OAuth-based and key-based auth methods -**Depends on**: Phase 5 -**Requirements**: BACK-01, BACK-02, BACK-03, BACK-04 -**Success Criteria** (what must be TRUE): - 1. User can select OneDrive as a backend, paste a pre-obtained rclone OAuth token, and generate a valid rclone.conf containing `[type = onedrive]` with the token field - 2. User can select SFTP as a backend, choose between password and private-key authentication, fill the appropriate fields, and generate a valid rclone.conf - 3. User can select Google Cloud Storage as a backend, fill in the required fields, and generate a valid rclone.conf containing `[type = google cloud storage]` - 4. User can select Backblaze B2 as a backend, enter their application key credentials, and generate a valid rclone.conf containing `[type = b2]` - 5. All four new backends appear in the BackendSelectionStep list and each produces a downloadable config+scripts bundle -**Plans**: 4 plans - -Plans: -- [ ] 06-00-PLAN.md — Wave 0 TDD stubs: failing tests for all four new backends across registry, rclone-conf, and RemoteConfigStep -- [ ] 06-01-PLAN.md — Registry + schema + RCLONE_TYPE_MAP for OneDrive, GCS, Backblaze B2 -- [ ] 06-02-PLAN.md — Registry + schema + RCLONE_TYPE_MAP for SFTP + SftpAuthToggle component -- [ ] 06-03-PLAN.md — Wire all four backends into RemoteConfigStep + human verification - -### Phase 7: Validation & UX Polish -**Goal**: Users receive immediate inline feedback when they enter incorrectly formatted values, and can access plain-language explanations on confusing credential fields without leaving the wizard -**Depends on**: Phase 6 -**Requirements**: VALID-01, UX-01 -**Success Criteria** (what must be TRUE): - 1. User who enters an Azure storage account name shorter than 3 characters or containing uppercase letters sees an inline error message before they can advance - 2. User who enters an S3 region in an invalid format (e.g., spaces or uppercase) sees an inline error message - 3. User can hover or click a tooltip icon on sensitive fields (SAS token, access key, SFTP auth method, OneDrive token) and read a plain-language explanation without navigating away - 4. Tooltip content accurately distinguishes SAS token from storage account key in the Azure backend form -**Plans**: 3 plans - -Plans: -- [ ] 07-00-PLAN.md — Wave 0 TDD stubs: failing tests for VALID-01 regex rejection/acceptance and UX-01 tooltip toggle -- [ ] 07-01-PLAN.md — VALID-01: FieldDef validate extension + buildZodSchema regex chaining for 3 fields -- [ ] 07-02-PLAN.md — UX-01: tooltipText in registry + FieldRenderer/PasswordField ⓘ toggle + AzureAuthToggle/SftpAuthToggle wiring + human verification +
## Progress @@ -89,6 +38,6 @@ Plans: | 2. Generators | v1.0 | 4/4 | Complete | 2026-03-26 | | 3. Wizard UI | v1.0 | 5/5 | Complete | 2026-03-27 | | 4. Review, Download & Security | v1.0 | 5/5 | Complete | 2026-03-27 | -| 5. Tech Debt | 4/4 | Complete | 2026-03-30 | - | -| 6. New Backends | 4/4 | Complete | 2026-03-31 | - | -| 7. Validation & UX Polish | 3/3 | Complete | 2026-03-31 | - | +| 5. Tech Debt | v1.1 | 4/4 | Complete | 2026-03-30 | +| 6. New Backends | v1.1 | 4/4 | Complete | 2026-03-31 | +| 7. Validation & UX Polish | v1.1 | 3/3 | Complete | 2026-03-31 | diff --git a/.planning/STATE.md b/.planning/STATE.md index 3293858..71806ec 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -2,10 +2,10 @@ gsd_state_version: 1.0 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:53:18.993Z" -last_activity: 2026-03-27 — v1.1 roadmap created, 11 requirements mapped across 3 phases +status: completed +stopped_at: Milestone v1.1 archived +last_updated: "2026-03-31T15:00:00Z" +last_activity: 2026-03-31 — v1.1 milestone completed and archived progress: total_phases: 3 completed_phases: 3 @@ -14,135 +14,26 @@ progress: percent: 100 --- ---- -gsd_state_version: 1.0 -milestone: v1.1 -milestone_name: Backlog & Tech Debt -status: planning -stopped_at: Completed 06-new-backends 06-02-PLAN.md -last_updated: "2026-03-30T16:15:00Z" -last_activity: 2026-03-27 — v1.1 roadmap created, 11 requirements mapped across 3 phases -progress: - [██████████] 100% - completed_phases: 1 - total_plans: 8 - completed_plans: 7 - percent: 88 ---- - ---- -gsd_state_version: 1.0 -milestone: v1.1 -milestone_name: Backlog & Tech Debt -status: planning -stopped_at: Completed 05-tech-debt 05-03-PLAN.md -last_updated: "2026-03-30T07:44:48.651Z" -last_activity: 2026-03-27 — v1.1 roadmap created, 11 requirements mapped across 3 phases -progress: - [█████████░] 88% - completed_phases: 1 - total_plans: 4 - completed_plans: 4 - percent: 0 ---- - # Project State ## Project Reference -See: .planning/PROJECT.md (updated 2026-03-27) +See: .planning/PROJECT.md (updated 2026-03-31) **Core value:** An IT pro can go from zero to a deployable rclone setup in minutes — without needing to know rclone's config syntax or PowerShell deployment conventions. -**Current focus:** Phase 5 — Tech Debt (ready to plan) +**Current focus:** v1.1 shipped — ready for next milestone ## Current Position -Phase: 5 of 7 (Tech Debt) -Plan: — (not yet planned) -Status: Ready to plan -Last activity: 2026-03-27 — v1.1 roadmap created, 11 requirements mapped across 3 phases +Milestone: v1.1 (SHIPPED) +Phase: All complete (5–7) +Status: Archived +Last activity: 2026-03-31 — v1.1 milestone completed and archived -Progress: [░░░░░░░░░░] 0% (v1.1) - -## Performance Metrics - -**Velocity (v1.0 reference):** -- Total plans completed: 18 -- Average duration: ~3 min -- Total execution time: ~54 min - -**v1.1 By Phase:** - -| Phase | Plans | Total | Avg/Plan | -|-------|-------|-------|----------| -| 5. Tech Debt | TBD | - | - | -| 6. New Backends | TBD | - | - | -| 7. Validation & UX Polish | TBD | - | - | - -*Updated after each plan completion* -| Phase 05-tech-debt P00 | 3 | 2 tasks | 2 files | -| Phase 05-tech-debt P02 | 4min | 1 tasks | 1 files | -| Phase 05-tech-debt P01 | 5 | 2 tasks | 4 files | -| Phase 05-tech-debt P03 | 3 | 2 tasks | 2 files | -| Phase 06-new-backends P00 | 5min | 3 tasks | 3 files | -| Phase 06-new-backends P01 | 5min | 2 tasks | 3 files | -| Phase 06-new-backends P02 | 4min | 2 tasks | 4 files | -| Phase 06-new-backends P03 | 10min | 2 tasks | 1 files | -| Phase 07-validation-ux-polish P00 | 10min | 1 tasks | 1 files | -| Phase 07-validation-ux-polish P01 | 5min | 2 tasks | 2 files | -| Phase 07-validation-ux-polish P02 | 2min | 2 tasks | 5 files | -| Phase 07-validation-ux-polish P02 | 15min | 3 tasks | 5 files | - -## Accumulated Context - -### Decisions - -Decisions are logged in PROJECT.md Key Decisions table. -Recent decisions affecting v1.1 work: - -- [v1.0] BACKEND_REGISTRY as single source of truth — Phase 5 wires BackendSelectionStep to it -- [v1.0] scriptTargets defaults to both ['intune','rmm'] — Phase 5 adds filtering in ReviewStep -- [v1.0] AzureAuthToggle uses CSS hidden (not conditional render) — Phase 6 SFTP auth toggle should follow same pattern -- [v1.0] Wave 0 TDD stubs written before implementation — continue this pattern in v1.1 -- [Phase 05-tech-debt]: Use label text not filename text for OutputBlock assertions — filename is a prop, not rendered DOM text -- [Phase 05-tech-debt]: WizardConsumerSetup pattern: in-test React component dispatches SET_DEPLOYMENT via useEffect for state injection without changing production code -- [Phase 05-tech-debt]: Unmount OutputBlocks entirely (conditional render with &&) not CSS hidden — avoids stale component state when toggling scriptTargets -- [Phase 05-tech-debt]: Keep useMemo calls for all scripts even when OutputBlocks hidden — ZIP handler always needs the content for dynamic bundle building -- [Phase 05-tech-debt]: BACKEND_REGISTRY shape enriched to { displayName, description, fields } — registry is single source of truth for display AND field data; BackendSelectionStep wired via Object.entries(BACKEND_REGISTRY) -- [Phase 05-tech-debt]: userEvent.setup() per test body pattern established — replaces fireEvent for async React state interactions -- [Phase 05-tech-debt]: vi.useFakeTimers() in beforeEach + vi.useRealTimers() in afterEach pattern established for suppressing setTimeout act() warnings -- [Phase 06-new-backends]: Wave 0 RED stubs: as BackendType cast allows test files to parse before BackendType union is extended -- [Phase 06-new-backends]: GCS rclone type = 'google cloud storage' (with spaces) not 'gcs' — verified against rclone docs, test asserts not.toContain('type = gcs') -- [Phase 06-new-backends]: SFTP CSS-hide tab toggle pattern follows AzureAuthToggle convention (div.hidden/div.block) -- [Phase 06-new-backends]: GCS rclone type = 'google cloud storage' (with spaces) not 'gcs' — critical for correct rclone.conf output, test asserts not.toContain('type = gcs') -- [Phase 06-new-backends]: OneDrive uses paste-based OAuth token (JSON token field), GCS uses service_account_credentials (paste JSON), B2 uses account + key — all follow stateless browser-paste pattern -- [Phase 06-new-backends]: SftpAuthToggle follows AzureAuthToggle CSS-hidden pattern: both pass and key_pem always registered with react-hook-form, tab visibility via div.block/div.hidden -- [Phase 06-new-backends]: RCLONE_TYPE_MAP and BACKEND_SCHEMAS extended for all 7 backends in plan 02 (not just sftp) to fix failing onedrive/gcs/b2 test assertions -- [Phase 06-new-backends]: Three-branch ternary in RemoteConfigStep (azureblob/sftp/else) keeps custom logic minimal; OneDrive/GCS/B2 render entirely via registry loop -- [Phase 07-validation-ux-polish]: Do not use vi.useFakeTimers() in form-submit tests — fake timers + userEvent.setup() deadlock waitFor when testing React async form submissions -- [Phase 07-validation-ux-polish]: RED acceptance tests (accepts valid X) are inherently green before implementation — they serve as regression guards, not RED indicators -- [Phase 07-validation-ux-polish]: Cast (schema as z.ZodString).regex() — ZodTypeAny does not expose .regex() at type level in Zod v4 -- [Phase 07-validation-ux-polish]: tooltipText added to FieldDef in Plan 07-01 (interface-only) to avoid second interface-only edit in Plan 07-02 -- [Phase 07-validation-ux-polish]: ⓘ button placed as sibling outside label element in flex container to avoid label text contamination -- [Phase 07-validation-ux-polish]: AzureAuthToggle reads tooltipText from BACKEND_REGISTRY at runtime — ensures tooltip stays in sync with registry as single source of truth -- [Phase 07-validation-ux-polish]: SFTP auth-method tooltip is section-level (above segmented control), not field-level — correctly scoped to the auth method choice -- [Phase 07-validation-ux-polish]: ⓘ button placed as sibling outside label element in flex container to avoid label text contamination -- [Phase 07-validation-ux-polish]: AzureAuthToggle reads tooltipText from BACKEND_REGISTRY at runtime — registry is single source of truth, tooltip stays in sync automatically -- [Phase 07-validation-ux-polish]: SFTP auth-method tooltip is section-level (above segmented control), not field-level — correctly scoped to the auth method choice - -### Pending Todos - -None yet. - -### Blockers/Concerns - -- [Phase 6] OneDrive: confirm current `rclone authorize` token JSON structure before designing token input field — token format may differ from v1.0 research -- [Phase 6] SFTP: verify exact rclone SFTP field names (key_file vs key_pem, etc.) against live rclone.org docs before writing registry entry -- [Phase 6] GCS: rclone GCS backend uses `service_account_file` or `token` — confirm auth approach before implementation -- [Phase 7] VALID-01: S3 region validation regex must match AWS region format exactly — verify against current AWS region list +Progress: [██████████] 100% (v1.1) ## Session Continuity -Last session: 2026-03-31T11:48:24.339Z -Stopped at: Completed 07-validation-ux-polish 07-02-PLAN.md +Last session: 2026-03-31T15:00:00Z +Stopped at: Milestone v1.1 archived — ready for /gsd:new-milestone Resume file: None diff --git a/.planning/milestones/v1.1-REQUIREMENTS.md b/.planning/milestones/v1.1-REQUIREMENTS.md new file mode 100644 index 0000000..d2111d4 --- /dev/null +++ b/.planning/milestones/v1.1-REQUIREMENTS.md @@ -0,0 +1,61 @@ +# Requirements Archive: v1.1 Backlog & Tech Debt + +**Defined:** 2026-03-30 +**Completed:** 2026-03-31 +**Core Value:** An IT pro can go from zero to a deployable rclone setup in minutes — without needing to know rclone's config syntax or PowerShell deployment conventions. + +## v1.1 Requirements — All Complete + +### Tech Debt + +- [x] **TECH-01**: User sees only the script output blocks matching their selected deployment targets (Intune and/or RMM) in ReviewStep — **validated** (Phase 5, Plan 05-02) +- [x] **TECH-02**: User can navigate back from ReviewStep using an explicit Back button — **validated** (Phase 5, Plan 05-02) +- [x] **TECH-03**: Backend list in BackendSelectionStep is automatically derived from BACKEND_REGISTRY keys (no hardcoded list) — **validated** (Phase 5, Plan 05-01) +- [x] **TECH-04**: Dead `BackendFormValues` export is removed from `src/schemas/index.ts` — **validated** (Phase 5, Plan 05-01) +- [x] **TECH-05**: BackendSelectionStep test suite runs without `act()` warnings — **validated** (Phase 5, Plan 05-03) + +### Backends + +- [x] **BACK-01**: User can configure an OneDrive remote (with OAuth token paste input and guidance) — **validated** (Phase 6, Plan 06-01/06-03) +- [x] **BACK-02**: User can configure an SFTP remote (host, user, password or key-based auth) — **validated** (Phase 6, Plan 06-02/06-03) +- [x] **BACK-03**: User can configure a Google Cloud Storage remote — **validated** (Phase 6, Plan 06-01/06-03) +- [x] **BACK-04**: User can configure a Backblaze B2 remote — **validated** (Phase 6, Plan 06-01/06-03) + +### Validation + +- [x] **VALID-01**: User sees inline validation error when a field value violates backend-specific format rules — **validated** (Phase 7, Plan 07-01) + +### UX + +- [x] **UX-01**: User can view a contextual tooltip on sensitive or complex fields — **validated** (Phase 7, Plan 07-02) + +## Out of Scope (carried forward) + +| Feature | Reason | +|---------|--------| +| Multiple remotes in one config | Significant wizard UX complexity — defer to v2 | +| OAuth flow in browser (OneDrive) | Requires backend proxy; paste pre-obtained token instead | +| Test connection / credential validation | Requires backend proxy (CORS blocks direct cloud API calls) | +| RMM-named script variants | Generic SYSTEM-context script covers all RMM platforms | +| Save/load configurations | localStorage = credentials in browser storage = security risk | + +## Final Traceability + +| Requirement | Phase | Plan(s) | Outcome | +|-------------|-------|---------|---------| +| TECH-01 | Phase 5 | 05-00, 05-02 | validated | +| TECH-02 | Phase 5 | 05-00, 05-02 | validated | +| TECH-03 | Phase 5 | 05-00, 05-01 | validated | +| TECH-04 | Phase 5 | 05-01 | validated | +| TECH-05 | Phase 5 | 05-03 | validated | +| BACK-01 | Phase 6 | 06-00, 06-01, 06-03 | validated | +| BACK-02 | Phase 6 | 06-00, 06-02, 06-03 | validated | +| BACK-03 | Phase 6 | 06-00, 06-01, 06-03 | validated | +| BACK-04 | Phase 6 | 06-00, 06-01, 06-03 | validated | +| VALID-01 | Phase 7 | 07-00, 07-01 | validated | +| UX-01 | Phase 7 | 07-00, 07-02 | validated | + +**Coverage:** 11/11 requirements validated + +--- +_Archived: 2026-03-31_ diff --git a/.planning/milestones/v1.1-ROADMAP.md b/.planning/milestones/v1.1-ROADMAP.md new file mode 100644 index 0000000..dba31dc --- /dev/null +++ b/.planning/milestones/v1.1-ROADMAP.md @@ -0,0 +1,105 @@ +# Milestone v1.1: Backlog & Tech Debt + +**Status:** ✅ SHIPPED 2026-03-31 +**Phases:** 5–7 +**Total Plans:** 11 + +## Overview + +Ship all deferred tech debt and backlog features from v1.0 — scriptTargets filtering, UX consistency fixes, registry-driven backend list, 4 new backends, field validation, and contextual tooltips. + +## Phases + +### Phase 5: Tech Debt + +**Goal**: The wizard behaves consistently and the codebase is clean — no visual noise from deselected script targets, ReviewStep has a Back button, BackendSelectionStep is driven by the registry, and dead code is removed +**Depends on**: Phase 4 (v1.0 complete) +**Requirements**: TECH-01, TECH-02, TECH-03, TECH-04, TECH-05 +**Plans**: 4 plans + +Plans: +- [x] 05-00: Wave 0 TDD stubs — ReviewStep filtering + Back button failing tests, registry.test.ts .fields prep +- [x] 05-01: Registry enrichment (TECH-03) + consumers update + dead export removal (TECH-04) +- [x] 05-02: ReviewStep scriptTargets filtering + Back button (TECH-01, TECH-02) +- [x] 05-03: act() warnings fix — userEvent migration + vi.useFakeTimers (TECH-05) + +**Success Criteria** (what must be TRUE): + 1. User who deselected RMM in DeploymentStep sees only the Intune output block in ReviewStep (and vice versa) + 2. User can click a Back button on ReviewStep to return to DeploymentStep without losing any form data + 3. Adding a new entry to BACKEND_REGISTRY automatically surfaces that backend in the BackendSelectionStep UI with no other code changes + 4. BackendSelectionStep test suite runs with zero `act()` warnings in the Vitest output + 5. `BackendFormValues` export is absent from `src/schemas/index.ts` and no TypeScript errors arise + +### Phase 6: New Backends + +**Goal**: IT pros can configure OneDrive, SFTP, Google Cloud Storage, and Backblaze B2 remotes through the same wizard flow, with appropriate guidance for OAuth-based and key-based auth methods +**Depends on**: Phase 5 +**Requirements**: BACK-01, BACK-02, BACK-03, BACK-04 +**Plans**: 4 plans + +Plans: +- [x] 06-00: Wave 0 TDD stubs — failing tests for all four new backends across registry, rclone-conf, and RemoteConfigStep +- [x] 06-01: Registry + schema + RCLONE_TYPE_MAP for OneDrive, GCS, Backblaze B2 +- [x] 06-02: Registry + schema + RCLONE_TYPE_MAP for SFTP + SftpAuthToggle component +- [x] 06-03: Wire all four backends into RemoteConfigStep + human verification + +**Success Criteria** (what must be TRUE): + 1. User can select OneDrive as a backend, paste a pre-obtained rclone OAuth token, and generate a valid rclone.conf containing `[type = onedrive]` with the token field + 2. User can select SFTP as a backend, choose between password and private-key authentication, fill the appropriate fields, and generate a valid rclone.conf + 3. User can select Google Cloud Storage as a backend, fill in the required fields, and generate a valid rclone.conf containing `[type = google cloud storage]` + 4. User can select Backblaze B2 as a backend, enter their application key credentials, and generate a valid rclone.conf containing `[type = b2]` + 5. All four new backends appear in the BackendSelectionStep list and each produces a downloadable config+scripts bundle + +### Phase 7: Validation & UX Polish + +**Goal**: Users receive immediate inline feedback when they enter incorrectly formatted values, and can access plain-language explanations on confusing credential fields without leaving the wizard +**Depends on**: Phase 6 +**Requirements**: VALID-01, UX-01 +**Plans**: 3 plans + +Plans: +- [x] 07-00: Wave 0 TDD stubs — failing tests for VALID-01 regex rejection/acceptance and UX-01 tooltip toggle +- [x] 07-01: VALID-01 — FieldDef validate extension + buildZodSchema regex chaining for 3 fields +- [x] 07-02: UX-01 — tooltipText in registry + FieldRenderer/PasswordField ⓘ toggle + AzureAuthToggle/SftpAuthToggle wiring + human verification + +**Success Criteria** (what must be TRUE): + 1. User who enters an Azure storage account name shorter than 3 characters or containing uppercase letters sees an inline error message before they can advance + 2. User who enters an S3 region in an invalid format (e.g., spaces or uppercase) sees an inline error message + 3. User can hover or click a tooltip icon on sensitive fields (SAS token, access key, SFTP auth method, OneDrive token) and read a plain-language explanation without navigating away + 4. Tooltip content accurately distinguishes SAS token from storage account key in the Azure backend form + +--- + +## Milestone Summary + +**Key Decisions:** +- BACKEND_REGISTRY shape enriched to `{ displayName, description, fields }` — single source of truth for display AND field data +- WizardConsumerSetup pattern: in-test React component dispatches SET_DEPLOYMENT via useEffect (no production code changes) +- Unmount OutputBlocks entirely (conditional render) not CSS hidden — avoids stale component state +- GCS rclone type = 'google cloud storage' (with spaces) not 'gcs' +- SftpAuthToggle follows AzureAuthToggle CSS-hidden pattern for auth method switching +- OneDrive/GCS use paste-based token input (stateless browser-paste pattern) +- Three-branch ternary in RemoteConfigStep (azureblob/sftp/else) — custom logic minimal; most backends render via registry loop +- FieldDef extended with `validate` and `tooltipText` — additive, non-breaking to existing backends +- ⓘ button placed as sibling outside label element (avoids label text contamination) +- SFTP auth-method tooltip is section-level (above segmented control), not field-level + +**Issues Resolved:** +- scriptTargets disconnect in ReviewStep (TECH-01) +- Missing Back button on ReviewStep (TECH-02) +- Hardcoded backend list in BackendSelectionStep (TECH-03) +- Dead `BackendFormValues` export (TECH-04) +- `act()` warnings in tests (TECH-05) + +**Issues Deferred:** +- 7 browser UI verifications still pending (inline validation error placement, tooltip toggle UX) — confirmatory, not discovery +- FieldRenderer aria inconsistency between text-branch (sr-only span) and select-branch (direct aria-label) — cosmetic + +**Technical Debt Incurred:** +- Phase 7 VALIDATION.md has `nyquist_compliant: false` (phases 5 and 6 are compliant) +- 07-01-SUMMARY.md missing `requirements-completed` field for VALID-01 (doc gap only — code verified) +- Stale RED-state comments in RemoteConfigStep.test.tsx (features now implemented) + +--- + +_For current project status, see .planning/ROADMAP.md_