From zenbu-powers
React IT Stage 5:重構階段。在測試保護下改善程式碼品質,小步前進, 嚴格遵守 /aibdd.auto.ts.it.code-quality 規範。 當 /aibdd.auto.ts.it.control-flow 呼叫重構階段,或使用者說「重構」「refactor」時觸發。
npx claudepluginhub zenbuapps/zenbu-powers --plugin zenbu-powersThis skill uses the workspace's default tool permissions.
在測試保護下,小步驟改善程式碼品質。
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Checks Next.js compilation errors using a running Turbopack dev server after code edits. Fixes actionable issues before reporting complete. Replaces `next build`.
Guides code writing, review, and refactoring with Karpathy-inspired rules to avoid overcomplication, ensure simplicity, surgical changes, and verifiable success criteria.
Share bugs, ideas, or general feedback.
在測試保護下,小步驟改善程式碼品質。
接收 FEATURE_FILE 參數,直接進入重構流程。
詢問目標範圍(特定 Feature 或全域),確認綠燈後進入重構流程。
執行測試(確認綠燈)
│
▼
【Phase A】重構測試碼(test files / helpers / factories)
│
▼
執行測試(確認仍然綠燈)
│
▼
【Phase B】重構產品碼(components / hooks / utils / api client)
│
▼
執行測試(確認仍然綠燈)
│
▼
完成
關鍵:Phase 順序不可顛倒。每個 Phase 結束跑測試,Phase 內每次小步驟也跑測試。
npx vitest run,失敗立即還原src/__tests__/**/*.integration.test.tsx(測試檔)src/test/helpers/**/*.ts(x)(render helper, user-event helper, msw-utils)src/test/factories/**/*.ts(test data factories)src/test/mocks/**/*.ts(MSW handlers, server)// 重構前
it('進度從 70% 更新到 80%', async () => {
// TODO: [States Prepare: aggregate-given] MSW handler for LessonProgress
// TODO: [Operation Invocation: command] user-event
// ...
});
// 重構後
it('進度從 70% 更新到 80%', async () => {
// 前置狀態:Alice 在課程 1 的進度為 70%
server.use(...);
// 使用者互動:填寫 80, 點擊更新
// ...
});
抽取重複 MSW setup → 提升到 beforeEach 或 factory
改善查詢選擇器 → getByText('submit') → getByRole('button', { name: /送出/i })
類型標註完整 → const requestRef = captureMswRequest(...) 確保泛型明確
src/app/**/*.tsx(頁面 / layout)src/components/**/*.tsx(React 元件)src/hooks/**/*.ts(自定義 hooks)src/lib/api/**/*.ts(API client functions)src/lib/types/**/*.ts(Zod schemas)// 重構前
export default function LessonProgressPage({ params }) {
const { data, isPending } = useQuery({
queryKey: ['lesson-progress', params.id],
queryFn: () => getLessonProgress(Number(params.id)),
});
const mutation = useMutation({ ... });
// ...
}
// 重構後
function useLessonProgress(lessonId: number) {
const query = useQuery({ ... });
const mutation = useMutation({ ... });
return { ...query, update: mutation.mutate };
}
export default function LessonProgressPage({ params }) {
const { data, isPending, update } = useLessonProgress(Number(params.id));
// ...
}
// 重構前:一個 Component 處理 display + form + validation
export default function LessonProgressPage() {
return <div>{/* 100+ lines */}</div>;
}
// 重構後:職責分離
export default function LessonProgressPage({ params }) {
return (
<>
<ProgressDisplay lessonId={Number(params.id)} />
<ProgressUpdateForm lessonId={Number(params.id)} />
</>
);
}
// 重構前
function Component({ data }) {
if (data) {
if (data.isValid) {
return <div>{data.content}</div>;
}
}
return null;
}
// 重構後
function Component({ data }: { data: Data | null }) {
if (!data) return null;
if (!data.isValid) return null;
return <div>{data.content}</div>;
}
型別加強 → 移除 any,改用 Zod infer
命名清晰 → process → updateVideoProgress
# 每次重構後必須執行
npx vitest run
# 特定測試檔(快速迭代)
npx vitest run src/__tests__/{feature-slug}.integration.test.tsx
# 型別檢查
npx tsc --noEmit
# Linter
npx eslint src/
npx tsc --noEmit 通過npx eslint src/ 通過(或僅剩無害警告)act(...) warnings、無 MSW unhandled request)完整 React IT 程式碼品質規範詳見 /zenbu-powers:aibdd.auto.ts.it.code-quality。核心面向:
getByRole > getByTestId、userEvent > fireEvent)any)