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 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

# 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

// 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

// 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

// 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