docs(v1.2): complete project research — stack, features, architecture, pitfalls, summary
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
+112
-155
@@ -1,219 +1,176 @@
|
||||
# Project Research Summary
|
||||
|
||||
**Project:** Ready2Blob
|
||||
**Domain:** Pure-frontend rclone configuration wizard / enterprise Windows deployment helper
|
||||
**Researched:** 2026-03-26
|
||||
**Confidence:** MEDIUM-HIGH (stack HIGH, pitfalls HIGH, features MEDIUM, architecture MEDIUM)
|
||||
**Project:** Ready2Blob v1.2 -- UI Polish & MD3 Overhaul
|
||||
**Domain:** Material Design 3 theming layer on existing React + Tailwind v4 wizard app
|
||||
**Researched:** 2026-03-31
|
||||
**Confidence:** HIGH
|
||||
|
||||
## Executive Summary
|
||||
|
||||
Ready2Blob is a client-side-only static web application that guides IT administrators through configuring rclone for cloud storage backends (Azure Blob, S3, OneDrive, SFTP) and generating PowerShell deployment scripts for Intune and RMM platforms. The product has no backend, no persistence, and no server: all credential handling, config generation, and file download happen entirely in the browser. The right technology choices are well-established — React + Vite + TypeScript with react-hook-form/Zod for per-step validation, and native Blob/JSZip APIs for file generation. This is a greenfield SPA with a small, stable dependency set and no novel architecture challenges.
|
||||
Ready2Blob v1.2 is a pure styling and UX content overhaul of an already-functional 4-step rclone configuration wizard. The existing stack (Vite 6, React 18, TypeScript 5, Tailwind v4, react-hook-form 7, Zod 4, 159 passing tests) is solid and does not need architectural changes. The research unanimously recommends a **zero new runtime dependencies** approach: define Material Design 3 color tokens as CSS custom properties, wire them into Tailwind v4's native `@theme` directive, and build a small set of reusable UI primitives (Button, Input, Card, Select) that replace the current scattered inline markup. The only new dependency is `@material/material-color-utilities` as a dev-only tool for generating MD3 color palettes from a seed color -- it never ships to the browser.
|
||||
|
||||
The recommended approach is to build from the inside out: define types and schemas first, build pure generator functions (config builder, PS script builder) second, then add the wizard UI shell on top. This order ensures the most critical output — the generated files — is correct and testable before any UI work begins. The Backend Schema Registry pattern (one static TS object describing all backend field definitions) is the architectural keystone: it decouples form rendering from backend-specific knowledge and makes adding new backends trivial without modifying UI components.
|
||||
The recommended approach is a bottom-up, layer-by-layer migration. First establish the CSS token foundation and dark mode infrastructure (zero component changes, zero test impact). Then extract UI primitives as new additive components. Then swap existing hardcoded colors for semantic tokens one component at a time, running all 159 tests after each change. This ordering is critical because the token system is the foundation for everything else -- dark mode, accent colors, MD3 components, and responsive improvements all depend on it. Content improvements (app intro, step descriptions, remote name clarity) are independent and can be parallelized.
|
||||
|
||||
The single largest risk category is PowerShell deployment correctness, not frontend development. Generated scripts must handle SYSTEM-context path resolution, UTF-8 no-BOM encoding, single-quoted here-strings to prevent `$` interpolation, 32-bit vs 64-bit host differences, and Intune's 200 KB script size limit. These are operational correctness requirements that will not surface during local development — they only manifest in real enterprise Intune or RMM environments. Every script template decision must be made with these constraints in mind from the first line of code.
|
||||
|
||||
---
|
||||
The primary risks are: breaking the 131 test selectors across 5 UI test files during component restyling, dark mode contrast failures (WCAG AA), and flash of unstyled content on dark mode load. All three are preventable with the disciplined layer-by-layer approach. The most dangerous anti-pattern is a big-bang restyle where all components are changed at once -- this makes test failures impossible to isolate and virtually guarantees regressions.
|
||||
|
||||
## Key Findings
|
||||
|
||||
### Recommended Stack
|
||||
|
||||
The stack is lean by design. React 18 + Vite 5 + TypeScript 5 provides the scaffold; Tailwind CSS 3 + shadcn/ui handles styling and accessible form primitives without a maintained design system; react-hook-form 7 + Zod 3 handles per-step validation with schema-driven field definitions that map directly to rclone backend specs. File generation uses only browser-native APIs (Blob, URL.createObjectURL) for single-file downloads and JSZip 3 for ZIP bundles. No backend, no external state library, no database.
|
||||
Zero new runtime dependencies. The existing Tailwind v4 handles all styling needs through its CSS-first `@theme` directive and `@custom-variant` for dark mode. One dev dependency added: `@material/material-color-utilities` (v0.4.0) to generate MD3 palettes at build time via a Node script. The output is static CSS custom properties -- zero bundle impact.
|
||||
|
||||
**Core technologies:**
|
||||
- React 18 + Vite 5: SPA scaffold — fast HMR, zero-config static build, no SSR overhead
|
||||
- TypeScript 5: type safety for generated-output correctness — wrong field name = broken config
|
||||
- react-hook-form 7 + Zod 3: per-step validation + backend schema definitions — uncontrolled inputs, schema-driven, performant
|
||||
- Tailwind CSS 3 + shadcn/ui: utility styling + accessible form components — no design system maintenance
|
||||
- Native Blob API: single-file download — zero dependency, browser built-in
|
||||
- JSZip 3: ZIP bundle of all artifacts — de-facto browser ZIP standard
|
||||
- React useReducer + Context: wizard state — sufficient at this scale, no Zustand/Redux needed
|
||||
**Core technologies (all existing, no changes):**
|
||||
- **Tailwind v4 `@theme`**: Maps MD3 tokens to utility classes (`bg-surface`, `text-on-primary`) -- native, no plugins
|
||||
- **Tailwind v4 `@custom-variant dark`**: Class-based dark mode toggle replacing the removed `darkMode: 'class'` config
|
||||
- **CSS custom properties**: ~20 semantic MD3 color roles, elevation shadows, shape radii, motion tokens
|
||||
|
||||
**Critical exclusions:** No Next.js (SSR overhead irrelevant), no Create React App (deprecated), no localStorage/sessionStorage (credentials must not persist), no backend of any kind.
|
||||
**New dev dependency only:**
|
||||
- **`@material/material-color-utilities` 0.4.0**: Official Google library, generates full MD3 palette from a single seed hex color. Used by a build script (`scripts/generate-theme.ts`) that outputs `src/theme-tokens.css`. NOT bundled.
|
||||
|
||||
**Explicitly rejected:** MUI, Material Tailwind, shadcn/ui, CSS-in-JS, next-themes, framer-motion, PostCSS plugins, tailwind.config.js, runtime color generation. See STACK.md for detailed rationale on each.
|
||||
|
||||
### Expected Features
|
||||
|
||||
IT admins evaluating this tool will immediately abandon it if any table-stakes feature is missing. The MVP must cover the full generation pipeline — backend selection through file download — for at least Azure Blob, S3, and OneDrive before any polish work begins.
|
||||
**Must have (table stakes -- P1):**
|
||||
- MD3 color token system (CSS custom properties for all color roles)
|
||||
- MD3 text fields (outlined variant with floating labels)
|
||||
- MD3 button hierarchy (filled, outlined, text)
|
||||
- MD3 card components with elevation
|
||||
- Dark mode toggle (system/light/dark, localStorage persistence)
|
||||
- MD3 step indicator (numbered circles, connecting lines, state indicators)
|
||||
- Responsive layout (mobile-friendly grids, collapsible step indicator)
|
||||
- App intro/landing section explaining what Ready2Blob does
|
||||
- Step-level descriptions on each wizard step
|
||||
- Remote name field clarity (prominent explanation, examples)
|
||||
- Accessible focus states (focus-visible, 3px outline)
|
||||
- Tech debt: FieldRenderer aria fix, StepIndicator inline style migration
|
||||
|
||||
**Must have (table stakes):**
|
||||
- Multi-step backend selection wizard with popular backends (Azure Blob, S3, OneDrive, SFTP) shown first
|
||||
- Per-backend field forms with labels, help text, and required-field validation matching rclone's own config flow
|
||||
- Valid rclone.conf output (INI format, correct key/value pairs per backend)
|
||||
- Remote name input with character validation (alphanumeric, dash, underscore only)
|
||||
- Intune PowerShell deployment script (handles SYSTEM context, idempotent, correct exit codes)
|
||||
- RMM PowerShell deployment script (self-contained, runs as SYSTEM)
|
||||
- Optional rclone install toggle (script downloads rclone binary from URL — never embeds it)
|
||||
- Security warning gate before download (credentials are plaintext — must be acknowledged)
|
||||
- Individual download buttons per artifact (conf, Intune script, RMM script)
|
||||
- Prominent "no data sent to server" assurance
|
||||
**Should have (differentiators -- P2, add after core is stable):**
|
||||
- User-selectable accent color (5-8 curated presets)
|
||||
- Animated step transitions (CSS fade/slide, 200ms)
|
||||
- Upgraded contextual help popovers
|
||||
- Scroll-to-error on validation failure
|
||||
|
||||
**Should have (differentiators):**
|
||||
- Live config preview (real-time generated file content visible before downloading)
|
||||
- Intune detection script generation (separate from install script — Intune Win32 requirement)
|
||||
- Config path selector: machine-wide `C:\ProgramData\rclone\` vs user profile (with explanation of SYSTEM context implications)
|
||||
- Rclone version pinning input (defaults to `rclone-current`; override for reproducible deployments)
|
||||
- Copy-to-clipboard for all output blocks (RMM tools often have a "run script" field)
|
||||
- Field-level validation for backend-specific formats (Azure account name: 3-24 lowercase alphanumeric)
|
||||
- Explanatory tooltips on credential fields (SAS token vs access key confusion is common)
|
||||
- ZIP "download all" bundle
|
||||
|
||||
**Defer to v2+:**
|
||||
- Multiple remotes in one config (adds significant wizard UX complexity)
|
||||
- RMM-named script variants (NinjaRMM-specific, Datto-specific execution contexts)
|
||||
- IntuneWinAppUtil packaging hints (valuable but can be a static docs page)
|
||||
- Test connection / credential validation (requires a proxy backend — violates no-server constraint)
|
||||
- Save/load configurations (requires localStorage = credentials in browser storage = security incident)
|
||||
- Graph API auto-push to Intune (massive scope; manual upload is acceptable for v1)
|
||||
- Multi-OS support (macOS/Linux scripts out of scope; state clearly "Windows endpoints only")
|
||||
**Defer (v2+):**
|
||||
- Custom MD3 select/dropdown (HIGH complexity for 2-3 selects)
|
||||
- Code syntax highlighting in review step
|
||||
- Arbitrary user hex color theming
|
||||
|
||||
### Architecture Approach
|
||||
|
||||
The architecture follows four clean layers: Wizard UI (React components, navigation), Wizard State (single useReducer store, shared via Context), Config Builders (pure functions: state in, file string out), and Download Manager (Blob URL or JSZip). The Backend Schema Registry is a static TypeScript object that defines all field definitions per backend type — it drives dynamic form rendering, Zod schema construction, and config key/value generation from one source of truth. All builders are pure functions with no side effects, making them immediately unit-testable without a browser.
|
||||
A CSS custom properties layer bridges MD3 tokens with Tailwind v4. A thin `ThemeToggle` component manages the `.dark` class on `<html>` via direct DOM manipulation -- NOT via React Context, to avoid re-rendering the entire wizard tree on toggle. Components are refactored bottom-up: primitives first (Button, Input, Card, Select), then composed components (FieldRenderer, BackendCard), then layout (AppShell, StepIndicator). The critical architectural insight is that theme state belongs in CSS (class on `<html>` + custom properties), not in React state.
|
||||
|
||||
**Major components:**
|
||||
1. Wizard UI + Navigation — step rendering, next/back/jump, step completion tracking
|
||||
2. Wizard State (useReducer + Context) — single source of truth for all form data; typed WizardState interface
|
||||
3. Backend Schema Registry — static TS object: BackendType → FieldDef[]; drives dynamic forms
|
||||
4. rclone.conf Builder — pure function: WizardState → INI string; plain template literals
|
||||
5. PowerShell Script Builder (Intune + RMM variants) — pure functions: WizardState → .ps1 string
|
||||
6. Download Manager — Blob URL (single file) + JSZip (bundle); no library for single files
|
||||
|
||||
**Key patterns:**
|
||||
- Centralized state — all form data in one typed store; never per-step local state
|
||||
- Schema Registry — one entry per backend = new backend support with zero UI changes
|
||||
- Pure builders — same input always produces same output; no DOM reads; fully unit-testable
|
||||
- PowerShell single-quoted here-strings — prevents `$` interpolation corrupting credentials
|
||||
1. **CSS Token Layer** (`index.css` + `theme-tokens.css`) -- MD3 color roles, elevation, shape, motion as `@theme` values
|
||||
2. **UI Primitives** (`ui/Button`, `ui/Input`, `ui/Select`, `ui/Card`) -- MD3-styled presentational components using `forwardRef` for react-hook-form compatibility
|
||||
3. **ThemeToggle** -- standalone component, local state only, toggles `.dark` class on `<html>`
|
||||
4. **AppShell** -- layout wrapper extracted from current WizardShell, houses ThemeToggle
|
||||
5. **Modified existing components** -- FieldRenderer, BackendCard, PasswordField, all wizard steps -- swap hardcoded colors for semantic tokens
|
||||
|
||||
### Critical Pitfalls
|
||||
|
||||
These are the failure modes that cause silent deployment breakage in production enterprise environments. All five must be addressed in the initial script template — retrofitting them later risks shipping broken scripts.
|
||||
|
||||
1. **SYSTEM context config path mismatch** — rclone config written to SYSTEM's `%APPDATA%` is invisible to the logged-in user. Always write to `C:\ProgramData\rclone\rclone.conf` (machine-wide path, no WOW64 redirection). Make the destination path explicit in the wizard and let the admin choose; never default to bare `%APPDATA%` expansion.
|
||||
|
||||
2. **PowerShell encoding writes UTF-16 BOM** — `Out-File` in PS 5.1 defaults to UTF-16 LE with BOM; rclone cannot parse it. Always use `[System.IO.File]::WriteAllText($path, $content, [System.Text.UTF8Encoding]::new($false))` to guarantee UTF-8 no-BOM. Hardcode this in every script template from day one.
|
||||
|
||||
3. **Secrets exposed in Intune script logs** — Intune logs all script output to the Azure portal. Generated scripts must never echo credential values. Use `Write-Host "Writing config to $configPath"` (path only), never `Write-Host $configContent`. No debug output containing credential variables, ever.
|
||||
|
||||
4. **Intune 200 KB script size limit** — Scripts that embed or base64-encode rclone binary content are rejected at upload. The generated script must always download rclone from a URL (`Invoke-WebRequest`) at deployment time — never embed the binary. Surface the download URL in the wizard and let admins specify a corporate mirror.
|
||||
|
||||
5. **SAS token / storage key corruption via `$` interpolation** — Azure credentials contain `$` characters. In double-quoted PowerShell strings, `$` triggers variable substitution, silently corrupting the credential. Always wrap the config content block in a single-quoted here-string (`@' ... '@`). Trim all credential inputs before inserting into the config to prevent newline truncation.
|
||||
|
||||
**Additional moderate pitfalls to address in script templates:**
|
||||
- OAuth backends (OneDrive, Google Drive) require a pre-obtained token from `rclone authorize` — the wizard cannot complete OAuth flow in the browser; show a prominent warning and a dedicated token input field
|
||||
- 32-bit PowerShell host (Intune default) causes WOW64 path redirection; use `C:\ProgramData\rclone\` or `$env:ProgramW6432` — recommend enabling 64-bit PS in Intune settings
|
||||
- Do not call `Set-ExecutionPolicy` in the generated script — Group Policy always overrides it; use `-ExecutionPolicy Bypass` on any sub-process calls instead
|
||||
- Auto-insert a `# Generated: [timestamp]` comment in each script so re-generated scripts always have different bytes, enabling Intune re-execution on config updates
|
||||
|
||||
---
|
||||
1. **Tailwind v4 dark mode misconfiguration** -- v3 `darkMode: 'class'` does not exist. Must use `@custom-variant dark (&:where(.dark, .dark *))` in CSS. Address in Phase 1 before any `dark:` classes are added.
|
||||
2. **73 hardcoded color classes** -- Adding `dark:` counterparts to each creates unmaintainable 100+ char classNames. Instead, replace all with semantic tokens (`bg-surface`, `text-on-surface`) that swap values automatically via CSS variable override.
|
||||
3. **Breaking 131 test selectors** -- Restyling touches the same JSX that tests query. Must restyle one component at a time, running all 159 tests after each. Never batch-restyle.
|
||||
4. **FOUC on dark mode load** -- React applies `.dark` class after first paint. Add a synchronous inline `<script>` in `index.html <head>` to set the class before paint.
|
||||
5. **Dark mode contrast failures** -- `text-gray-500` on dark backgrounds fails WCAG AA. Semantic tokens must define separate light/dark values verified for 4.5:1 contrast on every pair.
|
||||
6. **Theme context re-renders** -- Do NOT use React Context for theme. CSS class toggle on `<html>` causes zero React re-renders. Only the toggle button needs local state.
|
||||
|
||||
## Implications for Roadmap
|
||||
|
||||
Based on combined research, the architecture's inside-out build order maps directly to phases. The generator functions and schema registry have zero UI dependencies — build them first, test them in isolation, then layer UI on top. This order also front-loads the hardest correctness requirements (script encoding, path choices, credential handling) before any deployment to users.
|
||||
Based on research, suggested phase structure:
|
||||
|
||||
### Phase 1: Foundation — Types, Schema Registry, State Shape
|
||||
### Phase 1: Theme Foundation
|
||||
**Rationale:** The token system is the dependency root -- every visual component, dark mode, and accent colors depend on it. Must come first. Zero test impact makes it safe.
|
||||
**Delivers:** MD3 color tokens in CSS, dark mode infrastructure (`@custom-variant`, `.dark` overrides), FOUC prevention script in `index.html`, ThemeToggle component, theme generation script (`scripts/generate-theme.ts`)
|
||||
**Addresses:** Color token system, dark mode toggle (infrastructure)
|
||||
**Avoids:** Tailwind v4 dark mode misconfiguration (P1), FOUC (P5), theme context re-renders (P6)
|
||||
|
||||
**Rationale:** All other components depend on these definitions. Building them first prevents architectural drift where UI components hardcode backend knowledge. The schema registry is the keystone — it must exist before dynamic forms, before builders, before anything.
|
||||
**Delivers:** TypeScript type definitions (WizardState, BackendType, FieldDef, RemoteConfig), Backend Schema Registry (Azure Blob, S3, OneDrive, SFTP as Tier 1; GCS, Backblaze B2 as Tier 2), Zod schemas per backend derived from registry, Vite + React + TypeScript + Tailwind scaffold
|
||||
**Addresses:** Foundational architecture (ARCHITECTURE.md Pattern 2 — Backend Schema Registry)
|
||||
**Avoids:** Anti-Pattern 3 (hardcoding backend fields in step components)
|
||||
### Phase 2: UI Primitives
|
||||
**Rationale:** Primitives are the reuse boundary -- Input, Button, Card are used by multiple steps. Building them before modifying existing components means additive-only changes with zero existing test impact.
|
||||
**Delivers:** `ui/Button` (filled/outlined/text), `ui/Input` (outlined, floating label, error), `ui/Select`, `ui/Card` (elevation), new component tests
|
||||
**Addresses:** MD3 text fields, MD3 buttons, MD3 cards
|
||||
**Avoids:** Big-bang rewrite anti-pattern (P4)
|
||||
|
||||
### Phase 2: Core Generators — rclone.conf + PowerShell Script Builders
|
||||
### Phase 3: Component Token Migration
|
||||
**Rationale:** With tokens and primitives in place, swap hardcoded colors across all existing components. This is the highest-risk phase for test breakage -- one component at a time, tests after each.
|
||||
**Delivers:** All components using semantic tokens, FieldRenderer delegating to primitives, BackendCard using Card, PasswordField using Input, StepIndicator inline style migration, FieldRenderer aria-describedby fix
|
||||
**Addresses:** Hardcoded color migration (73 usages), tech debt items, form accessibility, MD3 step indicator
|
||||
**Avoids:** Hardcoded color dual-track (P2), test breakage (P4), accessibility regressions (P7)
|
||||
|
||||
**Rationale:** Pure functions with no UI dependencies. Build and unit-test these before any React work. This is where all the correctness requirements from PITFALLS.md live — encoding, path choices, credential handling, no-log rules must be baked in from the first line of the template.
|
||||
**Delivers:** `buildRcloneConf(remotes)` — pure function producing INI string with LF normalization; `buildIntuneScript(state)` — PS script with UTF-8 no-BOM write, single-quoted here-string, machine-wide path, download-only rclone install, timestamp comment, no credential logging; `buildRmmScript(state)` — same constraints; Download Manager (Blob URL + JSZip wrapper)
|
||||
**Implements:** ARCHITECTURE.md Patterns 3, 4, 5 (pure builders, Blob URL, JSZip)
|
||||
**Avoids:** Pitfalls 1, 2, 3, 5, 8 (SYSTEM path, 200 KB limit, encoding, credential corruption, OAuth warning)
|
||||
### Phase 4: Layout, Content, and Responsive
|
||||
**Rationale:** With all components styled, add the layout shell, content improvements, and responsive behavior. These are mostly independent of each other and can be parallelized.
|
||||
**Delivers:** AppShell layout, app intro section, step descriptions, remote name clarity, responsive grid/breakpoints, dark mode UX polish (scrollbars, select dropdowns, focus rings)
|
||||
**Addresses:** App intro, step descriptions, remote name clarity, responsive layout, accessible focus states
|
||||
**Avoids:** Dark mode contrast failures (P3) -- final contrast audit here
|
||||
|
||||
### Phase 3: Wizard Shell + State Wiring
|
||||
|
||||
**Rationale:** Navigation shell and state store can be built against mock/empty step content. Getting the state shape right before forms are built prevents having to refactor form registration later.
|
||||
**Delivers:** useReducer + Context store wired to WizardState shape; step navigation (stepper, next/back, URL-free step tracking); step completion state; mobile-responsive layout shell using Tailwind + shadcn/ui
|
||||
**Uses:** React 18, useReducer/Context, Tailwind, shadcn/ui
|
||||
**Avoids:** Anti-Pattern 1 (per-step local state losing data on back-navigation)
|
||||
|
||||
### Phase 4: Wizard Step Forms — Dynamic Backend Forms + Deployment Options
|
||||
|
||||
**Rationale:** Now that state, schema registry, and builders all exist, forms can be built as thin wrappers that write to the state store. The dynamic form component reads from the schema registry — one component handles all backends.
|
||||
**Delivers:** Step 1 — Backend type selector (popularity-ordered: Azure Blob, S3, OneDrive, SFTP first); Step 2 — `<DynamicBackendStep />` driven by Schema Registry (react-hook-form + Zod per backend); Step 3 — Deployment options (rclone install toggle, config path selector: machine-wide vs user profile, version pin field, script target selection); Remote name input with `[a-zA-Z0-9_-]` validation and live section header preview
|
||||
**Addresses:** Table-stakes features from FEATURES.md; Pitfall 4 (remote name validation); Pitfall 8 (OAuth token field + warning for OAuth backends)
|
||||
|
||||
### Phase 5: Review, Download + Security Gate
|
||||
|
||||
**Rationale:** Final wizard step assembles everything. Live preview builds trust and catches errors before the admin deploys a broken config. Security warning is a hard blocker before download.
|
||||
**Delivers:** Review step with live syntax-highlighted config preview (updates in real time); security warning modal (credentials in plaintext — cannot be dismissed without acknowledgment); individual download buttons (conf, Intune .ps1, RMM .ps1); "Download All as ZIP" via JSZip; copy-to-clipboard for each output block
|
||||
**Addresses:** Table-stakes and differentiator features from FEATURES.md (live preview, security gate, copy-to-clipboard, ZIP bundle)
|
||||
**Avoids:** Pitfall 5 (security warning gate)
|
||||
|
||||
### Phase 6: Polish + Correctness Hardening
|
||||
|
||||
**Rationale:** After end-to-end flow works, add the depth features that reduce support tickets and build admin trust. This phase also adds per-field validation beyond basic required-field checks and the contextual help text that reduces abandonment.
|
||||
**Delivers:** Per-field backend-specific validation (Azure account name format, SAS token trimming); explanatory tooltips on credential fields; Intune detection script generation (separate from install script); config path implications documentation in the wizard output pane; 64-bit PS host recommendation in Intune output; auto-inserted `# Generated: [timestamp]` comment in scripts; LF normalization on all generated output
|
||||
**Addresses:** Differentiator features from FEATURES.md; Pitfalls 6, 7, 9, 10, 11, 13
|
||||
### Phase 5: Polish and Differentiators
|
||||
**Rationale:** Accent colors and transitions layer on top of the stable token system. These are P2 features that should only land after core is validated.
|
||||
**Delivers:** Accent color selector (5-8 presets), step transitions (CSS), upgraded popovers, scroll-to-error
|
||||
**Addresses:** All P2 differentiator features
|
||||
**Avoids:** Premature accent color work before token system is proven
|
||||
|
||||
### Phase Ordering Rationale
|
||||
|
||||
- Phases 1 and 2 have no UI dependencies and contain the highest-risk correctness requirements — building them first allows unit testing before any user-facing code exists
|
||||
- The wizard shell (Phase 3) can be built with empty/mock steps while the generators are being built, if team size allows parallelism
|
||||
- Dynamic forms (Phase 4) depend on both the schema registry (Phase 1) and state wiring (Phase 3) being finalized
|
||||
- The download step (Phase 5) can only be meaningfully built once all builders (Phase 2) exist
|
||||
- Polish (Phase 6) is deliberately last — it adds depth but does not change the architecture
|
||||
- **Token system first** because 100% of visual components depend on it (see FEATURES.md dependency graph)
|
||||
- **Primitives before migration** because building new components is additive (zero test risk), while modifying existing components carries test risk
|
||||
- **One-component-at-a-time migration** because the 131 test selectors across 5 files make batch changes dangerous
|
||||
- **Content and layout after components** because layout depends on component dimensions and spacing, and content is independent
|
||||
- **Differentiators last** because accent colors multiply token sets (N accents x 2 themes) and must not be attempted until the base system is stable
|
||||
|
||||
### Research Flags
|
||||
|
||||
Phases likely needing deeper research during planning:
|
||||
|
||||
- **Phase 2 (Script Builders):** Verify current Intune PowerShell script execution model against live Microsoft docs before writing templates. Intune behavior around 32-bit/64-bit host defaults and script re-execution triggers can change between Intune releases. High-stakes: wrong behavior is invisible until tested on a real managed device.
|
||||
- **Phase 4 (Backend Forms):** Verify exact required field names for each backend against live rclone docs (rclone.org/azureblob, rclone.org/s3, etc.) before implementing the Schema Registry. Field names are the source of truth for config generation — a wrong key name produces a silently broken config.
|
||||
- **Phase 4 (OAuth backends):** Confirm current `rclone authorize` token extraction flow for OneDrive before designing the OAuth token input UX. The token JSON structure may have changed.
|
||||
- **Phase 2 (UI Primitives):** MD3 outlined text field with floating label is the most complex primitive. CSS-only floating label animation needs prototyping. `forwardRef` integration with react-hook-form `register()` needs verification.
|
||||
- **Phase 3 (Component Migration):** The FieldRenderer refactor to delegate to primitives is the highest-risk change. DOM structure changes could break tests. Needs careful planning of the migration path per field type.
|
||||
|
||||
Phases with standard patterns (skip research-phase):
|
||||
|
||||
- **Phase 1 (Foundation):** React + Vite + TypeScript scaffold is fully documented; schema registry is a static TS object; no novel decisions required
|
||||
- **Phase 3 (Wizard Shell):** Multi-step form navigation with useReducer + Context is a well-documented React pattern; react-hook-form per-step validation is standard
|
||||
- **Phase 5 (Download):** Blob URL download and JSZip are stable browser APIs with no version concerns; security modal is standard UI
|
||||
|
||||
---
|
||||
- **Phase 1 (Theme Foundation):** Fully documented in Tailwind v4 official docs. Token structure is defined. FOUC script is a known 5-line pattern.
|
||||
- **Phase 4 (Layout/Content):** Content writing and responsive Tailwind grids are standard work. No novel patterns.
|
||||
- **Phase 5 (Polish):** Accent colors are a token swap. Step transitions are CSS-only. Well-documented patterns.
|
||||
|
||||
## Confidence Assessment
|
||||
|
||||
| Area | Confidence | Notes |
|
||||
|------|------------|-------|
|
||||
| Stack | HIGH | React + Vite + TypeScript + react-hook-form + Zod is the industry-standard 2025 pairing; no credible alternatives for this use case. shadcn/ui CLI syntax should be verified before scaffolding. |
|
||||
| Features | MEDIUM-HIGH | Table-stakes and IT admin deployment expectations are HIGH confidence from domain knowledge. Specific rclone backend field names are MEDIUM — must be cross-checked against live rclone docs before implementing schema registry. |
|
||||
| Architecture | MEDIUM-HIGH | rclone.conf format is HIGH (stable since v1.x). Intune script patterns are MEDIUM (well-documented but behavior can change between releases). Blob/JSZip download patterns are HIGH (stable browser APIs). |
|
||||
| Pitfalls | HIGH | SYSTEM context, encoding, execution policy, and size-limit pitfalls are verified against official Microsoft docs. rclone-specific pitfalls (section name validation, config format edge cases) are MEDIUM — verify against live rclone docs. |
|
||||
| Stack | HIGH | Zero new runtime deps. Tailwind v4 `@theme` and `@custom-variant` verified in official docs. `@material/material-color-utilities` is official Google package. |
|
||||
| Features | MEDIUM | Table stakes and differentiators well-identified. MD3 web implementation patterns less established than MUI-based approaches since we are hand-rolling with Tailwind. |
|
||||
| Architecture | HIGH | CSS custom properties + Tailwind v4 `@theme` is the documented approach. Bottom-up migration is low-risk. ThemeToggle via DOM class (not Context) avoids re-render cascade. |
|
||||
| Pitfalls | HIGH | Based on direct codebase analysis (73 classNames, 131 selectors, 3 inline styles). Tailwind v4 dark mode gotchas verified against official docs and community reports. |
|
||||
|
||||
**Overall confidence:** MEDIUM-HIGH
|
||||
**Overall confidence:** HIGH
|
||||
|
||||
### Gaps to Address
|
||||
|
||||
- **rclone backend field names:** Every field key in the Schema Registry must match rclone's exact config key names. Verify each Tier 1 backend against rclone.org before implementing Phase 1. Wrong keys produce silently broken configs.
|
||||
- **rclone S3-compatible provider pattern:** The `provider = AWS` + optional `endpoint` field pattern for S3-compatible backends (Wasabi, MinIO, Cloudflare R2) should be confirmed against current rclone S3 docs before implementing the S3 schema entry.
|
||||
- **Intune re-execution trigger:** Confirm whether Intune re-runs a modified script based on byte-level content change or requires a script version increment. This affects the timestamp-comment strategy in Phase 6.
|
||||
- **OneDrive OAuth token format:** Confirm current `token = {...}` JSON structure for OneDrive to design the token input field correctly in Phase 4.
|
||||
- **shadcn/ui CLI commands:** Verify current `npx shadcn-ui@latest` command syntax before Phase 3 scaffolding — the CLI interface has historically changed between major versions.
|
||||
|
||||
---
|
||||
- **MD3 elevation box-shadow values**: Sourced from community reference, not official Google CSS. The exact shadow values are approximations. Validate visually during Phase 1 and adjust if needed.
|
||||
- **MD3 outlined text field floating label**: CSS-only implementation needs prototyping. May require a small JS hook for detecting input fill state (`:placeholder-shown` selector or `onFocus`/`onBlur` handlers). Validate during Phase 2 planning.
|
||||
- **Native `<select>` in dark mode**: Browser renders `<option>` with OS colors. May look broken on dark backgrounds in some browsers. Evaluate during Phase 4 whether to accept native rendering or build custom dropdown (deferred to v2+ per feature research).
|
||||
- **Pre-generated accent color token sets**: The approach of pre-generating N accent x 2 theme token sets at build time has not been prototyped. If the CSS file grows too large, runtime generation (bundling the color utility) may be reconsidered. Validate during Phase 5.
|
||||
|
||||
## Sources
|
||||
|
||||
### Primary (HIGH confidence)
|
||||
- Microsoft Learn — PowerShell scripts in Intune (2025-10-02) — SYSTEM context, size limits, exit codes, script re-execution
|
||||
- Microsoft Learn — Intune Management Extension (2026-03-17) — execution context, 32-bit/64-bit host defaults
|
||||
- Microsoft Learn — Set-ExecutionPolicy reference (2025-04-15) — Group Policy override behavior
|
||||
- Microsoft Learn — Naming Files, Paths, and Namespaces (Win32) — MAX_PATH constraints
|
||||
- MDN Web Docs — Blob API, URL.createObjectURL — browser file download pattern
|
||||
- PROJECT.md — project requirements and constraints (no backend, no persistence, static hosting)
|
||||
- [Tailwind v4 Dark Mode Documentation](https://tailwindcss.com/docs/dark-mode) -- `@custom-variant` syntax, class-based toggle
|
||||
- [Tailwind v4 Theme Documentation](https://tailwindcss.com/docs/theme) -- `@theme` directive, CSS variable generation
|
||||
- [Material Design 3 Color Roles](https://m3.material.io/styles/color/roles) -- semantic color role definitions
|
||||
- [Material Design 3 Design Tokens](https://m3.material.io/foundations/design-tokens) -- token naming conventions
|
||||
- [Material Design 3 Shape Scale](https://m3.material.io/styles/shape/corner-radius-scale) -- radius values
|
||||
- [Material Design 3 Elevation](https://m3.material.io/styles/elevation/applying-elevation) -- elevation levels 0-5
|
||||
- [@material/material-color-utilities](https://www.npmjs.com/package/@material/material-color-utilities) -- v0.4.0, official Google package
|
||||
- Codebase analysis: 73 className usages, 131 test selectors, 159 tests, 3 inline styles in StepIndicator
|
||||
|
||||
### Secondary (MEDIUM confidence)
|
||||
- rclone.org documentation — backend field names, config format, S3 provider pattern (training data, knowledge cutoff August 2025; verify before implementation)
|
||||
- rclone.conf INI format specification — training data (format is stable since v1.x; HIGH confidence on structure, MEDIUM on per-backend field names)
|
||||
- RMM deployment patterns (NinjaRMM, Datto, ConnectWise) — training data; verify execution context differences before adding RMM-named variants
|
||||
- [MD3 Box-Shadow CSS Values](https://studioncreations.com/blog/material-design-3-box-shadow-css-values/) -- elevation shadow approximations
|
||||
- [Tailwind v4 dark mode @custom-variant discussion](https://github.com/tailwindlabs/tailwindcss/discussions/15083) -- community verified pattern
|
||||
- [Tailwind v4 Multi-Theme Strategy](https://simonswiss.com/posts/tailwind-v4-multi-theme) -- community pattern for theme switching
|
||||
- [Material Theme Builder](https://material-foundation.github.io/material-theme-builder/) -- CSS export format reference
|
||||
- [Wizard Design Pattern (UX Planet)](https://uxplanet.org/wizard-design-pattern-8c86e14f2a38) -- wizard UX fundamentals
|
||||
- [Wizards (NN/g)](https://www.nngroup.com/articles/wizards/) -- Nielsen Norman Group guidelines
|
||||
- [Input Field Design Best Practices 2025](https://fireart.studio/blog/input-field-design-best-practice/) -- floating labels, error patterns
|
||||
|
||||
### Tertiary (LOW confidence)
|
||||
- Version numbers for all npm packages — training data cutoff August 2025; verify all versions against npmjs.com before scaffolding
|
||||
- [m3-tailwind-colors](https://github.com/somteacodes/m3-tailwind-colors) -- evaluated and rejected (3 stars, single maintainer)
|
||||
|
||||
---
|
||||
*Research completed: 2026-03-26*
|
||||
*Research completed: 2026-03-31*
|
||||
*Ready for roadmap: yes*
|
||||
|
||||
Reference in New Issue
Block a user