Smithery Logo
MCPsSkillsDocsPricing
Login
Smithery Logo

Accelerating the Agent Economy

Resources

DocumentationPrivacy PolicySystem Status

Company

PricingAboutBlog

Connect

© 2026 Smithery. All rights reserved.

    arpa73

    code-refactoring

    arpa73/code-refactoring
    Coding
    1

    About

    SKILL.md

    Install

    Install via Skills CLI

    or add to your agent
    • Claude Code
      Claude Code
    • Codex
      Codex
    • OpenClaw
      OpenClaw
    • Cursor
      Cursor
    • Amp
      Amp
    • GitHub Copilot
      GitHub Copilot
    • Gemini CLI
      Gemini CLI
    • Kilo Code
      Kilo Code
    • Junie
      Junie
    • Replit
      Replit
    • Windsurf
      Windsurf
    • Cline
      Cline
    • Continue
      Continue
    • OpenCode
      OpenCode
    • OpenHands
      OpenHands
    • Roo Code
      Roo Code
    • Augment
      Augment
    • Goose
      Goose
    • Trae
      Trae
    • Zencoder
      Zencoder
    • Antigravity
      Antigravity
    ├─
    ├─
    └─

    About

    Safe code refactoring guide for gnwebsite project. Use when refactoring components, removing duplication, improving code structure, or simplifying complex functions...

    SKILL.md

    Code Refactoring Guide

    Step-by-step guide for safely refactoring code without breaking functionality in the gnwebsite fullstack project.

    When to Use This Skill

    Use when:

    • User asks "How do I refactor this code?" or "Can I simplify this?"
    • Reducing code duplication (DRY violations)
    • Simplifying complex functions (>50 lines)
    • Extracting reusable logic to composables
    • Improving code structure or naming
    • Addressing technical debt
    • User mentions: "refactor", "clean up", "simplify", "reduce duplication"

    Do NOT use for:

    • Style preferences without measurable benefit
    • Just before deadlines
    • Code without existing tests
    • Changes that alter behavior (that's feature work, not refactoring)

    Decision Tree: Proposal or Direct Refactoring?

    Need to refactor?
    │
    ├─ Breaking changes? (API contracts, schemas, core patterns)
    │  └─ YES → Create OpenSpec proposal
    │
    ├─ Just reorganizing code? (internal structure, no external impact)
    │  └─ YES → Follow safe refactoring steps
    │
    └─ Unsure?
       └─ Create proposal (better safe than sorry!)
    

    Prerequisites (CRITICAL)

    NEVER refactor without tests!

    # Check test coverage
    cd frontend && npm run test:run -- --coverage
    cd backend && docker exec backend pytest --cov
    
    # If coverage < 80% for code being refactored:
    # 1. STOP
    # 2. Write tests FIRST
    # 3. THEN refactor
    

    Minimum requirements:

    • Unit tests exist for all functions being changed
    • Integration tests exist for workflows being changed
    • All tests currently passing ✅

    Phase 1: Preparation

    Step 1: Document Current Behavior

    Create temporary documentation:

    # Refactoring: [Component Name]
    
    ## Current Behavior
    - Input: X
    - Output: Y
    - Side effects: Z
    - Edge cases: A, B, C
    
    ## Existing Tests
    - test_case_1: normal flow
    - test_case_2: error handling
    - test_case_3: edge case
    
    ## Success Criteria
    After refactor: all tests pass, same behavior
    

    Step 2: Create Safety Backup

    # Create backup branch
    git checkout -b backup-before-refactor
    git checkout -b refactor-my-feature
    

    Step 3: Create Refactoring Checklist

    ## Refactoring Checklist
    
    ### Before
    - [ ] All existing tests pass
    - [ ] Coverage documented
    - [ ] Behavior documented
    - [ ] Backup branch created
    
    ### During
    - [ ] ONE change at a time
    - [ ] Run tests after EACH change
    - [ ] Commit after EACH success
    
    ### After
    - [ ] All tests still pass
    - [ ] No console errors
    - [ ] Manual testing complete
    - [ ] Performance unchanged/better
    - [ ] Documentation updated
    

    Phase 2: Refactoring Patterns

    Pattern A: Extract Function (Reduce Complexity)

    When: Function >50 lines or multiple responsibilities

    Before:

    async function processArticle(article: Article) {
      // Validation (10 lines)
      if (!article.title) throw new Error('Title required')
      if (!article.content) throw new Error('Content required')
      
      // Image processing (15 lines)
      const images = []
      for (const img of article.images || []) {
        const url = img.image?.fileUrl || img.image?.file_url
        if (url) images.push({ url, caption: img.caption })
      }
      
      // Save (20 lines)
      const response = await api.create({ title, content, images })
      return response
    }
    

    After:

    async function processArticle(article: Article) {
      validateArticle(article)
      const images = processImages(article.images)
      return await saveArticle(article, images)
    }
    
    function validateArticle(article: Article) {
      if (!article.title) throw new Error('Title required')
      if (!article.content) throw new Error('Content required')
      if (article.title.length > 200) throw new Error('Title too long')
    }
    
    function processImages(images?: ArticleImage[]) {
      return (images || [])
        .map(img => ({ url: getImageUrl(img.image), caption: img.caption }))
        .filter(img => img.url && img.url !== '/placeholder-image.png')
    }
    
    async function saveArticle(article: Article, images: ProcessedImage[]) {
      return await api.create({ 
        title: article.title, 
        content: article.content, 
        images 
      })
    }
    

    Steps:

    1. Extract ONE function at a time
    2. Run tests after each extraction
    3. Commit each success
    4. Add tests for new functions:
    describe('validateArticle', () => {
      it('should throw on missing title', () => {
        expect(() => validateArticle({ content: 'test' }))
          .toThrow('Title required')
      })
    })
    
    describe('processImages', () => {
      it('should extract URLs', () => {
        const imgs = [{ image: { fileUrl: 'test.jpg' }, caption: 'Test' }]
        expect(processImages(imgs)).toEqual([{ url: 'test.jpg', caption: 'Test' }])
      })
      
      it('should filter placeholders', () => {
        expect(processImages([{ image: null }])).toEqual([])
      })
    })
    

    Pattern B: Extract Composable (Reuse Logic)

    When: Same logic duplicated across 3+ components

    Before (duplicated in BlogView, ArticleView, CategoryView):

    <script setup>
    const items = ref([])
    const loading = ref(false)
    const error = ref('')
    
    const loadItems = async () => {
      loading.value = true
      try {
        const response = await blogService.getAll()
        items.value = response.results
      } catch (err) {
        error.value = 'Failed to load'
      } finally {
        loading.value = false
      }
    }
    
    onMounted(loadItems)
    </script>
    

    After:

    // composables/useDataLoader.ts
    export function useDataLoader<T>(
      loadFn: () => Promise<{ results: T[] }>
    ) {
      const items = ref<T[]>([])
      const loading = ref(false)
      const error = ref('')
      
      const load = async () => {
        loading.value = true
        error.value = ''
        try {
          const response = await loadFn()
          items.value = response.results || []
        } catch (err) {
          error.value = 'Failed to load items'
          console.error(err)
        } finally {
          loading.value = false
        }
      }
      
      onMounted(load)
      return { items, loading, error, reload: load }
    }
    
    <!-- All components now -->
    <script setup>
    import { useDataLoader } from '@/composables/useDataLoader'
    
    const { items, loading, error, reload } = useDataLoader(() => 
      blogService.getAll()
    )
    </script>
    

    Steps:

    1. Create composable
    2. Write composable tests
    3. Migrate ONE component
    4. Test that component
    5. Commit
    6. Repeat for remaining components

    Pattern C: Consolidate Styles

    When: Same CSS in 3+ components

    Before (duplicated in 6 form components):

    <style scoped>
    .form-group { margin-bottom: 1.5rem; }
    .form-control { width: 100%; padding: 0.75rem; }
    .btn-primary { background: #007bff; color: white; }
    </style>
    

    After:

    /* styles/admin-forms.css */
    .form-group { margin-bottom: 1.5rem; }
    .form-control { width: 100%; padding: 0.75rem; }
    .btn-primary { background: #007bff; color: white; }
    
    <!-- Components keep only unique styles -->
    <style scoped>
    .special-field { /* component-specific */ }
    </style>
    

    Steps:

    1. Extract to shared CSS file
    2. Import in main.ts/App.vue
    3. Remove from ONE component
    4. Visual test
    5. Commit
    6. Repeat for remaining

    Pattern D: Replace with Utility

    When: Same calculation in 5+ places

    Before (in 5 files):

    const imageUrl = img.image?.fileUrl || img.image?.file_url || '/placeholder-image.png'
    

    After:

    // utils/imageData.ts
    export function extractImageUrl(
      imageData: any, 
      fallback = '/placeholder-image.png'
    ): string {
      if (!imageData) return fallback
      return imageData.fileUrl || imageData.file_url || fallback
    }
    
    // All files:
    const imageUrl = extractImageUrl(img.image)
    

    Steps:

    1. Create utility
    2. Write comprehensive tests
    3. Replace in ONE location
    4. Test
    5. Commit
    6. Repeat for each location

    Phase 3: Incremental Execution

    CRITICAL WORKFLOW: One change → Test → Commit

    # 1. Create working branch
    git checkout -b refactor-my-feature
    
    # 2. Make ONE small change
    # ... edit code ...
    
    # 3. Run tests
    npm run test:run
    
    # 4. If pass, commit
    git add .
    git commit -m "refactor: extract validateArticle function
    
    - Moved validation from processArticle
    - All tests passing
    - No behavior changes"
    
    # 5. Repeat for next change
    # ... edit code ...
    npm run test:run
    git commit -m "refactor: extract processImages"
    
    # Continue until complete
    

    Testing After EVERY Change

    # After each change:
    
    # 1. Unit tests
    npm run test:run
    
    # 2. Type check
    npm run type-check
    
    # 3. Pattern check
    npm run test:patterns
    
    # 4. Manual spot check
    npm run dev
    # Test the specific feature
    
    # If ANY fail:
    git reset --hard HEAD  # Undo
    # OR fix before committing
    

    Phase 4: Validation

    Comprehensive Testing Checklist

    Automated:

    • All unit tests pass
    • All integration tests pass
    • Type check passes
    • Pattern enforcement passes
    • No new linting errors

    Manual:

    • Feature works exactly as before
    • No console errors
    • No visual regressions
    • Performance unchanged/better
    • Works in all browsers

    Code Quality:

    • More readable
    • More testable
    • Less duplication
    • Lower complexity
    • Reasonable file sizes

    Performance Verification

    # Before refactor
    npm run build
    # Note: size, time
    
    # After refactor
    npm run build
    # Compare: should be similar or better
    

    Phase 5: Documentation

    Update Project Docs

    If new patterns introduced:

    CODEBASE_ESSENTIALS.md:

    - **Image URL extraction:** Always use `extractImageUrl()` from `@/utils/imageData`. Prevents silent failures.
    

    CODEBASE_CHANGELOG.md:

    ### Session: Refactor Image URL Handling (Jan 13, 2026)
    
    **Goal**: Eliminate duplicated image URL logic
    
    **Changes**:
    - Created `extractImageUrl()` utility
    - Replaced 12 instances
    - Added tests (8 unit, 6 integration)
    
    **Impact**:
    - Reduced duplication by ~80 lines
    - Improved testability
    
    **Validation**:
    - ✅ All 227 tests pass
    - ✅ No behavior changes
    - ✅ Build size unchanged
    
    **Commit**: abc123
    

    Anti-Patterns (DON'T DO THIS)

    ❌ Big Bang Refactor

    # WRONG: Change 50 files at once
    git commit -m "refactor: everything"
    
    # CORRECT: Incremental commits
    git commit -m "refactor: extract validation"
    # test
    git commit -m "refactor: extract image processing"
    # test
    

    ❌ Refactor Without Tests

    // WRONG: No tests exist
    function refactoredFunction() {
      // Hope this works! 🤞
    }
    
    // CORRECT: Write tests first
    test('refactoredFunction works', () => { ... })
    function refactoredFunction() { ... }
    

    ❌ Change Behavior

    // WRONG: Added new validation during refactor
    function validateArticle(article: Article) {
      if (!article.title) throw new Error('Title required')
      if (!article.excerpt) throw new Error('Excerpt required')  // NEW!
    }
    
    // CORRECT: Preserve exact behavior
    function validateArticle(article: Article) {
      if (!article.title) throw new Error('Title required')
      // Same validation as before, just extracted
    }
    

    ❌ Premature Optimization

    // WRONG: No measured problem, making code complex
    // Replacing simple readable code with "faster" code
    
    // CORRECT: Measure first, optimize if needed
    // Keep code simple unless profiling shows issue
    

    ❌ Refactor Under Pressure

    // WRONG: "Production deploy tomorrow, let me refactor today!"
    // CORRECT: Refactor when you have time to test properly
    

    Common Scenarios

    Scenario 1: Component Too Large (>300 lines)

    Fix:

    1. Extract child components
    2. Extract composables for logic
    3. Extract utilities for helpers
    4. ONE responsibility per file

    Scenario 2: Duplicated Code (3+ places)

    Fix:

    1. Identify common pattern
    2. Extract to utility/composable
    3. Write tests
    4. Replace one by one
    5. Delete duplicates

    Scenario 3: Hard to Test

    Fix:

    1. Identify dependencies
    2. Extract to parameters
    3. Make functions pure
    4. Write tests with mocks

    Scenario 4: Unclear Naming

    Fix:

    1. Rename ONE identifier
    2. Use IDE refactor (F2 in VS Code)
    3. Run tests
    4. Commit
    5. Repeat

    Emergency Rollback

    If refactoring breaks something:

    # Option 1: Revert last commit
    git revert HEAD
    
    # Option 2: Restore from backup
    git checkout backup-before-refactor
    git checkout -b refactor-my-feature-v2
    
    # Option 3: Stash and investigate
    git stash
    npm run test:run  # Pass now?
    git stash pop     # Re-apply and fix
    
    # Option 4: Nuclear
    git reset --hard origin/development
    # Start over with smaller changes
    

    Success Metrics

    Refactoring succeeds when:

    ✅ All tests pass (no behavior changes)
    ✅ Code more readable (clear improvement)
    ✅ Complexity reduced (fewer lines, simpler logic)
    ✅ Duplication removed (DRY)
    ✅ Test coverage maintained/improved
    ✅ Performance unchanged/better
    ✅ No regressions (manual testing confirms)

    Key Commands

    # Before refactoring
    npm run test:run -- --coverage        # Check coverage
    docker exec backend pytest --cov      # Backend coverage
    git checkout -b backup-before-refactor # Safety backup
    
    # During refactoring (after EACH change)
    npm run test:run                      # Frontend tests
    npm run type-check                    # TypeScript
    npm run test:patterns                 # Pattern enforcement
    docker exec backend pytest -v         # Backend tests
    git commit -m "refactor: [change]"    # Commit success
    
    # After refactoring
    npm run build                         # Verify build
    npm run dev                          # Manual test
    git push origin refactor-my-feature   # Push when complete
    

    Examples

    Example 1: Extract Function

    # 1. Initial state: 80-line function
    # 2. Extract validation (commit)
    git commit -m "refactor: extract validateArticle"
    # 3. Extract image processing (commit)
    git commit -m "refactor: extract processImages"
    # 4. Simplify main function (commit)
    git commit -m "refactor: simplify processArticle"
    # Result: 3 small focused functions
    

    Example 2: Extract Composable

    # 1. Create useDataLoader composable
    # 2. Write tests for composable
    git commit -m "refactor: add useDataLoader composable"
    # 3. Migrate BlogView (test, commit)
    git commit -m "refactor: BlogView uses useDataLoader"
    # 4. Migrate ArticleView (test, commit)
    git commit -m "refactor: ArticleView uses useDataLoader"
    # 5. Migrate CategoryView (test, commit)
    git commit -m "refactor: CategoryView uses useDataLoader"
    # Result: Eliminated 60 lines of duplication
    

    When to Stop

    Stop refactoring when:

    • Tests start failing frequently (too aggressive)
    • Code is "good enough" (perfect is enemy of done)
    • Deadline approaching (commit what you have)
    • No measurable benefit (diminishing returns)
    • You're just tweaking style (not improving structure)

    Related Resources

    • developer-checklist - Pre-commit validation
    • feature-implementation - Adding features
    • CODEBASE_ESSENTIALS.md - Current patterns
    • CODEBASE_CHANGELOG.md - Historical changes
    • .archive/guides/DRY_REFACTORING_GUIDE.md - Past refactor example
    Recommended Servers
    Vercel Grep
    Vercel Grep
    Context7
    Context7
    Microsoft Learn MCP
    Microsoft Learn MCP
    Repository
    arpa73/aiknowsys
    Files