Files
Ready2Blob/.planning/phases/13-add-remaining-rclone-remotes/13-04-PLAN.md
T
kawaandClaude Opus 4.6 4bf3f1e45f docs(13): create phase plan for backend expansion
4 plans across 3 waves to expand from 7 to 17 rclone backends:
- Plan 01 (W1): Registry refactoring, BackendType derivation, 10 new entries
- Plan 02 (W2): OAuthInstructions, GdriveAuthToggle, BackendIcons components
- Plan 03 (W2): BackendSelectionStep UX overhaul with categories, search, icons
- Plan 04 (W3): RemoteConfigStep wiring for all new backends + visual verify

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 15:58:51 +02:00

12 KiB

phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
phase plan type wave depends_on files_modified autonomous requirements must_haves
13-add-remaining-rclone-remotes 04 execute 3
13-01
13-02
13-03
src/components/wizard/RemoteConfigStep.tsx
src/components/wizard/RemoteConfigStep.test.tsx
false
REMOTE-05
truths artifacts key_links
RemoteConfigStep renders correct form fields for every new backend
Google Drive shows GdriveAuthToggle with OAuth Token and Service Account tabs
Dropbox, Box, pCloud show OAuthInstructions + token field
FTP, WebDAV, SMB, HTTP, Seafile, Azure Files, Swift render via generic FieldRenderer loop
backendLabel is derived from registry displayName (not duplicated)
All form submissions produce correct remote params
path provides
src/components/wizard/RemoteConfigStep.tsx Form rendering for all 17 backends
path provides
src/components/wizard/RemoteConfigStep.test.tsx Tests for new backend form rendering
from to via pattern
src/components/wizard/RemoteConfigStep.tsx src/components/wizard/GdriveAuthToggle.tsx import and render for gdrive backend GdriveAuthToggle
from to via pattern
src/components/wizard/RemoteConfigStep.tsx src/components/wizard/OAuthInstructions.tsx import and render for OAuth backends OAuthInstructions
from to via pattern
src/components/wizard/RemoteConfigStep.tsx src/schemas/registry.ts BACKEND_REGISTRY field lookup BACKEND_REGISTRY[
Wire all 10 new backends into RemoteConfigStep so every backend type renders the correct configuration form with appropriate auth handling (AuthToggle, OAuthInstructions, or generic FieldRenderer loop).

Purpose: This is the final integration plan — connecting registry data to the form UI. After this, every backend is fully functional end-to-end. Output: Updated RemoteConfigStep with all backend branches, updated tests, visual verification.

<execution_context> @C:/Users/SebastienQUEROL/.claude/get-shit-done/workflows/execute-plan.md @C:/Users/SebastienQUEROL/.claude/get-shit-done/templates/summary.md </execution_context>

@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/phases/13-add-remaining-rclone-remotes/13-CONTEXT.md @.planning/phases/13-add-remaining-rclone-remotes/13-RESEARCH.md @.planning/phases/13-add-remaining-rclone-remotes/13-01-SUMMARY.md @.planning/phases/13-add-remaining-rclone-remotes/13-02-SUMMARY.md @.planning/phases/13-add-remaining-rclone-remotes/13-03-SUMMARY.md From src/schemas/registry.ts: ```typescript export type BackendType = keyof typeof BACKEND_REGISTRY; // Includes: azureblob, s3, s3-compatible, onedrive, sftp, gcs, b2, // azure-files, swift, gdrive, dropbox, box, pcloud, // ftp, webdav, smb, http, seafile ```

From src/components/wizard/OAuthInstructions.tsx:

interface OAuthInstructionsProps {
  backendName: string;
  authorizeCommand: string;
  steps?: string[];
}

From src/components/wizard/GdriveAuthToggle.tsx:

interface GdriveAuthToggleProps {
  register: UseFormRegister<any>;
  errors: {
    token?: FieldError;
    service_account_credentials?: FieldError;
  };
}

From src/components/wizard/RemoteConfigStep.tsx:

// Three-branch ternary: azureblob -> AzureAuthToggle, sftp -> SftpAuthToggle, else -> generic loop
// backendLabel: Record<NonNullable<typeof backendType>, string> — manual duplication
Task 1: Wire all new backends into RemoteConfigStep src/components/wizard/RemoteConfigStep.tsx 1. Replace the manual `backendLabel` record with auto-derived version: ```typescript const backendLabel = Object.fromEntries( Object.entries(BACKEND_REGISTRY).map(([k, v]) => [k, v.displayName]) ) as Record; ``` This eliminates the duplicate displayName maintenance per Pitfall 2 in the research.
  1. Import new components:
import { OAuthInstructions } from './OAuthInstructions';
import { GdriveAuthToggle } from './GdriveAuthToggle';
  1. Expand the rendering branch logic. The current three-branch ternary (azureblob/sftp/else) needs new branches for backends with special auth handling:

    a. gdrive — GdriveAuthToggle (handles token + service_account_credentials) + FieldRenderer for root_folder_id:

    ) : backendType === 'gdrive' ? (
      <>
        <GdriveAuthToggle
          register={register}
          errors={{
            token: errors.token as FieldError | undefined,
            service_account_credentials: errors.service_account_credentials as FieldError | undefined,
          }}
        />
        {BACKEND_REGISTRY.gdrive.fields
          .filter(f => f.key !== 'token' && f.key !== 'service_account_credentials')
          .map(field => (
            <FieldRenderer key={field.key} field={field} register={register} error={errors[field.key] as FieldError | undefined} />
          ))}
      </>
    

    b. dropbox — OAuthInstructions + generic FieldRenderer loop:

    ) : backendType === 'dropbox' ? (
      <>
        <OAuthInstructions backendName="Dropbox" authorizeCommand='rclone authorize "dropbox"' />
        {BACKEND_REGISTRY.dropbox.fields.map(field => (
          <FieldRenderer key={field.key} field={field} register={register} error={errors[field.key] as FieldError | undefined} />
        ))}
      </>
    

    c. box — OAuthInstructions + generic FieldRenderer loop:

    ) : backendType === 'box' ? (
      <>
        <OAuthInstructions backendName="Box" authorizeCommand='rclone authorize "box"' />
        {BACKEND_REGISTRY.box.fields.map(field => (
          <FieldRenderer key={field.key} field={field} register={register} error={errors[field.key] as FieldError | undefined} />
        ))}
      </>
    

    d. pcloud — OAuthInstructions + generic FieldRenderer loop:

    ) : backendType === 'pcloud' ? (
      <>
        <OAuthInstructions backendName="pCloud" authorizeCommand='rclone authorize "pcloud"' />
        {BACKEND_REGISTRY.pcloud.fields.map(field => (
          <FieldRenderer key={field.key} field={field} register={register} error={errors[field.key] as FieldError | undefined} />
        ))}
      </>
    

    e. All other new backends (azure-files, swift, ftp, webdav, smb, http, seafile) fall through to the existing generic else branch which iterates BACKEND_REGISTRY[backendType].fields — NO new branches needed for these since they have no auth toggles.

    f. onedrive already has OAuthInstructions-worthy fields but currently works via the generic loop. Add OAuthInstructions to onedrive too for consistency:

    ) : backendType === 'onedrive' ? (
      <>
        <OAuthInstructions backendName="OneDrive" authorizeCommand='rclone authorize "onedrive"' />
        {BACKEND_REGISTRY.onedrive.fields.map(field => (
          <FieldRenderer key={field.key} field={field} register={register} error={errors[field.key] as FieldError | undefined} />
        ))}
      </>
    
  2. The branch order should be: azureblob -> sftp -> gdrive -> onedrive -> dropbox -> box -> pcloud -> else (generic loop). Consider refactoring the deep ternary into a helper function or switch-like pattern for readability with 7 branches. A renderBackendFields() function with a switch statement is cleaner than nested ternaries.

  3. Verify the form still submits correctly — the onNext handler and validation logic should remain unchanged since BACKEND_SCHEMAS auto-generates for all types. npx tsc --noEmit 2>&1 | tail -10 && npx vitest run src/components/wizard/RemoteConfigStep.test.tsx --reporter=verbose 2>&1 | tail -30 RemoteConfigStep renders correct form for all 17 backends. GdriveAuthToggle shown for gdrive. OAuthInstructions shown for onedrive, dropbox, box, pcloud. Generic loop for all others. backendLabel derived from registry. TypeScript compiles, existing tests pass.

Task 2: Add tests for new backend form rendering src/components/wizard/RemoteConfigStep.test.tsx - Test 1: gdrive renders GdriveAuthToggle with "OAuth Token" and "Service Account" tabs - Test 2: dropbox renders OAuthInstructions with 'rclone authorize "dropbox"' command - Test 3: ftp renders host, username, password, port, TLS mode fields - Test 4: webdav renders URL, username, password, vendor select fields - Test 5: smb renders host, username fields - Test 6: http renders only URL field Add test cases to RemoteConfigStep.test.tsx following the existing test pattern: - Each test sets up WizardState with the target backendType - Renders RemoteConfigStep within WizardProvider - Asserts form fields are present by label text or role - For gdrive: assert the segmented control buttons exist (OAuth Token, Service Account) - For dropbox: assert OAuthInstructions toggle button is present - For protocol backends: assert expected fields render

Use the existing test setup pattern from the file. Each new backend test should be a focused assertion on field presence — not full form submission (submission is already tested for existing backends and the mechanism is generic).

Write tests first, then verify they pass against the implementation from Task 1. npx vitest run src/components/wizard/RemoteConfigStep.test.tsx --reporter=verbose 6 new test cases pass verifying form rendering for gdrive, dropbox, ftp, webdav, smb, and http backends.

Task 3: Visual verification of complete backend expansion n/a Human verifies the complete backend expansion visually. What was built: Complete backend expansion — 17 backends with categories, search, icons, OAuth instructions, and correct form rendering for each backend type. 1. Run `npm run dev` and open http://localhost:5173 2. Step 1 (Backend Selection): - Verify 3 category headings appear: "Cloud Object Storage", "Cloud Drives", "Protocol-based" - Verify all 17 backend cards are visible with icons - Type "ftp" in search — only FTP and SFTP should be visible - Type "Cloudflare" in search — S3-Compatible should appear - Clear search — all backends visible again 3. Select "Google Drive" — verify Step 2 shows OAuth Token / Service Account toggle - OAuth Token tab: collapsible instructions + token field - Service Account tab: service account credentials field 4. Go back, select "Dropbox" — verify Step 2 shows collapsible OAuth instructions + token field 5. Go back, select "FTP" — verify Step 2 shows host, username, password, port, TLS mode fields 6. Go back, select "WebDAV" — verify Step 2 shows URL, username, password, vendor select 7. Go back, select "SMB / Windows Share" — verify host, user, password, domain, port fields 8. Go back, select "HTTP (read-only)" — verify only URL field 9. Toggle dark mode — verify all new backends render correctly in dark mode 10. Run `npx vitest run` — all tests pass User approves visual appearance and functionality of all 17 backends in both light and dark modes. - `npx vitest run` — full suite green (all existing + new tests) - `npx tsc --noEmit` — no type errors - Visual verification of all 17 backends in both light and dark mode - Form submission works for at least 3 new backends (gdrive, ftp, webdav)

<success_criteria>

  • Every backend type in BACKEND_REGISTRY has a working form in RemoteConfigStep
  • OAuth backends (gdrive, dropbox, box, pcloud, onedrive) show OAuthInstructions
  • gdrive shows GdriveAuthToggle with two auth paths
  • Protocol backends render via generic FieldRenderer loop
  • backendLabel derived from registry (no manual duplication)
  • User approves visual appearance in both light and dark modes </success_criteria>
After completion, create `.planning/phases/13-add-remaining-rclone-remotes/13-04-SUMMARY.md`