trinity-method-sdk 2.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/CHANGELOG.md +116 -0
- package/LICENSE +21 -0
- package/README.md +555 -0
- package/dist/cli/commands/deploy/agents.d.ts +14 -0
- package/dist/cli/commands/deploy/agents.js +59 -0
- package/dist/cli/commands/deploy/ci-cd.d.ts +13 -0
- package/dist/cli/commands/deploy/ci-cd.js +50 -0
- package/dist/cli/commands/deploy/claude-setup.d.ts +17 -0
- package/dist/cli/commands/deploy/claude-setup.js +91 -0
- package/dist/cli/commands/deploy/configuration.d.ts +13 -0
- package/dist/cli/commands/deploy/configuration.js +215 -0
- package/dist/cli/commands/deploy/directories.d.ts +12 -0
- package/dist/cli/commands/deploy/directories.js +38 -0
- package/dist/cli/commands/deploy/gitignore.d.ts +12 -0
- package/dist/cli/commands/deploy/gitignore.js +53 -0
- package/dist/cli/commands/deploy/index.d.ts +38 -0
- package/dist/cli/commands/deploy/index.js +156 -0
- package/dist/cli/commands/deploy/knowledge-base.d.ts +16 -0
- package/dist/cli/commands/deploy/knowledge-base.js +75 -0
- package/dist/cli/commands/deploy/linting.d.ts +18 -0
- package/dist/cli/commands/deploy/linting.js +51 -0
- package/dist/cli/commands/deploy/metrics.d.ts +13 -0
- package/dist/cli/commands/deploy/metrics.js +34 -0
- package/dist/cli/commands/deploy/pre-flight.d.ts +13 -0
- package/dist/cli/commands/deploy/pre-flight.js +29 -0
- package/dist/cli/commands/deploy/root-files.d.ts +16 -0
- package/dist/cli/commands/deploy/root-files.js +178 -0
- package/dist/cli/commands/deploy/sdk-install.d.ts +12 -0
- package/dist/cli/commands/deploy/sdk-install.js +57 -0
- package/dist/cli/commands/deploy/summary.d.ts +14 -0
- package/dist/cli/commands/deploy/summary.js +130 -0
- package/dist/cli/commands/deploy/templates.d.ts +14 -0
- package/dist/cli/commands/deploy/templates.js +84 -0
- package/dist/cli/commands/deploy/types.d.ts +39 -0
- package/dist/cli/commands/deploy/types.js +5 -0
- package/dist/cli/commands/update/agents.d.ts +14 -0
- package/dist/cli/commands/update/agents.js +31 -0
- package/dist/cli/commands/update/backup.d.ts +31 -0
- package/dist/cli/commands/update/backup.js +97 -0
- package/dist/cli/commands/update/commands.d.ts +14 -0
- package/dist/cli/commands/update/commands.js +75 -0
- package/dist/cli/commands/update/index.d.ts +15 -0
- package/dist/cli/commands/update/index.js +118 -0
- package/dist/cli/commands/update/knowledge-base.d.ts +14 -0
- package/dist/cli/commands/update/knowledge-base.js +38 -0
- package/dist/cli/commands/update/pre-flight.d.ts +13 -0
- package/dist/cli/commands/update/pre-flight.js +37 -0
- package/dist/cli/commands/update/summary.d.ts +20 -0
- package/dist/cli/commands/update/summary.js +47 -0
- package/dist/cli/commands/update/templates.d.ts +14 -0
- package/dist/cli/commands/update/templates.js +25 -0
- package/dist/cli/commands/update/types.d.ts +13 -0
- package/dist/cli/commands/update/types.js +7 -0
- package/dist/cli/commands/update/utils.d.ts +11 -0
- package/dist/cli/commands/update/utils.js +19 -0
- package/dist/cli/commands/update/verification.d.ts +20 -0
- package/dist/cli/commands/update/verification.js +54 -0
- package/dist/cli/commands/update/version.d.ts +18 -0
- package/dist/cli/commands/update/version.js +36 -0
- package/dist/cli/commands/update.d.ts +7 -0
- package/dist/cli/commands/update.js +7 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.js +36 -0
- package/dist/cli/types.d.ts +77 -0
- package/dist/cli/types.js +5 -0
- package/dist/cli/utils/deploy-ci.d.ts +22 -0
- package/dist/cli/utils/deploy-ci.js +138 -0
- package/dist/cli/utils/deploy-linting.d.ts +3 -0
- package/dist/cli/utils/deploy-linting.js +136 -0
- package/dist/cli/utils/detect-stack.d.ts +3 -0
- package/dist/cli/utils/detect-stack.js +270 -0
- package/dist/cli/utils/error-classes.d.ts +63 -0
- package/dist/cli/utils/error-classes.js +84 -0
- package/dist/cli/utils/error-handler.d.ts +59 -0
- package/dist/cli/utils/error-handler.js +127 -0
- package/dist/cli/utils/errors.d.ts +52 -0
- package/dist/cli/utils/errors.js +102 -0
- package/dist/cli/utils/get-sdk-path.d.ts +18 -0
- package/dist/cli/utils/get-sdk-path.js +31 -0
- package/dist/cli/utils/inject-dependencies.d.ts +2 -0
- package/dist/cli/utils/inject-dependencies.js +55 -0
- package/dist/cli/utils/linting-tools.d.ts +8 -0
- package/dist/cli/utils/linting-tools.js +206 -0
- package/dist/cli/utils/metrics/code-quality.d.ts +32 -0
- package/dist/cli/utils/metrics/code-quality.js +122 -0
- package/dist/cli/utils/metrics/dependency-parser.d.ts +21 -0
- package/dist/cli/utils/metrics/dependency-parser.js +153 -0
- package/dist/cli/utils/metrics/file-complexity.d.ts +26 -0
- package/dist/cli/utils/metrics/file-complexity.js +77 -0
- package/dist/cli/utils/metrics/framework-detector.d.ts +17 -0
- package/dist/cli/utils/metrics/framework-detector.js +120 -0
- package/dist/cli/utils/metrics/git-metrics.d.ts +30 -0
- package/dist/cli/utils/metrics/git-metrics.js +83 -0
- package/dist/cli/utils/metrics/index.d.ts +28 -0
- package/dist/cli/utils/metrics/index.js +100 -0
- package/dist/cli/utils/template-processor.d.ts +10 -0
- package/dist/cli/utils/template-processor.js +188 -0
- package/dist/cli/utils/validate-path.d.ts +80 -0
- package/dist/cli/utils/validate-path.js +180 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +8 -0
- package/dist/templates/agents/aj-team/apo-documentation-specialist.md.template +572 -0
- package/dist/templates/agents/aj-team/bas-quality-gate.md.template +906 -0
- package/dist/templates/agents/aj-team/bon-dependency-manager.md.template +636 -0
- package/dist/templates/agents/aj-team/cap-configuration-specialist.md.template +670 -0
- package/dist/templates/agents/aj-team/dra-code-reviewer.md.template +768 -0
- package/dist/templates/agents/aj-team/kil-task-executor.md.template +764 -0
- package/dist/templates/agents/aj-team/uro-refactoring-specialist.md.template +759 -0
- package/dist/templates/agents/audit/juno-auditor.md.template +447 -0
- package/dist/templates/agents/deployment/ein-cicd.md.template +694 -0
- package/dist/templates/agents/deployment/ino-context.md.template +733 -0
- package/dist/templates/agents/deployment/tan-structure.md.template +661 -0
- package/dist/templates/agents/deployment/zen-knowledge.md.template +451 -0
- package/dist/templates/agents/leadership/aj-cc.md.template +462 -0
- package/dist/templates/agents/leadership/aj-maestro.md.template +943 -0
- package/dist/templates/agents/leadership/aly-cto.md.template +407 -0
- package/dist/templates/agents/planning/eus-decomposer.md.template +496 -0
- package/dist/templates/agents/planning/mon-requirements.md.template +323 -0
- package/dist/templates/agents/planning/ror-design.md.template +465 -0
- package/dist/templates/agents/planning/tra-planner.md.template +432 -0
- package/dist/templates/ci/cd.yml.template +175 -0
- package/dist/templates/ci/ci.yml.template +196 -0
- package/dist/templates/ci/generic-ci.yml +115 -0
- package/dist/templates/ci/github-actions.yml +86 -0
- package/dist/templates/ci/gitlab-ci.yml +103 -0
- package/dist/templates/claude/EMPLOYEE-DIRECTORY.md.template +545 -0
- package/dist/templates/documentation/ROOT-README.md.template +307 -0
- package/dist/templates/documentation/SUBDIRECTORY-README.md.template +261 -0
- package/dist/templates/investigations/bug.md.template +484 -0
- package/dist/templates/investigations/feature.md.template +564 -0
- package/dist/templates/investigations/performance.md.template +625 -0
- package/dist/templates/investigations/security.md.template +714 -0
- package/dist/templates/investigations/technical.md.template +433 -0
- package/dist/templates/knowledge-base/AI-DEVELOPMENT-GUIDE.md.template +957 -0
- package/dist/templates/knowledge-base/ARCHITECTURE.md.template +452 -0
- package/dist/templates/knowledge-base/CODING-PRINCIPLES.md.template +750 -0
- package/dist/templates/knowledge-base/DOCUMENTATION-CRITERIA.md.template +1118 -0
- package/dist/templates/knowledge-base/ISSUES.md.template +539 -0
- package/dist/templates/knowledge-base/TESTING-PRINCIPLES.md.template +894 -0
- package/dist/templates/knowledge-base/Technical-Debt.md.template +640 -0
- package/dist/templates/knowledge-base/To-do.md.template +407 -0
- package/dist/templates/knowledge-base/Trinity.md.template +464 -0
- package/dist/templates/linting/flutter/.pre-commit-config.yaml.template +27 -0
- package/dist/templates/linting/flutter/analysis_options.yaml.template +26 -0
- package/dist/templates/linting/nodejs/.eslintrc-commonjs.json.template +19 -0
- package/dist/templates/linting/nodejs/.eslintrc-esm.json.template +19 -0
- package/dist/templates/linting/nodejs/.eslintrc-typescript.json.template +22 -0
- package/dist/templates/linting/nodejs/.pre-commit-config.yaml.template +51 -0
- package/dist/templates/linting/nodejs/.prettierrc.json.template +10 -0
- package/dist/templates/linting/python/.flake8.template +16 -0
- package/dist/templates/linting/python/.pre-commit-config.yaml.template +30 -0
- package/dist/templates/linting/python/pyproject.toml.template +38 -0
- package/dist/templates/linting/rust/.pre-commit-config.yaml.template +28 -0
- package/dist/templates/linting/rust/clippy.toml.template +14 -0
- package/dist/templates/linting/rust/rustfmt.toml.template +12 -0
- package/dist/templates/root/CLAUDE.md.template +65 -0
- package/dist/templates/root/TRINITY.md.template +52 -0
- package/dist/templates/shared/claude-commands/trinity-agents.md.template +168 -0
- package/dist/templates/shared/claude-commands/trinity-audit.md.template +646 -0
- package/dist/templates/shared/claude-commands/trinity-changelog.md.template +624 -0
- package/dist/templates/shared/claude-commands/trinity-continue.md.template +549 -0
- package/dist/templates/shared/claude-commands/trinity-create-investigation.md.template +232 -0
- package/dist/templates/shared/claude-commands/trinity-decompose.md.template +181 -0
- package/dist/templates/shared/claude-commands/trinity-design.md.template +347 -0
- package/dist/templates/shared/claude-commands/trinity-docs.md.template +2093 -0
- package/dist/templates/shared/claude-commands/trinity-end.md.template +397 -0
- package/dist/templates/shared/claude-commands/trinity-init.md.template +606 -0
- package/dist/templates/shared/claude-commands/trinity-investigate-templates.md.template +725 -0
- package/dist/templates/shared/claude-commands/trinity-orchestrate.md.template +1061 -0
- package/dist/templates/shared/claude-commands/trinity-plan-investigation.md.template +135 -0
- package/dist/templates/shared/claude-commands/trinity-plan.md.template +201 -0
- package/dist/templates/shared/claude-commands/trinity-readme.md.template +1971 -0
- package/dist/templates/shared/claude-commands/trinity-requirements.md.template +148 -0
- package/dist/templates/shared/claude-commands/trinity-start.md.template +268 -0
- package/dist/templates/shared/claude-commands/trinity-verify.md.template +453 -0
- package/dist/templates/shared/claude-commands/trinity-workorder.md.template +249 -0
- package/dist/templates/source/base-CLAUDE.md.template +310 -0
- package/dist/templates/source/flutter-CLAUDE.md.template +593 -0
- package/dist/templates/source/nodejs-CLAUDE.md.template +531 -0
- package/dist/templates/source/python-CLAUDE.md.template +510 -0
- package/dist/templates/source/react-CLAUDE.md.template +513 -0
- package/dist/templates/source/rust-CLAUDE.md.template +653 -0
- package/dist/templates/source/tests-CLAUDE.md.template +432 -0
- package/dist/templates/trinity/CLAUDE.md.template +372 -0
- package/dist/templates/work-orders/ANALYSIS-TEMPLATE.md.template +276 -0
- package/dist/templates/work-orders/AUDIT-TEMPLATE.md.template +262 -0
- package/dist/templates/work-orders/IMPLEMENTATION-TEMPLATE.md.template +260 -0
- package/dist/templates/work-orders/INVESTIGATION-TEMPLATE.md.template +206 -0
- package/dist/templates/work-orders/PATTERN-TEMPLATE.md.template +320 -0
- package/dist/templates/work-orders/VERIFICATION-TEMPLATE.md.template +273 -0
- package/package.json +94 -0
|
@@ -0,0 +1,750 @@
|
|
|
1
|
+
# Coding Principles
|
|
2
|
+
|
|
3
|
+
**Version**: 2.0.0
|
|
4
|
+
**Last Updated**: {{date}}
|
|
5
|
+
**Project**: {{projectName}}
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Purpose
|
|
10
|
+
|
|
11
|
+
This document establishes coding standards and best practices for {{projectName}}. All code must adhere to these principles to ensure consistency, maintainability, and quality.
|
|
12
|
+
|
|
13
|
+
## 1. Function Design
|
|
14
|
+
|
|
15
|
+
### 1.1 Parameter Limit
|
|
16
|
+
|
|
17
|
+
**Rule**: Functions should have 0-2 parameters maximum.
|
|
18
|
+
|
|
19
|
+
**Rationale**: Functions with many parameters are difficult to understand, test, and maintain. They often indicate the function is doing too much.
|
|
20
|
+
|
|
21
|
+
**✅ Good Examples**:
|
|
22
|
+
|
|
23
|
+
```javascript
|
|
24
|
+
// 0 parameters - ideal for queries/getters
|
|
25
|
+
function getCurrentUser() {
|
|
26
|
+
return auth.user;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// 1 parameter - common and clear
|
|
30
|
+
function formatDate(date) {
|
|
31
|
+
return date.toISOString();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// 2 parameters - acceptable, still manageable
|
|
35
|
+
function createUser(email, password) {
|
|
36
|
+
return { email, password, createdAt: Date.now() };
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**❌ Bad Examples**:
|
|
41
|
+
|
|
42
|
+
```javascript
|
|
43
|
+
// 4 parameters - too many, hard to remember order
|
|
44
|
+
function createAccount(email, password, firstName, lastName) {
|
|
45
|
+
// ...
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// 6 parameters - terrible, impossible to use correctly
|
|
49
|
+
function processPayment(amount, currency, userId, cardNumber, cvv, expiry) {
|
|
50
|
+
// ...
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**✅ Refactoring Strategy - Use Configuration Objects**:
|
|
55
|
+
|
|
56
|
+
```javascript
|
|
57
|
+
// Refactor: Use config object for 3+ parameters
|
|
58
|
+
function createAccount(config) {
|
|
59
|
+
const { email, password, firstName, lastName } = config;
|
|
60
|
+
// ...
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Usage
|
|
64
|
+
createAccount({
|
|
65
|
+
email: 'user@example.com',
|
|
66
|
+
password: 'secure123',
|
|
67
|
+
firstName: 'John',
|
|
68
|
+
lastName: 'Doe'
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// Alternative: Use builder pattern for complex objects
|
|
72
|
+
const payment = new PaymentBuilder()
|
|
73
|
+
.amount(100)
|
|
74
|
+
.currency('USD')
|
|
75
|
+
.user(userId)
|
|
76
|
+
.card(cardDetails)
|
|
77
|
+
.build();
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### 1.2 Function Length
|
|
81
|
+
|
|
82
|
+
**Rule**: Functions should be 20-50 lines maximum, ideally <30 lines.
|
|
83
|
+
|
|
84
|
+
**Rationale**: Long functions are hard to understand, test, and maintain. They often do too much.
|
|
85
|
+
|
|
86
|
+
**✅ Good Example**:
|
|
87
|
+
|
|
88
|
+
```javascript
|
|
89
|
+
function validateUser(user) {
|
|
90
|
+
if (!user.email) {
|
|
91
|
+
throw new Error('Email required');
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (!isValidEmail(user.email)) {
|
|
95
|
+
throw new Error('Invalid email format');
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (!user.password || user.password.length < 8) {
|
|
99
|
+
throw new Error('Password must be at least 8 characters');
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return true;
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**❌ Bad Example**:
|
|
107
|
+
|
|
108
|
+
```javascript
|
|
109
|
+
function processOrder(order) {
|
|
110
|
+
// 150 lines of validation, calculation, database calls, email sending...
|
|
111
|
+
// Impossible to understand or test
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**✅ Refactoring Strategy - Extract Methods**:
|
|
116
|
+
|
|
117
|
+
```javascript
|
|
118
|
+
function processOrder(order) {
|
|
119
|
+
validateOrder(order);
|
|
120
|
+
const total = calculateTotal(order);
|
|
121
|
+
const payment = processPayment(order, total);
|
|
122
|
+
saveOrder(order, payment);
|
|
123
|
+
sendConfirmationEmail(order);
|
|
124
|
+
return { orderId: order.id, status: 'completed' };
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Each extracted function is focused and testable
|
|
128
|
+
function validateOrder(order) { /* ... */ }
|
|
129
|
+
function calculateTotal(order) { /* ... */ }
|
|
130
|
+
function processPayment(order, total) { /* ... */ }
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### 1.3 Single Responsibility Principle (SRP)
|
|
134
|
+
|
|
135
|
+
**Rule**: Each function should do one thing and do it well.
|
|
136
|
+
|
|
137
|
+
**✅ Good Examples**:
|
|
138
|
+
|
|
139
|
+
```javascript
|
|
140
|
+
// Focused: only validates email format
|
|
141
|
+
function isValidEmail(email) {
|
|
142
|
+
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Focused: only fetches user
|
|
146
|
+
async function getUserById(id) {
|
|
147
|
+
return await db.users.findOne({ id });
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Focused: only formats display name
|
|
151
|
+
function formatUserName(user) {
|
|
152
|
+
return `${user.firstName} ${user.lastName}`;
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
**❌ Bad Examples**:
|
|
157
|
+
|
|
158
|
+
```javascript
|
|
159
|
+
// Does too much: validates, saves, sends email, logs
|
|
160
|
+
async function registerUser(userData) {
|
|
161
|
+
// Validation
|
|
162
|
+
if (!isValidEmail(userData.email)) throw new Error('Invalid email');
|
|
163
|
+
|
|
164
|
+
// Database
|
|
165
|
+
const user = await db.users.create(userData);
|
|
166
|
+
|
|
167
|
+
// Email
|
|
168
|
+
await sendWelcomeEmail(user.email);
|
|
169
|
+
|
|
170
|
+
// Logging
|
|
171
|
+
logger.info(`User registered: ${user.id}`);
|
|
172
|
+
|
|
173
|
+
// Returns
|
|
174
|
+
return user;
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
**✅ Refactoring Strategy - Compose Functions**:
|
|
179
|
+
|
|
180
|
+
```javascript
|
|
181
|
+
async function registerUser(userData) {
|
|
182
|
+
validateUserData(userData);
|
|
183
|
+
const user = await createUser(userData);
|
|
184
|
+
await sendWelcomeEmail(user);
|
|
185
|
+
logUserRegistration(user);
|
|
186
|
+
return user;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Each function has a single responsibility
|
|
190
|
+
function validateUserData(data) { /* ... */ }
|
|
191
|
+
async function createUser(data) { /* ... */ }
|
|
192
|
+
async function sendWelcomeEmail(user) { /* ... */ }
|
|
193
|
+
function logUserRegistration(user) { /* ... */ }
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## 2. Error Handling
|
|
199
|
+
|
|
200
|
+
### 2.1 Always Use Try-Catch for Async Operations
|
|
201
|
+
|
|
202
|
+
**Rule**: All async operations must be wrapped in try-catch blocks.
|
|
203
|
+
|
|
204
|
+
**Rationale**: Unhandled promise rejections crash applications. Explicit error handling makes code robust.
|
|
205
|
+
|
|
206
|
+
**✅ Good Examples**:
|
|
207
|
+
|
|
208
|
+
```javascript
|
|
209
|
+
async function fetchUserData(userId) {
|
|
210
|
+
try {
|
|
211
|
+
const response = await api.get(`/users/${userId}`);
|
|
212
|
+
return response.data;
|
|
213
|
+
} catch (error) {
|
|
214
|
+
logger.error('Failed to fetch user:', error);
|
|
215
|
+
throw new Error(`User fetch failed: ${error.message}`);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
async function saveDocument(doc) {
|
|
220
|
+
try {
|
|
221
|
+
await db.documents.insert(doc);
|
|
222
|
+
return { success: true };
|
|
223
|
+
} catch (error) {
|
|
224
|
+
if (error.code === 'DUPLICATE_KEY') {
|
|
225
|
+
throw new Error('Document already exists');
|
|
226
|
+
}
|
|
227
|
+
throw error; // Re-throw unknown errors
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
**❌ Bad Examples**:
|
|
233
|
+
|
|
234
|
+
```javascript
|
|
235
|
+
// Missing try-catch - will crash on error
|
|
236
|
+
async function fetchUserData(userId) {
|
|
237
|
+
const response = await api.get(`/users/${userId}`);
|
|
238
|
+
return response.data;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Silent failure - errors swallowed
|
|
242
|
+
async function saveDocument(doc) {
|
|
243
|
+
try {
|
|
244
|
+
await db.documents.insert(doc);
|
|
245
|
+
} catch (error) {
|
|
246
|
+
// Empty catch - error disappears
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### 2.2 Meaningful Error Messages
|
|
252
|
+
|
|
253
|
+
**Rule**: Error messages must be descriptive and actionable.
|
|
254
|
+
|
|
255
|
+
**✅ Good Examples**:
|
|
256
|
+
|
|
257
|
+
```javascript
|
|
258
|
+
if (!user.email) {
|
|
259
|
+
throw new Error('Email is required for user registration');
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (age < 18) {
|
|
263
|
+
throw new Error('User must be at least 18 years old to register');
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (!fs.existsSync(filePath)) {
|
|
267
|
+
throw new Error(`File not found: ${filePath}. Please check the path and try again.`);
|
|
268
|
+
}
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
**❌ Bad Examples**:
|
|
272
|
+
|
|
273
|
+
```javascript
|
|
274
|
+
if (!user.email) {
|
|
275
|
+
throw new Error('Invalid'); // What's invalid?
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
if (age < 18) {
|
|
279
|
+
throw new Error('Error'); // Useless
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
if (!fs.existsSync(filePath)) {
|
|
283
|
+
throw new Error('Failed'); // No context
|
|
284
|
+
}
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### 2.3 Custom Error Classes
|
|
288
|
+
|
|
289
|
+
**Rule**: Use custom error classes for domain-specific errors.
|
|
290
|
+
|
|
291
|
+
**✅ Good Example**:
|
|
292
|
+
|
|
293
|
+
```javascript
|
|
294
|
+
class ValidationError extends Error {
|
|
295
|
+
constructor(field, message) {
|
|
296
|
+
super(message);
|
|
297
|
+
this.name = 'ValidationError';
|
|
298
|
+
this.field = field;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
class NotFoundError extends Error {
|
|
303
|
+
constructor(resource, id) {
|
|
304
|
+
super(`${resource} not found: ${id}`);
|
|
305
|
+
this.name = 'NotFoundError';
|
|
306
|
+
this.resource = resource;
|
|
307
|
+
this.id = id;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// Usage
|
|
312
|
+
if (!user) {
|
|
313
|
+
throw new NotFoundError('User', userId);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Catching specific errors
|
|
317
|
+
try {
|
|
318
|
+
await registerUser(data);
|
|
319
|
+
} catch (error) {
|
|
320
|
+
if (error instanceof ValidationError) {
|
|
321
|
+
return { error: error.message, field: error.field };
|
|
322
|
+
}
|
|
323
|
+
throw error;
|
|
324
|
+
}
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
---
|
|
328
|
+
|
|
329
|
+
## 3. Code Organization
|
|
330
|
+
|
|
331
|
+
### 3.1 DRY Principle (Don't Repeat Yourself)
|
|
332
|
+
|
|
333
|
+
**Rule**: Avoid code duplication. Extract common logic into reusable functions.
|
|
334
|
+
|
|
335
|
+
**❌ Bad Example**:
|
|
336
|
+
|
|
337
|
+
```javascript
|
|
338
|
+
function processAdminUser(user) {
|
|
339
|
+
if (!user.email) throw new Error('Email required');
|
|
340
|
+
if (!isValidEmail(user.email)) throw new Error('Invalid email');
|
|
341
|
+
if (!user.password || user.password.length < 8) throw new Error('Password too short');
|
|
342
|
+
// Admin-specific logic
|
|
343
|
+
user.role = 'admin';
|
|
344
|
+
return user;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
function processRegularUser(user) {
|
|
348
|
+
if (!user.email) throw new Error('Email required');
|
|
349
|
+
if (!isValidEmail(user.email)) throw new Error('Invalid email');
|
|
350
|
+
if (!user.password || user.password.length < 8) throw new Error('Password too short');
|
|
351
|
+
// Regular user logic
|
|
352
|
+
user.role = 'user';
|
|
353
|
+
return user;
|
|
354
|
+
}
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
**✅ Good Example**:
|
|
358
|
+
|
|
359
|
+
```javascript
|
|
360
|
+
function validateUser(user) {
|
|
361
|
+
if (!user.email) throw new Error('Email required');
|
|
362
|
+
if (!isValidEmail(user.email)) throw new Error('Invalid email');
|
|
363
|
+
if (!user.password || user.password.length < 8) throw new Error('Password too short');
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
function processAdminUser(user) {
|
|
367
|
+
validateUser(user);
|
|
368
|
+
user.role = 'admin';
|
|
369
|
+
return user;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
function processRegularUser(user) {
|
|
373
|
+
validateUser(user);
|
|
374
|
+
user.role = 'user';
|
|
375
|
+
return user;
|
|
376
|
+
}
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
### 3.2 File Organization
|
|
380
|
+
|
|
381
|
+
**Rule**: Group related functionality, limit file size to 200-300 lines.
|
|
382
|
+
|
|
383
|
+
**✅ Good Structure**:
|
|
384
|
+
|
|
385
|
+
```
|
|
386
|
+
src/
|
|
387
|
+
services/
|
|
388
|
+
userService.js # User CRUD operations
|
|
389
|
+
authService.js # Authentication logic
|
|
390
|
+
emailService.js # Email sending
|
|
391
|
+
utils/
|
|
392
|
+
validation.js # Validation helpers
|
|
393
|
+
formatting.js # Formatting utilities
|
|
394
|
+
models/
|
|
395
|
+
User.js # User model
|
|
396
|
+
Post.js # Post model
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
**❌ Bad Structure**:
|
|
400
|
+
|
|
401
|
+
```
|
|
402
|
+
src/
|
|
403
|
+
utils.js # 2000 lines, everything mixed
|
|
404
|
+
helpers.js # 1500 lines, random functions
|
|
405
|
+
index.js # 3000 lines, all logic here
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
### 3.3 Import Organization
|
|
409
|
+
|
|
410
|
+
**Rule**: Organize imports in logical groups: external, internal, relative.
|
|
411
|
+
|
|
412
|
+
**✅ Good Example**:
|
|
413
|
+
|
|
414
|
+
```javascript
|
|
415
|
+
// External dependencies
|
|
416
|
+
const express = require('express');
|
|
417
|
+
const jwt = require('jsonwebtoken');
|
|
418
|
+
|
|
419
|
+
// Internal modules
|
|
420
|
+
const userService = require('../services/userService');
|
|
421
|
+
const authMiddleware = require('../middleware/auth');
|
|
422
|
+
|
|
423
|
+
// Relative imports
|
|
424
|
+
const config = require('./config');
|
|
425
|
+
const helpers = require('./helpers');
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
**❌ Bad Example**:
|
|
429
|
+
|
|
430
|
+
```javascript
|
|
431
|
+
// Random order, hard to scan
|
|
432
|
+
const helpers = require('./helpers');
|
|
433
|
+
const express = require('express');
|
|
434
|
+
const config = require('./config');
|
|
435
|
+
const jwt = require('jsonwebtoken');
|
|
436
|
+
const userService = require('../services/userService');
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
---
|
|
440
|
+
|
|
441
|
+
## 4. Naming Conventions
|
|
442
|
+
|
|
443
|
+
### 4.1 Descriptive Names
|
|
444
|
+
|
|
445
|
+
**Rule**: Names should reveal intent without needing comments.
|
|
446
|
+
|
|
447
|
+
**✅ Good Examples**:
|
|
448
|
+
|
|
449
|
+
```javascript
|
|
450
|
+
const activeUsers = users.filter(u => u.isActive);
|
|
451
|
+
const formattedDate = formatDate(date);
|
|
452
|
+
function calculateOrderTotal(order) { /* ... */ }
|
|
453
|
+
function sendWelcomeEmail(user) { /* ... */ }
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
**❌ Bad Examples**:
|
|
457
|
+
|
|
458
|
+
```javascript
|
|
459
|
+
const x = users.filter(u => u.isActive); // What is x?
|
|
460
|
+
const temp = formatDate(date); // Temporary what?
|
|
461
|
+
function calc(o) { /* ... */ } // Calculate what?
|
|
462
|
+
function send(u) { /* ... */ } // Send what?
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
### 4.2 Naming Patterns
|
|
466
|
+
|
|
467
|
+
**Rule**: Follow consistent naming patterns.
|
|
468
|
+
|
|
469
|
+
- **Variables/Functions**: camelCase (`getUserName`, `totalPrice`)
|
|
470
|
+
- **Classes**: PascalCase (`UserService`, `PaymentProcessor`)
|
|
471
|
+
- **Constants**: UPPER_SNAKE_CASE (`MAX_RETRY_ATTEMPTS`, `API_BASE_URL`)
|
|
472
|
+
- **Private**: prefix with `_` (`_internalHelper`, `_validateInput`)
|
|
473
|
+
- **Booleans**: use `is/has/should` prefixes (`isActive`, `hasPermission`, `shouldRetry`)
|
|
474
|
+
|
|
475
|
+
**✅ Good Examples**:
|
|
476
|
+
|
|
477
|
+
```javascript
|
|
478
|
+
const MAX_LOGIN_ATTEMPTS = 3;
|
|
479
|
+
const isAuthenticated = checkAuth();
|
|
480
|
+
const hasPermission = user.permissions.includes('admin');
|
|
481
|
+
|
|
482
|
+
class UserService {
|
|
483
|
+
_internalCache = new Map();
|
|
484
|
+
|
|
485
|
+
async getUser(id) { /* ... */ }
|
|
486
|
+
|
|
487
|
+
_validateUser(user) { /* ... */ }
|
|
488
|
+
}
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
---
|
|
492
|
+
|
|
493
|
+
## 5. Comments & Documentation
|
|
494
|
+
|
|
495
|
+
### 5.1 Self-Documenting Code
|
|
496
|
+
|
|
497
|
+
**Rule**: Code should be self-explanatory. Use comments only for "why", not "what".
|
|
498
|
+
|
|
499
|
+
**✅ Good Examples**:
|
|
500
|
+
|
|
501
|
+
```javascript
|
|
502
|
+
// Good: Clear code, no comment needed
|
|
503
|
+
function calculateDiscountedPrice(price, discountPercent) {
|
|
504
|
+
return price * (1 - discountPercent / 100);
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
// Good: Comment explains "why" a non-obvious decision was made
|
|
508
|
+
function processLargeDataset(data) {
|
|
509
|
+
// Using chunking to avoid memory overflow on datasets >10MB
|
|
510
|
+
const chunkSize = 1000;
|
|
511
|
+
for (let i = 0; i < data.length; i += chunkSize) {
|
|
512
|
+
processChunk(data.slice(i, i + chunkSize));
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
// Good: Comment explains business rule
|
|
517
|
+
function calculateShipping(weight) {
|
|
518
|
+
// Free shipping for orders over 50 lbs per marketing policy
|
|
519
|
+
if (weight > 50) return 0;
|
|
520
|
+
return weight * 0.5;
|
|
521
|
+
}
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
**❌ Bad Examples**:
|
|
525
|
+
|
|
526
|
+
```javascript
|
|
527
|
+
// Bad: Comment states the obvious
|
|
528
|
+
// Add 1 to i
|
|
529
|
+
i = i + 1;
|
|
530
|
+
|
|
531
|
+
// Bad: Comment describes what code already shows
|
|
532
|
+
// Loop through users
|
|
533
|
+
users.forEach(user => {
|
|
534
|
+
// Print user name
|
|
535
|
+
console.log(user.name);
|
|
536
|
+
});
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
### 5.2 JSDoc for Public APIs
|
|
540
|
+
|
|
541
|
+
**Rule**: Document public functions with JSDoc.
|
|
542
|
+
|
|
543
|
+
**✅ Good Example**:
|
|
544
|
+
|
|
545
|
+
```javascript
|
|
546
|
+
/**
|
|
547
|
+
* Retrieves user by ID from the database
|
|
548
|
+
* @param {string} userId - The unique user identifier
|
|
549
|
+
* @returns {Promise<User>} User object
|
|
550
|
+
* @throws {NotFoundError} If user doesn't exist
|
|
551
|
+
* @example
|
|
552
|
+
* const user = await getUserById('123');
|
|
553
|
+
*/
|
|
554
|
+
async function getUserById(userId) {
|
|
555
|
+
const user = await db.users.findOne({ id: userId });
|
|
556
|
+
if (!user) {
|
|
557
|
+
throw new NotFoundError('User', userId);
|
|
558
|
+
}
|
|
559
|
+
return user;
|
|
560
|
+
}
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
---
|
|
564
|
+
|
|
565
|
+
## 6. Performance Considerations
|
|
566
|
+
|
|
567
|
+
### 6.1 Avoid Premature Optimization
|
|
568
|
+
|
|
569
|
+
**Rule**: Write clear code first, optimize only when needed (with profiling data).
|
|
570
|
+
|
|
571
|
+
**✅ Good Approach**:
|
|
572
|
+
|
|
573
|
+
```javascript
|
|
574
|
+
// Clear, readable, probably fast enough
|
|
575
|
+
function findUser(users, id) {
|
|
576
|
+
return users.find(u => u.id === id);
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
// Only optimize if profiling shows this is a bottleneck:
|
|
580
|
+
// Map for O(1) lookup if findUser is called frequently
|
|
581
|
+
const userMap = new Map(users.map(u => [u.id, u]));
|
|
582
|
+
function findUserOptimized(id) {
|
|
583
|
+
return userMap.get(id);
|
|
584
|
+
}
|
|
585
|
+
```
|
|
586
|
+
|
|
587
|
+
### 6.2 Avoid N+1 Queries
|
|
588
|
+
|
|
589
|
+
**Rule**: Batch database queries when possible.
|
|
590
|
+
|
|
591
|
+
**❌ Bad Example (N+1)**:
|
|
592
|
+
|
|
593
|
+
```javascript
|
|
594
|
+
async function getUsersWithPosts(userIds) {
|
|
595
|
+
const users = await db.users.find({ id: { $in: userIds } });
|
|
596
|
+
|
|
597
|
+
// N+1: Separate query for each user
|
|
598
|
+
for (const user of users) {
|
|
599
|
+
user.posts = await db.posts.find({ userId: user.id });
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
return users;
|
|
603
|
+
}
|
|
604
|
+
```
|
|
605
|
+
|
|
606
|
+
**✅ Good Example (Batched)**:
|
|
607
|
+
|
|
608
|
+
```javascript
|
|
609
|
+
async function getUsersWithPosts(userIds) {
|
|
610
|
+
const users = await db.users.find({ id: { $in: userIds } });
|
|
611
|
+
|
|
612
|
+
// Single query for all posts
|
|
613
|
+
const allPosts = await db.posts.find({
|
|
614
|
+
userId: { $in: users.map(u => u.id) }
|
|
615
|
+
});
|
|
616
|
+
|
|
617
|
+
// Group posts by user
|
|
618
|
+
const postsByUser = allPosts.reduce((acc, post) => {
|
|
619
|
+
if (!acc[post.userId]) acc[post.userId] = [];
|
|
620
|
+
acc[post.userId].push(post);
|
|
621
|
+
return acc;
|
|
622
|
+
}, {});
|
|
623
|
+
|
|
624
|
+
// Attach posts to users
|
|
625
|
+
users.forEach(user => {
|
|
626
|
+
user.posts = postsByUser[user.id] || [];
|
|
627
|
+
});
|
|
628
|
+
|
|
629
|
+
return users;
|
|
630
|
+
}
|
|
631
|
+
```
|
|
632
|
+
|
|
633
|
+
---
|
|
634
|
+
|
|
635
|
+
## 7. Testing Considerations
|
|
636
|
+
|
|
637
|
+
### 7.1 Write Testable Code
|
|
638
|
+
|
|
639
|
+
**Rule**: Design functions to be easy to test (pure functions, dependency injection).
|
|
640
|
+
|
|
641
|
+
**✅ Good Examples**:
|
|
642
|
+
|
|
643
|
+
```javascript
|
|
644
|
+
// Pure function - easy to test
|
|
645
|
+
function calculateTax(amount, rate) {
|
|
646
|
+
return amount * rate;
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
// Dependency injection - mockable
|
|
650
|
+
function createUserService(database) {
|
|
651
|
+
return {
|
|
652
|
+
async getUser(id) {
|
|
653
|
+
return await database.users.findOne({ id });
|
|
654
|
+
}
|
|
655
|
+
};
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
// Usage in tests
|
|
659
|
+
const mockDb = { users: { findOne: jest.fn() } };
|
|
660
|
+
const service = createUserService(mockDb);
|
|
661
|
+
```
|
|
662
|
+
|
|
663
|
+
**❌ Bad Examples**:
|
|
664
|
+
|
|
665
|
+
```javascript
|
|
666
|
+
// Hard to test - uses global state
|
|
667
|
+
function calculateTax(amount) {
|
|
668
|
+
return amount * window.TAX_RATE; // Coupled to window
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
// Hard to test - hardcoded dependency
|
|
672
|
+
function createUserService() {
|
|
673
|
+
return {
|
|
674
|
+
async getUser(id) {
|
|
675
|
+
return await realDatabase.users.findOne({ id }); // Can't mock
|
|
676
|
+
}
|
|
677
|
+
};
|
|
678
|
+
}
|
|
679
|
+
```
|
|
680
|
+
|
|
681
|
+
---
|
|
682
|
+
|
|
683
|
+
## Enforcement
|
|
684
|
+
|
|
685
|
+
### Automated Tools
|
|
686
|
+
|
|
687
|
+
- **ESLint**: Configured to enforce style rules
|
|
688
|
+
- **Prettier**: Auto-format code
|
|
689
|
+
- **BAS Quality Gate**: Phase 6 validates compliance with these principles
|
|
690
|
+
|
|
691
|
+
### Code Review Checklist
|
|
692
|
+
|
|
693
|
+
During code review, verify:
|
|
694
|
+
- [ ] Functions have 0-2 parameters (or use config objects)
|
|
695
|
+
- [ ] Functions are <50 lines (ideally <30)
|
|
696
|
+
- [ ] Each function has single responsibility
|
|
697
|
+
- [ ] Async operations use try-catch
|
|
698
|
+
- [ ] Error messages are descriptive
|
|
699
|
+
- [ ] No code duplication (DRY)
|
|
700
|
+
- [ ] Names are descriptive and follow conventions
|
|
701
|
+
- [ ] Comments explain "why", not "what"
|
|
702
|
+
- [ ] Code is testable
|
|
703
|
+
|
|
704
|
+
### Compliance Scoring
|
|
705
|
+
|
|
706
|
+
ZEN analyzes code against these principles and calculates compliance score:
|
|
707
|
+
- **90-100**: Excellent - fully compliant
|
|
708
|
+
- **80-89**: Good - minor issues
|
|
709
|
+
- **70-79**: Acceptable - some violations
|
|
710
|
+
- **<70**: Needs improvement - significant violations
|
|
711
|
+
|
|
712
|
+
---
|
|
713
|
+
|
|
714
|
+
## References
|
|
715
|
+
|
|
716
|
+
- Clean Code by Robert C. Martin
|
|
717
|
+
- JavaScript: The Good Parts by Douglas Crockford
|
|
718
|
+
- Effective JavaScript by David Herman
|
|
719
|
+
|
|
720
|
+
---
|
|
721
|
+
|
|
722
|
+
## 📝 WHEN TO UPDATE THIS DOCUMENT
|
|
723
|
+
|
|
724
|
+
This **standards document** updates infrequently - only when coding standards evolve.
|
|
725
|
+
|
|
726
|
+
### When to Update ⚠️
|
|
727
|
+
|
|
728
|
+
Update **only when standards change**:
|
|
729
|
+
|
|
730
|
+
- ✅ **New Pattern Discovered**: Team discovers recurring good/bad pattern worth documenting
|
|
731
|
+
- ✅ **Framework Upgrade**: New framework version introduces new best practices
|
|
732
|
+
- ✅ **Standard Violation**: Issue reveals gap in current standards (add principle to prevent)
|
|
733
|
+
- ✅ **Refactoring Pattern**: Team discovers better refactoring strategy worth sharing
|
|
734
|
+
|
|
735
|
+
### How to Update
|
|
736
|
+
|
|
737
|
+
1. Add new good/bad example pair to relevant section
|
|
738
|
+
2. Update framework-specific patterns if framework changed
|
|
739
|
+
3. Cross-reference to ISSUES.md if pattern prevents known issue
|
|
740
|
+
4. Update timestamp: `Last reviewed: {{date}}`
|
|
741
|
+
|
|
742
|
+
**Cross-References**: When updating, check [ISSUES.md](./ISSUES.md) - does new standard prevent known issues?
|
|
743
|
+
|
|
744
|
+
**Update Frequency**: Rare (quarterly or less) - standards are stable
|
|
745
|
+
|
|
746
|
+
---
|
|
747
|
+
|
|
748
|
+
**Document maintained by**: ZEN (Documentation Specialist)
|
|
749
|
+
**Enforced by**: BAS (Quality Fixer), DRA (Code Reviewer)
|
|
750
|
+
**Last reviewed**: {{date}}
|