mirror of
https://github.com/jpawlowski/hass.tibber_prices.git
synced 2026-03-29 21:03:40 +00:00
1 line
No EOL
26 KiB
JavaScript
1 line
No EOL
26 KiB
JavaScript
"use strict";(globalThis.webpackChunkdocs_split_developer=globalThis.webpackChunkdocs_split_developer||[]).push([[8657],{7386:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>t,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"refactoring-guide","title":"Refactoring Guide","description":"This guide explains how to plan and execute major refactorings in this project.","source":"@site/docs/refactoring-guide.md","sourceDirName":".","slug":"/refactoring-guide","permalink":"/hass.tibber_prices/developer/refactoring-guide","draft":false,"unlisted":false,"editUrl":"https://github.com/jpawlowski/hass.tibber_prices/tree/main/docs/developer/docs/refactoring-guide.md","tags":[],"version":"current","lastUpdatedAt":1764985026000,"frontMatter":{},"sidebar":"tutorialSidebar","previous":{"title":"Period Calculation Theory","permalink":"/hass.tibber_prices/developer/period-calculation-theory"},"next":{"title":"Performance Optimization","permalink":"/hass.tibber_prices/developer/performance"}}');var l=s(4848),r=s(8453);const t={},a="Refactoring Guide",c={},d=[{value:"When to Plan a Refactoring",id:"when-to-plan-a-refactoring",level:2},{value:"The Planning Process",id:"the-planning-process",level:2},{value:"1. Create a Planning Document",id:"1-create-a-planning-document",level:3},{value:"2. Use the Planning Template",id:"2-use-the-planning-template",level:3},{value:"3. Iterate Freely",id:"3-iterate-freely",level:3},{value:"4. Implementation Phase",id:"4-implementation-phase",level:3},{value:"5. After Completion",id:"5-after-completion",level:3},{value:"Real-World Example",id:"real-world-example",level:2},{value:"Phase-by-Phase Implementation",id:"phase-by-phase-implementation",level:2},{value:"Why Phases Matter",id:"why-phases-matter",level:3},{value:"Phase Structure",id:"phase-structure",level:3},{value:"Example Phase Documentation",id:"example-phase-documentation",level:3},{value:"Testing Strategy",id:"testing-strategy",level:2},{value:"After Each Phase",id:"after-each-phase",level:3},{value:"Comprehensive Testing (Final Phase)",id:"comprehensive-testing-final-phase",level:3},{value:"Common Pitfalls",id:"common-pitfalls",level:2},{value:"\u274c Skip Planning for Large Changes",id:"-skip-planning-for-large-changes",level:3},{value:"\u274c Implement All Phases at Once",id:"-implement-all-phases-at-once",level:3},{value:"\u274c Forget to Update Documentation",id:"-forget-to-update-documentation",level:3},{value:"\u274c Ignore the Planning Directory",id:"-ignore-the-planning-directory",level:3},{value:"Integration with AI Development",id:"integration-with-ai-development",level:2},{value:"Tools and Resources",id:"tools-and-resources",level:2},{value:"Planning Directory",id:"planning-directory",level:3},{value:"Example Plans",id:"example-plans",level:3},{value:"Helper Scripts",id:"helper-scripts",level:3},{value:"FAQ",id:"faq",level:2},{value:"Q: When should I create a plan vs. just start coding?",id:"q-when-should-i-create-a-plan-vs-just-start-coding",level:3},{value:"Q: How detailed should the plan be?",id:"q-how-detailed-should-the-plan-be",level:3},{value:"Q: What if the plan changes during implementation?",id:"q-what-if-the-plan-changes-during-implementation",level:3},{value:"Q: Should every refactoring follow this process?",id:"q-should-every-refactoring-follow-this-process",level:3},{value:"Q: How do I know when a refactoring is successful?",id:"q-how-do-i-know-when-a-refactoring-is-successful",level:3},{value:"Summary",id:"summary",level:2}];function o(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.header,{children:(0,l.jsx)(n.h1,{id:"refactoring-guide",children:"Refactoring Guide"})}),"\n",(0,l.jsx)(n.p,{children:"This guide explains how to plan and execute major refactorings in this project."}),"\n",(0,l.jsx)(n.h2,{id:"when-to-plan-a-refactoring",children:"When to Plan a Refactoring"}),"\n",(0,l.jsx)(n.p,{children:"Not every code change needs a detailed plan. Create a refactoring plan when:"}),"\n",(0,l.jsxs)(n.p,{children:["\ud83d\udd34 ",(0,l.jsx)(n.strong,{children:"Major changes requiring planning:"})]}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"Splitting modules into packages (>5 files affected, >500 lines moved)"}),"\n",(0,l.jsx)(n.li,{children:"Architectural changes (new packages, module restructuring)"}),"\n",(0,l.jsx)(n.li,{children:"Breaking changes (API changes, config format migrations)"}),"\n"]}),"\n",(0,l.jsxs)(n.p,{children:["\ud83d\udfe1 ",(0,l.jsx)(n.strong,{children:"Medium changes that might benefit from planning:"})]}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"Complex features with multiple moving parts"}),"\n",(0,l.jsx)(n.li,{children:"Changes affecting many files (>3 files, unclear best approach)"}),"\n",(0,l.jsx)(n.li,{children:"Refactorings with unclear scope"}),"\n"]}),"\n",(0,l.jsxs)(n.p,{children:["\ud83d\udfe2 ",(0,l.jsx)(n.strong,{children:"Small changes - no planning needed:"})]}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:["Bug fixes (straightforward, ",(0,l.jsx)(n.code,{children:"<"}),"100 lines)"]}),"\n",(0,l.jsxs)(n.li,{children:["Small features (",(0,l.jsx)(n.code,{children:"<"}),"3 files, clear approach)"]}),"\n",(0,l.jsx)(n.li,{children:"Documentation updates"}),"\n",(0,l.jsx)(n.li,{children:"Cosmetic changes (formatting, renaming)"}),"\n"]}),"\n",(0,l.jsx)(n.h2,{id:"the-planning-process",children:"The Planning Process"}),"\n",(0,l.jsx)(n.h3,{id:"1-create-a-planning-document",children:"1. Create a Planning Document"}),"\n",(0,l.jsxs)(n.p,{children:["Create a file in the ",(0,l.jsx)(n.code,{children:"planning/"})," directory (git-ignored for free iteration):"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"# Example:\ntouch planning/my-feature-refactoring-plan.md\n"})}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"Note:"})," The ",(0,l.jsx)(n.code,{children:"planning/"})," directory is git-ignored, so you can iterate freely without polluting git history."]}),"\n",(0,l.jsx)(n.h3,{id:"2-use-the-planning-template",children:"2. Use the Planning Template"}),"\n",(0,l.jsx)(n.p,{children:"Every planning document should include:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-markdown",children:"# <Feature> Refactoring Plan\n\n**Status**: \ud83d\udd04 PLANNING | \ud83d\udea7 IN PROGRESS | \u2705 COMPLETED | \u274c CANCELLED\n**Created**: YYYY-MM-DD\n**Last Updated**: YYYY-MM-DD\n\n## Problem Statement\n\n- What's the issue?\n- Why does it need fixing?\n- Current pain points\n\n## Proposed Solution\n\n- High-level approach\n- File structure (before/after)\n- Module responsibilities\n\n## Migration Strategy\n\n- Phase-by-phase breakdown\n- File lifecycle (CREATE/MODIFY/DELETE/RENAME)\n- Dependencies between phases\n- Testing checkpoints\n\n## Risks & Mitigation\n\n- What could go wrong?\n- How to prevent it?\n- Rollback strategy\n\n## Success Criteria\n\n- Measurable improvements\n- Testing requirements\n- Verification steps\n"})}),"\n",(0,l.jsxs)(n.p,{children:["See ",(0,l.jsx)(n.code,{children:"planning/README.md"})," for detailed template explanation."]}),"\n",(0,l.jsx)(n.h3,{id:"3-iterate-freely",children:"3. Iterate Freely"}),"\n",(0,l.jsxs)(n.p,{children:["Since ",(0,l.jsx)(n.code,{children:"planning/"})," is git-ignored:"]}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"Draft multiple versions"}),"\n",(0,l.jsx)(n.li,{children:"Get AI assistance without commit pressure"}),"\n",(0,l.jsx)(n.li,{children:"Refine until the plan is solid"}),"\n",(0,l.jsx)(n.li,{children:"No need to clean up intermediate versions"}),"\n"]}),"\n",(0,l.jsx)(n.h3,{id:"4-implementation-phase",children:"4. Implementation Phase"}),"\n",(0,l.jsx)(n.p,{children:"Once plan is approved:"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"Follow the phases defined in the plan"}),"\n",(0,l.jsx)(n.li,{children:"Test after each phase (don't skip!)"}),"\n",(0,l.jsx)(n.li,{children:"Update plan if issues discovered"}),"\n",(0,l.jsx)(n.li,{children:"Track progress through phase status"}),"\n"]}),"\n",(0,l.jsx)(n.h3,{id:"5-after-completion",children:"5. After Completion"}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"Option A: Archive in docs/development/"}),"\nIf the plan has lasting value (successful pattern, reusable approach):"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:'mv planning/my-feature-refactoring-plan.md docs/development/\ngit add docs/development/my-feature-refactoring-plan.md\ngit commit -m "docs: archive successful refactoring plan"\n'})}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"Option B: Delete"}),"\nIf the plan served its purpose and code is the source of truth:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"rm planning/my-feature-refactoring-plan.md\n"})}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"Option C: Keep locally (not committed)"}),'\nFor "why we didn\'t do X" reference:']}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"mkdir -p planning/archive\nmv planning/my-feature-refactoring-plan.md planning/archive/\n# Still git-ignored, just organized\n"})}),"\n",(0,l.jsx)(n.h2,{id:"real-world-example",children:"Real-World Example"}),"\n",(0,l.jsxs)(n.p,{children:["The ",(0,l.jsx)(n.strong,{children:"sensor/ package refactoring"})," (Nov 2025) is a successful example:"]}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Before:"})}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"sensor.py"})," - 2,574 lines, hard to navigate"]}),"\n"]}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"After:"})}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"sensor/"})," package with 5 focused modules"]}),"\n",(0,l.jsxs)(n.li,{children:["Each module ",(0,l.jsx)(n.code,{children:"<"}),"800 lines"]}),"\n",(0,l.jsx)(n.li,{children:"Clear separation of concerns"}),"\n"]}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Process:"})}),"\n",(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsxs)(n.li,{children:["Created ",(0,l.jsx)(n.code,{children:"planning/module-splitting-plan.md"})," (now in ",(0,l.jsx)(n.code,{children:"docs/development/"}),")"]}),"\n",(0,l.jsx)(n.li,{children:"Defined 6 phases with clear file lifecycle"}),"\n",(0,l.jsx)(n.li,{children:"Implemented phase by phase"}),"\n",(0,l.jsx)(n.li,{children:"Tested after each phase"}),"\n",(0,l.jsx)(n.li,{children:"Documented in AGENTS.md"}),"\n",(0,l.jsxs)(n.li,{children:["Moved plan to ",(0,l.jsx)(n.code,{children:"docs/development/"})," as reference"]}),"\n"]}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Key learnings:"})}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:["Temporary ",(0,l.jsx)(n.code,{children:"_impl.py"})," files avoid Python package conflicts"]}),"\n",(0,l.jsx)(n.li,{children:"Test after EVERY phase (don't accumulate changes)"}),"\n",(0,l.jsx)(n.li,{children:"Clear file lifecycle (CREATE/MODIFY/DELETE/RENAME)"}),"\n",(0,l.jsx)(n.li,{children:"Phase-by-phase approach enables safe rollback"}),"\n"]}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"Note:"})," The complete module splitting plan was documented during implementation but has been superseded by the actual code structure."]}),"\n",(0,l.jsx)(n.h2,{id:"phase-by-phase-implementation",children:"Phase-by-Phase Implementation"}),"\n",(0,l.jsx)(n.h3,{id:"why-phases-matter",children:"Why Phases Matter"}),"\n",(0,l.jsx)(n.p,{children:"Breaking refactorings into phases:"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"\u2705 Enables testing after each change (catch bugs early)"}),"\n",(0,l.jsx)(n.li,{children:"\u2705 Allows rollback to last good state"}),"\n",(0,l.jsx)(n.li,{children:"\u2705 Makes progress visible"}),"\n",(0,l.jsx)(n.li,{children:"\u2705 Reduces cognitive load (focus on one thing)"}),"\n",(0,l.jsx)(n.li,{children:"\u274c Takes more time (but worth it!)"}),"\n"]}),"\n",(0,l.jsx)(n.h3,{id:"phase-structure",children:"Phase Structure"}),"\n",(0,l.jsx)(n.p,{children:"Each phase should:"}),"\n",(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.strong,{children:"Have clear goal"})," - What's being changed?"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.strong,{children:"Document file lifecycle"})," - CREATE/MODIFY/DELETE/RENAME"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.strong,{children:"Define success criteria"})," - How to verify it worked?"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.strong,{children:"Include testing steps"})," - What to test?"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.strong,{children:"Estimate time"})," - Realistic time budget"]}),"\n"]}),"\n",(0,l.jsx)(n.h3,{id:"example-phase-documentation",children:"Example Phase Documentation"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-markdown",children:"### Phase 3: Extract Helper Functions (Session 3)\n\n**Goal**: Move pure utility functions to helpers.py\n\n**File Lifecycle**:\n\n- \u2728 CREATE `sensor/helpers.py` (utility functions)\n- \u270f\ufe0f MODIFY `sensor/core.py` (import from helpers.py)\n\n**Steps**:\n\n1. Create sensor/helpers.py\n2. Move pure functions (no state, no self)\n3. Add comprehensive docstrings\n4. Update imports in core.py\n\n**Estimated time**: 45 minutes\n\n**Success criteria**:\n\n- \u2705 All pure functions moved\n- \u2705 `./scripts/lint-check` passes\n- \u2705 HA starts successfully\n- \u2705 All entities work correctly\n"})}),"\n",(0,l.jsx)(n.h2,{id:"testing-strategy",children:"Testing Strategy"}),"\n",(0,l.jsx)(n.h3,{id:"after-each-phase",children:"After Each Phase"}),"\n",(0,l.jsx)(n.p,{children:"Minimum testing checklist:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"# 1. Linting passes\n./scripts/lint-check\n\n# 2. Home Assistant starts\n./scripts/develop\n# Watch for startup errors in logs\n\n# 3. Integration loads\n# Check: Settings \u2192 Devices & Services \u2192 Tibber Prices\n# Verify: All entities appear\n\n# 4. Basic functionality\n# Test: Data updates without errors\n# Check: Entity states update correctly\n"})}),"\n",(0,l.jsx)(n.h3,{id:"comprehensive-testing-final-phase",children:"Comprehensive Testing (Final Phase)"}),"\n",(0,l.jsx)(n.p,{children:"After completing all phases:"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"Test all entities (sensors, binary sensors)"}),"\n",(0,l.jsx)(n.li,{children:"Test configuration flow (add/modify/remove)"}),"\n",(0,l.jsx)(n.li,{children:"Test options flow (change settings)"}),"\n",(0,l.jsx)(n.li,{children:"Test services (custom service calls)"}),"\n",(0,l.jsx)(n.li,{children:"Test error handling (disconnect API, invalid data)"}),"\n",(0,l.jsx)(n.li,{children:"Test caching (restart HA, verify cache loads)"}),"\n",(0,l.jsx)(n.li,{children:"Test time-based updates (quarter-hour refresh)"}),"\n"]}),"\n",(0,l.jsx)(n.h2,{id:"common-pitfalls",children:"Common Pitfalls"}),"\n",(0,l.jsx)(n.h3,{id:"-skip-planning-for-large-changes",children:"\u274c Skip Planning for Large Changes"}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"Problem:"}),' "This seems straightforward, I\'ll just start coding..."']}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"Result:"})," Halfway through, realize the approach doesn't work. Wasted time."]}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"Solution:"})," If unsure, spend 30 minutes on a rough plan. Better to plan and discard than get stuck."]}),"\n",(0,l.jsx)(n.h3,{id:"-implement-all-phases-at-once",children:"\u274c Implement All Phases at Once"}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"Problem:"}),' "I\'ll do all phases, then test everything..."']}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"Result:"})," 10+ files changed, 2000+ lines modified, hard to debug if something breaks."]}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"Solution:"})," Test after EVERY phase. Commit after each successful phase."]}),"\n",(0,l.jsx)(n.h3,{id:"-forget-to-update-documentation",children:"\u274c Forget to Update Documentation"}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"Problem:"})," Code is refactored, but AGENTS.md and docs/ still reference old structure."]}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"Result:"})," AI/humans get confused by outdated documentation."]}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"Solution:"}),' Include "Documentation Phase" at the end of every refactoring plan.']}),"\n",(0,l.jsx)(n.h3,{id:"-ignore-the-planning-directory",children:"\u274c Ignore the Planning Directory"}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"Problem:"}),' "I\'ll just create the plan in docs/ directly..."']}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"Result:"}),' Git history polluted with draft iterations, or pressure to "commit something" too early.']}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"Solution:"})," Always use ",(0,l.jsx)(n.code,{children:"planning/"})," for work-in-progress. Move to ",(0,l.jsx)(n.code,{children:"docs/"})," only when done."]}),"\n",(0,l.jsx)(n.h2,{id:"integration-with-ai-development",children:"Integration with AI Development"}),"\n",(0,l.jsx)(n.p,{children:"This project uses AI heavily (GitHub Copilot, Claude). The planning process supports AI development:"}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"AI reads from:"})}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"AGENTS.md"})," - Long-term memory, patterns, conventions (AI-focused)"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"docs/development/"})," - Human-readable guides (human-focused)"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"planning/"})," - Active refactoring plans (shared context)"]}),"\n"]}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"AI updates:"})}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"AGENTS.md"})," - When patterns change"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"planning/*.md"})," - During refactoring implementation"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"docs/development/"})," - After successful completion"]}),"\n"]}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Why separate AGENTS.md and docs/development/?"})}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"AGENTS.md"}),": Technical, comprehensive, AI-optimized"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"docs/development/"}),": Practical, focused, human-optimized"]}),"\n",(0,l.jsx)(n.li,{children:"Both stay in sync but serve different audiences"}),"\n"]}),"\n",(0,l.jsxs)(n.p,{children:["See ",(0,l.jsx)(n.a,{href:"https://github.com/jpawlowski/hass.tibber_prices/blob/v0.20.0/AGENTS.md",children:"AGENTS.md"}),' section "Planning Major Refactorings" for AI-specific guidance.']}),"\n",(0,l.jsx)(n.h2,{id:"tools-and-resources",children:"Tools and Resources"}),"\n",(0,l.jsx)(n.h3,{id:"planning-directory",children:"Planning Directory"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"planning/"})," - Git-ignored workspace for drafts"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"planning/README.md"})," - Detailed planning documentation"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"planning/*.md"})," - Active refactoring plans"]}),"\n"]}),"\n",(0,l.jsx)(n.h3,{id:"example-plans",children:"Example Plans"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"docs/development/module-splitting-plan.md"})," - \u2705 Completed, archived"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"planning/config-flow-refactoring-plan.md"})," - \ud83d\udd04 Planned (1013 lines \u2192 4 modules)"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"planning/binary-sensor-refactoring-plan.md"})," - \ud83d\udd04 Planned (644 lines \u2192 4 modules)"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"planning/coordinator-refactoring-plan.md"})," - \ud83d\udd04 Planned (1446 lines, high complexity)"]}),"\n"]}),"\n",(0,l.jsx)(n.h3,{id:"helper-scripts",children:"Helper Scripts"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:"./scripts/lint-check # Verify code quality\n./scripts/develop # Start HA for testing\n./scripts/lint # Auto-fix issues\n"})}),"\n",(0,l.jsx)(n.h2,{id:"faq",children:"FAQ"}),"\n",(0,l.jsx)(n.h3,{id:"q-when-should-i-create-a-plan-vs-just-start-coding",children:"Q: When should I create a plan vs. just start coding?"}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"A:"})," If you're asking this question, you probably need a plan. \ud83d\ude0a"]}),"\n",(0,l.jsx)(n.p,{children:"Simple rule: If you can't describe the entire change in 3 sentences, create a plan."}),"\n",(0,l.jsx)(n.h3,{id:"q-how-detailed-should-the-plan-be",children:"Q: How detailed should the plan be?"}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"A:"})," Detailed enough to execute without major surprises, but not a line-by-line script."]}),"\n",(0,l.jsx)(n.p,{children:"Good plan level:"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"Lists all files affected (CREATE/MODIFY/DELETE)"}),"\n",(0,l.jsx)(n.li,{children:"Defines phases with clear boundaries"}),"\n",(0,l.jsx)(n.li,{children:"Includes testing strategy"}),"\n",(0,l.jsx)(n.li,{children:"Estimates time per phase"}),"\n"]}),"\n",(0,l.jsx)(n.p,{children:"Too detailed:"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"Exact code snippets for every change"}),"\n",(0,l.jsx)(n.li,{children:"Line-by-line instructions"}),"\n"]}),"\n",(0,l.jsx)(n.p,{children:"Too vague:"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:'"Refactor sensor.py to be better"'}),"\n",(0,l.jsx)(n.li,{children:"No phase breakdown"}),"\n",(0,l.jsx)(n.li,{children:"No testing strategy"}),"\n"]}),"\n",(0,l.jsx)(n.h3,{id:"q-what-if-the-plan-changes-during-implementation",children:"Q: What if the plan changes during implementation?"}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"A:"})," Update the plan! Planning documents are living documents."]}),"\n",(0,l.jsx)(n.p,{children:"If you discover:"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:'Better approach \u2192 Update "Proposed Solution"'}),"\n",(0,l.jsx)(n.li,{children:'More phases needed \u2192 Add to "Migration Strategy"'}),"\n",(0,l.jsx)(n.li,{children:'New risks \u2192 Update "Risks & Mitigation"'}),"\n"]}),"\n",(0,l.jsx)(n.p,{children:"Document WHY the plan changed (helps future refactorings)."}),"\n",(0,l.jsx)(n.h3,{id:"q-should-every-refactoring-follow-this-process",children:"Q: Should every refactoring follow this process?"}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"A:"})," No! Use judgment:"]}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:[(0,l.jsxs)(n.strong,{children:["Small changes (",(0,l.jsx)(n.code,{children:"<"}),"100 lines, clear approach)"]}),": Just do it, no plan needed"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.strong,{children:"Medium changes (unclear scope)"}),": Write rough outline, refine if needed"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.strong,{children:"Large changes (>500 lines, >5 files)"}),": Full planning process"]}),"\n"]}),"\n",(0,l.jsx)(n.h3,{id:"q-how-do-i-know-when-a-refactoring-is-successful",children:"Q: How do I know when a refactoring is successful?"}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"A:"}),' Check the "Success Criteria" from your plan:']}),"\n",(0,l.jsx)(n.p,{children:"Typical criteria:"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"\u2705 All linting checks pass"}),"\n",(0,l.jsx)(n.li,{children:"\u2705 HA starts without errors"}),"\n",(0,l.jsx)(n.li,{children:"\u2705 All entities functional"}),"\n",(0,l.jsx)(n.li,{children:"\u2705 No regressions (existing features work)"}),"\n",(0,l.jsx)(n.li,{children:"\u2705 Code easier to understand/modify"}),"\n",(0,l.jsx)(n.li,{children:"\u2705 Documentation updated"}),"\n"]}),"\n",(0,l.jsx)(n.p,{children:"If you can't tick all boxes, the refactoring isn't done."}),"\n",(0,l.jsx)(n.h2,{id:"summary",children:"Summary"}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Key takeaways:"})}),"\n",(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.strong,{children:"Plan when scope is unclear"})," (>500 lines, >5 files, breaking changes)"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.strong,{children:"Use planning/ directory"})," for free iteration (git-ignored)"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.strong,{children:"Work in phases"})," and test after each phase"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.strong,{children:"Document file lifecycle"})," (CREATE/MODIFY/DELETE/RENAME)"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.strong,{children:"Update documentation"})," after completion (AGENTS.md, docs/)"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.strong,{children:"Archive or delete"})," plan after implementation"]}),"\n"]}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"Remember:"})," Good planning prevents half-finished refactorings and makes rollback easier when things go wrong."]}),"\n",(0,l.jsx)(n.hr,{}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Next steps:"})}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:["Read ",(0,l.jsx)(n.code,{children:"planning/README.md"})," for detailed template"]}),"\n",(0,l.jsxs)(n.li,{children:["Check ",(0,l.jsx)(n.code,{children:"docs/development/module-splitting-plan.md"})," for real example"]}),"\n",(0,l.jsxs)(n.li,{children:["Browse ",(0,l.jsx)(n.code,{children:"planning/"})," for active refactoring plans"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,l.jsx)(n,{...e,children:(0,l.jsx)(o,{...e})}):o(e)}}}]); |