@avisek_yorkie/cursor-rules 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/.cursorrules +153 -0
- package/README.md +291 -0
- package/SETUP.md +122 -0
- package/package.json +28 -0
- package/rules/code-quality.mdc +417 -0
- package/rules/documentation.mdc +411 -0
- package/rules/naming-conventions.mdc +291 -0
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
# Code Quality Standards
|
|
2
|
+
|
|
3
|
+
These standards apply to the TypeScript/JavaScript ecosystem. Core principles are universal across languages.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Core Principles
|
|
8
|
+
|
|
9
|
+
### SOLID Principles
|
|
10
|
+
- **S**ingle Responsibility: One class/function does one thing
|
|
11
|
+
- **O**pen/Closed: Open for extension, closed for modification
|
|
12
|
+
- **L**iskov Substitution: Subtypes must be substitutable for their base types
|
|
13
|
+
- **I**nterface Segregation: Many specific interfaces > one general interface
|
|
14
|
+
- **D**ependency Inversion: Depend on abstractions, not concretions
|
|
15
|
+
|
|
16
|
+
### DRY (Don't Repeat Yourself)
|
|
17
|
+
- ✅ Extract repeated logic into reusable functions/classes
|
|
18
|
+
- ✅ Use configuration over duplication
|
|
19
|
+
- ❌ Never copy-paste code without refactoring
|
|
20
|
+
|
|
21
|
+
### KISS (Keep It Simple, Stupid)
|
|
22
|
+
- ✅ Simple solution > clever solution
|
|
23
|
+
- ✅ Readable code > clever code
|
|
24
|
+
- ❌ Avoid premature optimization
|
|
25
|
+
- ❌ Don't over-engineer
|
|
26
|
+
|
|
27
|
+
### YAGNI (You Aren't Gonna Need It)
|
|
28
|
+
- ✅ Build what you need now
|
|
29
|
+
- ❌ Don't build for hypothetical future requirements
|
|
30
|
+
- ❌ Remove unused code immediately
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Code Structure
|
|
35
|
+
|
|
36
|
+
### Function/Method Length
|
|
37
|
+
- **Maximum 50 lines** per function/method (ideally 20-30)
|
|
38
|
+
- If longer, break into smaller functions
|
|
39
|
+
- Each function should do ONE thing
|
|
40
|
+
|
|
41
|
+
### File Length
|
|
42
|
+
- **Maximum 300-500 lines** per file
|
|
43
|
+
- If longer, split into multiple files
|
|
44
|
+
- Group related functionality
|
|
45
|
+
|
|
46
|
+
### Code Organization
|
|
47
|
+
- Separate concerns: business logic, data access, presentation, utilities
|
|
48
|
+
- Use consistent file and folder structure
|
|
49
|
+
- Keep imports organized: external libraries first, then internal modules
|
|
50
|
+
- Remove unused imports, variables, and code
|
|
51
|
+
|
|
52
|
+
### Nesting Depth
|
|
53
|
+
- **Maximum 3 levels** of nesting
|
|
54
|
+
- Use early returns to reduce nesting
|
|
55
|
+
- Extract nested logic into separate functions
|
|
56
|
+
|
|
57
|
+
```javascript
|
|
58
|
+
// ✅ Good - Early return
|
|
59
|
+
function processUser(user) {
|
|
60
|
+
if (!user) return null;
|
|
61
|
+
if (!user.active) return null;
|
|
62
|
+
|
|
63
|
+
return processActiveUser(user);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// ❌ Bad - Deep nesting
|
|
67
|
+
function processUser(user) {
|
|
68
|
+
if (user) {
|
|
69
|
+
if (user.active) {
|
|
70
|
+
if (user.hasPermission) {
|
|
71
|
+
// deeply nested logic
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Cyclomatic Complexity
|
|
79
|
+
- **Maximum complexity of 10** per function
|
|
80
|
+
- Reduce complexity by: breaking into smaller functions, using early returns, extracting conditional logic
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Naming Conventions
|
|
85
|
+
|
|
86
|
+
See `naming-conventions.mdc` for full details. Summary:
|
|
87
|
+
|
|
88
|
+
### General Rules
|
|
89
|
+
- ✅ Use descriptive, meaningful names that reveal intent
|
|
90
|
+
- ❌ Avoid abbreviations (unless universal like `id`, `url`, `http`)
|
|
91
|
+
- ❌ No single-letter variables (except loop counters `i`, `j`, `k`)
|
|
92
|
+
|
|
93
|
+
### Functions/Methods
|
|
94
|
+
- Use verbs: `getUserData()`, `calculateTotal()`, `validateEmail()`
|
|
95
|
+
- Boolean functions: `isActive()`, `hasPermission()`, `canEdit()`
|
|
96
|
+
|
|
97
|
+
### Variables
|
|
98
|
+
- Use nouns: `userData`, `totalPrice`, `emailAddress`
|
|
99
|
+
- Boolean variables: `isActive`, `hasPermission`, `canEdit`
|
|
100
|
+
|
|
101
|
+
### Constants
|
|
102
|
+
- Use UPPERCASE_WITH_UNDERSCORES: `MAX_RETRY_ATTEMPTS`, `API_BASE_URL`
|
|
103
|
+
|
|
104
|
+
```javascript
|
|
105
|
+
// ✅ Good Names
|
|
106
|
+
const userAge = 25;
|
|
107
|
+
const isAdult = userAge >= 18;
|
|
108
|
+
function calculateTotalPrice(items) { }
|
|
109
|
+
function validateEmailAddress(email) { }
|
|
110
|
+
|
|
111
|
+
// ❌ Bad Names
|
|
112
|
+
const x = 25;
|
|
113
|
+
const flag = true;
|
|
114
|
+
function calc(i) { }
|
|
115
|
+
function do() { }
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## Comments
|
|
121
|
+
|
|
122
|
+
### When to Comment
|
|
123
|
+
- ✅ WHY something is done (not WHAT)
|
|
124
|
+
- ✅ Complex algorithms that need explanation
|
|
125
|
+
- ✅ Workarounds or non-obvious solutions
|
|
126
|
+
- ✅ TODOs with ticket references
|
|
127
|
+
|
|
128
|
+
### When NOT to Comment
|
|
129
|
+
- ❌ Obvious code (code should be self-documenting)
|
|
130
|
+
- ❌ Redundant comments that repeat the code
|
|
131
|
+
- ❌ Commented-out code (delete it; it's in git history)
|
|
132
|
+
|
|
133
|
+
```javascript
|
|
134
|
+
// ✅ Good Comment - Explains WHY
|
|
135
|
+
// Retry 3 times to handle transient network failures
|
|
136
|
+
// as recommended by the API provider
|
|
137
|
+
const MAX_RETRIES = 3;
|
|
138
|
+
|
|
139
|
+
// ❌ Bad Comment - States the obvious
|
|
140
|
+
// Set the count to zero
|
|
141
|
+
const count = 0;
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Error Handling
|
|
147
|
+
|
|
148
|
+
### Never Fail Silently
|
|
149
|
+
|
|
150
|
+
```javascript
|
|
151
|
+
// ❌ Bad - Swallows errors
|
|
152
|
+
try {
|
|
153
|
+
riskyOperation();
|
|
154
|
+
} catch (error) {
|
|
155
|
+
// Silent failure
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// ✅ Good - Handles errors
|
|
159
|
+
try {
|
|
160
|
+
riskyOperation();
|
|
161
|
+
} catch (error) {
|
|
162
|
+
logger.error('Failed to execute risky operation', error);
|
|
163
|
+
notifyErrorTracking(error);
|
|
164
|
+
showUserFriendlyError();
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Fail Fast
|
|
169
|
+
- ✅ Validate inputs early at function boundaries
|
|
170
|
+
- ✅ Throw errors immediately when something is wrong
|
|
171
|
+
- ❌ Don't let invalid data propagate through the system
|
|
172
|
+
|
|
173
|
+
### Specific Error Messages
|
|
174
|
+
|
|
175
|
+
```javascript
|
|
176
|
+
// ❌ Bad - Generic error
|
|
177
|
+
throw new Error('Error occurred');
|
|
178
|
+
|
|
179
|
+
// ✅ Good - Specific error
|
|
180
|
+
throw new Error('User with ID 123 not found in database');
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### General Rules
|
|
184
|
+
- Use appropriate error types for different scenarios
|
|
185
|
+
- Log errors with context (no sensitive data)
|
|
186
|
+
- Use try-catch where exceptions can occur
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## Input Validation
|
|
191
|
+
- Validate all inputs at function boundaries
|
|
192
|
+
- Check for null/undefined/empty values
|
|
193
|
+
- Validate data types and ranges
|
|
194
|
+
- Sanitize user inputs to prevent injection attacks
|
|
195
|
+
- Return clear validation error messages
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## Code Duplication
|
|
200
|
+
|
|
201
|
+
### The Rule of Three
|
|
202
|
+
1. First time: Write it
|
|
203
|
+
2. Second time: Copy it (reluctantly)
|
|
204
|
+
3. Third time: Refactor it into a reusable function
|
|
205
|
+
|
|
206
|
+
### Extract Common Logic
|
|
207
|
+
|
|
208
|
+
```javascript
|
|
209
|
+
// ❌ Bad - Duplicated validation
|
|
210
|
+
function createUser(data) {
|
|
211
|
+
if (!data.email || !data.email.includes('@')) {
|
|
212
|
+
throw new Error('Invalid email');
|
|
213
|
+
}
|
|
214
|
+
// create user
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function updateUser(data) {
|
|
218
|
+
if (!data.email || !data.email.includes('@')) {
|
|
219
|
+
throw new Error('Invalid email');
|
|
220
|
+
}
|
|
221
|
+
// update user
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// ✅ Good - Extracted validation
|
|
225
|
+
function validateEmail(email) {
|
|
226
|
+
if (!email || !email.includes('@')) {
|
|
227
|
+
throw new Error('Invalid email');
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function createUser(data) {
|
|
232
|
+
validateEmail(data.email);
|
|
233
|
+
// create user
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
function updateUser(data) {
|
|
237
|
+
validateEmail(data.email);
|
|
238
|
+
// update user
|
|
239
|
+
}
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## Magic Numbers and Strings
|
|
245
|
+
|
|
246
|
+
### Never Use Magic Values
|
|
247
|
+
|
|
248
|
+
```javascript
|
|
249
|
+
// ❌ Bad - Magic numbers
|
|
250
|
+
if (user.age > 18) { }
|
|
251
|
+
setTimeout(callback, 5000);
|
|
252
|
+
|
|
253
|
+
// ✅ Good - Named constants
|
|
254
|
+
const ADULT_AGE = 18;
|
|
255
|
+
const TIMEOUT_MS = 5000;
|
|
256
|
+
|
|
257
|
+
if (user.age > ADULT_AGE) { }
|
|
258
|
+
setTimeout(callback, TIMEOUT_MS);
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
- Replace magic strings with constants or enums
|
|
262
|
+
- Use configuration for environment-specific values
|
|
263
|
+
- Group related constants together
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## Function Parameters
|
|
268
|
+
|
|
269
|
+
### Maximum 3-4 Parameters
|
|
270
|
+
- If more parameters needed, use a configuration object
|
|
271
|
+
|
|
272
|
+
```javascript
|
|
273
|
+
// ❌ Bad - Too many parameters
|
|
274
|
+
function createUser(name, email, age, address, phone, role, department) {
|
|
275
|
+
// ...
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// ✅ Good - Configuration object
|
|
279
|
+
function createUser(config) {
|
|
280
|
+
const { name, email, age, address, phone, role, department } = config;
|
|
281
|
+
// ...
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
createUser({
|
|
285
|
+
name: 'John Doe',
|
|
286
|
+
email: 'john@example.com',
|
|
287
|
+
age: 30,
|
|
288
|
+
// ...
|
|
289
|
+
});
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
---
|
|
293
|
+
|
|
294
|
+
## Code Smells to Avoid
|
|
295
|
+
|
|
296
|
+
| Smell | Rule | Solution |
|
|
297
|
+
|-------|------|----------|
|
|
298
|
+
| **Long Parameter Lists** | More than 4 parameters | Use configuration object |
|
|
299
|
+
| **Large Classes/Files** | More than 500 lines | Split into smaller modules |
|
|
300
|
+
| **Feature Envy** | Function accessing another's data more than its own | Move logic to where the data lives |
|
|
301
|
+
| **Data Clumps** | Same group of variables appearing together | Create a class/object to group them |
|
|
302
|
+
| **Divergent Change** | One class changed for different reasons | Split into separate classes |
|
|
303
|
+
| **Shotgun Surgery** | One change requires modifying many classes | Consolidate related changes into one place |
|
|
304
|
+
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
## Security Best Practices
|
|
308
|
+
- Never hardcode secrets, API keys, or credentials
|
|
309
|
+
- Use environment variables for configuration
|
|
310
|
+
- Validate and sanitize all user inputs
|
|
311
|
+
- Use parameterized queries to prevent SQL injection
|
|
312
|
+
- Implement proper authentication and authorization
|
|
313
|
+
- Follow principle of least privilege
|
|
314
|
+
- Keep dependencies updated to avoid vulnerabilities
|
|
315
|
+
|
|
316
|
+
---
|
|
317
|
+
|
|
318
|
+
## Testing
|
|
319
|
+
|
|
320
|
+
### Write Testable Code
|
|
321
|
+
- ✅ Small, focused functions
|
|
322
|
+
- ✅ Inject dependencies (don't hardcode)
|
|
323
|
+
- ✅ Avoid global state
|
|
324
|
+
- ✅ Pure functions when possible
|
|
325
|
+
|
|
326
|
+
### Test Coverage
|
|
327
|
+
- ✅ Aim for 80%+ code coverage
|
|
328
|
+
- ✅ Focus on business logic
|
|
329
|
+
- ✅ Test edge cases and error paths
|
|
330
|
+
- ✅ Include unit tests, integration tests
|
|
331
|
+
- Keep tests simple and focused
|
|
332
|
+
|
|
333
|
+
---
|
|
334
|
+
|
|
335
|
+
## Performance
|
|
336
|
+
|
|
337
|
+
### Premature Optimization is Bad
|
|
338
|
+
- ✅ Write clean, readable code first
|
|
339
|
+
- ✅ Optimize only when you have performance metrics
|
|
340
|
+
- ❌ Don't sacrifice readability for minor performance gains
|
|
341
|
+
|
|
342
|
+
### When to Optimize
|
|
343
|
+
- After profiling identifies bottlenecks
|
|
344
|
+
- When performance impacts user experience
|
|
345
|
+
- When costs (server, bandwidth) are high
|
|
346
|
+
|
|
347
|
+
### General
|
|
348
|
+
- Use efficient algorithms and data structures
|
|
349
|
+
- Minimize database queries and API calls
|
|
350
|
+
- Cache appropriately when beneficial
|
|
351
|
+
- Avoid unnecessary computations in loops
|
|
352
|
+
- Use lazy loading when appropriate
|
|
353
|
+
|
|
354
|
+
---
|
|
355
|
+
|
|
356
|
+
## Refactoring Guidelines
|
|
357
|
+
- Refactor when code smells are detected
|
|
358
|
+
- Improve code incrementally
|
|
359
|
+
- Don't refactor and add features in the same commit
|
|
360
|
+
- Ensure tests pass before and after refactoring
|
|
361
|
+
- Refactor in small, safe steps
|
|
362
|
+
|
|
363
|
+
---
|
|
364
|
+
|
|
365
|
+
## Code Metrics to Monitor
|
|
366
|
+
- Cyclomatic complexity
|
|
367
|
+
- Code duplication percentage
|
|
368
|
+
- Test coverage percentage
|
|
369
|
+
- Number of dependencies
|
|
370
|
+
- File and function size
|
|
371
|
+
- Technical debt indicators
|
|
372
|
+
|
|
373
|
+
---
|
|
374
|
+
|
|
375
|
+
## Code Review Checklist
|
|
376
|
+
|
|
377
|
+
Before submitting code for review, verify:
|
|
378
|
+
|
|
379
|
+
- [ ] Code follows naming conventions
|
|
380
|
+
- [ ] No duplicated code
|
|
381
|
+
- [ ] Functions are small and focused
|
|
382
|
+
- [ ] No magic numbers or strings
|
|
383
|
+
- [ ] Errors are handled properly (never fail silently)
|
|
384
|
+
- [ ] Code is self-documenting
|
|
385
|
+
- [ ] Comments explain WHY, not WHAT
|
|
386
|
+
- [ ] Tests are included and passing
|
|
387
|
+
- [ ] No commented-out code
|
|
388
|
+
- [ ] No stray console.log (use proper logging)
|
|
389
|
+
- [ ] No hardcoded values (use constants/config)
|
|
390
|
+
- [ ] Input validation is present at boundaries
|
|
391
|
+
- [ ] No security vulnerabilities
|
|
392
|
+
- [ ] No unused imports or dead code
|
|
393
|
+
|
|
394
|
+
---
|
|
395
|
+
|
|
396
|
+
## JavaScript/TypeScript Guidelines
|
|
397
|
+
- Use strict mode
|
|
398
|
+
- Prefer `const` over `let`, avoid `var`
|
|
399
|
+
- Use arrow functions for callbacks
|
|
400
|
+
- Avoid `==`, always use `===`
|
|
401
|
+
- Use async/await over promise chains
|
|
402
|
+
- Handle promise rejections properly
|
|
403
|
+
|
|
404
|
+
---
|
|
405
|
+
|
|
406
|
+
## Summary: The Golden Rules
|
|
407
|
+
|
|
408
|
+
1. **Readability > Cleverness** - Code is read 10x more than written
|
|
409
|
+
2. **Simple > Complex** - The simplest solution is usually the best
|
|
410
|
+
3. **DRY** - Don't Repeat Yourself
|
|
411
|
+
4. **YAGNI** - You Aren't Gonna Need It
|
|
412
|
+
5. **Fail Fast** - Validate early, fail loudly
|
|
413
|
+
6. **Test Your Code** - If you can't test it, refactor it
|
|
414
|
+
7. **Small Functions** - One function, one responsibility
|
|
415
|
+
8. **Meaningful Names** - Names should reveal intent
|
|
416
|
+
9. **Handle Errors** - Never fail silently
|
|
417
|
+
10. **Delete Code** - Dead code should be removed, not commented out
|