# Implementation Plan: Config Wizard ## Overview Implement `configure.js` as a single-file interactive CLI wizard at the project root. The implementation follows the design's module structure: constants/registry, parsing, validation, display/prompt, file writing, and main flow orchestration. Property-based tests use fast-check in `backend/__tests__/`. ## Tasks - [x] 1. Set up project structure and install test dependencies - [x] 1.1 Create `configure.js` with shebang, constants, and variable descriptor registry - Add `#!/usr/bin/env node` header - Define `VARIABLE_DESCRIPTORS` array with all 32 managed variables and their metadata (name, group, required, default, description, docUrl, sensitive, validator) - Define `GROUP_ORDER` array, `GROUP_DESCRIPTIONS` object, and `SENSITIVE_VARS` list - Export constants for testability using `module.exports` at the bottom (conditionally, so the file still runs as a script) - _Requirements: 2.1, 2.2, 2.3, 2.4, 2.5, 3.1, 3.2, 3.3, 3.4_ - [x] 1.2 Install fast-check as a dev dependency in backend - Run `npm install --save-dev fast-check` in `backend/` - _Requirements: N/A (test infrastructure)_ - [x] 2. Implement parsing functions - [x] 2.1 Implement `resolveShellDefault(str)` function - Extract default value from `${VAR:-default}` pattern - Return original string if pattern not found - _Requirements: 4.1_ - [x] 2.2 Implement `parseDockerCompose(filePath)` function - Line-by-line state machine parser for docker-compose.yml - Extract POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB, and host port - Resolve shell variable substitution via `resolveShellDefault` - Return `null` if file missing or unparseable - _Requirements: 4.1, 4.2, 4.3, 4.4_ - [x] 2.3 Implement `parseEnvFile(filePath)` function - Read file line by line, split on first `=` - Separate managed variables from unmanaged lines (including preceding comments) - Handle quoted values (strip surrounding double quotes) - Return `{ managed: Map, unmanaged: String[] }` - Return empty maps if file doesn't exist or is unreadable - _Requirements: 9.1, 9.2, 9.4, 9.6_ - [ ]* 2.4 Write property test for shell default resolution - **Property 5: Shell variable default resolution** - **Validates: Requirements 4.1** - [ ]* 2.5 Write property test for DATABASE_URL construction - **Property 6: DATABASE_URL construction** - **Validates: Requirements 4.2** - [ ]* 2.6 Write property test for env file round-trip parsing - **Property 16: Env file round-trip parsing** - **Validates: Requirements 9.1, 9.2** - [x] 3. Implement validation functions - [x] 3.1 Implement all validation functions - `validatePort(value)` — integer in [1, 65535] - `validateCorsOrigins(value)` — each comma-separated entry starts with http:// or https:// - `validateDatabaseUrl(value)` — starts with `postgresql://` or equals `sqlite` - `validateSessionSecret(value)` — at least 16 characters - `validateRequired(value)` — non-empty, non-whitespace-only - _Requirements: 5.1, 5.2, 5.3, 5.4, 5.6_ - [ ]* 3.2 Write property tests for validation functions - **Property 8: Port validation** - **Property 9: CORS origins validation** - **Property 10: DATABASE_URL validation** - **Property 11: SESSION_SECRET validation** - **Property 12: Required variable rejection of whitespace** - **Validates: Requirements 5.1, 5.2, 5.3, 5.4, 5.6** - [x] 4. Implement display and prompt functions - [x] 4.1 Implement display functions - `printWelcome()` — purpose and instructions - `printGroupHeader(group)` — group name and description - `printSummary(config, skippedGroups)` — table with masked sensitive values, target file paths, overwrite indicators - `maskSensitive(name, value)` — first 4 + last 4 with asterisks for strings > 8 chars, full value otherwise - _Requirements: 1.2, 2.3, 3.4, 8.1, 8.2, 8.3_ - [x] 4.2 Implement prompt functions - `promptVariable(rl, descriptor, currentValue)` — display label, description, default/current, docUrl; validate input; re-prompt on failure - `promptYesNo(rl, question, defaultNo)` — yes/no with configurable default - `promptOverwrite(rl, filePath)` — confirm overwrite, offer backup - _Requirements: 3.1, 3.2, 3.3, 3.5, 5.5, 6.5, 7.1, 9.3_ - [ ]* 4.3 Write property test for sensitive value masking - **Property 4: Sensitive value masking** - **Validates: Requirements 3.4** - [ ]* 4.4 Write property test for derived URL defaults from PORT - **Property 7: Derived URL defaults from PORT** - **Validates: Requirements 4.6** - [x] 5. Checkpoint - Ensure all tests pass, ask the user if questions arise. - [x] 6. Implement file writing functions - [x] 6.1 Implement `generateEnvContent(variables, groupOrder, groupDescriptions, unmanagedLines)` function - Group header comments (`# --- Group Name ---`) - `KEY=value` lines with conditional double-quote wrapping (spaces, `#`, quotes) - Omit optional variables with no value and no default - Append unmanaged variables in `# --- Custom Variables ---` section - _Requirements: 6.1, 6.2, 6.3, 6.4, 9.4, 9.5_ - [x] 6.2 Implement `writeEnvFile(filePath, content)` and `createBackup(filePath)` functions - Write content to file path using `fs.writeFileSync` - `createBackup` copies existing file to `{filename}.backup.{YYYYMMDD_HHmmss}` - Handle filesystem errors with descriptive messages - _Requirements: 6.5, 6.6_ - [ ]* 6.3 Write property test for env value quoting - **Property 13: Env value quoting** - **Validates: Requirements 6.3** - [ ]* 6.4 Write property test for optional variable omission - **Property 14: Optional variable omission** - **Validates: Requirements 6.4** - [ ]* 6.5 Write property test for skipped group exclusion - **Property 15: Skipped group exclusion** - **Validates: Requirements 7.2, 7.3** - [ ]* 6.6 Write property test for unmanaged variable preservation - **Property 17: Unmanaged variable preservation** - **Validates: Requirements 9.4** - [ ]* 6.7 Write property test for managed key deduplication - **Property 18: Managed key deduplication** - **Validates: Requirements 9.5** - [x] 7. Implement main flow orchestration - [x] 7.1 Implement `main()` function and wire all components together - Validate project root (check `backend/` and `frontend/` exist) - Parse existing env files for pre-fill defaults - Parse docker-compose.yml for derived defaults - Set up readline interface and SIGINT handler - Group loop: iterate GROUP_ORDER, prompt skip for optional groups, prompt each variable - Derive REACT_APP_API_BASE, REACT_APP_API_HOST, CORS_ORIGINS from confirmed PORT - Display summary, prompt confirmation (approve / restart / exit) - Handle overwrite prompts and write both env files - Display success message with next steps - Exit code 0 on success, 1 on error/cancel - _Requirements: 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 4.5, 4.6, 7.1, 7.2, 7.3, 7.4, 8.1, 8.2, 8.3, 8.4, 8.5_ - [x] 8. Checkpoint - Ensure all tests pass, ask the user if questions arise. - [ ] 9. Write descriptor registry property tests - [ ]* 9.1 Write property test for descriptor registry invariants - **Property 1: Descriptor registry invariants** - **Validates: Requirements 2.3, 2.5** - [ ]* 9.2 Write property test for variable ordering within groups - **Property 2: Variable ordering within groups** - **Validates: Requirements 2.4** - [ ]* 9.3 Write property test for group presentation order - **Property 3: Group presentation order** - **Validates: Requirements 2.1** - [ ] 10. Write integration and unit tests - [ ]* 10.1 Write unit tests for parseDockerCompose - Test valid compose files, missing files, malformed content - _Requirements: 4.1, 4.2, 4.3, 4.4_ - [ ]* 10.2 Write unit tests for parseEnvFile - Test standard files, quoted values, comments, empty lines, malformed lines - _Requirements: 9.1, 9.2, 9.4, 9.6_ - [ ]* 10.3 Write unit tests for generateEnvContent - Test group headers, quoting rules, omission of empty optionals, custom variables section - _Requirements: 6.1, 6.2, 6.3, 6.4, 9.4, 9.5_ - [ ]* 10.4 Write integration tests for full wizard flow - Test full run with defaults accepted, existing env pre-fill, skipped groups, SIGINT handling, missing project structure error - Use temporary directories and mock readline input - _Requirements: 1.1, 1.4, 1.5, 7.1, 7.2, 7.3, 8.4, 8.5, 9.1_ - [x] 11. Final checkpoint - Ensure all tests pass, ask the user if questions arise. ## Notes - Tasks marked with `*` are optional and can be skipped for faster MVP - Each task references specific requirements for traceability - Checkpoints ensure incremental validation - Property tests validate universal correctness properties from the design document - Unit tests validate specific examples and edge cases - All code goes in a single `configure.js` file at the project root - Tests go in `backend/__tests__/` using Jest + fast-check - The file uses `module.exports` conditionally (only when `require.main !== module`) so it can be both a runnable script and importable for testing ## Task Dependency Graph ```json { "waves": [ { "id": 0, "tasks": ["1.1", "1.2"] }, { "id": 1, "tasks": ["2.1", "2.2", "2.3", "3.1"] }, { "id": 2, "tasks": ["2.4", "2.5", "2.6", "3.2", "4.1", "4.2"] }, { "id": 3, "tasks": ["4.3", "4.4", "6.1", "6.2"] }, { "id": 4, "tasks": ["6.3", "6.4", "6.5", "6.6", "6.7", "7.1"] }, { "id": 5, "tasks": ["9.1", "9.2", "9.3", "10.1", "10.2", "10.3"] }, { "id": 6, "tasks": ["10.4"] } ] } ```