class-ai-agent 1.2.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.
Files changed (93) hide show
  1. package/.claude/CLAUDE.md +155 -0
  2. package/.claude/agents/backend.md +395 -0
  3. package/.claude/agents/code-reviewer.md +110 -0
  4. package/.claude/agents/copywriter-seo.md +236 -0
  5. package/.claude/agents/frontend.md +384 -0
  6. package/.claude/agents/project-manager.md +201 -0
  7. package/.claude/agents/qa.md +221 -0
  8. package/.claude/agents/security-auditor.md +143 -0
  9. package/.claude/agents/systems-architect.md +211 -0
  10. package/.claude/agents/test-engineer.md +123 -0
  11. package/.claude/agents/ui-ux-designer.md +210 -0
  12. package/.claude/commands/build.md +132 -0
  13. package/.claude/commands/debug.md +242 -0
  14. package/.claude/commands/deploy.md +40 -0
  15. package/.claude/commands/fix-issue.md +42 -0
  16. package/.claude/commands/plan.md +125 -0
  17. package/.claude/commands/review.md +50 -0
  18. package/.claude/commands/simplify.md +222 -0
  19. package/.claude/commands/spec.md +95 -0
  20. package/.claude/commands/test.md +214 -0
  21. package/.claude/references/accessibility-checklist.md +174 -0
  22. package/.claude/references/performance-checklist.md +150 -0
  23. package/.claude/references/security-checklist.md +94 -0
  24. package/.claude/references/testing-patterns.md +183 -0
  25. package/.claude/rules/api-conventions.md +79 -0
  26. package/.claude/rules/clean-code.md +205 -0
  27. package/.claude/rules/code-style.md +86 -0
  28. package/.claude/rules/database.md +60 -0
  29. package/.claude/rules/error-handling.md +92 -0
  30. package/.claude/rules/git-workflow.md +77 -0
  31. package/.claude/rules/monitoring.md +311 -0
  32. package/.claude/rules/naming-conventions.md +260 -0
  33. package/.claude/rules/project-structure.md +65 -0
  34. package/.claude/rules/security.md +90 -0
  35. package/.claude/rules/system-design.md +162 -0
  36. package/.claude/rules/tech-stack.md +456 -0
  37. package/.claude/rules/testing.md +104 -0
  38. package/.claude/settings.json +14 -0
  39. package/.claude/skills/code-review/SKILL.md +208 -0
  40. package/.claude/skills/deploy/SKILL.md +68 -0
  41. package/.claude/skills/deploy/deploy.md +735 -0
  42. package/.claude/skills/incremental-implementation/SKILL.md +210 -0
  43. package/.claude/skills/security-review/SKILL.md +71 -0
  44. package/.claude/skills/tdd/SKILL.md +217 -0
  45. package/.cursor/CURSOR.md +112 -0
  46. package/.cursor/agents/backend.md +395 -0
  47. package/.cursor/agents/code-reviewer.md +110 -0
  48. package/.cursor/agents/copywriter-seo.md +236 -0
  49. package/.cursor/agents/frontend.md +384 -0
  50. package/.cursor/agents/project-manager.md +201 -0
  51. package/.cursor/agents/qa.md +221 -0
  52. package/.cursor/agents/security-auditor.md +143 -0
  53. package/.cursor/agents/systems-architect.md +211 -0
  54. package/.cursor/agents/test-engineer.md +123 -0
  55. package/.cursor/agents/ui-ux-designer.md +210 -0
  56. package/.cursor/commands/build.md +132 -0
  57. package/.cursor/commands/debug.md +242 -0
  58. package/.cursor/commands/deploy.md +40 -0
  59. package/.cursor/commands/fix-issue.md +42 -0
  60. package/.cursor/commands/plan.md +125 -0
  61. package/.cursor/commands/review.md +50 -0
  62. package/.cursor/commands/simplify.md +222 -0
  63. package/.cursor/commands/spec.md +95 -0
  64. package/.cursor/commands/test.md +214 -0
  65. package/.cursor/references/accessibility-checklist.md +174 -0
  66. package/.cursor/references/performance-checklist.md +150 -0
  67. package/.cursor/references/security-checklist.md +94 -0
  68. package/.cursor/references/testing-patterns.md +183 -0
  69. package/.cursor/rules/api-conventions.mdc +85 -0
  70. package/.cursor/rules/clean-code.mdc +211 -0
  71. package/.cursor/rules/code-style.mdc +92 -0
  72. package/.cursor/rules/cursor-overview.mdc +35 -0
  73. package/.cursor/rules/database.mdc +66 -0
  74. package/.cursor/rules/error-handling.mdc +98 -0
  75. package/.cursor/rules/git-workflow.mdc +83 -0
  76. package/.cursor/rules/monitoring.mdc +317 -0
  77. package/.cursor/rules/naming-conventions.mdc +266 -0
  78. package/.cursor/rules/project-structure.mdc +71 -0
  79. package/.cursor/rules/security.mdc +95 -0
  80. package/.cursor/rules/system-design.mdc +168 -0
  81. package/.cursor/rules/tech-stack.mdc +462 -0
  82. package/.cursor/rules/testing.mdc +110 -0
  83. package/.cursor/settings.json +8 -0
  84. package/.cursor/skills/code-review/SKILL.md +208 -0
  85. package/.cursor/skills/deploy/SKILL.md +68 -0
  86. package/.cursor/skills/deploy/deploy.md +735 -0
  87. package/.cursor/skills/incremental-implementation/SKILL.md +210 -0
  88. package/.cursor/skills/security-review/SKILL.md +71 -0
  89. package/.cursor/skills/tdd/SKILL.md +217 -0
  90. package/AGENTS.md +11 -0
  91. package/README.md +405 -0
  92. package/bin/class-ai-agent.cjs +176 -0
  93. package/package.json +38 -0
