Claude Code से सुरक्षित Refactoring Automation की व्यावहारिक प्रक्रिया
Claude Code refactoring workflow: before/after उदाहरण, tests, git diff review, pitfalls और copy-paste prompts.
पहले सुरक्षा सीमा तय करें
Claude Code से refactoring automation करते समय सबसे खतरनाक शुरुआत है: “पूरे codebase को clean कर दो”। यह तेज लग सकता है, लेकिन अक्सर बहुत बड़ा diff बनाता है जिसे ठीक से review करना मुश्किल हो जाता है। Refactoring का मतलब है code की internal structure सुधारना, लेकिन user, API, tests और external systems के behavior को न बदलना। अगर यह सीमा साफ नहीं है, तो automation अनजाने में feature change बन सकता है।
इस लेख में Claude Code को magic button नहीं, बल्कि practical teammate की तरह उपयोग करेंगे: पहले inspect, फिर छोटा plan, फिर एक focused change, फिर verification commands, और अंत में git diff की explanation। Official common workflows इस तरीके को समझने में मदद करते हैं। Command permissions और project configuration के लिए settings भी देखें।
अगर आपकी team अभी rules बना रही है, तो Claude Code permissions guide और Claude Code context management भी उपयोगी हैं। यहाँ focus daily workflow पर है: पहले क्या पूछना है, beginner के लिए कौन से refactor safe हैं, test कैसे करने हैं, और diff कैसे review करना है।
Masa की verification note: छोटे प्रयोगों में Claude Code ने rename, pure function extraction, TypeScript types स्पष्ट करने और regression tests जोड़ने में अच्छा काम किया। लेकिन “इस service को modern बना दो” जैसे broad prompt से diff बड़ा हो गया। Practical rule सरल है: छोटा scope, स्पष्ट tests, readable diff.
Safe workflow: inspect, plan, one diff, verify
जब तक team comfortable न हो, यह order रखें।
| Step | Claude Code क्या करता है | Human क्या check करता है |
|---|---|---|
| 1. Inspect | files, dependencies, tests पढ़ता है | scope बहुत बड़ा तो नहीं |
| 2. Plan | तीन step या कम का plan देता है | hidden behavior change तो नहीं |
| 3. Edit | सिर्फ एक theme बदलता है | diff reviewable है या नहीं |
| 4. Verify | test, typecheck, lint चलाता है | failure clearly explain हुआ या नहीं |
| 5. Review | git diff और risk summarize करता है | before/after behavior same है या नहीं |
सबसे पहले edit-free prompt दें।
इस repository में safe refactoring candidates inspect करें।
अभी कोई file edit न करें।
Conditions:
- External behavior change न करें
- एक diff अधिकतम 3 files
- existing tests वाले area को priority दें
- candidate, reason, verification command, risk वाली table दें
“अभी कोई file edit न करें” बहुत जरूरी है। Claude Code जल्दी read से edit mode में जा सकता है। Investigation और implementation अलग रखने से risk कम होता है।
Branch बनाकर baseline record करें।
git status --short
git checkout -b refactor/safe-extract-order-total
npm test
npm run typecheck
npm run lint
Commands को अपने package.json के अनुसार बदलें। अगर tests पहले से fail हैं, तो पहले note करें। वरना बाद में पता नहीं चलेगा कि failure पुराना था या refactor से आया।
Use case 1: नाम सुधारना और छोटी pure function निकालना
सबसे safe exercise है naming सुधारना और pure function extract करना। Pure function same input पर same output देती है और database update, email, API call या global state change नहीं करती। Claude Code के लिए यह अच्छा task है क्योंकि success condition testable है।
// before: src/domain/order.ts
export function calc(o: { items: { p: number; q: number }[]; d?: number }) {
let t = 0;
for (const i of o.items) {
t += i.p * i.q;
}
if (o.d) {
t = t - o.d;
}
return Math.max(t, 0);
}
Code छोटा है, पर p, q, d business meaning नहीं बताते। Claude Code से पहले tests जोड़ने, फिर names सुधारने को कहें।
src/domain/order.ts में calc function को safely refactor करें।
Requirements:
- Implementation बदलने से पहले current behavior lock करने वाले unit tests जोड़ें
- इस diff में exported name calc को न बदलें
- variable और type names readable बनाएं
- total negative न होने का rule preserve करें
- change के बाद npm test -- order चलाएं
Good after state:
// after: src/domain/order.ts
type OrderLine = {
price: number;
quantity: number;
};
type OrderInput = {
items: OrderLine[];
discount?: number;
};
export function calc(order: OrderInput): number {
const subtotal = order.items.reduce(
(sum, item) => sum + item.price * item.quantity,
0
);
return Math.max(subtotal - (order.discount ?? 0), 0);
}
Copy-paste test:
// src/domain/order.test.ts
import { describe, expect, it } from "vitest";
import { calc } from "./order";
describe("calc", () => {
it("multiplies price and quantity", () => {
expect(calc({ items: [{ price: 1200, quantity: 2 }] })).toBe(2400);
});
it("applies discount without returning a negative total", () => {
expect(calc({ items: [{ price: 500, quantity: 1 }], discount: 800 })).toBe(0);
});
});
Review commands:
git diff -- src/domain/order.ts src/domain/order.test.ts
npm test -- order
npm run typecheck
Review question यह नहीं है कि code smart दिख रहा है या नहीं। असली सवाल है: same input का business meaning same रहा या नहीं। Calculation, exported name और tests को देखें।
Use case 2: any हटाते समय boundary से शुरू करें
any कम करना अच्छा है, लेकिन पूरे project में एक साथ करना common mistake है। API response, form payload, config, webhook और imported rows जैसे boundary से शुरू करें। यहीं unknown data system में आता है।
// before: src/lib/user-api.ts
export async function fetchUser(id: string): Promise<any> {
const response = await fetch(`/api/users/${id}`);
return response.json();
}
export function getDisplayName(user: any): string {
return user.profile.displayName || user.name;
}
Prompt narrow रखें और missing data behavior लिखें।
src/lib/user-api.ts में any usage कम करें।
Requirements:
- API response के लिए type जोड़ें
- fetch URL और return meaning न बदलें
- profile missing होने पर getDisplayName safe रहे
- current display name behavior के tests जोड़ें
- npm test -- user-api और npm run typecheck चलाएं
Acceptable first diff:
// after: src/lib/user-api.ts
export type UserResponse = {
id: string;
name: string;
profile?: {
displayName?: string;
};
};
export async function fetchUser(id: string): Promise<UserResponse> {
const response = await fetch(`/api/users/${id}`);
return response.json() as Promise<UserResponse>;
}
export function getDisplayName(user: UserResponse): string {
return user.profile?.displayName ?? user.name;
}
यह cast runtime data validate नहीं करता। अगर runtime safety चाहिए, तो दूसरे diff में zod या existing parser जोड़ें। Beginner diff में “any हटाना” और “validation library जोड़ना” mix न करें।
// src/lib/user-api.test.ts
import { describe, expect, it } from "vitest";
import { getDisplayName, type UserResponse } from "./user-api";
describe("getDisplayName", () => {
it("uses profile displayName when present", () => {
const user: UserResponse = {
id: "u1",
name: "Masa",
profile: { displayName: "Masa I." },
};
expect(getDisplayName(user)).toBe("Masa I.");
});
it("falls back to name when profile is missing", () => {
expect(getDisplayName({ id: "u2", name: "Guest" })).toBe("Guest");
});
});
Review में dangerous shortcut देखें: as any, swallowed errors, empty string fallback, optional fields का changed meaning. Type-safe diff भी behavior तोड़ सकता है।
Use case 3: बड़ी function को tests के बाद split करें
Large service function tempting होती है, पर behavior अक्सर वहीं छिपा होता है। Orders, billing, permissions, notifications और import jobs में validation, calculation, persistence और side effects mix होते हैं। Claude Code से पहले सिर्फ एक pure calculation extract कराएं।
// before: src/services/order-service.ts
export async function createOrder(input: CreateOrderInput) {
if (input.items.length === 0) {
throw new Error("items required");
}
const subtotal = input.items.reduce((sum, item) => sum + item.price * item.quantity, 0);
const shippingFee = subtotal >= 10000 ? 0 : 800;
const total = subtotal + shippingFee;
const order = await db.order.create({
data: { userId: input.userId, subtotal, shippingFee, total },
});
await mailer.sendOrderCreated(order.id);
return order;
}
Prompt में out-of-scope भी लिखें।
src/services/order-service.ts में createOrder को छोटा करें।
इस diff में:
- सिर्फ shipping और total calculation को pure function में extract करें
- नाम calculateOrderTotals रखें
- calculateOrderTotals के unit tests जोड़ें
- database write और email order same रखें
इस diff में नहीं:
- DB schema change
- error message change
- API response shape change
- unrelated functions move
- पूरे file की formatting
After:
// after: src/services/order-service.ts
export function calculateOrderTotals(items: OrderItem[]) {
const subtotal = items.reduce(
(sum, item) => sum + item.price * item.quantity,
0
);
const shippingFee = subtotal >= 10000 ? 0 : 800;
return {
subtotal,
shippingFee,
total: subtotal + shippingFee,
};
}
Review:
git diff --stat
git diff -- src/services/order-service.ts
git diff -- src/services/order-service.test.ts
npm test -- order-service
अगर Claude Code unrelated formatting कर दे:
यह diff बहुत बड़ा है।
Formatting-only changes revert करें और सिर्फ calculateOrderTotals extraction plus tests रखें।
External behavior, error text, DB write, email order न बदलें।
git diff से review करें, feeling से नहीं
Claude Code की explanation helpful है, पर truth diff में है।
git diff --check
git diff --stat
git diff --name-only
git diff --word-diff -- src/domain/order.ts
| Area | क्या check करें |
|---|---|
| Behavior | inputs, outputs, exceptions, HTTP status, persistence order |
| Diff size | change एक human review में पढ़ा जा सके |
| Tests | existing behavior tests से protected हो |
| Types | नया as any, unsafe cast, ignored error न हो |
| Side effects | API, email, billing, delete, permission order same रहे |
| Summary | Claude Code summary actual diff से match करे |
Review prompt:
इस git diff को review करें।
Check:
- क्या change refactoring scope से बाहर गया?
- कौन सा behavior tests से protected नहीं है?
- unsafe casts या swallowed errors हैं?
- कौन सी files human को ध्यान से देखनी चाहिए?
Output:
- Looks safe
- Needs human confirmation
- Must fix
with file names and reasons.
Pitfall: common failure और risk
पहला failure है broad prompt।
इस service layer को cleaner बना दो।
इससे extraction, naming, error design, file move और formatting सब mix हो सकते हैं। Better:
createOrder से केवल shipping-fee calculation को pure function में extract करें।
Processing order, error message और return value न बदलें।
दूसरा risk है tests के बिना clean diff accept करना। Readability improve हो सकती है, पर discount, free shipping, permission denial, retry या null handling बदल सकते हैं। तीसरा mistake है formatting और structural refactoring को mix करना। Prettier अगर सैकड़ों lines बदल दे, तो real change छिप जाता है। चौथा risk है command permissions बहुत जल्दी खोलना। पहले read, test, typecheck, lint तक सीमित रखें।
Checklist और CTA
## Refactoring checklist
- [ ] Change का एक ही purpose है
- [ ] Baseline tests editing से पहले run हुए
- [ ] before/after behavior equivalent है
- [ ] New या existing tests behavior protect करते हैं
- [ ] git diff --stat reviewable है
- [ ] git diff --check pass है
- [ ] कोई नया any, unsafe cast, swallowed error नहीं
- [ ] DB, email, billing, delete, permission order same है
Final prompt:
एक safe refactoring diff execute करें।
Target:
- src/services/order-service.ts
- src/services/order-service.test.ts
Success criteria:
- External behavior नहीं बदलता
- calculateOrderTotals extract होता है
- Existing और added tests pass होते हैं
- git diff --stat और चलाए गए commands report करें
Forbidden:
- DB schema changes
- API response changes
- Error-message changes
- Unrelated file edits
मेरे verification में सबसे असरदार दो आदतें थीं: पहले no-edit plan मांगना, और implementation के अंत में git diff summary अनिवार्य करना। इसे Claude Code review checklist और CLAUDE.md best practices के साथ जोड़ें।
अगर आपकी team Claude Code को सुरक्षित तरीके से अपनाना चाहती है, तो Claude Code training में permissions, prompts, review rules और workflow design को साथ में व्यवस्थित किया जा सकता है। Refactoring automation की value बड़े diff में नहीं, बल्कि maintenance risk कम करने में है।
मुफ़्त PDF: Claude Code cheatsheet
Email डालें और commands, review habits तथा safe workflow वाली एक-page PDF पाएँ.
हम आपका data सुरक्षित रखते हैं और spam नहीं भेजते.
लेखक के बारे में
Masa
Claude Code workflow और team adoption पर काम करने वाला engineer.
संबंधित लेख
Claude Code Obsidian to CLAUDE.md workflow: context बार-बार न समझाएं
Obsidian notes को CLAUDE.md operating notes में बदलकर Claude Code sessions को resume करना आसान बनाएं.
Claude Code Revenue CTA Routing: article से PDF, Gumroad और consultation तक
Reader intent के आधार पर free PDF, Gumroad products और consultation तक CTA route करने वाला workflow.
Claude Code टीम हैंडऑफ नियम: review proof, permissions, rollback और revenue path
Claude Code टीम काम के लिए evidence, permission rules, rollback, free PDF, Gumroad और consultation path वाला handoff.