Step 2 · Plan

Goal

Translate the assessment into a precise, sequenced execution plan where each step is atomic, safe, and independently verifiable. A good plan has no guesswork — you know exactly what you will do and what success looks like at each step.

Instructions

You are in workflow step 2 of the refactor-cycle. You know what is wrong and what good looks like. Now plan the exact sequence of changes.


Tasks to Perform

1. Map the Current State

Read all the files in scope one more time. Create a precise inventory:

# Count lines in the target
wc -l [target files]

# Find all callers
grep -rn "[TargetClass\|targetFunction]" \
  --include="*.{php,js,ts,py,go,rb}" . | grep -v node_modules | grep -v vendor | grep -v test

# Check what other files import from the module being refactored
grep -rn "from.*[module-name]\|require.*[module-name]\|use.*[Namespace]" \
  --include="*.{php,js,ts,py,go,rb}" . | grep -v node_modules | grep -v vendor

2. Define the Target State

Sketch what the code should look like after the refactoring. This does not need to be complete code — just structural sketches:

CURRENT: UserService (450 lines)
  - handleLogin()
  - createUser()
  - updateProfile()
  - sendEmail()
  - validatePasswordPolicy()
  - hashPassword()

TARGET: 
  UserService (120 lines) — orchestration only
  UserValidator (60 lines) — validatePasswordPolicy(), validateEmail(), etc.
  PasswordService (40 lines) — hashPassword(), verifyPassword()
  [email sending already exists in EmailService]

3. Sequence the Steps (additive/refactoring order)

Order the steps so each one is smallest possible and reversible:

Additive first (safest):

  1. Add the new class/function (don't delete anything yet)
  2. Move code to the new class
  3. Redirect callers to the new location
  4. Delete the old code

Anti-pattern: Don't do:

  • Rename + move + change logic in one step
  • Extract + change callers + delete original in one commit

4. Identify All Affected Callers

For every piece of code being moved, list every caller that will need to be updated:

Method/Function Callers (file:line) Update required
UserService::validatePassword auth/LoginController.php:45 Update import only
UserService::validatePassword tests/Auth/LoginTest.php:23 Update mock setup

5. Write the Step-by-Step Plan

Update docs/refactoring/REFACTOR-MODULE-NAME.md:

## Execution Steps

### Step 1: Add UserValidator class (new file, no deletions)
- Create `src/Services/UserValidator.php`
- Copy (not move) validatePasswordPolicy() into it
- Verify tests still pass

### Step 2: Redirect UserService to use UserValidator
- Inject UserValidator into UserService
- Change validatePasswordPolicy() to delegate to UserValidator
- Verify tests still pass

### Step 3: Remove duplicated validatePasswordPolicy from UserService
- Delete the body now that it delegates
- Verify tests still pass

### Step 4: Extract hashPassword() similarly...

Each step ends with "verify tests still pass" — this is not optional.

6. Define Success Criteria

What does "done" look like?

## Success Criteria
- [ ] No function exceeds 30 lines
- [ ] All classes have a single clear responsibility  
- [ ] Test coverage is the same or higher
- [ ] No duplicate password validation code
- [ ] All existing tests still pass
- [ ] Code review: a new developer understands each class without asking questions

7. Update TODO.md

Replace high-level refactoring tasks with the specific sequenced steps. Include a source reference on every task so origin is traceable. Status rules: [ ] = not started · [~] = in progress (one at a time) · [x] = done (prefix the date).

## Todo
- [ ] refactor: create UserValidator class with validatePasswordPolicy() _(ref: workflows/refactor-cycle/02-plan.md)_
- [ ] refactor: inject UserValidator into UserService, delegate call _(ref: workflows/refactor-cycle/02-plan.md)_
- [ ] refactor: remove duplicate validatePasswordPolicy() from UserService _(ref: workflows/refactor-cycle/02-plan.md)_
- [ ] refactor: create PasswordService with hashPassword(), verifyPassword() _(ref: workflows/refactor-cycle/02-plan.md)_
- [ ] refactor: inject PasswordService into UserService, update callers _(ref: workflows/refactor-cycle/02-plan.md)_
- [ ] refactor: remove hash/verify methods from UserService _(ref: workflows/refactor-cycle/02-plan.md)_
- [ ] test: add tests for UserValidator in isolation _(ref: workflows/refactor-cycle/02-plan.md)_
- [ ] test: add tests for PasswordService in isolation _(ref: workflows/refactor-cycle/02-plan.md)_

Exit Criteria

This step is complete when:

  • [ ] All callers of code being moved are mapped
  • [ ] Step sequence is written in additive order
  • [ ] Each step is atomic (one logical change)
  • [ ] Success criteria are defined and measurable
  • [ ] TODO.md reflects the granular ordered steps
  • [ ] Ready to proceed to Step 3 (Execute)