Files
Ready2Blob/.planning/phases/06-new-backends/06-01-PLAN.md
T
kawaandClaude Sonnet 4.6 b314e65536 docs(06-new-backends): create phase plan
4 plans across 3 waves: Wave 0 TDD stubs, Wave 1 data layer (parallel: OneDrive/GCS/B2 + SFTP/SftpAuthToggle), Wave 2 RemoteConfigStep wiring.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 13:38:46 +02:00

11 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
06-new-backends 01 execute 1
06-00
src/schemas/registry.ts
src/schemas/index.ts
src/generators/rclone-conf.ts
true
BACK-01
BACK-03
BACK-04
truths artifacts key_links
BackendType union includes 'onedrive', 'gcs', 'b2' (and 'sftp' added by Plan 02)
BACKEND_REGISTRY has onedrive, gcs, b2 entries with correct field keys matching rclone docs
BACKEND_SCHEMAS has onedrive, gcs, b2 entries built via buildZodSchema
RCLONE_TYPE_MAP maps gcs to 'google cloud storage' (with spaces)
buildRcloneConf(gcsState) outputs 'type = google cloud storage'
buildRcloneConf(b2State) outputs 'type = b2'
buildRcloneConf(onedriveState) outputs 'type = onedrive'
path provides contains
src/schemas/registry.ts BackendType union with 6 types (onedrive, gcs, b2 added); registry entries for all three onedrive.*gcs.*b2
path provides contains
src/schemas/index.ts BACKEND_SCHEMAS with onedrive, gcs, b2 buildZodSchema('onedrive')
path provides contains
src/generators/rclone-conf.ts RCLONE_TYPE_MAP with gcs mapped to 'google cloud storage' google cloud storage
from to via pattern
src/schemas/index.ts src/schemas/registry.ts buildZodSchema calls — BackendType must include new types before BACKEND_SCHEMAS can reference them buildZodSchema('(onedrive|gcs|b2)')
from to via pattern
src/generators/rclone-conf.ts RCLONE_TYPE_MAP gcs key maps to string with spaces — critical for correct rclone.conf output gcs.*google cloud storage
Add OneDrive, GCS, and Backblaze B2 to the data layer — BackendType union, registry entries, Zod schemas, and RCLONE_TYPE_MAP.

Purpose: Three simple backends (no custom toggle UI) that follow the pure registry + FieldRenderer pattern. Implementing them first keeps SFTP (Plan 02) isolated. Output: registry.ts, index.ts, rclone-conf.ts updated; registry and rclone-conf tests go green for these three backends.

<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/STATE.md @.planning/phases/06-new-backends/06-RESEARCH.md @.planning/phases/06-new-backends/06-00-SUMMARY.md

From src/schemas/registry.ts (current):

export type BackendType = 'azureblob' | 's3' | 's3-compatible';

export interface FieldDef {
  key: string;
  label: string;
  inputType: 'text' | 'password' | 'select' | 'toggle';
  required: boolean;
  placeholder?: string;
  helpText?: string;
  options?: { value: string; label: string }[];
}

export const BACKEND_REGISTRY: Record<BackendType, {
  displayName: string;
  description: string;
  fields: FieldDef[];
}> = { azureblob: {...}, s3: {...}, 's3-compatible': {...} };

From src/schemas/index.ts (current):

function buildZodSchema(backendType: BackendType): z.ZodObject<Record<string, z.ZodTypeAny>>
export const BACKEND_SCHEMAS = {
  azureblob: buildZodSchema('azureblob'),
  s3: buildZodSchema('s3'),
  's3-compatible': buildZodSchema('s3-compatible'),
} as const;

From src/generators/rclone-conf.ts (current):

