proagents 1.6.16 → 1.6.18
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/.claude/settings.local.json +169 -0
- package/COMMANDS.md +595 -0
- package/README.md +22 -64
- package/bin/proagents.js +0 -2
- package/lib/commands/init.js +4 -174
- package/package.json +2 -7
- package/.proagents/ai-models/README.md +0 -141
- package/.proagents/ai-models/cost-management.md +0 -362
- package/.proagents/ai-models/fallbacks.md +0 -342
- package/.proagents/ai-models/model-config.md +0 -318
- package/.proagents/ai-models/task-routing.md +0 -503
- package/.proagents/ai-training/README.md +0 -155
- package/.proagents/ai-training/continuous-learning.md +0 -413
- package/.proagents/ai-training/domain-knowledge.md +0 -378
- package/.proagents/ai-training/pattern-learning.md +0 -455
- package/.proagents/ai-training/training-data.md +0 -337
- package/.proagents/ai-training/user-preferences.md +0 -346
- package/.proagents/approval-workflows/README.md +0 -146
- package/.proagents/approval-workflows/approval-config.md +0 -332
- package/.proagents/approval-workflows/approval-stages.md +0 -503
- package/.proagents/approval-workflows/emergency-bypass.md +0 -351
- package/.proagents/approval-workflows/examples.md +0 -859
- package/.proagents/approval-workflows/notifications.md +0 -320
- package/.proagents/compliance/README.md +0 -206
- package/.proagents/compliance/access-control.md +0 -310
- package/.proagents/compliance/audit-logging.md +0 -444
- package/.proagents/compliance/compliance-frameworks.md +0 -429
- package/.proagents/compliance/reports.md +0 -491
- package/.proagents/compliance/retention-policies.md +0 -454
- package/.proagents/config-versioning/README.md +0 -120
- package/.proagents/config-versioning/changelog.md +0 -300
- package/.proagents/config-versioning/rollback.md +0 -283
- package/.proagents/config-versioning/versioning.md +0 -330
- package/.proagents/contract-testing/README.md +0 -223
- package/.proagents/contract-testing/contract-testing.md +0 -614
- package/.proagents/contract-testing/pact-integration.md +0 -507
- package/.proagents/contract-testing/schema-validation.md +0 -565
- package/.proagents/dependency-management/README.md +0 -140
- package/.proagents/dependency-management/automation.md +0 -363
- package/.proagents/dependency-management/compatibility.md +0 -319
- package/.proagents/dependency-management/security-scanning.md +0 -413
- package/.proagents/dependency-management/update-policies.md +0 -374
- package/.proagents/disaster-recovery/README.md +0 -247
- package/.proagents/disaster-recovery/automation.md +0 -366
- package/.proagents/disaster-recovery/backup-recovery.md +0 -571
- package/.proagents/disaster-recovery/incident-response.md +0 -565
- package/.proagents/disaster-recovery/rollback-procedures.md +0 -499
- package/.proagents/disaster-recovery/runbooks.md +0 -603
- package/.proagents/disaster-recovery/scenarios.md +0 -892
- package/.proagents/disaster-recovery/testing.md +0 -438
- package/.proagents/environments/README.md +0 -244
- package/.proagents/environments/configuration.md +0 -437
- package/.proagents/environments/promotion.md +0 -434
- package/.proagents/environments/setup.md +0 -420
- package/.proagents/examples/README.md +0 -55
- package/.proagents/examples/backend-nodejs/README.md +0 -188
- package/.proagents/examples/backend-nodejs/complete-conversation.md +0 -601
- package/.proagents/examples/backend-nodejs/proagents.config.yaml +0 -415
- package/.proagents/examples/backend-nodejs/workflow-example.md +0 -909
- package/.proagents/examples/fullstack-nextjs/README.md +0 -155
- package/.proagents/examples/fullstack-nextjs/complete-conversation.md +0 -604
- package/.proagents/examples/fullstack-nextjs/proagents.config.yaml +0 -287
- package/.proagents/examples/fullstack-nextjs/workflow-example.md +0 -553
- package/.proagents/examples/mobile-react-native/README.md +0 -171
- package/.proagents/examples/mobile-react-native/complete-conversation.md +0 -825
- package/.proagents/examples/mobile-react-native/proagents.config.yaml +0 -330
- package/.proagents/examples/mobile-react-native/workflow-example.md +0 -723
- package/.proagents/examples/web-frontend-react/README.md +0 -125
- package/.proagents/examples/web-frontend-react/complete-conversation.md +0 -556
- package/.proagents/examples/web-frontend-react/proagents.config.yaml +0 -183
- package/.proagents/examples/web-frontend-react/workflow-example.md +0 -603
- package/.proagents/existing-projects/README.md +0 -65
- package/.proagents/existing-projects/challenges.md +0 -861
- package/.proagents/existing-projects/coexistence-mode.md +0 -483
- package/.proagents/existing-projects/compatibility-assessment.md +0 -541
- package/.proagents/existing-projects/gradual-adoption.md +0 -515
- package/.proagents/existing-projects/migration-strategies.md +0 -788
- package/.proagents/existing-projects/pattern-reconciliation.md +0 -489
- package/.proagents/existing-projects/team-onboarding.md +0 -617
- package/.proagents/existing-projects/technical-debt-handling.md +0 -644
- package/.proagents/feature-flags/README.md +0 -263
- package/.proagents/feature-flags/ab-testing.md +0 -413
- package/.proagents/feature-flags/configuration.md +0 -420
- package/.proagents/feature-flags/kill-switches.md +0 -444
- package/.proagents/feature-flags/rollout-strategies.md +0 -392
- package/.proagents/history.log +0 -12
- package/.proagents/i18n/README.md +0 -133
- package/.proagents/i18n/extraction.md +0 -433
- package/.proagents/i18n/tms-integration.md +0 -332
- package/.proagents/i18n/translation-workflow.md +0 -413
- package/.proagents/i18n/validation.md +0 -355
- package/.proagents/logging/README.md +0 -276
- package/.proagents/logging/aggregation.md +0 -475
- package/.proagents/logging/log-levels.md +0 -376
- package/.proagents/logging/sensitive-data.md +0 -423
- package/.proagents/logging/structured-logging.md +0 -406
- package/.proagents/metrics/README.md +0 -69
- package/.proagents/metrics/code-quality-kpis.md +0 -461
- package/.proagents/metrics/deployment-metrics.md +0 -517
- package/.proagents/metrics/developer-productivity.md +0 -368
- package/.proagents/metrics/learning-effectiveness.md +0 -478
- package/.proagents/migrations/README.md +0 -77
- package/.proagents/migrations/from-claude-projects.md +0 -313
- package/.proagents/migrations/from-cursor-rules.md +0 -345
- package/.proagents/migrations/from-custom-workflows.md +0 -410
- package/.proagents/monitoring/README.md +0 -308
- package/.proagents/monitoring/alerting.md +0 -449
- package/.proagents/monitoring/dashboards.md +0 -454
- package/.proagents/monitoring/health-checks.md +0 -436
- package/.proagents/monitoring/metrics.md +0 -434
- package/.proagents/multi-project/README.md +0 -170
- package/.proagents/multi-project/coordinated-deploy.md +0 -510
- package/.proagents/multi-project/cross-project-deps.md +0 -395
- package/.proagents/multi-project/unified-changelog.md +0 -477
- package/.proagents/multi-project/walkthroughs/monorepo-setup.md +0 -787
- package/.proagents/multi-project/workspace-config.md +0 -408
- package/.proagents/notifications/README.md +0 -151
- package/.proagents/notifications/channels.md +0 -457
- package/.proagents/notifications/preferences.md +0 -415
- package/.proagents/notifications/routing.md +0 -449
- package/.proagents/notifications/scheduling.md +0 -425
- package/.proagents/notifications/templates.md +0 -446
- package/.proagents/offline-mode/README.md +0 -145
- package/.proagents/offline-mode/caching.md +0 -344
- package/.proagents/offline-mode/offline-operations.md +0 -312
- package/.proagents/offline-mode/queue-specifications.md +0 -679
- package/.proagents/offline-mode/sync.md +0 -475
- package/.proagents/parallel-features/README.md +0 -85
- package/.proagents/parallel-features/conflict-detection.md +0 -226
- package/.proagents/parallel-features/dependency-management.md +0 -392
- package/.proagents/parallel-features/merge-coordination.md +0 -506
- package/.proagents/parallel-features/tracking-system.md +0 -416
- package/.proagents/performance/README.md +0 -59
- package/.proagents/performance/bundle-analysis.md +0 -375
- package/.proagents/performance/load-testing.md +0 -563
- package/.proagents/performance/runtime-metrics.md +0 -489
- package/.proagents/performance/web-vitals.md +0 -425
- package/.proagents/plugins/README.md +0 -139
- package/.proagents/plugins/creating-plugins.md +0 -504
- package/.proagents/plugins/plugin-api.md +0 -467
- package/.proagents/plugins/plugin-registry.md +0 -276
- package/.proagents/reporting/README.md +0 -158
- package/.proagents/reporting/dashboards.md +0 -366
- package/.proagents/reporting/exports.md +0 -524
- package/.proagents/reporting/quality-metrics.md +0 -385
- package/.proagents/reporting/templates/README.md +0 -56
- package/.proagents/reporting/templates/dashboard-config.json +0 -187
- package/.proagents/reporting/templates/metrics-queries.md +0 -427
- package/.proagents/reporting/templates/react-dashboard.tsx +0 -544
- package/.proagents/reporting/templates/widgets.md +0 -451
- package/.proagents/reporting/velocity-metrics.md +0 -340
- package/.proagents/reverse-engineering/README.md +0 -151
- package/.proagents/reverse-engineering/architecture-extraction.md +0 -325
- package/.proagents/reverse-engineering/code-analysis.md +0 -377
- package/.proagents/reverse-engineering/dependency-mapping.md +0 -567
- package/.proagents/reverse-engineering/diagram-generation.md +0 -586
- package/.proagents/reverse-engineering/documentation-generation.md +0 -468
- package/.proagents/reverse-engineering/pattern-detection.md +0 -569
- package/.proagents/reverse-engineering/quality-assessment.md +0 -733
- package/.proagents/secrets/README.md +0 -278
- package/.proagents/secrets/access-control.md +0 -443
- package/.proagents/secrets/rotation.md +0 -403
- package/.proagents/secrets/scanning.md +0 -487
- package/.proagents/secrets/storage.md +0 -394
- package/.proagents/webhooks/README.md +0 -126
- package/.proagents/webhooks/endpoints.md +0 -298
- package/.proagents/webhooks/events.md +0 -316
- package/.proagents/webhooks/payloads.md +0 -325
- package/.proagents/webhooks/reliability.md +0 -363
- package/.proagents/webhooks/security.md +0 -380
|
@@ -1,427 +0,0 @@
|
|
|
1
|
-
# Metrics Queries
|
|
2
|
-
|
|
3
|
-
SQL and API queries for dashboard metrics.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Overview
|
|
8
|
-
|
|
9
|
-
These queries can be used to populate ProAgents dashboards. Adapt them to your database schema and API structure.
|
|
10
|
-
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## Feature Metrics
|
|
14
|
-
|
|
15
|
-
### Features Completed (Count)
|
|
16
|
-
|
|
17
|
-
```sql
|
|
18
|
-
-- PostgreSQL
|
|
19
|
-
SELECT COUNT(*) as count
|
|
20
|
-
FROM features
|
|
21
|
-
WHERE status = 'completed'
|
|
22
|
-
AND completed_at >= NOW() - INTERVAL '30 days';
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
```typescript
|
|
26
|
-
// API Endpoint
|
|
27
|
-
app.get('/api/metrics/features/completed', async (req, res) => {
|
|
28
|
-
const { timeRange = '30d' } = req.query;
|
|
29
|
-
const days = parseInt(timeRange);
|
|
30
|
-
|
|
31
|
-
const count = await db.feature.count({
|
|
32
|
-
where: {
|
|
33
|
-
status: 'completed',
|
|
34
|
-
completedAt: {
|
|
35
|
-
gte: new Date(Date.now() - days * 24 * 60 * 60 * 1000),
|
|
36
|
-
},
|
|
37
|
-
},
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
const previousCount = await db.feature.count({
|
|
41
|
-
where: {
|
|
42
|
-
status: 'completed',
|
|
43
|
-
completedAt: {
|
|
44
|
-
gte: new Date(Date.now() - days * 2 * 24 * 60 * 60 * 1000),
|
|
45
|
-
lt: new Date(Date.now() - days * 24 * 60 * 60 * 1000),
|
|
46
|
-
},
|
|
47
|
-
},
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
const change = previousCount > 0
|
|
51
|
-
? ((count - previousCount) / previousCount) * 100
|
|
52
|
-
: 0;
|
|
53
|
-
|
|
54
|
-
res.json({ value: count, change: Math.round(change) });
|
|
55
|
-
});
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
### Average Feature Completion Time
|
|
59
|
-
|
|
60
|
-
```sql
|
|
61
|
-
SELECT AVG(
|
|
62
|
-
EXTRACT(EPOCH FROM (completed_at - created_at)) / 86400
|
|
63
|
-
) as avg_days
|
|
64
|
-
FROM features
|
|
65
|
-
WHERE status = 'completed'
|
|
66
|
-
AND completed_at >= NOW() - INTERVAL '30 days';
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
```typescript
|
|
70
|
-
// API Endpoint
|
|
71
|
-
app.get('/api/metrics/features/avg-time', async (req, res) => {
|
|
72
|
-
const features = await db.feature.findMany({
|
|
73
|
-
where: {
|
|
74
|
-
status: 'completed',
|
|
75
|
-
completedAt: { gte: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000) },
|
|
76
|
-
},
|
|
77
|
-
select: { createdAt: true, completedAt: true },
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
const totalDays = features.reduce((sum, f) => {
|
|
81
|
-
const days = (f.completedAt.getTime() - f.createdAt.getTime()) / (1000 * 60 * 60 * 24);
|
|
82
|
-
return sum + days;
|
|
83
|
-
}, 0);
|
|
84
|
-
|
|
85
|
-
const avgDays = features.length > 0 ? totalDays / features.length : 0;
|
|
86
|
-
res.json({ value: Math.round(avgDays * 10) / 10 });
|
|
87
|
-
});
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
### Features by Phase
|
|
91
|
-
|
|
92
|
-
```sql
|
|
93
|
-
SELECT phase, COUNT(*) as count
|
|
94
|
-
FROM features
|
|
95
|
-
WHERE status = 'active'
|
|
96
|
-
GROUP BY phase
|
|
97
|
-
ORDER BY count DESC;
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
```typescript
|
|
101
|
-
// API Endpoint
|
|
102
|
-
app.get('/api/metrics/features/by-phase', async (req, res) => {
|
|
103
|
-
const result = await db.feature.groupBy({
|
|
104
|
-
by: ['phase'],
|
|
105
|
-
where: { status: 'active' },
|
|
106
|
-
_count: { phase: true },
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
const data = result.reduce((acc, r) => {
|
|
110
|
-
acc[r.phase] = r._count.phase;
|
|
111
|
-
return acc;
|
|
112
|
-
}, {} as Record<string, number>);
|
|
113
|
-
|
|
114
|
-
res.json(data);
|
|
115
|
-
});
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
---
|
|
119
|
-
|
|
120
|
-
## Bug Metrics
|
|
121
|
-
|
|
122
|
-
### Bugs Fixed (Count)
|
|
123
|
-
|
|
124
|
-
```sql
|
|
125
|
-
SELECT COUNT(*) as count
|
|
126
|
-
FROM bugs
|
|
127
|
-
WHERE status = 'fixed'
|
|
128
|
-
AND fixed_at >= NOW() - INTERVAL '30 days';
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
### Average Bug Fix Time
|
|
132
|
-
|
|
133
|
-
```sql
|
|
134
|
-
SELECT AVG(
|
|
135
|
-
EXTRACT(EPOCH FROM (fixed_at - created_at)) / 3600
|
|
136
|
-
) as avg_hours
|
|
137
|
-
FROM bugs
|
|
138
|
-
WHERE status = 'fixed'
|
|
139
|
-
AND fixed_at >= NOW() - INTERVAL '30 days';
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
### Bugs by Severity
|
|
143
|
-
|
|
144
|
-
```sql
|
|
145
|
-
SELECT severity, COUNT(*) as count
|
|
146
|
-
FROM bugs
|
|
147
|
-
WHERE status = 'open'
|
|
148
|
-
GROUP BY severity
|
|
149
|
-
ORDER BY
|
|
150
|
-
CASE severity
|
|
151
|
-
WHEN 'critical' THEN 1
|
|
152
|
-
WHEN 'high' THEN 2
|
|
153
|
-
WHEN 'medium' THEN 3
|
|
154
|
-
WHEN 'low' THEN 4
|
|
155
|
-
END;
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
---
|
|
159
|
-
|
|
160
|
-
## Quality Metrics
|
|
161
|
-
|
|
162
|
-
### Test Coverage
|
|
163
|
-
|
|
164
|
-
```sql
|
|
165
|
-
-- From latest coverage report
|
|
166
|
-
SELECT coverage_percentage
|
|
167
|
-
FROM coverage_reports
|
|
168
|
-
ORDER BY created_at DESC
|
|
169
|
-
LIMIT 1;
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
```typescript
|
|
173
|
-
// API Endpoint (reads from coverage file)
|
|
174
|
-
app.get('/api/metrics/quality/coverage', async (req, res) => {
|
|
175
|
-
try {
|
|
176
|
-
const coverageFile = await fs.readFile('./coverage/coverage-summary.json', 'utf-8');
|
|
177
|
-
const coverage = JSON.parse(coverageFile);
|
|
178
|
-
const percentage = coverage.total.lines.pct;
|
|
179
|
-
res.json({ value: percentage });
|
|
180
|
-
} catch {
|
|
181
|
-
res.json({ value: 0, error: 'Coverage report not found' });
|
|
182
|
-
}
|
|
183
|
-
});
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
### Lint Errors
|
|
187
|
-
|
|
188
|
-
```sql
|
|
189
|
-
SELECT COUNT(*) as count
|
|
190
|
-
FROM lint_reports
|
|
191
|
-
WHERE created_at >= NOW() - INTERVAL '24 hours'
|
|
192
|
-
AND severity = 'error';
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
### Technical Debt Items
|
|
196
|
-
|
|
197
|
-
```sql
|
|
198
|
-
SELECT COUNT(*) as count
|
|
199
|
-
FROM technical_debt
|
|
200
|
-
WHERE status = 'open';
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
---
|
|
204
|
-
|
|
205
|
-
## Team Metrics
|
|
206
|
-
|
|
207
|
-
### Team Contributions
|
|
208
|
-
|
|
209
|
-
```sql
|
|
210
|
-
SELECT
|
|
211
|
-
u.name as developer,
|
|
212
|
-
COUNT(DISTINCT f.id) FILTER (WHERE f.status = 'completed') as features,
|
|
213
|
-
COUNT(DISTINCT b.id) FILTER (WHERE b.status = 'fixed') as bugs,
|
|
214
|
-
COUNT(DISTINCT r.id) as reviews
|
|
215
|
-
FROM users u
|
|
216
|
-
LEFT JOIN features f ON f.assignee_id = u.id
|
|
217
|
-
AND f.completed_at >= NOW() - INTERVAL '30 days'
|
|
218
|
-
LEFT JOIN bugs b ON b.assignee_id = u.id
|
|
219
|
-
AND b.fixed_at >= NOW() - INTERVAL '30 days'
|
|
220
|
-
LEFT JOIN reviews r ON r.reviewer_id = u.id
|
|
221
|
-
AND r.created_at >= NOW() - INTERVAL '30 days'
|
|
222
|
-
WHERE u.role = 'developer'
|
|
223
|
-
GROUP BY u.id, u.name
|
|
224
|
-
ORDER BY features DESC;
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
```typescript
|
|
228
|
-
// API Endpoint
|
|
229
|
-
app.get('/api/metrics/team/contributions', async (req, res) => {
|
|
230
|
-
const thirtyDaysAgo = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000);
|
|
231
|
-
|
|
232
|
-
const users = await db.user.findMany({
|
|
233
|
-
where: { role: 'developer' },
|
|
234
|
-
include: {
|
|
235
|
-
features: {
|
|
236
|
-
where: { status: 'completed', completedAt: { gte: thirtyDaysAgo } },
|
|
237
|
-
},
|
|
238
|
-
bugs: {
|
|
239
|
-
where: { status: 'fixed', fixedAt: { gte: thirtyDaysAgo } },
|
|
240
|
-
},
|
|
241
|
-
reviews: {
|
|
242
|
-
where: { createdAt: { gte: thirtyDaysAgo } },
|
|
243
|
-
},
|
|
244
|
-
},
|
|
245
|
-
});
|
|
246
|
-
|
|
247
|
-
const contributions = users.map((u) => ({
|
|
248
|
-
developer: u.name,
|
|
249
|
-
features: u.features.length,
|
|
250
|
-
bugs: u.bugs.length,
|
|
251
|
-
reviews: u.reviews.length,
|
|
252
|
-
}));
|
|
253
|
-
|
|
254
|
-
res.json(contributions.sort((a, b) => b.features - a.features));
|
|
255
|
-
});
|
|
256
|
-
```
|
|
257
|
-
|
|
258
|
-
---
|
|
259
|
-
|
|
260
|
-
## Velocity Metrics
|
|
261
|
-
|
|
262
|
-
### Weekly Velocity
|
|
263
|
-
|
|
264
|
-
```sql
|
|
265
|
-
SELECT
|
|
266
|
-
DATE_TRUNC('week', completed_at) as week,
|
|
267
|
-
COUNT(*) FILTER (WHERE type = 'feature') as features,
|
|
268
|
-
COUNT(*) FILTER (WHERE type = 'bug') as bugs
|
|
269
|
-
FROM (
|
|
270
|
-
SELECT 'feature' as type, completed_at FROM features WHERE status = 'completed'
|
|
271
|
-
UNION ALL
|
|
272
|
-
SELECT 'bug' as type, fixed_at as completed_at FROM bugs WHERE status = 'fixed'
|
|
273
|
-
) combined
|
|
274
|
-
WHERE completed_at >= NOW() - INTERVAL '90 days'
|
|
275
|
-
GROUP BY week
|
|
276
|
-
ORDER BY week;
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
```typescript
|
|
280
|
-
// API Endpoint
|
|
281
|
-
app.get('/api/metrics/velocity', async (req, res) => {
|
|
282
|
-
const { timeRange = '90d', granularity = 'week' } = req.query;
|
|
283
|
-
|
|
284
|
-
// Get features and bugs grouped by week
|
|
285
|
-
const features = await db.$queryRaw`
|
|
286
|
-
SELECT DATE_TRUNC('week', completed_at) as week, COUNT(*) as count
|
|
287
|
-
FROM features
|
|
288
|
-
WHERE status = 'completed'
|
|
289
|
-
AND completed_at >= NOW() - INTERVAL '90 days'
|
|
290
|
-
GROUP BY week
|
|
291
|
-
ORDER BY week
|
|
292
|
-
`;
|
|
293
|
-
|
|
294
|
-
const bugs = await db.$queryRaw`
|
|
295
|
-
SELECT DATE_TRUNC('week', fixed_at) as week, COUNT(*) as count
|
|
296
|
-
FROM bugs
|
|
297
|
-
WHERE status = 'fixed'
|
|
298
|
-
AND fixed_at >= NOW() - INTERVAL '90 days'
|
|
299
|
-
GROUP BY week
|
|
300
|
-
ORDER BY week
|
|
301
|
-
`;
|
|
302
|
-
|
|
303
|
-
res.json({ features, bugs });
|
|
304
|
-
});
|
|
305
|
-
```
|
|
306
|
-
|
|
307
|
-
---
|
|
308
|
-
|
|
309
|
-
## Deployment Metrics
|
|
310
|
-
|
|
311
|
-
### Deployments Count
|
|
312
|
-
|
|
313
|
-
```sql
|
|
314
|
-
SELECT
|
|
315
|
-
environment,
|
|
316
|
-
COUNT(*) as deployments,
|
|
317
|
-
COUNT(*) FILTER (WHERE status = 'success') as successful,
|
|
318
|
-
COUNT(*) FILTER (WHERE status = 'failed') as failed
|
|
319
|
-
FROM deployments
|
|
320
|
-
WHERE deployed_at >= NOW() - INTERVAL '30 days'
|
|
321
|
-
GROUP BY environment;
|
|
322
|
-
```
|
|
323
|
-
|
|
324
|
-
### Deployment Frequency
|
|
325
|
-
|
|
326
|
-
```sql
|
|
327
|
-
SELECT
|
|
328
|
-
DATE_TRUNC('day', deployed_at) as day,
|
|
329
|
-
COUNT(*) as count
|
|
330
|
-
FROM deployments
|
|
331
|
-
WHERE environment = 'production'
|
|
332
|
-
AND deployed_at >= NOW() - INTERVAL '30 days'
|
|
333
|
-
GROUP BY day
|
|
334
|
-
ORDER BY day;
|
|
335
|
-
```
|
|
336
|
-
|
|
337
|
-
### Mean Time to Recovery (MTTR)
|
|
338
|
-
|
|
339
|
-
```sql
|
|
340
|
-
SELECT AVG(
|
|
341
|
-
EXTRACT(EPOCH FROM (resolved_at - detected_at)) / 60
|
|
342
|
-
) as avg_minutes
|
|
343
|
-
FROM incidents
|
|
344
|
-
WHERE resolved_at IS NOT NULL
|
|
345
|
-
AND resolved_at >= NOW() - INTERVAL '90 days';
|
|
346
|
-
```
|
|
347
|
-
|
|
348
|
-
---
|
|
349
|
-
|
|
350
|
-
## Activity Feed
|
|
351
|
-
|
|
352
|
-
### Recent Activity
|
|
353
|
-
|
|
354
|
-
```sql
|
|
355
|
-
SELECT
|
|
356
|
-
'feature_complete' as type,
|
|
357
|
-
CONCAT('Feature completed: ', name) as message,
|
|
358
|
-
completed_at as timestamp
|
|
359
|
-
FROM features
|
|
360
|
-
WHERE status = 'completed'
|
|
361
|
-
AND completed_at >= NOW() - INTERVAL '7 days'
|
|
362
|
-
|
|
363
|
-
UNION ALL
|
|
364
|
-
|
|
365
|
-
SELECT
|
|
366
|
-
'deployment' as type,
|
|
367
|
-
CONCAT('Deployed to ', environment) as message,
|
|
368
|
-
deployed_at as timestamp
|
|
369
|
-
FROM deployments
|
|
370
|
-
WHERE deployed_at >= NOW() - INTERVAL '7 days'
|
|
371
|
-
|
|
372
|
-
UNION ALL
|
|
373
|
-
|
|
374
|
-
SELECT
|
|
375
|
-
'pr_merged' as type,
|
|
376
|
-
CONCAT('PR merged: ', title) as message,
|
|
377
|
-
merged_at as timestamp
|
|
378
|
-
FROM pull_requests
|
|
379
|
-
WHERE merged_at >= NOW() - INTERVAL '7 days'
|
|
380
|
-
|
|
381
|
-
ORDER BY timestamp DESC
|
|
382
|
-
LIMIT 20;
|
|
383
|
-
```
|
|
384
|
-
|
|
385
|
-
```typescript
|
|
386
|
-
// API Endpoint
|
|
387
|
-
app.get('/api/activity/feed', async (req, res) => {
|
|
388
|
-
const { limit = 20 } = req.query;
|
|
389
|
-
const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);
|
|
390
|
-
|
|
391
|
-
const [features, deployments, prs] = await Promise.all([
|
|
392
|
-
db.feature.findMany({
|
|
393
|
-
where: { status: 'completed', completedAt: { gte: sevenDaysAgo } },
|
|
394
|
-
select: { name: true, completedAt: true },
|
|
395
|
-
}),
|
|
396
|
-
db.deployment.findMany({
|
|
397
|
-
where: { deployedAt: { gte: sevenDaysAgo } },
|
|
398
|
-
select: { environment: true, deployedAt: true },
|
|
399
|
-
}),
|
|
400
|
-
db.pullRequest.findMany({
|
|
401
|
-
where: { mergedAt: { gte: sevenDaysAgo } },
|
|
402
|
-
select: { title: true, mergedAt: true },
|
|
403
|
-
}),
|
|
404
|
-
]);
|
|
405
|
-
|
|
406
|
-
const activities = [
|
|
407
|
-
...features.map((f) => ({
|
|
408
|
-
type: 'feature_complete',
|
|
409
|
-
message: `Feature completed: ${f.name}`,
|
|
410
|
-
timestamp: f.completedAt,
|
|
411
|
-
})),
|
|
412
|
-
...deployments.map((d) => ({
|
|
413
|
-
type: 'deployment',
|
|
414
|
-
message: `Deployed to ${d.environment}`,
|
|
415
|
-
timestamp: d.deployedAt,
|
|
416
|
-
})),
|
|
417
|
-
...prs.map((p) => ({
|
|
418
|
-
type: 'pr_merged',
|
|
419
|
-
message: `PR merged: ${p.title}`,
|
|
420
|
-
timestamp: p.mergedAt,
|
|
421
|
-
})),
|
|
422
|
-
];
|
|
423
|
-
|
|
424
|
-
activities.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
|
|
425
|
-
res.json(activities.slice(0, parseInt(limit as string)));
|
|
426
|
-
});
|
|
427
|
-
```
|