@@ -0,0 +1,94 @@
1
+ # Security Checklist
2
+
3
+ > Quick reference for security review. See `.claude/rules/security.md` for full rules.
4
+
5
+ ## Pre-Commit Checks
6
+
7
+ - [ ] No secrets in code (API keys, passwords, tokens)
8
+ - [ ] `.gitignore` excludes sensitive files (`.env`, credentials)
9
+ - [ ] `.env.example` contains only placeholder values
10
+ - [ ] No hardcoded URLs with credentials
11
+
12
+ ## Authentication
13
+
14
+ - [ ] Passwords hashed with bcrypt (rounds >= 12) or argon2
15
+ - [ ] Session cookies: `httpOnly`, `secure`, `sameSite: 'lax'`
16
+ - [ ] JWT tokens have reasonable expiry (15min access, 7d refresh)
17
+ - [ ] Rate limiting on auth endpoints (max 10 attempts/15min)
18
+ - [ ] Logout invalidates session/token
19
+
20
+ ## Authorization
21
+
22
+ - [ ] Every endpoint checks authentication
23
+ - [ ] Resource ownership verified (no IDOR)
24
+ - [ ] API keys are scoped appropriately
25
+ - [ ] JWT signature, expiration, and issuer validated
26
+ - [ ] Admin functions protected
27
+
28
+ ## Input Validation
29
+
30
+ - [ ] All user input validated at system boundary
31
+ - [ ] Allowlist validation preferred over blocklist
32
+ - [ ] String lengths constrained
33
+ - [ ] Numeric ranges validated
34
+ - [ ] File uploads restricted by type and size
35
+ - [ ] SQL queries parameterized (never string concat)
36
+
37
+ ## Security Headers
38
+
39
+ ```javascript
40
+ // Required headers
41
+ Content-Security-Policy: default-src 'self'
42
+ Strict-Transport-Security: max-age=31536000; includeSubDomains
43
+ X-Content-Type-Options: nosniff
44
+ X-Frame-Options: DENY
45
+ Permissions-Policy: geolocation=(), camera=()
46
+ ```
47
+
48
+ ## CORS
49
+
50
+ - [ ] Restrictive origin allowlist (no `*` in production)
51
+ - [ ] Credentials mode appropriate
52
+ - [ ] Methods and headers restricted
53
+
54
+ ## Data Protection
55
+
56
+ - [ ] Sensitive fields excluded from API responses
57
+ - [ ] No secrets in logs
58
+ - [ ] PII encrypted when required
59
+ - [ ] HTTPS enforced
60
+ - [ ] Database backups encrypted
61
+
62
+ ## Dependencies
63
+
64
+ ```bash
65
+ # Run regularly
66
+ npm audit
67
+ npm audit fix
68
+ ```
69
+
70
+ - [ ] No critical vulnerabilities
71
+ - [ ] Dependencies up to date
72
+ - [ ] Lock file committed
73
+
74
+ ## Error Handling
75
+
76
+ - [ ] Generic error messages in production
77
+ - [ ] No stack traces exposed
78
+ - [ ] No database details in errors
79
+ - [ ] No internal paths revealed
80
+
81
+ ## OWASP Top 10 Quick Check
82
+
83
+ | # | Vulnerability | Check |
84
+ |---|--------------|-------|
85
+ | 1 | Broken Access Control | Auth on all endpoints? |
86
+ | 2 | Cryptographic Failures | Secrets encrypted? HTTPS? |
87
+ | 3 | Injection | Inputs sanitized? Queries parameterized? |
88
+ | 4 | Insecure Design | Threat modeling done? |
89
+ | 5 | Security Misconfiguration | Headers set? Defaults changed? |
90
+ | 6 | Vulnerable Components | `npm audit` clean? |
91
+ | 7 | Auth Failures | Rate limiting? Strong passwords? |
92
+ | 8 | Data Integrity | Signatures verified? |
93
+ | 9 | Logging Failures | Security events logged? |
94
+ | 10 | SSRF | External URLs validated? |
@@ -0,0 +1,183 @@
1
+ # Testing Patterns Reference
2
+
3
+ > Quick reference for test patterns. See `.claude/rules/testing.md` for full rules.
4
+
5
+ ## Test Pyramid
6
+
7
+ ```
8
+ ┌─────────┐
9
+ │ E2E │ 5% Critical user flows
10
+ ├─────────┤
11
+ │ Integ │ 15% API + DB interactions
12
+ ├─────────┤
13
+ │ Unit │ 80% Pure logic, fast
14
+ └─────────┘
15
+ ```
16
+
17
+ ## Test Structure (AAA)
18
+
19
+ ```javascript
20
+ it('should [expected behavior] when [condition]', () => {
21
+ // Arrange — Setup
22
+ const user = createTestUser({ role: 'admin' });
23
+
24
+ // Act — Execute
25
+ const result = checkPermission(user, 'delete');
26
+
27
+ // Assert — Verify
28
+ expect(result).toBe(true);
29
+ });
30
+ ```
31
+
32
+ ## Unit Test Example
33
+
34
+ ```javascript
35
+ describe('calculateDiscount', () => {
36
+ it('should return 10% for orders over $100', () => {
37
+ expect(calculateDiscount(150)).toBe(15);
38
+ });
39
+
40
+ it('should return 0 for orders under $100', () => {
41
+ expect(calculateDiscount(50)).toBe(0);
42
+ });
43
+
44
+ it('should handle edge case at exactly $100', () => {
45
+ expect(calculateDiscount(100)).toBe(0);
46
+ });
47
+ });
48
+ ```
49
+
50
+ ## Integration Test Example
51
+
52
+ ```javascript
53
+ describe('POST /api/users', () => {
54
+ it('should create user and return 201', async () => {
55
+ const response = await request(app)
56
+ .post('/api/users')
57
+ .send({ email: 'test@example.com', name: 'Test' })
58
+ .set('Authorization', `Bearer ${token}`);
59
+
60
+ expect(response.status).toBe(201);
61
+ expect(response.body.data.email).toBe('test@example.com');
62
+
63
+ // Verify in database
64
+ const user = await db.user.findUnique({
65
+ where: { email: 'test@example.com' }
66
+ });
67
+ expect(user).toBeDefined();
68
+ });
69
+ });
70
+ ```
71
+
72
+ ## E2E Test Example (Playwright)
73
+
74
+ ```javascript
75
+ test('user can complete checkout flow', async ({ page }) => {
76
+ // Login
77
+ await page.goto('/login');
78
+ await page.fill('[name="email"]', 'user@example.com');
79
+ await page.fill('[name="password"]', 'password');
80
+ await page.click('button[type="submit"]');
81
+
82
+ // Add to cart
83
+ await page.goto('/products/1');
84
+ await page.click('button:has-text("Add to Cart")');
85
+
86
+ // Checkout
87
+ await page.goto('/checkout');
88
+ await page.fill('[name="card"]', '4242424242424242');
89
+ await page.click('button:has-text("Pay")');
90
+
91
+ // Verify
92
+ await expect(page.locator('.success-message')).toBeVisible();
93
+ });
94
+ ```
95
+
96
+ ## React Component Test
97
+
98
+ ```javascript
99
+ import { render, screen, fireEvent } from '@testing-library/react';
100
+
101
+ describe('Counter', () => {
102
+ it('should increment count when button clicked', () => {
103
+ render(<Counter initialCount={0} />);
104
+
105
+ const button = screen.getByRole('button', { name: /increment/i });
106
+ fireEvent.click(button);
107
+
108
+ expect(screen.getByText('Count: 1')).toBeInTheDocument();
109
+ });
110
+ });
111
+ ```
112
+
113
+ ## Test Doubles
114
+
115
+ ```javascript
116
+ // 1. Real (preferred)
117
+ const db = createTestDatabase();
118
+
119
+ // 2. Fake (in-memory)
120
+ const fakeUserRepo = {
121
+ users: [],
122
+ create(user) { this.users.push(user); return user; },
123
+ findById(id) { return this.users.find(u => u.id === id); }
124
+ };
125
+
126
+ // 3. Stub (canned response)
127
+ const stubbedApi = {
128
+ getUser: () => Promise.resolve({ id: '1', name: 'Test' })
129
+ };
130
+
131
+ // 4. Mock (verify interactions — use sparingly)
132
+ const mockLogger = vi.fn();
133
+ ```
134
+
135
+ ## Naming Convention
136
+
137
+ ```javascript
138
+ // Pattern: should [expected] when [condition]
139
+
140
+ // ✅ Good
141
+ 'should return null when user not found'
142
+ 'should throw ValidationError when email invalid'
143
+ 'should emit event when order placed'
144
+
145
+ // ❌ Bad
146
+ 'works'
147
+ 'test user'
148
+ 'error handling'
149
+ ```
150
+
151
+ ## Anti-Patterns
152
+
153
+ | Pattern | Problem | Fix |
154
+ |---------|---------|-----|
155
+ | Testing internals | Breaks on refactor | Test behavior |
156
+ | Shared state | Tests affect each other | Reset in beforeEach |
157
+ | Flaky tests | Random failures | Deterministic data |
158
+ | Over-mocking | False confidence | Real implementations |
159
+ | No assertions | Test always passes | Assert outcomes |
160
+ | Magic numbers | Hard to understand | Named constants |
161
+
162
+ ## Coverage Thresholds
163
+
164
+ ```javascript
165
+ // vitest.config.js
166
+ coverage: {
167
+ thresholds: {
168
+ lines: 80,
169
+ branches: 80,
170
+ functions: 80,
171
+ statements: 80
172
+ }
173
+ }
174
+ ```
175
+
176
+ ## Commands
177
+
178
+ ```bash
179
+ npm test # Run all tests
180
+ npm test -- --watch # Watch mode
181
+ npm test -- --coverage # Coverage report
182
+ npm run test:e2e # E2E tests
183
+ ```
@@ -0,0 +1,79 @@
1
+ # API Conventions
2
+
3
+ ## REST API Design Standards
4
+
5
+ ### URL Structure
6
+ - Use **kebab-case** for URL paths: `/api/user-profiles`
7
+ - Use **plural nouns** for resource collections: `/api/users`, `/api/products`
8
+ - Nest related resources: `/api/users/:id/orders`
9
+ - API version prefix: `/api/v1/...`
10
+
11
+ ### HTTP Methods
12
+ | Method | Usage |
13
+ |--------|-------|
14
+ | GET | Read resources (idempotent) |
15
+ | POST | Create new resource |
16
+ | PUT | Replace entire resource |
17
+ | PATCH | Partial update |
18
+ | DELETE | Remove resource |
19
+
20
+ ### HTTP Status Codes
21
+ | Code | Meaning |
22
+ |------|---------|
23
+ | 200 | OK — Successful GET/PUT/PATCH |
24
+ | 201 | Created — Successful POST |
25
+ | 204 | No Content — Successful DELETE |
26
+ | 400 | Bad Request — Invalid input |
27
+ | 401 | Unauthorized — Not authenticated |
28
+ | 403 | Forbidden — No permission |
29
+ | 404 | Not Found |
30
+ | 409 | Conflict |
31
+ | 422 | Unprocessable Entity — Validation failed |
32
+ | 500 | Internal Server Error |
33
+
34
+ ### Request/Response Format
35
+ ```json
36
+ // Success response
37
+ {
38
+ "success": true,
39
+ "data": { ... },
40
+ "message": "Optional message"
41
+ }
42
+
43
+ // Error response
44
+ {
45
+ "success": false,
46
+ "error": {
47
+ "code": "VALIDATION_ERROR",
48
+ "message": "Human readable message",
49
+ "details": [ ... ]
50
+ }
51
+ }
52
+
53
+ // Paginated list response
54
+ {
55
+ "success": true,
56
+ "data": [ ... ],
57
+ "pagination": {
58
+ "page": 1,
59
+ "limit": 20,
60
+ "total": 100,
61
+ "totalPages": 5
62
+ }
63
+ }
64
+ ```
65
+
66
+ ### Naming Conventions
67
+ - Request/response body fields: **camelCase**
68
+ - Query parameters: **camelCase**
69
+ - Always return consistent field names
70
+
71
+ ### Filtering & Pagination
72
+ ```
73
+ GET /api/users?page=1&limit=20&sortBy=createdAt&order=desc
74
+ GET /api/products?category=electronics&minPrice=100
75
+ ```
76
+
77
+ ### Documentation
78
+ - Every endpoint MUST have JSDoc/Swagger annotations
79
+ - Include request body schema, response schema, and error codes
@@ -0,0 +1,205 @@
1
+ # Clean Code — JavaScript Rules
2
+ > Source: [clean-code-javascript](https://github.com/ryanmcdermott/clean-code-javascript) by Ryan McDermott
3
+
4
+ ## 📦 Variables
5
+
6
+ ### ✅ Use meaningful, pronounceable names
7
+ ```js
8
+ // ❌ Bad
9
+ const yyyymmdstr = moment().format('YYYY/MM/DD');
10
+
11
+ // ✅ Good
12
+ const currentDate = moment().format('YYYY/MM/DD');
13
+ ```
14
+
15
+ ### ✅ Same vocabulary for same type
16
+ ```js
17
+ // ❌ getUserInfo(), getClientData(), getCustomerRecord()
18
+ // ✅ getUser()
19
+ ```
20
+
21
+ ### ✅ Use searchable names (no magic numbers)
22
+ ```js
23
+ // ❌ setTimeout(blastOff, 86400000);
24
+ const MILLISECONDS_PER_DAY = 60 * 60 * 24 * 1000;
25
+ setTimeout(blastOff, MILLISECONDS_PER_DAY); // ✅
26
+ ```
27
+
28
+ ### ✅ Use explanatory variables
29
+ ```js
30
+ // ❌ Bad
31
+ saveCityZipCode(address.match(regex)[1], address.match(regex)[2]);
32
+
33
+ // ✅ Good
34
+ const [_, city, zipCode] = address.match(cityZipCodeRegex) || [];
35
+ saveCityZipCode(city, zipCode);
36
+ ```
37
+
38
+ ### ✅ Avoid mental mapping — be explicit
39
+ ```js
40
+ // ❌ locations.forEach(l => { dispatch(l); });
41
+ // ✅ locations.forEach(location => { dispatch(location); });
42
+ ```
43
+
44
+ ### ✅ Don't add redundant context
45
+ ```js
46
+ // ❌ const Car = { carMake, carModel, carColor }
47
+ // ✅ const Car = { make, model, color }
48
+ ```
49
+
50
+ ### ✅ Use default parameters
51
+ ```js
52
+ // ❌ const name = name || 'Default';
53
+ // ✅ function create(name = 'Default') {}
54
+ ```
55
+
56
+ ---
57
+
58
+ ## 🔧 Functions
59
+
60
+ ### ✅ 2 arguments or fewer — use object destructuring for more
61
+ ```js
62
+ // ❌ function createMenu(title, body, buttonText, cancellable) {}
63
+ // ✅ function createMenu({ title, body, buttonText, cancellable }) {}
64
+ ```
65
+
66
+ ### ✅ Functions should do ONE thing
67
+ ```js
68
+ // ❌ emailClients() — fetches DB + checks active + sends email
69
+ // ✅ emailActiveClients() calls isActiveClient() separately
70
+ ```
71
+
72
+ ### ✅ Function names should say what they do
73
+ ```js
74
+ // ❌ addToDate(date, 1) → unclear what is added
75
+ // ✅ addMonthToDate(1, date) → crystal clear
76
+ ```
77
+
78
+ ### ✅ One level of abstraction per function
79
+ ```js
80
+ // ❌ parseBetterJSAlternative() — tokenizes + parses + AST walks in one function
81
+ // ✅ parseBetterJSAlternative() → calls tokenize() → calls parse()
82
+ ```
83
+
84
+ ### ✅ Remove duplicate code — extract shared logic
85
+ ### ✅ No flag parameters — split into separate functions
86
+ ```js
87
+ // ❌ function createFile(name, isTemp) { if (isTemp) ... }
88
+ // ✅ function createFile(name) {}
89
+ // function createTempFile(name) {}
90
+ ```
91
+
92
+ ### ✅ Avoid Side Effects
93
+ - Don't mutate global state
94
+ - Don't mutate function arguments (use copies)
95
+ ```js
96
+ // ✅ Return new array instead of mutating
97
+ function addItemToCart(cart, item) {
98
+ return [...cart, { item, date: Date.now() }];
99
+ }
100
+ ```
101
+
102
+ ### ✅ Favor functional programming
103
+ ```js
104
+ // ❌ for loop with mutations
105
+ // ✅ filter(), map(), reduce()
106
+ const totalOutput = programmerOutput
107
+ .filter(p => p.linesOfCode > 0)
108
+ .reduce((acc, p) => acc + p.linesOfCode, 0);
109
+ ```
110
+
111
+ ### ✅ Encapsulate conditionals
112
+ ```js
113
+ // ❌ if (fsm.state === 'fetching' && isEmpty(listNode)) {}
114
+ // ✅ if (shouldShowSpinner(fsmInstance, listNodeInstance)) {}
115
+ ```
116
+
117
+ ### ✅ Avoid negative conditionals
118
+ ```js
119
+ // ❌ if (!isNotDOMNodePresent(node)) {}
120
+ // ✅ if (isDOMNodePresent(node)) {}
121
+ ```
122
+
123
+ ### ✅ Remove dead code immediately
124
+
125
+ ---
126
+
127
+ ## 🏛️ Classes
128
+
129
+ ### ✅ Prefer ES6 classes
130
+ ### ✅ Use method chaining (builder pattern)
131
+ ```js
132
+ class QueryBuilder {
133
+ select(fields) { this.fields = fields; return this; }
134
+ from(table) { this.table = table; return this; }
135
+ build() { return `SELECT ${this.fields} FROM ${this.table}`; }
136
+ }
137
+ new QueryBuilder().select('*').from('users').build();
138
+ ```
139
+
140
+ ### ✅ Prefer composition over inheritance
141
+ > "Favor has-a over is-a"
142
+
143
+ ---
144
+
145
+ ## 🧱 SOLID Principles
146
+
147
+ | Principle | Rule |
148
+ |-----------|------|
149
+ | **S** — Single Responsibility | One class = one job. Never combine unrelated concerns |
150
+ | **O** — Open/Closed | Open for extension, closed for modification |
151
+ | **L** — Liskov Substitution | Subclasses must be substitutable for their base class |
152
+ | **I** — Interface Segregation | Clients shouldn't depend on interfaces they don't use |
153
+ | **D** — Dependency Inversion | Depend on abstractions, not concretions |
154
+
155
+ ```js
156
+ // ✅ D — Dependency Inversion
157
+ class InventoryService {
158
+ constructor(inventoryRequester) { // inject the dependency
159
+ this.inventoryRequester = inventoryRequester;
160
+ }
161
+ requestItems(customer) {
162
+ return this.inventoryRequester.requestItem(customer.purchaseHistory);
163
+ }
164
+ }
165
+ ```
166
+
167
+ ---
168
+
169
+ ## ⚡ Concurrency
170
+
171
+ ### ✅ Use Promises over callbacks
172
+ ### ✅ Use async/await over Promises
173
+ ```js
174
+ // ✅ Clearest form
175
+ async function getCleanCodeArticle() {
176
+ try {
177
+ const response = await request.get(cleanCodeUrl);
178
+ await fs.writeFile('article.html', response);
179
+ } catch (err) {
180
+ console.error(err);
181
+ }
182
+ }
183
+ ```
184
+
185
+ ---
186
+
187
+ ## 🗒️ Comments
188
+
189
+ ### ✅ Only comment business logic complexity
190
+ ### ❌ Never leave commented-out code
191
+ ### ❌ No journal comments (use git log instead)
192
+ ### ❌ No positional markers (`/////`)
193
+ ```js
194
+ // ✅ Good comment — explains WHY
195
+ // We retry 3x because OAuth2 tokens can have clock skew
196
+ const MAX_RETRIES = 3;
197
+ ```
198
+
199
+ ---
200
+
201
+ ## 📐 Formatting
202
+
203
+ - Use consistent capitalization (camelCase for vars/fns, PascalCase for classes, UPPER_SNAKE for constants)
204
+ - Keep callers and callees close in the file
205
+ - Related code should appear together
@@ -0,0 +1,86 @@
1
+ # Code Style Guide
2
+
3
+ ## General Principles
4
+ - **Clarity over cleverness** — Write code that is easy to read and understand
5
+ - **Consistency** — Follow existing patterns in the codebase
6
+ - **DRY** — Don't Repeat Yourself, but don't over-abstract
7
+
8
+ ## JavaScript / TypeScript
9
+
10
+ ### Formatting
11
+ - Indentation: **2 spaces** (no tabs)
12
+ - Max line length: **100 characters**
13
+ - Use **single quotes** for strings
14
+ - Always use **semicolons**
15
+ - Trailing commas in multi-line structures
16
+
17
+ ### Naming
18
+ ```js
19
+ // Variables and functions: camelCase
20
+ const userProfile = {};
21
+ function getUserById(id) {}
22
+
23
+ // Classes and interfaces: PascalCase
24
+ class UserService {}
25
+ interface UserRepository {}
26
+
27
+ // Constants: UPPER_SNAKE_CASE
28
+ const MAX_RETRY_COUNT = 3;
29
+ const API_BASE_URL = 'https://api.example.com';
30
+
31
+ // Files: kebab-case
32
+ // user-service.js, auth-middleware.js
33
+ ```
34
+
35
+ ### Functions
36
+ ```js
37
+ // ✅ Good — Arrow functions for simple operations
38
+ const double = (x) => x * 2;
39
+
40
+ // ✅ Good — Named functions for complex logic
41
+ function processUserData(user) {
42
+ // ...
43
+ }
44
+
45
+ // ❌ Avoid — Functions longer than 30 lines (extract helpers)
46
+ ```
47
+
48
+ ### Async/Await
49
+ ```js
50
+ // ✅ Always use async/await over raw promises
51
+ async function fetchUser(id) {
52
+ try {
53
+ const user = await userRepository.findById(id);
54
+ return user;
55
+ } catch (error) {
56
+ throw new AppError('User not found', 404);
57
+ }
58
+ }
59
+
60
+ // ❌ Avoid promise chains
61
+ fetchUser(id).then(...).catch(...);
62
+ ```
63
+
64
+ ### Imports
65
+ ```js
66
+ // Order: 1. Node built-ins, 2. External deps, 3. Internal modules
67
+ import path from 'path';
68
+ import express from 'express';
69
+ import { UserService } from './user-service.js';
70
+ ```
71
+
72
+ ## Comments
73
+ ```js
74
+ // ✅ Explain WHY, not WHAT
75
+ // We retry 3 times because the external API has transient failures
76
+ const MAX_RETRIES = 3;
77
+
78
+ // ❌ Avoid obvious comments
79
+ // Set x to 5
80
+ const x = 5;
81
+ ```
82
+
83
+ ## File Organization
84
+ - One class/service per file
85
+ - Group related files in feature folders
86
+ - Index files for clean imports
@@ -0,0 +1,60 @@
1
+ doc# Database Rules
2
+
3
+ ## General Rules
4
+ - **Never** write raw SQL strings directly in business logic
5
+ - Always use an ORM (Prisma/Sequelize/TypeORM) or query builder
6
+ - All database calls must be inside try/catch blocks
7
+ - Use **transactions** for multi-step operations
8
+
9
+ ## Connection Management
10
+ ```js
11
+ // ✅ Use connection pooling
12
+ const pool = new Pool({ max: 10, idleTimeoutMillis: 30000 });
13
+
14
+ // ❌ Never create a new connection per request
15
+ ```
16
+
17
+ ## Query Best Practices
18
+ ```js
19
+ // ✅ Select only needed fields
20
+ const user = await db.user.findUnique({
21
+ where: { id },
22
+ select: { id: true, email: true, name: true }
23
+ });
24
+
25
+ // ❌ Avoid SELECT *
26
+ const user = await db.user.findUnique({ where: { id } });
27
+
28
+ // ✅ Use pagination for lists
29
+ const users = await db.user.findMany({
30
+ take: limit,
31
+ skip: (page - 1) * limit,
32
+ orderBy: { createdAt: 'desc' }
33
+ });
34
+ ```
35
+
36
+ ## Transactions
37
+ ```js
38
+ // ✅ Use transactions for atomic operations
39
+ await db.$transaction(async (tx) => {
40
+ const order = await tx.order.create({ data: orderData });
41
+ await tx.inventory.update({ where: { id: productId }, data: { stock: { decrement: 1 } } });
42
+ return order;
43
+ });
44
+ ```
45
+
46
+ ## Migrations
47
+ - Always use migration files, never modify the database schema directly
48
+ - Migration files are version-controlled and immutable
49
+ - Run migrations in CI/CD before deploying
50
+
51
+ ## Naming Conventions
52
+ - Tables: **snake_case** plural (`user_profiles`, `order_items`)
53
+ - Columns: **snake_case** (`created_at`, `user_id`)
54
+ - Indexes: `idx_[table]_[column]`
55
+ - Foreign keys: `fk_[table]_[referenced_table]`
56
+
57
+ ## Security
58
+ - Never log query results containing sensitive data (passwords, tokens)
59
+ - Use parameterized queries — never string concatenation
60
+ - Apply row-level security where applicable