const RCLONE_TYPE_MAP: Record<string, string> = {
  azureblob: 'azureblob',
  s3: 's3',
  's3-compatible': 's3',
};
Task 1: Extend registry.ts — BackendType union + onedrive/gcs/b2 entries src/schemas/registry.ts - BackendType union becomes: 'azureblob' | 's3' | 's3-compatible' | 'onedrive' | 'sftp' | 'gcs' | 'b2' (include 'sftp' in union now — Plan 02 adds its registry entry; including it in the union prevents TypeScript errors in Plan 02's parallel work) - BACKEND_REGISTRY gains onedrive entry: token (password, required), drive_id (text, required), drive_type (select, required, options: personal/business/documentLibrary) - BACKEND_REGISTRY gains gcs entry: project_number (text, required), service_account_credentials (password, required) - BACKEND_REGISTRY gains b2 entry: account (text, required), key (password, required) - sftp entry NOT added here — Plan 02 adds it. TypeScript will error on BACKEND_REGISTRY type until Plan 02 adds sftp. This is acceptable during parallel execution. - `npx vitest run src/schemas/registry.test.ts` passes for onedrive, gcs, b2 assertions; sftp assertions still fail (Plan 02 fixes those) Edit src/schemas/registry.ts:
1. Replace BackendType line with:
   `export type BackendType = 'azureblob' | 's3' | 's3-compatible' | 'onedrive' | 'sftp' | 'gcs' | 'b2';`

2. Add three new entries to BACKEND_REGISTRY after the 's3-compatible' entry:

```typescript
onedrive: {
  displayName: 'OneDrive',
  description: 'Microsoft OneDrive (paste pre-obtained rclone token)',
  fields: [
    {
      key: 'token',
      label: 'OAuth Token (JSON)',
      inputType: 'password',
      required: true,
      placeholder: '{"access_token":"...","token_type":"Bearer","refresh_token":"...","expiry":"..."}',
      helpText: 'Paste the JSON token from: rclone authorize "onedrive"',
    },
    {
      key: 'drive_id',
      label: 'Drive ID',
      inputType: 'text',
      required: true,
      placeholder: 'b!...',
      helpText: 'The drive ID from your OneDrive. Found in the rclone authorize output.',
    },
    {
      key: 'drive_type',
      label: 'Drive Type',
      inputType: 'select',
      required: true,
      options: [
        { value: 'personal', label: 'Personal' },
        { value: 'business', label: 'Business' },
        { value: 'documentLibrary', label: 'SharePoint Document Library' },
      ],
      helpText: 'Personal for consumer OneDrive, Business for Microsoft 365',
    },
  ],
},
gcs: {
  displayName: 'Google Cloud Storage',
  description: 'Google Cloud Storage',
  fields: [
    {
      key: 'project_number',
      label: 'Project Number',
      inputType: 'text',
      required: true,
      placeholder: '123456789',
      helpText: 'Your GCP project number (not project ID)',
    },
    {
      key: 'service_account_credentials',
      label: 'Service Account JSON',
      inputType: 'password',
      required: true,
      placeholder: '{"type":"service_account","project_id":"..."}',
      helpText: 'Paste the full content of your service account JSON key file',
    },
  ],
},
b2: {
  displayName: 'Backblaze B2',
  description: 'Backblaze B2 Cloud Storage',
  fields: [
    {
      key: 'account',
      label: 'Application Key ID',
      inputType: 'text',
      required: true,
      placeholder: 'your-application-key-id',
      helpText: 'The applicationKeyId — not the master account ID',
    },
    {
      key: 'key',
      label: 'Application Key',
      inputType: 'password',
      required: true,
      helpText: 'The application key (secret value from the B2 dashboard)',
    },
  ],
},
```

Note: BACKEND_REGISTRY type is `Record<BackendType, ...>` which requires ALL BackendType values. After this task, TypeScript will error because 'sftp' is in the union but not yet in the BACKEND_REGISTRY object. Plan 02 adds the sftp entry. If running `npx tsc --noEmit` between plans, expect this error temporarily. The Vitest tests will still run.
npx vitest run src/schemas/registry.test.ts 2>&1 | tail -20 BackendType includes all 7 types; onedrive, gcs, b2 registry entries present with correct field keys; registry tests pass for those three backends Task 2: Extend index.ts and rclone-conf.ts — schemas + type map for onedrive/gcs/b2 src/schemas/index.ts, src/generators/rclone-conf.ts - BACKEND_SCHEMAS gains onedrive, gcs, b2 entries using buildZodSchema - RCLONE_TYPE_MAP gains: onedrive → 'onedrive', gcs → 'google cloud storage', b2 → 'b2' - buildRcloneConf(gcsState) produces a line 'type = google cloud storage' (with spaces — NOT 'type = gcs') - buildRcloneConf(b2State) produces 'type = b2' with account and key lines - buildRcloneConf(onedriveState) produces 'type = onedrive' with token, drive_id, drive_type lines - `npx vitest run src/generators/rclone-conf.test.ts` passes for onedrive, gcs, b2 describe blocks **src/schemas/index.ts:** Add three entries to BACKEND_SCHEMAS: ```typescript export const BACKEND_SCHEMAS = { azureblob: buildZodSchema('azureblob'), s3: buildZodSchema('s3'), 's3-compatible': buildZodSchema('s3-compatible'), onedrive: buildZodSchema('onedrive'), gcs: buildZodSchema('gcs'), b2: buildZodSchema('b2'), } as const; ``` Do NOT add sftp yet — Plan 02 adds it after adding the sftp registry entry.
**src/generators/rclone-conf.ts:** Extend RCLONE_TYPE_MAP:
```typescript
const RCLONE_TYPE_MAP: Record<string, string> = {
  azureblob:       'azureblob',
  s3:              's3',
  's3-compatible': 's3',
  onedrive:        'onedrive',
  gcs:             'google cloud storage',  // NOTE: spaces in rclone type value — do NOT shorten
  b2:              'b2',
};
```
Do NOT add sftp yet — Plan 02 adds it.

After editing, run full suite to confirm existing tests still pass and new backend tests pass.
npx vitest run src/schemas/registry.test.ts src/generators/rclone-conf.test.ts 2>&1 | tail -20 BACKEND_SCHEMAS covers onedrive/gcs/b2; RCLONE_TYPE_MAP maps gcs to 'google cloud storage'; rclone-conf tests for onedrive/gcs/b2 pass; no regressions on existing backends `npx vitest run src/schemas/registry.test.ts src/generators/rclone-conf.test.ts` Expected: onedrive/gcs/b2 tests GREEN; sftp tests still RED (Plan 02 fixes those); no regressions on azureblob/s3/s3-compatible.

npx tsc --noEmit — expect one error: BACKEND_REGISTRY missing 'sftp' key (fixed by Plan 02). All other TypeScript must be clean.

<success_criteria>

  • BackendType union has all 7 types
  • onedrive, gcs, b2 registry entries with correct rclone key names
  • BACKEND_SCHEMAS covers onedrive, gcs, b2
  • gcs maps to 'google cloud storage' in RCLONE_TYPE_MAP
  • rclone-conf tests pass for onedrive, gcs, b2
  • Zero TypeScript errors outside the known sftp-missing-key error </success_criteria>
After completion, create `.planning/phases/06-new-backends/06-01-SUMMARY.md`