Spaces:
Sleeping
Sleeping
| # Workflow β Refactoring Code | |
| ## Purpose | |
| Read this file every time you need to refactor existing code. | |
| Refactoring means improving structure without changing behaviour. | |
| If behaviour changes β that is a feature, not a refactor. | |
| --- | |
| ## Core Principle | |
| **Tests must pass before AND after every refactor.** | |
| If tests fail after refactor β you changed behaviour. Revert and retry. | |
| Never refactor and fix a bug in the same commit. | |
| --- | |
| ## Step 1 β Confirm Refactor Scope | |
| Before touching any code, state this out loud: | |
| Refactor target: [file or function] | |
| Reason for refactor: [why this needs to change] | |
| Behaviour change: none | |
| Files I will touch: [exact list] | |
| Files I will NOT touch: [everything else] | |
| - [ ] Confirm with user that this refactor is needed now | |
| - [ ] Confirm all current tests pass before starting: | |
| ```bash | |
| bash scripts/test.sh | |
| ``` | |
| - [ ] Do not proceed if any test is currently failing | |
| --- | |
| ## Step 2 β Identify What to Refactor | |
| Valid reasons to refactor: | |
| - [ ] Duplicate logic across multiple functions | |
| - [ ] Function doing more than one thing | |
| - [ ] Deeply nested conditionals reducing readability | |
| - [ ] Magic numbers or hardcoded strings | |
| - [ ] Missing or inconsistent error handling format | |
| - [ ] Inconsistent naming conventions | |
| - [ ] Dead code or unused imports | |
| Not valid reasons: | |
| - "It looks messy" without a specific structural problem | |
| - Preference for a different syntax that does the same thing | |
| - Rewriting working code during a bug fix session | |
| --- | |
| ## Step 3 β Refactor in Small Steps | |
| - [ ] Change one thing at a time | |
| - [ ] Run tests after each individual change | |
| - [ ] Do not batch multiple refactors into one step | |
| - [ ] Keep original logic visible until new logic is confirmed working | |
| ### Order of operations: | |
| Extract repeated logic into a shared utility function | |
| Simplify conditionals (early returns over nested if/else) | |
| Rename for clarity (variables, functions) | |
| Remove dead code and unused imports | |
| Standardise error handling format per docs/debugging.md | |
| --- | |
| ## Step 4 β Run Tests After Every Change | |
| ```bash | |
| # After each individual change | |
| npm test -- tests/unit/[affected-file].test.ts 2>&1 | tee logs/test.log | |
| # After all changes complete | |
| bash scripts/test.sh | |
| ``` | |
| - [ ] Every test that passed before must still pass | |
| - [ ] If a test fails β revert the last change, do not chain fixes | |
| --- | |
| ## Step 5 β Update Tests if Needed | |
| Refactoring may require test updates only in these cases: | |
| - [ ] A function was renamed β update test description and import | |
| - [ ] A function was split into two β write tests for both | |
| - [ ] A utility was extracted β write a unit test for the utility | |
| Do NOT update tests to make them pass after a refactor. | |
| If a test fails after refactor β the refactor changed behaviour β revert. | |
| --- | |
| ## Step 6 β Self Review Checklist | |
| Before declaring refactor done: | |
| - [ ] Behaviour is identical before and after | |
| - [ ] All tests pass | |
| - [ ] No new files created outside the plan in Step 1 | |
| - [ ] Error handling format matches `docs/debugging.md` | |
| - [ ] No console.log left in code | |
| - [ ] No dead code or unused imports remain | |
| - [ ] No hardcoded values introduced | |
| --- | |
| ## Step 7 β Update Docs | |
| - [ ] Update `docs/architecture.md` if structure changed | |
| - [ ] Add one-liner to `docs/progress.md` | |
| - [ ] Append one line to `session/phase-log.md` | |
| - [ ] Update `session/summary.md` | |
| - [ ] If a pattern was discovered that saves time β add to `docs/learnings.md` | |
| --- | |
| ## Step 8 β Git Commit Message | |
| Provide one-liner commit message in this format: | |
| refactor([scope]): [what was improved and how] | |
| Examples: | |
| refactor(auth): extract session validation into shared utility | |
| refactor(dashboard): replace nested conditionals with early returns | |
| refactor(db): standardise error handling across all supabase queries | |
| refactor(utils): remove dead code and unused imports from helpers | |
| **Do NOT push to GitHub. Hand the message to the user.** | |
| --- | |
| ## Step 9 β Confirm with User | |
| - [ ] Show exactly what changed and in which files | |
| - [ ] Show before/after for key changes | |
| - [ ] Show test results confirming no behaviour change | |
| - [ ] Show commit message | |
| - [ ] Ask: "Refactor complete β ready to continue?" | |
| - [ ] Do NOT proceed until user confirms | |
| --- | |
| ## Refactor Decision Tree | |
| Refactor needed? | |
| β | |
| βΌ | |
| All tests passing? | |
| β | |
| βββ No β fix failing tests first, then refactor | |
| β | |
| βββ Yes β confirm scope β refactor one thing at a time | |
| β | |
| βΌ | |
| Run tests after each change | |
| β | |
| βββ Pass β continue next change | |
| β | |
| βββ Fail β revert last change | |
| β reassess scope | |
| β do not chain fixes | |
| --- | |
| ## Refactor Patterns | |
| ### Extract repeated logic | |
| ```typescript | |
| // Before β same null check in 3 functions | |
| if (!userId || userId === '') return null | |
| // After β shared utility | |
| function isValidId(id: string | null | undefined): boolean { | |
| return !!id && id.trim() !== '' | |
| } | |
| ``` | |
| ### Early returns over nested conditionals | |
| ```typescript | |
| // Before | |
| function processUser(user: User | null) { | |
| if (user) { | |
| if (user.isActive) { | |
| if (user.hasProfile) { | |
| return user.profile | |
| } | |
| } | |
| } | |
| return null | |
| } | |
| // After | |
| function processUser(user: User | null) { | |
| if (!user) return null | |
| if (!user.isActive) return null | |
| if (!user.hasProfile) return null | |
| return user.profile | |
| } | |
| ``` | |
| ### Standardise error handling | |
| ```typescript | |
| // Before β inconsistent | |
| try { | |
| ... | |
| } catch (e) { | |
| console.log(e) // wrong | |
| } | |
| // After β per docs/debugging.md | |
| try { | |
| ... | |
| } catch (err) { | |
| handleError(err, 'lib/users.ts', 'processUser') | |
| return null | |
| } | |
| ``` | |
| --- | |
| ## What NOT to Do | |
| - Do not refactor and fix a bug in the same commit | |
| - Do not refactor files not listed in Step 1 | |
| - Do not update tests to force them to pass after refactor | |
| - Do not batch all refactors into one large change | |
| - Do not refactor during a feature build session | |
| - Do not push to GitHub | |
| - Do not start a refactor if any test is currently failing |