This document defines the standard operating procedure for migrating code between languages, frameworks, or versions (e.g., JavaScript to TypeScript, Python 2 to 3, Flask to ASP.NET).
Core Philosophy: Tests are the source of truth. The migration or refactoring is not complete until the new code compiles AND passes the original behaviour tests. Every refactoring, no matter how small, follows this loop.
When asked to migrate "Stack 1" (Legacy) to "Stack 2" (Target), you must strictly follow this iterative loop. Do not attempt to migrate logic blindly.
Before writing a single line of target code, you must ensure the legacy code is fully covered by tests.
- Analyze Existing Tests: Check coverage of the legacy code.
- Fill the Gaps: If coverage is low (< 90%), write new unit/integration tests against the Legacy code.
- Verify Baseline: Run these tests. They must pass against the legacy code.
- Why? If tests fail now, you won't know if failures later are due to your migration or pre-existing bugs.
Convert the code to the target stack. Focus on syntax and structure first.
- Draft Migration: Translate the code to the target language/framework.
- Tip: Keep logic 1:1 where possible initially. Refactor for idiom after functionality is verified.
- Compile/Lint: Run the compiler or linter (e.g.,
tsc,dotnet build). - Fix Syntax Errors:
- Feed error messages back into your context.
- Fix types, imports, and syntax issues.
- Repeat until the code compiles cleanly.
Now that the code compiles, does it actually work?
- Migrate Tests: Translate the Baseline Tests from Phase 1 to the target language.
- Run Tests: Execute the new test suite against the new code.
- Analyze Failures:
- Do NOT change the tests (unless the API contract explicitly changed).
- Use the failure output (stack traces, expected vs. actual) to fix the Migrated Code.
- Repeat: Fix code -> Run Tests -> Check Failures.
- Success: The loop ends only when 100% of tests pass.
Once tests pass, the code is safe to improve. This is NOT optional for any change that introduces new classes, services, or modifies more than one file.
- Structural improvements: Apply Martin Fowler refactoring techniques (Extract Method, Extract Class, Replace Conditional with Polymorphism, etc.) to achieve clean architecture. Consult
GOF_PATTERNS.mdfor pattern applicability. - Compliance check: Verify the refactored code meets
CODING_STYLE.md(max 30-line methods, max 3 nesting levels, one type per file, Allman braces). - Idiomatic polish: Replace direct translations with language-specific features (e.g., changing a
forloop to a LINQ query or.map()). - Verify: Run tests after EACH refactoring step. If a test fails, revert the last change and investigate.
-
Phase 1:
- User asks to migrate
utils.js. - Agent Action: Check for
utils.test.js. If missing, create it. Runjest utils.test.jsto confirm it passes.
- User asks to migrate
-
Phase 2:
- Agent Action: Rename
utils.jstoutils.ts. Add type annotations (anyis acceptable temporarily if strictness causes blocks, but aim for specific types). - Run
tsc. Fix "Implicit any" or "Property does not exist" errors.
- Agent Action: Rename
-
Phase 3:
- Agent Action: Rename
utils.test.jstoutils.test.ts. - Run
jest. - Error: "Expected 5, got '5'".
- Fix: Update
utils.tsto ensure return type isnumber, not string.
- Agent Action: Rename
-
Phase 4:
- Agent Action: Change
interfacedefinitions to be more specific. Run tests. Pass.
- Agent Action: Change
- Pre-Flight: Are there passing tests for the legacy or existing code? Is coverage =90% for the affected area?
- Draft: Is the code translated or refactored?
- Compile: Does the build command succeed without errors or warnings?
- Verify: Do all tests (migrated and regression) pass against the new code?
- Refactor: Does the code follow
CODING_STYLE.md? Are GoF patterns applied where appropriate perGOF_PATTERNS.md? Are methods =30 lines? Are classes =500 lines of logic? - Cleanup: Did you remove temporary files, "commented out" legacy code, and orphaned imports?
- Commit: Single logical change per commit with conventional message (
refactor: ...,feat: ...,fix: ...).