cursor-quality-suite 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +155 -0
- package/bin/cli.js +303 -0
- package/commands/code-quality/churn-map.md +431 -0
- package/commands/code-quality/code-standards.md +219 -0
- package/commands/code-quality/pattern-drift.md +295 -0
- package/commands/code-quality/visualize-architecture.md +464 -0
- package/commands/testing/mutation-audit.md +229 -0
- package/commands/testing/risk-test-gen.md +232 -0
- package/commands/testing/write-unit-tests.md +42 -0
- package/package.json +36 -0
|
@@ -0,0 +1,431 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Analyze git history to find high-churn files, hotspots, technical debt interest, and refactor candidates
|
|
3
|
+
category: Context & Analysis
|
|
4
|
+
aliases: [churn, hotspots, change-analysis, tech-debt]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Churn Map - Analyze File Change Patterns
|
|
8
|
+
|
|
9
|
+
Analyze file churn to identify hotspots, stable cores, **technical debt interest rate**, and refactor candidates.
|
|
10
|
+
|
|
11
|
+
**Make refactoring discussions data-driven, not emotional.**
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
/churn-map {PATH}
|
|
17
|
+
/churn-map {PATH} --last=6mo
|
|
18
|
+
/churn-map {PATH} --compare=3mo,6mo,12mo # Show trends
|
|
19
|
+
/churn-map {PATH} --debt-rate # Technical debt interest analysis
|
|
20
|
+
/churn-map --repo # Full repo analysis
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Examples
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
/churn-map src/features/checkout
|
|
27
|
+
/churn-map src/components --last=3mo
|
|
28
|
+
/churn-map src/features/checkout/src/components --compare=3mo,6mo
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## What This Produces
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
════════════════════════════════════════════════════════════════
|
|
35
|
+
CHURN MAP: src/features/checkout (Last 6 Months)
|
|
36
|
+
════════════════════════════════════════════════════════════════
|
|
37
|
+
|
|
38
|
+
📊 SUMMARY
|
|
39
|
+
Total files analyzed: 234
|
|
40
|
+
Total commits: 1,847
|
|
41
|
+
Unique authors: 23
|
|
42
|
+
Average commits/file: 7.9
|
|
43
|
+
|
|
44
|
+
════════════════════════════════════════════════════════════════
|
|
45
|
+
🔴 HIGH CHURN (Top 10 Hotspots)
|
|
46
|
+
════════════════════════════════════════════════════════════════
|
|
47
|
+
|
|
48
|
+
| Rank | File | Commits | Authors | Churn Score |
|
|
49
|
+
|------|------|---------|---------|-------------|
|
|
50
|
+
| 1 | MainWithBooking.tsx | 145 | 12 | 🔥 Critical |
|
|
51
|
+
| 2 | BookingDetails.tsx | 128 | 8 | 🔥 Critical |
|
|
52
|
+
| 3 | PackagesV2.tsx | 89 | 6 | 🔥 Critical |
|
|
53
|
+
| 4 | helpers.ts | 67 | 5 | ⚠️ High |
|
|
54
|
+
| 5 | useCheckoutState.ts | 54 | 7 | ⚠️ High |
|
|
55
|
+
| 6 | PaymentForm.tsx | 48 | 4 | ⚠️ High |
|
|
56
|
+
| 7 | ProtectionPackageCard.tsx | 42 | 5 | ⚠️ High |
|
|
57
|
+
| 8 | CoverageAndAddOns.tsx | 38 | 4 | ⚠️ High |
|
|
58
|
+
| 9 | VehicleSelection.tsx | 35 | 3 | 🟡 Medium |
|
|
59
|
+
| 10 | types/index.ts | 32 | 6 | 🟡 Medium |
|
|
60
|
+
|
|
61
|
+
Recommendation: Files with 🔥 Critical churn are candidates for:
|
|
62
|
+
- /migration-plan (structured decomposition)
|
|
63
|
+
- /refactor-new --churn-aware (prioritized refactoring)
|
|
64
|
+
|
|
65
|
+
════════════════════════════════════════════════════════════════
|
|
66
|
+
🟢 STABLE CORE (Bottom 10 - Don't Touch)
|
|
67
|
+
════════════════════════════════════════════════════════════════
|
|
68
|
+
|
|
69
|
+
| Rank | File | Commits | Last Changed | Status |
|
|
70
|
+
|------|------|---------|--------------|--------|
|
|
71
|
+
| 1 | constants.ts | 2 | 5 months ago | 🛡️ Stable |
|
|
72
|
+
| 2 | Layout.tsx | 3 | 4 months ago | 🛡️ Stable |
|
|
73
|
+
| 3 | theme.ts | 4 | 3 months ago | 🛡️ Stable |
|
|
74
|
+
| 4 | ErrorBoundary.tsx | 3 | 6 months ago | 🛡️ Stable |
|
|
75
|
+
| 5 | useMediaQuery.ts | 5 | 4 months ago | 🛡️ Stable |
|
|
76
|
+
|
|
77
|
+
⚠️ Warning: Touching stable files increases risk.
|
|
78
|
+
These files rarely change because they work well.
|
|
79
|
+
Refactoring here requires strong justification.
|
|
80
|
+
|
|
81
|
+
════════════════════════════════════════════════════════════════
|
|
82
|
+
📈 CHURN TRENDS
|
|
83
|
+
════════════════════════════════════════════════════════════════
|
|
84
|
+
|
|
85
|
+
MainWithBooking.tsx:
|
|
86
|
+
Last 3 months: 45 commits ████████████████████
|
|
87
|
+
Previous 3mo: 62 commits ██████████████████████████████
|
|
88
|
+
Trend: ↓ Decreasing (-27%) ✅
|
|
89
|
+
|
|
90
|
+
BookingDetails.tsx:
|
|
91
|
+
Last 3 months: 58 commits ██████████████████████████
|
|
92
|
+
Previous 3mo: 42 commits ██████████████████
|
|
93
|
+
Trend: ↑ Increasing (+38%) ⚠️
|
|
94
|
+
|
|
95
|
+
PackagesV2.tsx:
|
|
96
|
+
Last 3 months: 52 commits ████████████████████████
|
|
97
|
+
Previous 3mo: 37 commits █████████████████
|
|
98
|
+
Trend: ↑ Increasing (+41%) ⚠️
|
|
99
|
+
|
|
100
|
+
════════════════════════════════════════════════════════════════
|
|
101
|
+
🎯 REFACTOR CANDIDATES
|
|
102
|
+
════════════════════════════════════════════════════════════════
|
|
103
|
+
|
|
104
|
+
Based on churn analysis, prioritize these refactors:
|
|
105
|
+
|
|
106
|
+
1. 🔴 MainWithBooking.tsx (770 lines, 145 commits)
|
|
107
|
+
Problem: Too many responsibilities
|
|
108
|
+
Suggested: Split into route + providers + steps
|
|
109
|
+
ROI: High (reduces merge conflicts significantly)
|
|
110
|
+
|
|
111
|
+
2. 🔴 BookingDetails.tsx (1,148 lines, 128 commits)
|
|
112
|
+
Problem: God component, increasing churn
|
|
113
|
+
Suggested: Extract sections into sub-components
|
|
114
|
+
ROI: Very High (biggest pain point)
|
|
115
|
+
|
|
116
|
+
3. 🟠 PackagesV2.tsx (450 lines, 89 commits)
|
|
117
|
+
Problem: Mixed concerns, growing complexity
|
|
118
|
+
Suggested: Extract package-specific logic to hooks
|
|
119
|
+
ROI: Medium-High
|
|
120
|
+
|
|
121
|
+
Run: /migration-plan to generate detailed refactor plans
|
|
122
|
+
|
|
123
|
+
════════════════════════════════════════════════════════════════
|
|
124
|
+
💰 ROI ESTIMATION (Data-Driven Justification)
|
|
125
|
+
════════════════════════════════════════════════════════════════
|
|
126
|
+
|
|
127
|
+
## Refactoring Investment Analysis
|
|
128
|
+
|
|
129
|
+
| File | Refactor Effort | Maintenance Saved | Payback | ROI |
|
|
130
|
+
|------|-----------------|-------------------|---------|-----|
|
|
131
|
+
| BookingDetails.tsx | 24h | 8h/month | 3 months | 📈 300% |
|
|
132
|
+
| MainWithBooking.tsx | 16h | 5h/month | 3.2 months | 📈 275% |
|
|
133
|
+
| PackagesV2.tsx | 8h | 2h/month | 4 months | 📈 200% |
|
|
134
|
+
|
|
135
|
+
## Calculation Methodology
|
|
136
|
+
|
|
137
|
+
### Maintenance Cost (Current State)
|
|
138
|
+
Based on 6-month churn analysis:
|
|
139
|
+
|
|
140
|
+
| File | Merge Conflicts | Debug Time | PR Revisions | Monthly Cost |
|
|
141
|
+
|------|-----------------|------------|--------------|--------------|
|
|
142
|
+
| BookingDetails.tsx | 12/mo | 4h/mo | 3/mo | ~8h |
|
|
143
|
+
| MainWithBooking.tsx | 8/mo | 3h/mo | 2/mo | ~5h |
|
|
144
|
+
| PackagesV2.tsx | 4/mo | 1h/mo | 1/mo | ~2h |
|
|
145
|
+
|
|
146
|
+
### Refactoring Investment
|
|
147
|
+
| File | Analysis | Implementation | Testing | Review | Total |
|
|
148
|
+
|------|----------|----------------|---------|--------|-------|
|
|
149
|
+
| BookingDetails.tsx | 4h | 12h | 4h | 4h | 24h |
|
|
150
|
+
| MainWithBooking.tsx | 2h | 10h | 2h | 2h | 16h |
|
|
151
|
+
| PackagesV2.tsx | 1h | 4h | 2h | 1h | 8h |
|
|
152
|
+
|
|
153
|
+
### 12-Month Projection
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
BookingDetails.tsx:
|
|
158
|
+
Refactor cost: 24 hours
|
|
159
|
+
Maintenance saved: 8h × 12 = 96 hours
|
|
160
|
+
Net savings: 72 hours ✅
|
|
161
|
+
|
|
162
|
+
MainWithBooking.tsx:
|
|
163
|
+
Refactor cost: 16 hours
|
|
164
|
+
Maintenance saved: 5h × 12 = 60 hours
|
|
165
|
+
Net savings: 44 hours ✅
|
|
166
|
+
|
|
167
|
+
PackagesV2.tsx:
|
|
168
|
+
Refactor cost: 8 hours
|
|
169
|
+
Maintenance saved: 2h × 12 = 24 hours
|
|
170
|
+
Net savings: 16 hours ✅
|
|
171
|
+
|
|
172
|
+
TOTAL ANNUAL SAVINGS: 132 hours (~3.3 weeks developer time)
|
|
173
|
+
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Business Impact
|
|
177
|
+
|
|
178
|
+
| Metric | Before Refactor | After (Projected) |
|
|
179
|
+
|--------|-----------------|-------------------|
|
|
180
|
+
| Avg PR merge time | 2.3 days | 1.1 days |
|
|
181
|
+
| Merge conflicts/week | 8 | 2 |
|
|
182
|
+
| Regression rate | 12% | 4% |
|
|
183
|
+
| Onboarding time | 3 weeks | 1.5 weeks |
|
|
184
|
+
|
|
185
|
+
### Executive Summary
|
|
186
|
+
|
|
187
|
+
> **Investment:** 48 engineering hours (1 week)
|
|
188
|
+
> **Return:** 132 hours saved annually
|
|
189
|
+
> **Payback Period:** ~3 months
|
|
190
|
+
> **ROI:** 275%
|
|
191
|
+
|
|
192
|
+
Recommendation: ✅ Prioritize BookingDetails.tsx refactoring in next sprint
|
|
193
|
+
|
|
194
|
+
════════════════════════════════════════════════════════════════
|
|
195
|
+
📉 TECHNICAL DEBT INTEREST RATE
|
|
196
|
+
════════════════════════════════════════════════════════════════
|
|
197
|
+
|
|
198
|
+
## What is Technical Debt Interest Rate?
|
|
199
|
+
|
|
200
|
+
The "interest" you pay on technical debt is the ongoing cost of NOT refactoring:
|
|
201
|
+
- Extra time on every PR touching that file
|
|
202
|
+
- Merge conflicts
|
|
203
|
+
- Debugging time
|
|
204
|
+
- Onboarding friction
|
|
205
|
+
- Regression fixes
|
|
206
|
+
|
|
207
|
+
## Debt Interest Calculation
|
|
208
|
+
|
|
209
|
+
### Per-File Interest Rate
|
|
210
|
+
|
|
211
|
+
| File | Change Freq | Avg PR Time | Conflict Rate | Interest/Month |
|
|
212
|
+
|------|-------------|-------------|---------------|----------------|
|
|
213
|
+
| BookingDetails.tsx | 21/mo | +2.1 days | 38% | **8.4 dev-hours** |
|
|
214
|
+
| MainWithBooking.tsx | 18/mo | +1.8 days | 32% | **6.2 dev-hours** |
|
|
215
|
+
| PackagesV2.tsx | 14/mo | +0.9 days | 18% | **3.1 dev-hours** |
|
|
216
|
+
| helpers.ts | 11/mo | +0.5 days | 12% | **1.8 dev-hours** |
|
|
217
|
+
|
|
218
|
+
### Formula
|
|
219
|
+
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Debt Interest = (Change Frequency × Extra PR Time) + (Conflict Rate × Conflict Resolution Time)
|
|
223
|
+
|
|
224
|
+
Where:
|
|
225
|
+
|
|
226
|
+
- Change Frequency = commits/month
|
|
227
|
+
- Extra PR Time = time above baseline for files of similar size
|
|
228
|
+
- Conflict Rate = % of merges with conflicts
|
|
229
|
+
- Resolution Time = avg time to resolve conflicts
|
|
230
|
+
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Aggregate Debt Interest
|
|
234
|
+
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
════════════════════════════════════════════════════════════════
|
|
238
|
+
TOP 10 DEBT INTEREST PAYERS
|
|
239
|
+
════════════════════════════════════════════════════════════════
|
|
240
|
+
|
|
241
|
+
│ Rank │ File │ Interest/Month │ Annual Cost │
|
|
242
|
+
│------│-----------------------│----------------|-------------|
|
|
243
|
+
│ 1 │ BookingDetails.tsx │ 8.4 hours │ 100.8 hours │
|
|
244
|
+
│ 2 │ MainWithBooking.tsx │ 6.2 hours │ 74.4 hours │
|
|
245
|
+
│ 3 │ PackagesV2.tsx │ 3.1 hours │ 37.2 hours │
|
|
246
|
+
│ 4 │ helpers.ts │ 1.8 hours │ 21.6 hours │
|
|
247
|
+
│ 5 │ useCheckoutState.ts │ 1.5 hours │ 18.0 hours │
|
|
248
|
+
│------│-----------------------│----------------|-------------|
|
|
249
|
+
│ │ TOTAL TOP 5 │ 21.0 hours/mo │ 252 hours │
|
|
250
|
+
│ │ (Equivalent) │ (~3 dev-days) │ (~6 weeks) │
|
|
251
|
+
════════════════════════════════════════════════════════════════
|
|
252
|
+
|
|
253
|
+
Annual cost of NOT refactoring top 5 files: ~6 weeks of dev time
|
|
254
|
+
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### Debt Payoff Analysis
|
|
258
|
+
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
262
|
+
│ REFACTOR vs CONTINUE PAYING INTEREST │
|
|
263
|
+
├─────────────────────────────────────────────────────────────┤
|
|
264
|
+
│ │
|
|
265
|
+
│ BookingDetails.tsx │
|
|
266
|
+
│ ├── Current debt interest: 8.4 hours/month │
|
|
267
|
+
│ ├── Refactor investment: 24 hours (one-time) │
|
|
268
|
+
│ ├── Post-refactor interest: ~1.2 hours/month │
|
|
269
|
+
│ ├── Monthly savings: 7.2 hours │
|
|
270
|
+
│ └── Payback period: 3.3 months │
|
|
271
|
+
│ │
|
|
272
|
+
│ RECOMMENDATION: ✅ Refactor NOW │
|
|
273
|
+
│ Every month delayed = 7.2 hours wasted │
|
|
274
|
+
│ │
|
|
275
|
+
└─────────────────────────────────────────────────────────────┘
|
|
276
|
+
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Velocity Impact
|
|
280
|
+
|
|
281
|
+
How debt affects team velocity:
|
|
282
|
+
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
│ Metric │ Current │ Post-Refactor │ Improvement │
|
|
286
|
+
│---------------------------│---------|---------------|-------------|
|
|
287
|
+
│ Avg PR merge time │ 2.3 days│ 1.1 days │ -52% │
|
|
288
|
+
│ Merge conflicts/week │ 8 │ 2 │ -75% │
|
|
289
|
+
│ Regression rate │ 12% │ 4% │ -67% │
|
|
290
|
+
│ New dev onboarding │ 3 weeks │ 1.5 weeks │ -50% │
|
|
291
|
+
│ Time to first PR │ 5 days │ 2 days │ -60% │
|
|
292
|
+
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
════════════════════════════════════════════════════════════════
|
|
296
|
+
👥 AUTHOR CONCENTRATION
|
|
297
|
+
════════════════════════════════════════════════════════════════
|
|
298
|
+
|
|
299
|
+
Files with single-author concentration (bus factor risk):
|
|
300
|
+
|
|
301
|
+
| File | Primary Author | % of Commits |
|
|
302
|
+
|------|----------------|--------------|
|
|
303
|
+
| PaymentFlow.tsx | @dev-1 | 78% ⚠️ |
|
|
304
|
+
| usePaymentState.ts | @dev-1 | 85% ⚠️ |
|
|
305
|
+
| CheckoutTracking.ts | @dev-2 | 92% ⚠️ |
|
|
306
|
+
|
|
307
|
+
Recommendation: Schedule knowledge sharing for these files.
|
|
308
|
+
|
|
309
|
+
════════════════════════════════════════════════════════════════
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
## Churn Scoring
|
|
313
|
+
|
|
314
|
+
| Score | Commits/6mo | Authors | Action |
|
|
315
|
+
| ----------- | ----------- | ------- | ---------------------------- |
|
|
316
|
+
| 🔥 Critical | >100 | >5 | Immediate refactor candidate |
|
|
317
|
+
| ⚠️ High | 50-100 | 3-5 | Consider refactoring |
|
|
318
|
+
| 🟡 Medium | 20-50 | 2-4 | Monitor |
|
|
319
|
+
| 🟢 Low | <20 | 1-2 | Stable, protect |
|
|
320
|
+
| 🛡️ Stable | <5 | any | Core, don't touch |
|
|
321
|
+
|
|
322
|
+
## Commands Used
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
# Get commit count per file
|
|
326
|
+
git log --since="6 months ago" --name-only --pretty=format: | \
|
|
327
|
+
sort | uniq -c | sort -rn
|
|
328
|
+
|
|
329
|
+
# Get authors per file
|
|
330
|
+
git log --since="6 months ago" --format='%an' -- {FILE} | \
|
|
331
|
+
sort | uniq -c | sort -rn
|
|
332
|
+
|
|
333
|
+
# Get commit frequency over time
|
|
334
|
+
git log --since="6 months ago" --format='%ai' -- {FILE} | \
|
|
335
|
+
cut -d- -f1-2 | sort | uniq -c
|
|
336
|
+
|
|
337
|
+
# Get merge conflict history
|
|
338
|
+
git log --since="6 months ago" --all --oneline --grep="Merge conflict" -- {PATH}
|
|
339
|
+
|
|
340
|
+
# Get files changed together (coupling)
|
|
341
|
+
git log --since="6 months ago" --name-only --pretty=format: | \
|
|
342
|
+
awk 'NF' | sort | uniq -c | sort -rn
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
## Integration with Other Commands
|
|
346
|
+
|
|
347
|
+
| Use Before | Why |
|
|
348
|
+
| ----------------------------- | -------------------------------------------------- |
|
|
349
|
+
| `/migration-plan` | Identify which files need structured decomposition |
|
|
350
|
+
| `/refactor-new --churn-aware` | Focus effort on high-ROI files |
|
|
351
|
+
| `/full-flow` | Understand if your changes touch hotspots |
|
|
352
|
+
| `/pr-review` | Context on file stability |
|
|
353
|
+
| `/decision-record` | Document why stable files should stay stable |
|
|
354
|
+
|
|
355
|
+
## Compare Mode
|
|
356
|
+
|
|
357
|
+
See how churn changes over time:
|
|
358
|
+
|
|
359
|
+
```
|
|
360
|
+
/churn-map src/features/checkout --compare=3mo,6mo,12mo
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
Output:
|
|
364
|
+
|
|
365
|
+
```
|
|
366
|
+
════════════════════════════════════════════════════════════════
|
|
367
|
+
CHURN COMPARISON: src/features/checkout
|
|
368
|
+
════════════════════════════════════════════════════════════════
|
|
369
|
+
|
|
370
|
+
MainWithBooking.tsx:
|
|
371
|
+
Last 3mo: 45 commits ████████████████
|
|
372
|
+
Last 6mo: 107 commits ████████████████████████████████████
|
|
373
|
+
Last 12mo: 189 commits ████████████████████████████████████████████████████
|
|
374
|
+
|
|
375
|
+
Trend: Decreasing ↓ (good! refactoring is working)
|
|
376
|
+
|
|
377
|
+
BookingDetails.tsx:
|
|
378
|
+
Last 3mo: 58 commits ██████████████████████
|
|
379
|
+
Last 6mo: 100 commits ██████████████████████████████████████
|
|
380
|
+
Last 12mo: 145 commits ████████████████████████████████████████████████
|
|
381
|
+
|
|
382
|
+
Trend: Stable → (needs attention)
|
|
383
|
+
|
|
384
|
+
PackagesV2.tsx:
|
|
385
|
+
Last 3mo: 52 commits ████████████████████
|
|
386
|
+
Last 6mo: 89 commits ██████████████████████████████████
|
|
387
|
+
Last 12mo: 89 commits ██████████████████████████████████
|
|
388
|
+
|
|
389
|
+
Trend: Increasing ↑ (recent growth, monitor closely)
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
## Coupling Analysis
|
|
393
|
+
|
|
394
|
+
Find files that change together (hidden dependencies):
|
|
395
|
+
|
|
396
|
+
```
|
|
397
|
+
/churn-map src/features/checkout --coupling
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
Output:
|
|
401
|
+
|
|
402
|
+
```
|
|
403
|
+
════════════════════════════════════════════════════════════════
|
|
404
|
+
FILE COUPLING ANALYSIS
|
|
405
|
+
════════════════════════════════════════════════════════════════
|
|
406
|
+
|
|
407
|
+
Files frequently changed together:
|
|
408
|
+
|
|
409
|
+
1. PackagesV2.tsx + helpers.ts
|
|
410
|
+
Co-changed: 34 times (67%)
|
|
411
|
+
→ Consider: Merging or explicit interface
|
|
412
|
+
|
|
413
|
+
2. MainWithBooking.tsx + useCheckoutState.ts
|
|
414
|
+
Co-changed: 28 times (54%)
|
|
415
|
+
→ Consider: These are tightly coupled
|
|
416
|
+
|
|
417
|
+
3. types/index.ts + 15 other files
|
|
418
|
+
Co-changed: 89 times
|
|
419
|
+
→ Consider: Type changes have wide impact
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
## AI Execution
|
|
423
|
+
|
|
424
|
+
When user runs `/churn-map {PATH}`:
|
|
425
|
+
|
|
426
|
+
1. **Run git analysis** on the specified path
|
|
427
|
+
2. **Calculate churn scores** for each file
|
|
428
|
+
3. **Identify trends** (increasing/decreasing)
|
|
429
|
+
4. **Flag refactor candidates** based on scores
|
|
430
|
+
5. **Identify stable core** files to protect
|
|
431
|
+
6. **Generate recommendations** with ROI estimates
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Reference guide for code quality standards, component limits, hook patterns
|
|
3
|
+
category: Code Quality
|
|
4
|
+
aliases: [standards, quality, limits]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Code Standards Enforcement
|
|
8
|
+
|
|
9
|
+
Guidelines based on historical codebase analysis.
|
|
10
|
+
|
|
11
|
+
**Purpose:** Reference for analytical commands (not real-time enforcement)
|
|
12
|
+
|
|
13
|
+
**Auto-enforced version:** `.cursor/rules/web-standards.mdc` (enforces while typing)
|
|
14
|
+
|
|
15
|
+
**Used by:** `/full-flow`, `/pr-review`, `/pr-fix`, `/pr-checklist`, `/migration-plan`
|
|
16
|
+
|
|
17
|
+
**Run automated check:**
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
.cursor/scripts/code-quality-check.sh {PATH}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
> **Note:** Static constraints are auto-enforced by `.mdc` rules.
|
|
24
|
+
> This command provides the reference documentation and analytical context.
|
|
25
|
+
|
|
26
|
+
## Component Size Limits (MUST ENFORCE)
|
|
27
|
+
|
|
28
|
+
When generating or reviewing code, check these limits:
|
|
29
|
+
|
|
30
|
+
| Metric | ✅ Target | ⚠️ Warning | 🔴 Refactor |
|
|
31
|
+
| --------------- | --------- | ---------- | ----------- |
|
|
32
|
+
| Lines of code | < 150 | 150-300 | > 300 |
|
|
33
|
+
| Imports | < 20 | 20-35 | > 35 |
|
|
34
|
+
| useState calls | < 4 | 4-6 | > 6 |
|
|
35
|
+
| useEffect calls | < 3 | 3-5 | > 5 |
|
|
36
|
+
| Custom hooks | < 8 | 8-15 | > 15 |
|
|
37
|
+
|
|
38
|
+
### Enforcement Actions
|
|
39
|
+
|
|
40
|
+
**When generating new code:**
|
|
41
|
+
|
|
42
|
+
- NEVER create components exceeding warning limits
|
|
43
|
+
- Split into sub-components proactively
|
|
44
|
+
- Extract hooks for complex logic
|
|
45
|
+
|
|
46
|
+
**When reviewing existing code:**
|
|
47
|
+
|
|
48
|
+
- Flag violations in review comments
|
|
49
|
+
- Suggest decomposition strategy
|
|
50
|
+
- Reference this checklist
|
|
51
|
+
|
|
52
|
+
## Feature Structure (MUST FOLLOW)
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
FeatureName/
|
|
56
|
+
├── FeatureName.tsx # Orchestrator (< 100 lines)
|
|
57
|
+
├── FeatureName.styled.ts # Styles only
|
|
58
|
+
├── FeatureName.types.ts # Types/interfaces
|
|
59
|
+
├── FeatureName.test.tsx # Tests
|
|
60
|
+
├── FeatureName.mock.ts # Shared mocks
|
|
61
|
+
│
|
|
62
|
+
├── hooks/ # Feature-specific hooks
|
|
63
|
+
│ ├── useFeatureState.ts
|
|
64
|
+
│ ├── useFeatureData.ts
|
|
65
|
+
│ └── useFeatureTracking.ts
|
|
66
|
+
│
|
|
67
|
+
├── components/ # Sub-components (each < 150 lines)
|
|
68
|
+
│ ├── FeatureHeader/
|
|
69
|
+
│ ├── FeatureContent/
|
|
70
|
+
│ └── FeatureActions/
|
|
71
|
+
│
|
|
72
|
+
└── utils/
|
|
73
|
+
└── helpers.ts
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Hook Design Rules
|
|
77
|
+
|
|
78
|
+
### ✅ GOOD Patterns
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
// Single responsibility
|
|
82
|
+
export const useFeatureData = (id: string) => {
|
|
83
|
+
// Only data fetching logic
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
// Composition
|
|
87
|
+
export const useFeature = () => {
|
|
88
|
+
const data = useFeatureData();
|
|
89
|
+
const state = useFeatureState();
|
|
90
|
+
return { ...data, ...state };
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
// AbortController for async
|
|
94
|
+
useEffect(() => {
|
|
95
|
+
const controller = new AbortController();
|
|
96
|
+
fetchData({ signal: controller.signal });
|
|
97
|
+
return () => controller.abort();
|
|
98
|
+
}, [dep]);
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### ❌ BAD Patterns (NEVER Generate)
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
// God hook with 30+ returns
|
|
105
|
+
export const useEverything = () => {
|
|
106
|
+
const [a, setA] = useState();
|
|
107
|
+
const [b, setB] = useState();
|
|
108
|
+
// ... 15 more states
|
|
109
|
+
useEffect(() => {}, []);
|
|
110
|
+
useEffect(() => {}, []);
|
|
111
|
+
// ... 8 more effects
|
|
112
|
+
return { a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p };
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
// Missing cleanup
|
|
116
|
+
useEffect(() => {
|
|
117
|
+
fetchData().then(setData); // Race condition!
|
|
118
|
+
}, []);
|
|
119
|
+
|
|
120
|
+
// watch() instead of useWatch
|
|
121
|
+
const value = methods.watch(); // Causes re-renders
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Styling Rules
|
|
125
|
+
|
|
126
|
+
### ALWAYS Use Design Tokens
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
// ✅ GOOD
|
|
130
|
+
import { spacing } from '@your-org/design-system/src/utils/spacing';
|
|
131
|
+
import { color } from '@your-org/design-system/src/utils/colors';
|
|
132
|
+
|
|
133
|
+
padding: ${spacing('xs')};
|
|
134
|
+
background: ${color('container1')};
|
|
135
|
+
|
|
136
|
+
// ❌ BAD - Never hardcode
|
|
137
|
+
padding: 16px;
|
|
138
|
+
background: #ffffff;
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Responsive Patterns
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
import { OXBiggerThan } from '@your-org/design-system/src/enums/OXBiggerThan';
|
|
145
|
+
|
|
146
|
+
// ✅ GOOD
|
|
147
|
+
@media ${OXBiggerThan.Small} {
|
|
148
|
+
padding: ${spacing('m')};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// ❌ BAD
|
|
152
|
+
@media (min-width: 768px) {
|
|
153
|
+
padding: 24px;
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## State Management Rules
|
|
158
|
+
|
|
159
|
+
### Colocation Principle
|
|
160
|
+
|
|
161
|
+
```typescript
|
|
162
|
+
// ✅ State where it's used
|
|
163
|
+
const FeatureSection = () => {
|
|
164
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
165
|
+
return <Collapsible open={isOpen} />;
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
// ✅ Context for shared state
|
|
169
|
+
const FeatureProvider = ({ children }) => {
|
|
170
|
+
const [state, dispatch] = useReducer(reducer, initial);
|
|
171
|
+
return (
|
|
172
|
+
<FeatureContext.Provider value={{ state, dispatch }}>
|
|
173
|
+
{children}
|
|
174
|
+
</FeatureContext.Provider>
|
|
175
|
+
);
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
// ❌ Prop drilling > 3 levels
|
|
179
|
+
<A data={x}><B data={x}><C data={x}><D data={x} /></C></B></A>
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## Import Organization
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
// 1. External libraries
|
|
186
|
+
import { useState, useEffect } from 'react';
|
|
187
|
+
|
|
188
|
+
// 2. YourCompany packages (alphabetical)
|
|
189
|
+
import { useOXBreakpoint } from '@your-org/design-system';
|
|
190
|
+
import { OXTypography } from '@your-org/design-system/src/ui/components/p100/Typography';
|
|
191
|
+
|
|
192
|
+
// 3. Relative imports
|
|
193
|
+
import * as S from './Component.styled';
|
|
194
|
+
import type { IComponent } from './Component.types';
|
|
195
|
+
import { useComponentData } from './hooks/useComponentData';
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## Decomposition Triggers
|
|
199
|
+
|
|
200
|
+
When you see these patterns, IMMEDIATELY suggest decomposition:
|
|
201
|
+
|
|
202
|
+
1. **File > 300 lines** → Split by responsibility
|
|
203
|
+
2. **> 6 useState** → Extract to useReducer or custom hook
|
|
204
|
+
3. **> 5 useEffect** → Split into focused hooks
|
|
205
|
+
4. **> 35 imports** → Component doing too much
|
|
206
|
+
5. **Nested ternaries** → Extract to sub-components
|
|
207
|
+
6. **Repeated JSX blocks** → Extract to component
|
|
208
|
+
|
|
209
|
+
## Quick Check Before Generating
|
|
210
|
+
|
|
211
|
+
Before generating any component:
|
|
212
|
+
|
|
213
|
+
- [ ] Will it exceed 150 lines?
|
|
214
|
+
- [ ] Does it need > 4 useState?
|
|
215
|
+
- [ ] Does it need > 3 useEffect?
|
|
216
|
+
- [ ] Are there > 20 imports?
|
|
217
|
+
- [ ] Is there a simpler decomposition?
|
|
218
|
+
|
|
219
|
+
If ANY answer is "yes", restructure BEFORE generating.
|