MetaDebate / docs /workflows /refactor.md
vajeeda's picture
base structure of the project formed
b6e19c7
|
Raw
History Blame Contribute Delete
5.89 kB
# 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