Skip to main content

migrate

[UDS] Guide systematic code migration, framework upgrades, and technology modernization. Use when: planning a framework or major-version upgrade, assessing migration risk, capturing contract-test fixtures before an API migration. Not for: in-place improvement that keeps the same framework — use /refactor; database schema design — use /database. Keywords: migration, framework upgrade, modernization, breaking change, dependency upgrade, 遷移, 升級, 技術現代化.

Quellinformationen

Repository
AsiaOstrich/universal-dev-standards
Letzte Quellaktivität
17. August 2026 um 06:20
Erkannte Sprache von SKILL.md
Mehrsprachig
Sterne
76
Forks
13

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
migrate
scope
universal
description
[UDS] Guide systematic code migration, framework upgrades, and technology modernization. Use when: planning a framework or major-version upgrade, assessing migration risk, capturing contract-test fixtures before an API migration. Not for: in-place improvement that keeps the same framework — use /refactor; database schema design — use /database. Keywords: migration, framework upgrade, modernization, breaking change, dependency upgrade, 遷移, 升級, 技術現代化.
allowed-tools
Read, Grep, Glob, Bash(npm:*, git:*)
argument-hint
[migration target or framework | 遷移目標或框架]
# Migration Assistant | 遷移助手 Guide systematic code migration, framework upgrades, and technology modernization. 引導系統性程式碼遷移、框架升級與技術現代化。 ## Usage | 使用方式 | Command | Purpose | 用途 | |---------|---------|------| | `/migrate` | Start interactive migration guide | 啟動互動式遷移引導 | | `/migrate --assess` | Risk assessment only | 僅風險評估 | | `/migrate "Vue 2 to 3"` | Guide specific migration | 引導特定遷移 | | `/migrate --deps` | Dependency upgrade analysis | 依賴升級分析 | | `/migrate --rollback` | Plan rollback strategy | 規劃回滾策略 | ## Migration Types | 遷移類型 | Type | Examples | Risk | 風險 | |------|----------|------|------| | **Framework Upgrade** | React 17→18, Vue 2→3, Angular 15→17 | Medium-High | 中高 | | **Language Migration** | JS→TS, Python 2→3, Java 8→17 | High | 高 | | **API Version** | REST v1→v2, GraphQL schema update | Medium | 中 | | **Database Migration** | MySQL→PostgreSQL, SQL→NoSQL | Very High | 極高 | | **Build Tool** | Webpack→Vite, Grunt→ESBuild | Low-Medium | 低中 | | **Package Manager** | npm→pnpm, pip→poetry | Low | 低 | ## Risk Assessment Matrix | 風險評估矩陣 | | Low Impact | Medium Impact | High Impact | |---|-----------|---------------|-------------| | **Low Complexity** | Safe (proceed) | Caution | Plan carefully | | **Medium Complexity** | Caution | Plan + test | Staged rollout | | **High Complexity** | Plan + test | Staged rollout | Full SDD spec | | | 低影響 | 中影響 | 高影響 | |---|--------|--------|--------| | **低複雜度** | 安全(直接進行) | 謹慎 | 仔細規劃 | | **中複雜度** | 謹慎 | 規劃 + 測試 | 分階段發布 | | **高複雜度** | 規劃 + 測試 | 分階段發布 | 完整 SDD 規格 | ## Workflow | 工作流程 1. **ASSESS** - Evaluate current state, identify breaking changes 2. **PLAN** - Create migration checklist with dependencies 3. **PREPARE** - Set up codemods, compatibility layers, feature flags 4. **MIGRATE** - Execute migration in phases with tests 5. **VERIFY** - Run full test suite, check for regressions 6. **CLEANUP** - Remove compatibility shims, old dependencies --- 1. **評估** - 評估現狀、識別破壞性變更 2. **規劃** - 建立含依賴關係的遷移清單 3. **準備** - 設定 codemods、相容層、功能旗標 4. **遷移** - 分階段執行遷移並測試 5. **驗證** - 執行完整測試套件、檢查回歸 6. **清理** - 移除相容層、舊依賴 ## API Migration Contract Tests | API 遷移合約測試 When migrating an API endpoint from one tech stack to another (PHP → .NET, Express → Spring, Python → Go), unit tests on the **new** implementation verify against the **new DTO** — they cannot catch fields that the legacy returned but the new implementation forgot. Missing fields, renamed fields, type drift, and top-level vs nested placement drift will silently survive into production and break the existing frontend that still expects the legacy shape. This is **NOT** caught by unit tests, integration tests, or code review alone. A real 2026-05-24 production incident shipped with 67/67 green tests and was discovered by the customer. 當 API endpoint 從一個技術棧遷至另一個(PHP → .NET、Express → Spring 等),對**新**實作的單元測試只驗證**新 DTO**——無法捕捉「舊版有但新版漏掉」「欄位 rename」「型別漂移」「頂層 vs nested 層級漂移」等問題。這些缺陷會靜默流入生產,導致前端(仍預期舊版回應 shape)失靈。 **僅靠單元測試、整合測試或 code review 無法防止**。2026-05-24 真實 PROD 事故:67/67 測試全綠流入正式環境,由客戶發現缺漏。 ### Mandatory rule | 強制規則 Every migrated API endpoint **MUST** ship with at least one contract test that compares the new implementation's response against a fixture captured from the legacy implementation. Structural equivalence (keys, types, placement), not value equality, is verified. 每個被遷移的 API endpoint **必須**至少有一份 contract test,比對新實作的 response 與從 legacy 捕獲的 fixture。驗證的是結構性等價(keys、type、層級位置),而非值等價。 ### Fixture capture protocol | Fixture 捕獲協議 **While legacy is still running (typical migration window) | Legacy 仍運行(典型遷移窗口):** ```bash # 1. Capture ≥3 representative inputs (happy path, edge case, empty result) curl -X POST $LEGACY_BASE/endpoint -d @input1.json \ > tests/fixtures/migration/endpoint/scenario1.json curl -X POST $LEGACY_BASE/endpoint -d @input2_empty.json \ > tests/fixtures/migration/endpoint/scenario2_empty.json curl -X POST $LEGACY_BASE/endpoint -d @input3_edge.json \ > tests/fixtures/migration/endpoint/scenario3_edge.json # 2. Scrub PII and volatile values (timestamps, generated IDs) jq 'walk(if type == "string" and test("@") then "redacted@example.com" else . end)' \ tests/fixtures/migration/endpoint/scenario1.json > tmp && mv tmp ... # 3. Commit fixtures git add tests/fixtures/migration/endpoint/ ``` **When legacy is already retired but source-readable | Legacy 已退役但 source 可讀:** - Trace through legacy source code, manually construct the expected response shape - Document each field's origin (SQL column, computed expression, hardcoded) in a sibling `.notes.md` file - 從 legacy source code 推導預期 response shape;每個欄位來源(SQL 欄位 / 計算式 / hardcoded)記錄於同位置 `.notes.md` ### Contract test template **C# / xUnit:** ```csharp [Theory] [InlineData("scenario1")] [InlineData("scenario2_empty")] [InlineData("scenario3_edge")] public async Task Endpoint_ResponseShape_MatchesLegacyFixture(string scenario) { var fixture = LoadFixture($"migration/endpoint/{scenario}"); var response = await CallNewImpl(fixture.Input); // StructuralEquivalence checks keys + types + placement, ignores values StructuralEquivalence.Assert(response, fixture.ExpectedShape); } ``` **TypeScript / Jest:** ```typescript import { structuralEquivalence } from "./test-utils/structural-equivalence"; describe.each([ ["scenario1"], ["scenario2_empty"], ["scenario3_edge"], ])("Endpoint response shape vs legacy fixture (%s)", (scenario) => { test("matches", async () => { const fixture = loadFixture(`migration/endpoint/${scenario}.json`); const response = await callNewImpl(fixture.input); structuralEquivalence(response, fixture.expectedShape); }); }); ``` `structuralEquivalence` / `StructuralEquivalence.Assert` rule: same set of keys at each level (no missing, no extra unless explicitly opted in), same primitive type per key, same placement (top-level vs nested). Values can differ (timestamps, IDs); types and structure cannot. ### Field-by-field migration audit checklist Before merging any migrated endpoint: - [ ] All legacy response fields mapped to new DTO (no silent drops) - [ ] Naming preserved where possible (avoid `TotalX` rename that drops the "per-member" semantic) - [ ] Top-level vs nested placement preserved - [ ] Type compatibility verified (string→int conversions explicit, not coincidental) - [ ] Error path return codes match legacy (`509` not `506`; `404` not `400`) - [ ] Contract test fixture committed under `tests/fixtures/migration/` - [ ] Cross-link to [contract-test-assistant](../contract-test-assistant/SKILL.md) for ongoing consumer-side verification 合併前必確認: - [ ] 所有 legacy response 欄位 mapping 至新 DTO(無 silent drop) - [ ] 命名儘量保留 - [ ] 頂層 vs nested 層級保留 - [ ] 型別相容性已明確驗證 - [ ] Error path return code 與 legacy 一致 - [ ] Contract test fixture 已 commit - [ ] Cross-link 至 contract-test-assistant 做持續消費端驗證 ## Post-Cutover Data Reconciliation | Cutover 後生產資料對帳 > **Implements**: XSPEC-284 R2 (axis ③ persisted-data semantics) / closes UDS issue [#134](https://github.com/AsiaOstrich/universal-dev-standards/issues/134). Contract tests (above) and `behavior-snapshot` catch **interface** divergence but are blind to **persisted-data semantic** divergence. Two blind spots both share: 1. **You can only assert what you thought to enumerate.** The rules that actually ship broken are the *implicit, undocumented* ones — especially the semantics of a persisted field (when is it non-zero? when is it overwritten?). Nobody writes a scenario for a rule they don't know exists. 2. **Per-request parity ≠ data-at-rest parity.** A field written by an **asynchronous** process (delivery-receipt sync, settlement job, status reconciler) against a live external provider is not a deterministic request you can replay. Its correctness only emerges in **aggregate over real production volume**, not in a single happy-path snapshot. Contract test 與 `behavior-snapshot`只能捕捉**介面**分歧,對**持久化資料語義**分歧視而不見。兩者共有兩個盲區:(1) 你只能驗證你想得到要列舉的規則——真正出包的永遠是沒人寫下來的隱含規則(某欄位何時非零、何時被覆寫);(2) per-request parity ≠ data-at-rest parity——由**非同步**程序(DR sync、結算批次、狀態對帳器)對 live 外部供應商寫入的欄位,不是可重放的確定性請求,其正確性只在**真實生產量的聚合**中浮現。 ### Failure fingerprint | 事故指紋(#134) 某企業 SMS 平台 PHP→.NET 重寫:每筆金額由**非同步** DR sync 覆寫(`record.Cost = gatewayDr.Cost`)。legacy 對 carrier-failure 仍計費,rewrite 寫 gateway 回報的 `0` → cutover 邊界兩側同一失敗狀態的金額分歧。**所有既有 gate 全部漏接**(response shape 相同 → contract test 過;無人 curated「失敗仍計費」場景;欄位由背景作業對 live gateway 寫入 → 不可重放)。最後靠 ops 跑生產 `SUM(cost) GROUP BY status, day` 跨邊界彙總才發現。**單日抽樣甚至誤判「失敗不計費=正常」**——只有跨 cutover 邊界的多週聚合才揭露真相。 ### Mandatory rule | 強制規則 When a migration loads legacy data into the **same store** as new data, the old/new boundary is a **free differential oracle**. For each business-critical persisted field you **MUST**: - Define **aggregate reconciliation invariants** comparing the distribution of **legacy-origin vs new-origin** rows along key dimensions (e.g. `SUM(money) / COUNT(*) GROUP BY status, period`). - Run them **on a schedule against production** and alert when divergence exceeds a declared tolerance. - Investigate over a **multi-week window spanning the cutover** — never a single-day sample (a sampled check can confirm a *wrong* conclusion). 當 migration 將 legacy 資料載入與 new 相同的**儲存**,新舊邊界即是**免費差分神諭**。對每個 business-critical 持久化欄位**必須**:定義聚合對帳不變量(比對 legacy-origin vs new-origin 列沿關鍵維度的分佈)、對生產**排程執行**並於分歧超過宣告容差時告警、以跨 cutover 的**多週窗口**調查(切忌單日抽樣,抽樣可能坐實錯誤結論)。 ### Cutover-boundary reconciliation SQL template | 對帳 SQL 模板 ```sql -- Reconcile a money/state field across the migration cutover boundary. SELECT status, SUM(CASE WHEN created < @cutover THEN 1 ELSE 0 END) AS legacy_rows, SUM(CASE WHEN created < @cutover AND money_field > 0 THEN 1 ELSE 0 END) AS legacy_nonzero, SUM(CASE WHEN created >= @cutover THEN 1 ELSE 0 END) AS new_rows, SUM(CASE WHEN created >= @cutover AND money_field > 0 THEN 1 ELSE 0 END) AS new_nonzero FROM records GROUP BY status; -- Invariant: nonzero-ratio per status must not differ across the boundary beyond tolerance. ``` ### Tolerance & alerting guidance | 容差與告警指引 | Aspect | Guidance | 指引 | |--------|----------|------| | **Invariant type** | nonzero-ratio / `SUM` / `COUNT` / `DISTINCT` / checksum per `GROUP BY status, period` | 每維度的非零比率 / 聚合相等 / checksum | | **Tolerance** | Declare per field; 0% for hard accounting invariants, a small ε only for known legitimate drift (e.g. rounding) | 逐欄宣告;硬會計不變量 0%,僅已知合法漂移容許小 ε | | **Window** | Multi-week, spanning cutover; bucket by `period` to localise the boundary | 多週、橫跨 cutover;以 `period` 分桶定位邊界 | | **Schedule** | Standing post-cutover cron (daily) until boundary rows age out of active reporting | post-cutover 排程(每日)直到邊界列退出活躍報表 | | **Alert** | Page on divergence > tolerance; route via `observability-assistant` alert rules | 分歧超過容差即告警;經 `observability-assistant` 告警規則路由 | ### Gate 0 — Implicit-rule capture for persisted business fields | 隱含規則擷取 Before migrating any feature that writes a persisted business field, **explicitly answer for each such field** three questions, then lock the answer as a snapshot scenario **or** a reconciliation invariant: > 1. **When is this value SET?** 何時設值? > 2. **When is it OVERWRITTEN?** 何時被覆寫?(尤其非同步路徑) > 3. **When is it ZEROED / nulled?** 何時歸零/清空? **High-risk implicit-rule checklist** — empirically recurring fingerprints | 高風險隱含規則檢查清單(經驗反覆出現的指紋): - [ ] **Billing / charge semantics** — charged on submit vs on delivery; refund-on-failure? | 計費語義(提交時計費 vs 送達時計費;失敗退費?) - [ ] **Enum / status-code mapping** — every legacy code mapped; "success set" defined identically | 列舉/狀態碼對映(每個 legacy 碼都對映;「成功集合」定義一致) - [ ] **Null / empty handling** — empty string vs null vs absent; default-on-missing | 空值處理(空字串 vs null vs 不存在;缺值預設) - [ ] **Field-name casing / serialization** — snake_case vs camelCase binding | 欄位命名大小寫/序列化(snake_case vs camelCase 綁定) - [ ] **Timezone** — stored UTC vs local; report boundaries | 時區(存 UTC vs local;報表邊界) - [ ] **Rounding / type coercion** — `"2.00"` (text) parsed as int → dropped to 0 | 四捨五入/型別強轉(`"2.00"` 文字被當 int 解析 → 掉成 0) ### 3-gate positioning | 3-gate 定位表 Make the boundary between gates explicit so each axis has an owner and nothing falls into the seam: | Gate | Scope | When | 範圍 / 時機 | |------|-------|------|------| | [`behavior-snapshot`](../../core/behavior-snapshot.md) | per-request, **curated** scenarios | pre-UAT CI | per-request、人工 curated 場景;pre-UAT CI | | Contract tests (above / #112) | response **shape** (keys / types / placement) | unit / integration | response shape(keys/型別/層級);單元/整合 | | **This section (#134)** | **aggregate, data-at-rest semantics of async-written fields, over real volume** | **post-cutover, scheduled, production** | **非同步寫入欄位的聚合、靜態資料語義,跨真實量;post-cutover 排程生產** | > Cross-ref: [`behavior-snapshot`](../../core/behavior-snapshot.md) (curated golden masters), [`observability-assistant`](../observability-assistant/SKILL.md) (reconciliation schedule + alert templates). ## Background Job / Side-Effect Completeness | 背景作業/副作用完整性 > **Implements**: XSPEC-284 R3 (axis ⑤). Migration inventories (`/vo-inventory`, XSPEC-200 `type:background_job`) and Devil's-Advocate grep (XSPEC-201 Step 4) **annotate** cron / queue consumers / scheduled batches / webhooks / mail-send points — but annotation alone proves nothing. A background job can be listed in the manifest, exist in code, and still **never actually run** in the new system. 遷移清單與副作用 grep 只是**標注**背景作業——標注本身不證明任何事。背景作業可能在 manifest 列出、程式碼存在,卻在新系統**從未真正執行**。 ### Mandatory rule | 強制規則 For every background side-effect carried over from legacy, verify **two** things — annotation is not enough: | Check | Pre-flight | Post-cutover | |-------|-----------|--------------| | **(a) Exists** — the cron / queue consumer / webhook / mail point is implemented in the new system | source grep + registration check | — |
Auf GitHub ansehen
Diese SKILL.md ist sehr gross, daher zeigt SkillsMP hier nur den ersten Abschnitt. Auf GitHub ansehen