@ryuenn3123/agentic-senior-core 1.8.0 → 1.8.1
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/.agent-context/blueprints/mobile-app.md +21 -0
- package/.agent-context/review-checklists/frontend-skill-parity.md +28 -0
- package/.agent-context/skills/README.md +63 -0
- package/.agent-context/skills/backend/README.md +68 -0
- package/.agent-context/skills/backend/architecture.md +361 -0
- package/.agent-context/skills/backend/data-access.md +231 -0
- package/.agent-context/skills/backend/errors.md +138 -0
- package/.agent-context/skills/backend/validation.md +117 -0
- package/.agent-context/skills/backend.md +29 -0
- package/.agent-context/skills/cli/README.md +50 -0
- package/.agent-context/skills/cli/init.md +38 -0
- package/.agent-context/skills/cli/output.md +36 -0
- package/.agent-context/skills/cli/upgrade.md +38 -0
- package/.agent-context/skills/cli.md +29 -0
- package/.agent-context/skills/distribution/README.md +19 -0
- package/.agent-context/skills/distribution/compatibility.md +32 -0
- package/.agent-context/skills/distribution/publish.md +37 -0
- package/.agent-context/skills/distribution/rollback.md +32 -0
- package/.agent-context/skills/distribution.md +29 -0
- package/.agent-context/skills/frontend/README.md +36 -0
- package/.agent-context/skills/frontend/accessibility.md +107 -0
- package/.agent-context/skills/frontend/motion.md +67 -0
- package/.agent-context/skills/frontend/performance.md +63 -0
- package/.agent-context/skills/frontend/ui-architecture.md +128 -0
- package/.agent-context/skills/frontend.md +30 -0
- package/.agent-context/skills/fullstack/README.md +19 -0
- package/.agent-context/skills/fullstack/contracts.md +53 -0
- package/.agent-context/skills/fullstack/end-to-end.md +42 -0
- package/.agent-context/skills/fullstack/feature-slicing.md +65 -0
- package/.agent-context/skills/fullstack.md +27 -0
- package/.agent-context/skills/index.json +107 -0
- package/.agent-context/skills/review-quality/README.md +19 -0
- package/.agent-context/skills/review-quality/benchmark.md +30 -0
- package/.agent-context/skills/review-quality/planning.md +38 -0
- package/.agent-context/skills/review-quality/security.md +34 -0
- package/.agent-context/skills/review-quality.md +28 -0
- package/.agent-context/stacks/flutter.md +16 -0
- package/.agent-context/stacks/react-native.md +16 -0
- package/.agent-context/state/benchmark-analysis.json +431 -0
- package/.agent-context/state/benchmark-thresholds.json +10 -0
- package/.agent-context/state/benchmark-watchlist.json +19 -0
- package/.agent-context/state/skill-platform.json +38 -0
- package/.cursorrules +1 -1
- package/.github/workflows/benchmark-intelligence.yml +50 -0
- package/.windsurfrules +1 -1
- package/README.md +81 -2
- package/bin/agentic-senior-core.js +412 -3
- package/package.json +4 -2
- package/scripts/benchmark-gate.mjs +121 -0
- package/scripts/benchmark-intelligence.mjs +140 -0
- package/scripts/skill-tier-policy.mjs +76 -0
- package/scripts/validate.mjs +82 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
# Database Patterns & Query Optimization
|
|
2
|
+
|
|
3
|
+
**Tier:** EXPERT | **Source:** awesome-copilot (schema design) + antigravity (N+1 patterns) + minimax (Django ORM)
|
|
4
|
+
|
|
5
|
+
## Part 1: Schema Design (3NF Normalization)
|
|
6
|
+
|
|
7
|
+
### The Problem: Data Redundancy
|
|
8
|
+
|
|
9
|
+
**Denormalized (redundant):**
|
|
10
|
+
```sql
|
|
11
|
+
CREATE TABLE orders (
|
|
12
|
+
id UUID PRIMARY KEY,
|
|
13
|
+
customer_name VARCHAR(255), -- Redundant: can look up from customers table
|
|
14
|
+
customer_email VARCHAR(255), -- Redundant
|
|
15
|
+
customer_tier VARCHAR(50), -- Redundant
|
|
16
|
+
amount DECIMAL(10,2),
|
|
17
|
+
created_at TIMESTAMP
|
|
18
|
+
);
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Problem: Update customer name -> must update in `orders` table too (data inconsistency risk).
|
|
22
|
+
|
|
23
|
+
### **3NF (Normalized):**
|
|
24
|
+
|
|
25
|
+
```sql
|
|
26
|
+
CREATE TABLE customers (
|
|
27
|
+
id UUID PRIMARY KEY,
|
|
28
|
+
name VARCHAR(255),
|
|
29
|
+
email VARCHAR(255),
|
|
30
|
+
tier VARCHAR(50),
|
|
31
|
+
created_at TIMESTAMP
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
CREATE TABLE orders (
|
|
35
|
+
id UUID PRIMARY KEY,
|
|
36
|
+
customer_id UUID NOT NULL REFERENCES customers(id),
|
|
37
|
+
amount DECIMAL(10,2),
|
|
38
|
+
created_at TIMESTAMP
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
-- To get order with customer name:
|
|
42
|
+
SELECT o.id, o.amount, c.name
|
|
43
|
+
FROM orders o
|
|
44
|
+
JOIN customers c ON o.customer_id = c.id;
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**Benefits:**
|
|
48
|
+
- Single source of truth (customer name in one place)
|
|
49
|
+
- Updates atomic (change name, not duplicated)
|
|
50
|
+
- Consistent joins
|
|
51
|
+
|
|
52
|
+
### When to Break 3NF (Denormalization)
|
|
53
|
+
|
|
54
|
+
Denormalize **only if** profiling shows JOIN is bottleneck:
|
|
55
|
+
|
|
56
|
+
```sql
|
|
57
|
+
-- ONLY if "SELECT ... JOIN customers" is slow:
|
|
58
|
+
ALTER TABLE orders ADD COLUMN customer_name VARCHAR(255);
|
|
59
|
+
|
|
60
|
+
-- Keep redundancy in sync with trigger:
|
|
61
|
+
CREATE TRIGGER sync_customer_name
|
|
62
|
+
AFTER UPDATE ON customers
|
|
63
|
+
FOR EACH ROW
|
|
64
|
+
UPDATE orders SET customer_name = NEW.name WHERE customer_id = NEW.id;
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Part 2: Indexes (FK + Query Optimization)
|
|
70
|
+
|
|
71
|
+
### Rule: Always Index Foreign Keys
|
|
72
|
+
|
|
73
|
+
```sql
|
|
74
|
+
CREATE TABLE orders (
|
|
75
|
+
id UUID PRIMARY KEY,
|
|
76
|
+
customer_id UUID NOT NULL REFERENCES customers(id),
|
|
77
|
+
created_at TIMESTAMP,
|
|
78
|
+
|
|
79
|
+
-- Foreign key queries need fast lookup
|
|
80
|
+
INDEX idx_customer_id (customer_id),
|
|
81
|
+
-- Query by date also common
|
|
82
|
+
INDEX idx_created_at (created_at)
|
|
83
|
+
);
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Without index on `customer_id`, query `SELECT * FROM orders WHERE customer_id = ?` scans entire table (O(n)).
|
|
87
|
+
|
|
88
|
+
With index, it's O(log n) via B-tree lookup.
|
|
89
|
+
|
|
90
|
+
### Composite Indexes (When Queries Filter by Multiple Columns)
|
|
91
|
+
|
|
92
|
+
```sql
|
|
93
|
+
-- If queries often filter by (customer_id, created_at > date):
|
|
94
|
+
INDEX idx_customer_date (customer_id, created_at DESC);
|
|
95
|
+
|
|
96
|
+
-- Good for: SELECT * FROM orders WHERE customer_id = ? AND created_at > ?
|
|
97
|
+
-- Bad for: SELECT * FROM orders WHERE created_at > ? (first column must match)
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Part 3: Query Patterns (Anti-Patterns)
|
|
103
|
+
|
|
104
|
+
### Anti-Pattern #1: N+1 Query Problem
|
|
105
|
+
|
|
106
|
+
**WRONG:**
|
|
107
|
+
```javascript
|
|
108
|
+
const customers = await db.query('SELECT * FROM customers');
|
|
109
|
+
for (const customer of customers) {
|
|
110
|
+
customer.orders = await db.query(
|
|
111
|
+
'SELECT * FROM orders WHERE customer_id = $1',
|
|
112
|
+
[customer.id] // <- Executes once per customer (N+1 queries!)
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**Cost:** 1 query (customers) + N queries (orders per customer) = **N+1 total**. If 100 customers, 101 queries.
|
|
118
|
+
|
|
119
|
+
**CORRECT (JOIN):**
|
|
120
|
+
```javascript
|
|
121
|
+
const results = await db.query(`
|
|
122
|
+
SELECT
|
|
123
|
+
c.id as customer_id,
|
|
124
|
+
c.name,
|
|
125
|
+
o.id as order_id,
|
|
126
|
+
o.amount
|
|
127
|
+
FROM customers c
|
|
128
|
+
LEFT JOIN orders o ON c.id = o.customer_id
|
|
129
|
+
`);
|
|
130
|
+
|
|
131
|
+
// Post-process to group
|
|
132
|
+
const customersWithOrders = {};
|
|
133
|
+
for (const row of results) {
|
|
134
|
+
if (!customersWithOrders[row.customer_id]) {
|
|
135
|
+
customersWithOrders[row.customer_id] = {
|
|
136
|
+
id: row.customer_id,
|
|
137
|
+
name: row.name,
|
|
138
|
+
orders: []
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
if (row.order_id) {
|
|
142
|
+
customersWithOrders[row.customer_id].orders.push({ id: row.order_id, amount: row.amount });
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
**Cost:** 1 JOIN query (fast).
|
|
148
|
+
|
|
149
|
+
### Anti-Pattern #2: SELECT * (Load Unnecessary Columns)
|
|
150
|
+
|
|
151
|
+
**WRONG:**
|
|
152
|
+
```javascript
|
|
153
|
+
const customer = await db.one('SELECT * FROM customers WHERE id = $1', [id]);
|
|
154
|
+
console.log(customer.name); // But loaded email, phone, address too
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
**CORRECT (Project columns):**
|
|
158
|
+
```javascript
|
|
159
|
+
const customer = await db.one(
|
|
160
|
+
'SELECT id, name, email FROM customers WHERE id = $1',
|
|
161
|
+
[id] // Only load what's needed
|
|
162
|
+
);
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## Part 4: Safe Zero-Downtime Migrations
|
|
168
|
+
|
|
169
|
+
### The Problem: Data Migrations Block Requests
|
|
170
|
+
|
|
171
|
+
```sql
|
|
172
|
+
ALTER TABLE customers ADD COLUMN phone VARCHAR(20);
|
|
173
|
+
-- ^ Blocks all INSERT/UPDATE on customers table during migration (can be seconds~minutes for large tables)
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Strategy: Backward-Compatible Migrations
|
|
177
|
+
|
|
178
|
+
**Step 1: Add column (no default = already nullable):**
|
|
179
|
+
```sql
|
|
180
|
+
ALTER TABLE customers ADD COLUMN phone VARCHAR(20);
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
**Step 2: Backfill data (in batches to avoid lock):**
|
|
184
|
+
```javascript
|
|
185
|
+
// Run offline / in background job
|
|
186
|
+
const BATCH_SIZE = 10000;
|
|
187
|
+
let offset = 0;
|
|
188
|
+
while (true) {
|
|
189
|
+
const updated = await db.query(`
|
|
190
|
+
UPDATE customers
|
|
191
|
+
SET phone = ''
|
|
192
|
+
WHERE id IN (
|
|
193
|
+
SELECT id FROM customers
|
|
194
|
+
WHERE phone IS NULL
|
|
195
|
+
LIMIT $1
|
|
196
|
+
)
|
|
197
|
+
`, [BATCH_SIZE]);
|
|
198
|
+
if (updated.rowCount === 0) break;
|
|
199
|
+
offset += BATCH_SIZE;
|
|
200
|
+
await sleep(1000); // Rate limit to avoid overwhelming DB
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
**Step 3: Code deployment (app handles both old + new):**
|
|
205
|
+
```javascript
|
|
206
|
+
// Service layer reads/writes phone
|
|
207
|
+
if (newCustomer.phone) {
|
|
208
|
+
await customerRepo.update(customerId, { phone: newCustomer.phone });
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Old code still works (ignores phone), new code uses it.
|
|
213
|
+
|
|
214
|
+
**Step 4: After migration successful, remove the column (or rename old):**
|
|
215
|
+
```sql
|
|
216
|
+
-- Keep old column renamed for rollback safety
|
|
217
|
+
ALTER TABLE customers RENAME COLUMN phone_old TO phone_deprecated;
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## Checklist
|
|
223
|
+
|
|
224
|
+
- [ ] All tables in 3NF
|
|
225
|
+
- [ ] Foreign keys indexed
|
|
226
|
+
- [ ] JOIN queries avoid N+1 (load related data in one query)
|
|
227
|
+
- [ ] SELECT projects specific columns (not *)
|
|
228
|
+
- [ ] Indexes match WHERE + ORDER BY + JOIN ON patterns
|
|
229
|
+
- [ ] Migrations backward-compatible + batched
|
|
230
|
+
- [ ] Query performance profiled (EXPLAIN ANALYZE)
|
|
231
|
+
- Watch for N+1 and hidden coupling.
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# Error Handling & Recovery
|
|
2
|
+
|
|
3
|
+
**Tier:** ADVANCE | **Source:** awesome-copilot (typed errors) + antigravity (recovery patterns) + minimax (error boundary)
|
|
4
|
+
|
|
5
|
+
## Rule: Never Swallow Errors
|
|
6
|
+
|
|
7
|
+
**WRONG:**
|
|
8
|
+
```javascript
|
|
9
|
+
try {
|
|
10
|
+
const payment = await processPayment();
|
|
11
|
+
} catch (err) {
|
|
12
|
+
console.log('oops'); // <- Error lost, no recovery
|
|
13
|
+
}
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
**CORRECT:**
|
|
17
|
+
```javascript
|
|
18
|
+
try {
|
|
19
|
+
const payment = await processPayment();
|
|
20
|
+
} catch (err) {
|
|
21
|
+
if (err instanceof PaymentDeclinedError) {
|
|
22
|
+
// KNOWN: Card declined, user can try again with different card
|
|
23
|
+
throw err;
|
|
24
|
+
} else if (err instanceof NetworkTimeoutError) {
|
|
25
|
+
// MAYBE TEMPORARY: Retry with exponential backoff
|
|
26
|
+
return await retryWithBackoff(() => processPayment());
|
|
27
|
+
} else {
|
|
28
|
+
// UNKNOWN: Log + alert ops team
|
|
29
|
+
logger.error({ err, context: { customerId, amount } });
|
|
30
|
+
throw new InternalServerError('Payment processing failed');
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Typed Error Codes
|
|
38
|
+
|
|
39
|
+
Instead of generic "Error", use specific, typed errors:
|
|
40
|
+
|
|
41
|
+
### Node.js + Custom Error Classes
|
|
42
|
+
|
|
43
|
+
```javascript
|
|
44
|
+
class ApplicationError extends Error {
|
|
45
|
+
constructor(code, message, statusCode = 500, details = {}) {
|
|
46
|
+
super(message);
|
|
47
|
+
this.code = code; // Machine-readable
|
|
48
|
+
this.statusCode = statusCode; // HTTP status
|
|
49
|
+
this.details = details;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
class PaymentDeclinedError extends ApplicationError {
|
|
54
|
+
constructor(reason) {
|
|
55
|
+
super('PAYMENT_DECLINED', `Card declined: ${reason}`, 402, { reason });
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Usage in service:
|
|
60
|
+
if (customer.balance < amount) {
|
|
61
|
+
throw new PaymentDeclinedError('Insufficient funds');
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Transport layer catches and responds:
|
|
65
|
+
app.post('/payments/charge', async (req, res) => {
|
|
66
|
+
try {
|
|
67
|
+
const result = await paymentService.charge(req.body);
|
|
68
|
+
res.json(result);
|
|
69
|
+
} catch (err) {
|
|
70
|
+
if (err instanceof ApplicationError) {
|
|
71
|
+
res.status(err.statusCode).json({
|
|
72
|
+
error: err.code,
|
|
73
|
+
message: err.message,
|
|
74
|
+
details: err.details
|
|
75
|
+
});
|
|
76
|
+
} else {
|
|
77
|
+
res.status(500).json({ error: 'INTERNAL_SERVER_ERROR' });
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Correlation IDs (Debug Multi-Service Requests)
|
|
86
|
+
|
|
87
|
+
When requests span multiple services, trace them with correlation IDs:
|
|
88
|
+
|
|
89
|
+
```javascript
|
|
90
|
+
// Transport layer: Generate or receive correlation ID
|
|
91
|
+
app.use((req, res, next) => {
|
|
92
|
+
req.correlationId = req.headers['x-correlation-id'] || generateUUID();
|
|
93
|
+
res.setHeader('x-correlation-id', req.correlationId);
|
|
94
|
+
next();
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// Service layer: Attach to all logs
|
|
98
|
+
logger.info({
|
|
99
|
+
message: 'Processing payment',
|
|
100
|
+
correlationId: req.correlationId,
|
|
101
|
+
customerId,
|
|
102
|
+
amount
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
// Logs across all services will have same correlationId
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Retry Strategy
|
|
111
|
+
|
|
112
|
+
```javascript
|
|
113
|
+
async function retryWithBackoff(fn, maxAttempts = 3) {
|
|
114
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
115
|
+
try {
|
|
116
|
+
return await fn();
|
|
117
|
+
} catch (err) {
|
|
118
|
+
if (attempt === maxAttempts) throw err;
|
|
119
|
+
if (!(err instanceof NetworkTimeoutError)) throw err;
|
|
120
|
+
|
|
121
|
+
const delay = Math.pow(2, attempt - 1) * 1000; // 1s, 2s, 4s
|
|
122
|
+
await sleep(delay);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Checklist
|
|
131
|
+
|
|
132
|
+
- [ ] All caught errors are typed (not generic `Error`)
|
|
133
|
+
- [ ] All errors have machine-readable code
|
|
134
|
+
- [ ] Production errors logged with context (correlationId, userId)
|
|
135
|
+
- [ ] Retry logic only for transient failures (timeouts, 5xx)
|
|
136
|
+
- [ ] User-level errors have helpful messages (no SQL/stack traces)
|
|
137
|
+
- [ ] Critical errors alert ops (Slack, PagerDuty)
|
|
138
|
+
- Keep retry and rollback behavior explicit.
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# Input Validation & Parameterized Queries
|
|
2
|
+
|
|
3
|
+
**Tier:** ADVANCE | **Source:** awesome-copilot (boundaries) + antigravity (security halt) + minimax (validation patterns)
|
|
4
|
+
|
|
5
|
+
## Why Validation at Boundaries Matters
|
|
6
|
+
|
|
7
|
+
Rule: **All external input is untrusted.** Validate at API entry point before touching business logic or database.
|
|
8
|
+
|
|
9
|
+
Common vulnerabilities when skipped:
|
|
10
|
+
- SQL injection: Unparameterized queries with user input
|
|
11
|
+
- Type confusion: String input treated as number
|
|
12
|
+
- Business logic bypass: Missing eligibility checks
|
|
13
|
+
- Data corruption: Invalid state transitions
|
|
14
|
+
|
|
15
|
+
**SECURITY HALT:** If you find unvalidated input directly in database queries, stop feature development. Fix first.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Layer 1: HTTP Request Validation
|
|
20
|
+
|
|
21
|
+
Validate shape, type, required fields **before** touching service layer.
|
|
22
|
+
|
|
23
|
+
### Node.js + Zod (Type-Safe)
|
|
24
|
+
|
|
25
|
+
```javascript
|
|
26
|
+
import { z } from 'zod';
|
|
27
|
+
|
|
28
|
+
const chargeSchema = z.object({
|
|
29
|
+
amount: z.number().min(50).max(100000),
|
|
30
|
+
customerId: z.string().uuid(),
|
|
31
|
+
cardToken: z.string().min(10).max(1000),
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
app.post('/payments/charge', async (req, res) => {
|
|
35
|
+
// Validate shape + types
|
|
36
|
+
const parsed = chargeSchema.safeParse(req.body);
|
|
37
|
+
if (!parsed.success) {
|
|
38
|
+
return res.status(400).json({
|
|
39
|
+
error: 'Invalid request',
|
|
40
|
+
details: parsed.error.errors
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Now safe to pass to service
|
|
45
|
+
const result = await paymentService.charge(parsed.data);
|
|
46
|
+
res.json(result);
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Python + Pydantic
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
from pydantic import BaseModel, Field
|
|
54
|
+
|
|
55
|
+
class ChargeRequest(BaseModel):
|
|
56
|
+
amount: float = Field(..., ge=50, le=100000)
|
|
57
|
+
customer_id: str = Field(..., min_length=36, max_length=36)
|
|
58
|
+
card_token: str = Field(..., min_length=10, max_length=1000)
|
|
59
|
+
|
|
60
|
+
@app.post("/payments/charge")
|
|
61
|
+
async def charge_payment(req: ChargeRequest):
|
|
62
|
+
result = await payment_service.charge(req.dict())
|
|
63
|
+
return result
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Layer 2: SQL Query Parameterization
|
|
69
|
+
|
|
70
|
+
### WRONG (SQL Injection)
|
|
71
|
+
|
|
72
|
+
```javascript
|
|
73
|
+
const customerId = req.body.customerId;
|
|
74
|
+
const query = `SELECT * FROM customers WHERE id = '${customerId}'`;
|
|
75
|
+
// Input: '; DROP TABLE customers; --'
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### CORRECT (Parameterized)
|
|
79
|
+
|
|
80
|
+
```javascript
|
|
81
|
+
await db.one(
|
|
82
|
+
'SELECT * FROM customers WHERE id = $1',
|
|
83
|
+
[customerId] // Parameterized
|
|
84
|
+
);
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Layer 3: Business Logic Validation
|
|
90
|
+
|
|
91
|
+
```javascript
|
|
92
|
+
async charge({ amount, customerId, cardToken }) {
|
|
93
|
+
// Already validated: amount in range, customerId is UUID
|
|
94
|
+
|
|
95
|
+
// Now validate business rules
|
|
96
|
+
const customer = await customerRepo.findById(customerId);
|
|
97
|
+
if (!customer) throw new NotFoundError('Customer');
|
|
98
|
+
if (customer.status !== 'active') throw new BusinessError('Account suspended');
|
|
99
|
+
if (customer.dailyLimit && customer.dailySpent + amount > customer.dailyLimit) {
|
|
100
|
+
throw new BusinessError('Daily limit exceeded');
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Safe to proceed
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Checklist
|
|
110
|
+
|
|
111
|
+
- [ ] All route handlers validate request shape (Zod/Pydantic)
|
|
112
|
+
- [ ] All database queries use parameterized statements
|
|
113
|
+
- [ ] All external API responses validated before use
|
|
114
|
+
- [ ] Business rules checked in Service layer
|
|
115
|
+
- [ ] Error messages safe (no SQL leaked to client)
|
|
116
|
+
- [ ] Tests cover invalid inputs
|
|
117
|
+
- Keep validation deterministic and testable.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Backend Skill Pack
|
|
2
|
+
|
|
3
|
+
Default tier: `advance`
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
Build backend systems with strict layer separation, typed boundaries, and operational safety.
|
|
7
|
+
|
|
8
|
+
## In Scope
|
|
9
|
+
- Transport, service, repository, and domain separation
|
|
10
|
+
- Validation at boundaries
|
|
11
|
+
- Error handling and observability
|
|
12
|
+
- Data access and transaction safety
|
|
13
|
+
- API and event contract design
|
|
14
|
+
|
|
15
|
+
## Must-Have Checks
|
|
16
|
+
- No business logic in transport layer
|
|
17
|
+
- No HTTP objects in application layer
|
|
18
|
+
- No raw SQL in controllers or services
|
|
19
|
+
- All external input validated before business logic
|
|
20
|
+
- Typed errors and explicit failure paths
|
|
21
|
+
|
|
22
|
+
## Evidence
|
|
23
|
+
- Unit and integration tests
|
|
24
|
+
- API contract docs
|
|
25
|
+
- Validation schemas
|
|
26
|
+
- Release gate output
|
|
27
|
+
|
|
28
|
+
## Fallback
|
|
29
|
+
- Standard mode is allowed only for legacy compatibility and must be flagged in release evidence.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# CLI Engineering Skills
|
|
2
|
+
|
|
3
|
+
Default tier: `advance`
|
|
4
|
+
|
|
5
|
+
This domain covers command design, safe mutation workflows, and machine-readable output conventions for automation.
|
|
6
|
+
|
|
7
|
+
## Topics
|
|
8
|
+
- [Init Flow](init.md) - Deterministic project initialization with explicit write plans
|
|
9
|
+
- [Upgrade Flow](upgrade.md) - Safe upgrades with dry-run, rollback, and compatibility checks
|
|
10
|
+
- [Machine-Readable Output](output.md) - Stable JSON output and deterministic exit semantics
|
|
11
|
+
|
|
12
|
+
## Operating Model
|
|
13
|
+
- Use `advance` for normal command work.
|
|
14
|
+
- Escalate to `expert` when commands mutate user state or require migration safety.
|
|
15
|
+
|
|
16
|
+
## Above-Line Additions
|
|
17
|
+
- Mandatory dry-run support for mutating commands.
|
|
18
|
+
- Structured error payloads for CI/CD and bots.
|
|
19
|
+
- Explicit rollback plans for upgrade paths.
|
|
20
|
+
- Plug-and-play init presets for common stacks and blueprints.
|
|
21
|
+
|
|
22
|
+
## Installation and Entry Paths
|
|
23
|
+
|
|
24
|
+
Choose the path that fits your workflow:
|
|
25
|
+
|
|
26
|
+
- `agentic-senior-core launch` for a numbered interactive chooser.
|
|
27
|
+
- `npm install -g @fatidaprilian/agentic-senior-core` for a global command.
|
|
28
|
+
- `npm exec --yes @fatidaprilian/agentic-senior-core init` for a one-off run.
|
|
29
|
+
- `npx @fatidaprilian/agentic-senior-core init` for a package-managed local run.
|
|
30
|
+
- GitHub template for zero-install project bootstrap.
|
|
31
|
+
|
|
32
|
+
## Preset Starts
|
|
33
|
+
|
|
34
|
+
Use presets when you want fewer choices at the start:
|
|
35
|
+
|
|
36
|
+
- `frontend-web` - TypeScript + API Next.js + balanced profile.
|
|
37
|
+
- `backend-api` - Python + FastAPI + balanced profile.
|
|
38
|
+
- `fullstack-product` - TypeScript + API Next.js + balanced profile.
|
|
39
|
+
- `platform-governance` - Go + Go service + strict profile.
|
|
40
|
+
- `mobile-react-native` - React Native + mobile app + balanced profile.
|
|
41
|
+
- `mobile-flutter` - Flutter + mobile app + balanced profile.
|
|
42
|
+
- `observability-platform` - Go + observability + strict profile.
|
|
43
|
+
|
|
44
|
+
Example:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
agentic-senior-core init --preset frontend-web
|
|
48
|
+
agentic-senior-core init --preset backend-api --ci true
|
|
49
|
+
agentic-senior-core launch
|
|
50
|
+
```
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Init Flow
|
|
2
|
+
|
|
3
|
+
Tier: ADVANCE
|
|
4
|
+
|
|
5
|
+
Initialization commands must be deterministic, reversible where possible, and explicit about filesystem mutations.
|
|
6
|
+
|
|
7
|
+
## Design Principles
|
|
8
|
+
|
|
9
|
+
- Predictable output for identical input flags.
|
|
10
|
+
- Safe defaults when users omit options.
|
|
11
|
+
- Preflight summary before any file write.
|
|
12
|
+
|
|
13
|
+
## Required Init Sequence
|
|
14
|
+
|
|
15
|
+
1. Validate prerequisites (runtime, permissions, existing files).
|
|
16
|
+
2. Resolve stack/profile/blueprint selection.
|
|
17
|
+
3. Print write plan summary.
|
|
18
|
+
4. Apply scaffold atomically.
|
|
19
|
+
5. Emit machine-readable onboarding report.
|
|
20
|
+
|
|
21
|
+
## Write Safety
|
|
22
|
+
|
|
23
|
+
- Refuse to overwrite existing files without explicit flag.
|
|
24
|
+
- Use idempotent initialization where feasible.
|
|
25
|
+
- Keep generated files grouped by feature intent, not random dump.
|
|
26
|
+
|
|
27
|
+
## Anti-Patterns
|
|
28
|
+
|
|
29
|
+
- Hidden writes without disclosure.
|
|
30
|
+
- Interactive-only flow with no non-interactive equivalent.
|
|
31
|
+
- Ambiguous defaults that vary by environment.
|
|
32
|
+
|
|
33
|
+
## Review Checklist
|
|
34
|
+
|
|
35
|
+
- [ ] Preflight checks are explicit and actionable.
|
|
36
|
+
- [ ] Generated file set is deterministic.
|
|
37
|
+
- [ ] Dry-run preview exists for init planning.
|
|
38
|
+
- [ ] Exit codes distinguish validation vs runtime failures.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Machine-Readable Output
|
|
2
|
+
|
|
3
|
+
Tier: ADVANCE
|
|
4
|
+
|
|
5
|
+
CLI output must support both human readability and automation reliability.
|
|
6
|
+
|
|
7
|
+
## Output Contract
|
|
8
|
+
|
|
9
|
+
- Human mode: concise narrative and actionable next steps.
|
|
10
|
+
- JSON mode: deterministic schema, stable field names, and clear status.
|
|
11
|
+
|
|
12
|
+
## JSON Schema Guidelines
|
|
13
|
+
|
|
14
|
+
- Include `version`, `timestamp`, `status`, and `summary`.
|
|
15
|
+
- Include `artifacts` list for produced files.
|
|
16
|
+
- Include `errors` array with machine-readable codes.
|
|
17
|
+
- Avoid embedding plain stack traces in public payloads.
|
|
18
|
+
|
|
19
|
+
## Exit Code Conventions
|
|
20
|
+
|
|
21
|
+
- `0`: success
|
|
22
|
+
- `1`: validation or runtime failure
|
|
23
|
+
- `2`: policy/gate failure
|
|
24
|
+
|
|
25
|
+
## Determinism Rules
|
|
26
|
+
|
|
27
|
+
- Stable key ordering where practical.
|
|
28
|
+
- No random IDs unless explicitly requested.
|
|
29
|
+
- Timestamps in ISO 8601 format.
|
|
30
|
+
|
|
31
|
+
## Review Checklist
|
|
32
|
+
|
|
33
|
+
- [ ] JSON output passes schema validation.
|
|
34
|
+
- [ ] Exit codes match documented behavior.
|
|
35
|
+
- [ ] Error payload includes code and remediation hint.
|
|
36
|
+
- [ ] Human output remains concise and useful.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Upgrade Flow
|
|
2
|
+
|
|
3
|
+
Tier: ADVANCE
|
|
4
|
+
|
|
5
|
+
Upgrade commands must prioritize compatibility, transparency, and recovery.
|
|
6
|
+
|
|
7
|
+
## Required Controls
|
|
8
|
+
|
|
9
|
+
- Dry-run mode to preview changes.
|
|
10
|
+
- Compatibility checks before mutation.
|
|
11
|
+
- Backup or rollback path for critical files.
|
|
12
|
+
|
|
13
|
+
## Upgrade Sequence
|
|
14
|
+
|
|
15
|
+
1. Read current version and target version.
|
|
16
|
+
2. Evaluate compatibility matrix.
|
|
17
|
+
3. Produce migration plan (files to add/change/remove).
|
|
18
|
+
4. Execute with transactional mindset.
|
|
19
|
+
5. Emit post-upgrade report with changed artifacts.
|
|
20
|
+
|
|
21
|
+
## Failure Handling
|
|
22
|
+
|
|
23
|
+
- On partial failure, rollback modified artifacts or provide deterministic recovery instructions.
|
|
24
|
+
- Never leave silent half-upgraded state.
|
|
25
|
+
- Exit with explicit status code and structured error payload.
|
|
26
|
+
|
|
27
|
+
## Anti-Patterns
|
|
28
|
+
|
|
29
|
+
- In-place mutation without preview.
|
|
30
|
+
- Version bump without migration note.
|
|
31
|
+
- Breaking changes in minor release without contract guard.
|
|
32
|
+
|
|
33
|
+
## Review Checklist
|
|
34
|
+
|
|
35
|
+
- [ ] Dry-run output is complete and stable.
|
|
36
|
+
- [ ] Upgrade report captures all changed files.
|
|
37
|
+
- [ ] Rollback path is tested.
|
|
38
|
+
- [ ] Compatibility failures block mutation.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# CLI Skill Pack
|
|
2
|
+
|
|
3
|
+
Default tier: `advance`
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
Create smart command-line workflows that guide users efficiently and safely.
|
|
7
|
+
|
|
8
|
+
## In Scope
|
|
9
|
+
- Interactive initialization and upgrade flows
|
|
10
|
+
- Safe defaults and confirmation steps
|
|
11
|
+
- Machine-readable output for automation
|
|
12
|
+
- Validation and self-healing hooks
|
|
13
|
+
- Cross-platform shell behavior
|
|
14
|
+
|
|
15
|
+
## Must-Have Checks
|
|
16
|
+
- Explicit command help and examples
|
|
17
|
+
- Deterministic output format for automation
|
|
18
|
+
- Safe destructive-action guards
|
|
19
|
+
- Validation before mutation
|
|
20
|
+
- Exit codes reflect success and failure clearly
|
|
21
|
+
|
|
22
|
+
## Evidence
|
|
23
|
+
- CLI smoke tests
|
|
24
|
+
- Machine-readable report output
|
|
25
|
+
- Upgrade dry-run output
|
|
26
|
+
- Cross-platform execution notes
|
|
27
|
+
|
|
28
|
+
## Fallback
|
|
29
|
+
- Standard mode can remain available for compatibility, but advance is the default user experience.
|