@kaddo/cli 3.72.2 → 3.73.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/dist/admin-dist/assets/index-BPt-9--k.css +2 -0
- package/dist/admin-dist/assets/index-CiJRX9Ps.js +38 -0
- package/dist/admin-dist/index.html +2 -2
- package/dist/admin-server/index.js +373 -200
- package/dist/core.js +427 -11
- package/package.json +1 -1
- package/dist/admin-dist/assets/index-D4sr_XCt.css +0 -2
- package/dist/admin-dist/assets/index-DEZExhWd.js +0 -38
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<title>admin</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
9
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-CiJRX9Ps.js"></script>
|
|
9
|
+
<link rel="stylesheet" crossorigin href="/assets/index-BPt-9--k.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
12
12
|
<div id="root"></div>
|
|
@@ -61,6 +61,12 @@ import {
|
|
|
61
61
|
getWorkItems as coreGetWorkItems,
|
|
62
62
|
getWorkItem as coreGetWorkItem,
|
|
63
63
|
WorkItemNotFoundError,
|
|
64
|
+
createWorkItem as coreCreateWorkItem,
|
|
65
|
+
updateWorkItem as coreUpdateWorkItem,
|
|
66
|
+
getWorkItemForEdit as coreGetWorkItemForEdit,
|
|
67
|
+
validateWorkItem as coreValidateWorkItem,
|
|
68
|
+
transitionWorkItem as coreTransitionWorkItem,
|
|
69
|
+
WorkItemWriteError,
|
|
64
70
|
exists,
|
|
65
71
|
join,
|
|
66
72
|
readFile
|
|
@@ -114,6 +120,57 @@ function getWorkItemDetail(dir, workItemId) {
|
|
|
114
120
|
throw err;
|
|
115
121
|
}
|
|
116
122
|
}
|
|
123
|
+
function assertValidWorkItemId(workItemId) {
|
|
124
|
+
if (!workItemId || workItemId.includes("..") || workItemId.includes("/") || workItemId.includes("\\") || workItemId.startsWith(".")) {
|
|
125
|
+
throw new CoreError("INVALID_WORK_ITEM_ID", "Invalid Work Item identifier.");
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
function mapWriteError(err) {
|
|
129
|
+
if (err instanceof WorkItemWriteError) throw new CoreError(err.code, err.message);
|
|
130
|
+
throw err;
|
|
131
|
+
}
|
|
132
|
+
function createWorkItemAdmin(dir, body) {
|
|
133
|
+
try {
|
|
134
|
+
const res = coreCreateWorkItem(dir, { intent: body.intent, type: body.type });
|
|
135
|
+
return { id: res.id, path: res.path, revision: res.revision, status: "draft" };
|
|
136
|
+
} catch (err) {
|
|
137
|
+
mapWriteError(err);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
function getWorkItemEdit(dir, workItemId) {
|
|
141
|
+
assertValidWorkItemId(workItemId);
|
|
142
|
+
try {
|
|
143
|
+
return coreGetWorkItemForEdit(dir, workItemId);
|
|
144
|
+
} catch (err) {
|
|
145
|
+
mapWriteError(err);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
function updateWorkItemAdmin(dir, workItemId, body) {
|
|
149
|
+
assertValidWorkItemId(workItemId);
|
|
150
|
+
try {
|
|
151
|
+
const res = coreUpdateWorkItem(dir, workItemId, body.model, body.expectedRevision);
|
|
152
|
+
return { id: workItemId, path: res.path, revision: res.revision };
|
|
153
|
+
} catch (err) {
|
|
154
|
+
mapWriteError(err);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
function validateWorkItemAdmin(dir, workItemId) {
|
|
158
|
+
assertValidWorkItemId(workItemId);
|
|
159
|
+
try {
|
|
160
|
+
return coreValidateWorkItem(dir, workItemId);
|
|
161
|
+
} catch (err) {
|
|
162
|
+
mapWriteError(err);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
function transitionWorkItemAdmin(dir, workItemId, to, expectedRevision) {
|
|
166
|
+
assertValidWorkItemId(workItemId);
|
|
167
|
+
try {
|
|
168
|
+
const res = coreTransitionWorkItem(dir, workItemId, to, expectedRevision);
|
|
169
|
+
return { id: workItemId, path: res.path, revision: res.revision, status: res.status };
|
|
170
|
+
} catch (err) {
|
|
171
|
+
mapWriteError(err);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
117
174
|
function getModules(dir) {
|
|
118
175
|
const mapped = loadMappedModules(dir);
|
|
119
176
|
return {
|
|
@@ -255,7 +312,271 @@ var CoreError = class extends Error {
|
|
|
255
312
|
code;
|
|
256
313
|
};
|
|
257
314
|
|
|
315
|
+
// src/contracts/schemas.ts
|
|
316
|
+
import { z } from "zod";
|
|
317
|
+
var ProjectSummarySchema = z.object({
|
|
318
|
+
name: z.string(),
|
|
319
|
+
state: z.string(),
|
|
320
|
+
structure: z.string(),
|
|
321
|
+
language: z.string(),
|
|
322
|
+
teamSize: z.string()
|
|
323
|
+
});
|
|
324
|
+
var KnowledgeSummarySchema = z.object({
|
|
325
|
+
layers: z.array(z.object({
|
|
326
|
+
layer: z.string(),
|
|
327
|
+
status: z.string()
|
|
328
|
+
})),
|
|
329
|
+
missing: z.array(z.string())
|
|
330
|
+
});
|
|
331
|
+
var WorkItemSummarySchema = z.object({
|
|
332
|
+
total: z.number(),
|
|
333
|
+
byState: z.record(z.string(), z.number()),
|
|
334
|
+
byType: z.record(z.string(), z.number()),
|
|
335
|
+
items: z.array(z.object({
|
|
336
|
+
id: z.string(),
|
|
337
|
+
title: z.string(),
|
|
338
|
+
type: z.string(),
|
|
339
|
+
lifecycle: z.string(),
|
|
340
|
+
initiative: z.string()
|
|
341
|
+
}))
|
|
342
|
+
});
|
|
343
|
+
var ModuleSummarySchema = z.object({
|
|
344
|
+
modules: z.array(z.object({
|
|
345
|
+
id: z.string(),
|
|
346
|
+
role: z.string(),
|
|
347
|
+
path: z.string().optional(),
|
|
348
|
+
available: z.boolean()
|
|
349
|
+
}))
|
|
350
|
+
});
|
|
351
|
+
var ProjectReadinessSchema = z.object({
|
|
352
|
+
overall: z.string(),
|
|
353
|
+
recommendedNextStep: z.object({
|
|
354
|
+
label: z.string(),
|
|
355
|
+
command: z.string().optional()
|
|
356
|
+
})
|
|
357
|
+
});
|
|
358
|
+
var RouteStepSchema = z.object({
|
|
359
|
+
id: z.string(),
|
|
360
|
+
label: z.string(),
|
|
361
|
+
status: z.string(),
|
|
362
|
+
evidence: z.array(z.string()).optional(),
|
|
363
|
+
reason: z.string().optional(),
|
|
364
|
+
command: z.string().optional()
|
|
365
|
+
});
|
|
366
|
+
var ProjectRouteSchema = z.object({
|
|
367
|
+
type: z.string(),
|
|
368
|
+
completed: z.number(),
|
|
369
|
+
total: z.number(),
|
|
370
|
+
progressPercent: z.number(),
|
|
371
|
+
steps: z.array(RouteStepSchema)
|
|
372
|
+
});
|
|
373
|
+
var FindingsSummarySchema = z.object({
|
|
374
|
+
blocking: z.number(),
|
|
375
|
+
warning: z.number(),
|
|
376
|
+
fyi: z.number(),
|
|
377
|
+
items: z.array(z.object({
|
|
378
|
+
level: z.enum(["blocking", "warning", "fyi"]),
|
|
379
|
+
message: z.string()
|
|
380
|
+
}))
|
|
381
|
+
});
|
|
382
|
+
var ProjectOverviewSchema = z.object({
|
|
383
|
+
project: ProjectSummarySchema,
|
|
384
|
+
knowledge: KnowledgeSummarySchema,
|
|
385
|
+
workItems: WorkItemSummarySchema,
|
|
386
|
+
modules: ModuleSummarySchema,
|
|
387
|
+
readiness: ProjectReadinessSchema,
|
|
388
|
+
route: ProjectRouteSchema,
|
|
389
|
+
findings: FindingsSummarySchema
|
|
390
|
+
});
|
|
391
|
+
var KnowledgeArtifactSummarySchema = z.object({
|
|
392
|
+
id: z.string(),
|
|
393
|
+
title: z.string(),
|
|
394
|
+
layer: z.string(),
|
|
395
|
+
path: z.string(),
|
|
396
|
+
status: z.string(),
|
|
397
|
+
type: z.string().optional()
|
|
398
|
+
});
|
|
399
|
+
var KnowledgeInventoryLayerSchema = z.object({
|
|
400
|
+
id: z.string(),
|
|
401
|
+
label: z.string(),
|
|
402
|
+
status: z.string(),
|
|
403
|
+
artifacts: z.array(KnowledgeArtifactSummarySchema)
|
|
404
|
+
});
|
|
405
|
+
var KnowledgeInventorySchema = z.object({
|
|
406
|
+
layers: z.array(KnowledgeInventoryLayerSchema)
|
|
407
|
+
});
|
|
408
|
+
var KnowledgeArtifactDetailSchema = z.object({
|
|
409
|
+
id: z.string(),
|
|
410
|
+
title: z.string(),
|
|
411
|
+
layer: z.string(),
|
|
412
|
+
path: z.string(),
|
|
413
|
+
status: z.string(),
|
|
414
|
+
format: z.string(),
|
|
415
|
+
content: z.string(),
|
|
416
|
+
type: z.string().optional()
|
|
417
|
+
});
|
|
418
|
+
var WorkItemsSummaryStatsSchema = z.object({
|
|
419
|
+
total: z.number(),
|
|
420
|
+
active: z.number(),
|
|
421
|
+
draft: z.number(),
|
|
422
|
+
ready: z.number(),
|
|
423
|
+
inProgress: z.number(),
|
|
424
|
+
blocked: z.number(),
|
|
425
|
+
completed: z.number(),
|
|
426
|
+
archived: z.number()
|
|
427
|
+
});
|
|
428
|
+
var WorkItemListItemSchema = z.object({
|
|
429
|
+
id: z.string(),
|
|
430
|
+
title: z.string(),
|
|
431
|
+
type: z.string(),
|
|
432
|
+
status: z.string(),
|
|
433
|
+
implementationStatus: z.string().nullable(),
|
|
434
|
+
validationStatus: z.string().nullable(),
|
|
435
|
+
releaseStatus: z.string().nullable(),
|
|
436
|
+
affectedModules: z.array(z.string()),
|
|
437
|
+
scopeConfidenceLevel: z.string().nullable(),
|
|
438
|
+
initiative: z.string().nullable()
|
|
439
|
+
});
|
|
440
|
+
var WorkItemsListSchema = z.object({
|
|
441
|
+
summary: WorkItemsSummaryStatsSchema,
|
|
442
|
+
items: z.array(WorkItemListItemSchema),
|
|
443
|
+
modules: z.array(z.string())
|
|
444
|
+
});
|
|
445
|
+
var CoverageEntrySchema = z.object({ id: z.string(), status: z.string(), reason: z.string().optional() });
|
|
446
|
+
var ImpactEntrySchema = z.object({
|
|
447
|
+
surface: z.string(),
|
|
448
|
+
status: z.string(),
|
|
449
|
+
reason: z.string().optional(),
|
|
450
|
+
question: z.string().optional()
|
|
451
|
+
});
|
|
452
|
+
var AcceptanceCriterionSchema = z.object({ text: z.string(), checked: z.boolean().nullable() });
|
|
453
|
+
var ReleaseGateEntrySchema = z.object({
|
|
454
|
+
id: z.string(),
|
|
455
|
+
status: z.string(),
|
|
456
|
+
reason: z.string().optional(),
|
|
457
|
+
requiredFor: z.string().optional()
|
|
458
|
+
});
|
|
459
|
+
var CompletionExceptionEntrySchema = z.object({
|
|
460
|
+
id: z.string(),
|
|
461
|
+
status: z.string(),
|
|
462
|
+
reason: z.string().optional(),
|
|
463
|
+
category: z.string().optional(),
|
|
464
|
+
impact: z.string().optional()
|
|
465
|
+
});
|
|
466
|
+
var RepoValidationSchema = z.object({ command: z.string(), status: z.string(), reason: z.string().optional() });
|
|
467
|
+
var RepoMigrationSchema = z.object({
|
|
468
|
+
id: z.string(),
|
|
469
|
+
environment: z.string(),
|
|
470
|
+
status: z.string(),
|
|
471
|
+
reason: z.string().optional()
|
|
472
|
+
});
|
|
473
|
+
var EvidenceRepoSchema = z.object({
|
|
474
|
+
module: z.string(),
|
|
475
|
+
role: z.string(),
|
|
476
|
+
status: z.string(),
|
|
477
|
+
changedPaths: z.array(z.string()),
|
|
478
|
+
validations: z.array(RepoValidationSchema),
|
|
479
|
+
migrations: z.array(RepoMigrationSchema)
|
|
480
|
+
});
|
|
481
|
+
var LinkedDecisionSchema = z.object({
|
|
482
|
+
id: z.string(),
|
|
483
|
+
title: z.string().optional(),
|
|
484
|
+
knowledgeId: z.string().optional(),
|
|
485
|
+
knowledgeLayer: z.string().optional()
|
|
486
|
+
});
|
|
487
|
+
var LinkedKnowledgeSchema = z.object({ id: z.string(), title: z.string(), layer: z.string() });
|
|
488
|
+
var WorkItemDetailSchema = WorkItemListItemSchema.extend({
|
|
489
|
+
actor: z.string().nullable(),
|
|
490
|
+
outcome: z.string().nullable(),
|
|
491
|
+
currentBehavior: z.string().nullable(),
|
|
492
|
+
targetBehavior: z.string().nullable(),
|
|
493
|
+
entryPoints: z.string().nullable(),
|
|
494
|
+
endToEndFlow: z.string().nullable(),
|
|
495
|
+
scopeConfidence: z.object({ level: z.string(), reasons: z.array(z.string()) }).nullable(),
|
|
496
|
+
scopeUnknowns: z.array(z.string()),
|
|
497
|
+
moduleCoverage: z.array(CoverageEntrySchema),
|
|
498
|
+
impactAnalysis: z.array(ImpactEntrySchema),
|
|
499
|
+
acceptanceCriteria: z.array(AcceptanceCriterionSchema),
|
|
500
|
+
implementationEvidence: z.array(EvidenceRepoSchema),
|
|
501
|
+
releaseGates: z.array(ReleaseGateEntrySchema),
|
|
502
|
+
completionExceptions: z.array(CompletionExceptionEntrySchema),
|
|
503
|
+
decisions: z.array(LinkedDecisionSchema),
|
|
504
|
+
relatedKnowledge: z.array(LinkedKnowledgeSchema),
|
|
505
|
+
source: z.object({ type: z.string(), id: z.string().optional(), inferred: z.boolean() }).passthrough(),
|
|
506
|
+
path: z.string()
|
|
507
|
+
});
|
|
508
|
+
var WorkItemInputSchema = z.object({
|
|
509
|
+
title: z.string(),
|
|
510
|
+
type: z.string(),
|
|
511
|
+
summary: z.string().optional(),
|
|
512
|
+
actor: z.string().optional(),
|
|
513
|
+
outcome: z.string().optional(),
|
|
514
|
+
currentBehavior: z.string().optional(),
|
|
515
|
+
targetBehavior: z.string().optional(),
|
|
516
|
+
entryPoints: z.string().optional(),
|
|
517
|
+
endToEndFlow: z.string().optional(),
|
|
518
|
+
scopeConfidence: z.object({ level: z.string(), reasons: z.array(z.string()) }).nullable(),
|
|
519
|
+
scopeUnknowns: z.array(z.string()),
|
|
520
|
+
affectedModules: z.array(z.string()),
|
|
521
|
+
moduleCoverage: z.array(z.object({ id: z.string(), status: z.string(), reason: z.string().optional() })),
|
|
522
|
+
impactAnalysis: z.array(z.object({ surface: z.string(), status: z.string(), reason: z.string().optional(), question: z.string().optional() })),
|
|
523
|
+
acceptanceCriteria: z.array(z.object({ text: z.string(), checked: z.boolean().nullable() })),
|
|
524
|
+
decisions: z.array(z.string()),
|
|
525
|
+
relatedKnowledge: z.array(z.string())
|
|
526
|
+
});
|
|
527
|
+
var WorkItemCreateSchema = z.object({
|
|
528
|
+
intent: z.string().min(1),
|
|
529
|
+
type: z.string().min(1)
|
|
530
|
+
});
|
|
531
|
+
var WorkItemUpdateSchema = z.object({
|
|
532
|
+
model: WorkItemInputSchema,
|
|
533
|
+
expectedRevision: z.string().min(1)
|
|
534
|
+
});
|
|
535
|
+
var WorkItemTransitionSchema = z.object({
|
|
536
|
+
expectedRevision: z.string().min(1)
|
|
537
|
+
});
|
|
538
|
+
var WorkItemEditModelSchema = WorkItemInputSchema.extend({
|
|
539
|
+
id: z.string(),
|
|
540
|
+
status: z.string(),
|
|
541
|
+
revision: z.string(),
|
|
542
|
+
path: z.string(),
|
|
543
|
+
editable: z.boolean(),
|
|
544
|
+
editableReason: z.string().optional()
|
|
545
|
+
});
|
|
546
|
+
var ValidationResultSchema = z.object({
|
|
547
|
+
findings: z.array(z.object({ level: z.enum(["blocking", "warning", "fyi"]), message: z.string() })),
|
|
548
|
+
canMarkReady: z.boolean()
|
|
549
|
+
});
|
|
550
|
+
var WorkItemWriteResultSchema = z.object({
|
|
551
|
+
id: z.string(),
|
|
552
|
+
path: z.string(),
|
|
553
|
+
revision: z.string(),
|
|
554
|
+
status: z.string().optional()
|
|
555
|
+
});
|
|
556
|
+
var ErrorResponseSchema = z.object({
|
|
557
|
+
error: z.object({
|
|
558
|
+
code: z.string(),
|
|
559
|
+
message: z.string()
|
|
560
|
+
})
|
|
561
|
+
});
|
|
562
|
+
|
|
258
563
|
// src/server.ts
|
|
564
|
+
var WRITE_METHODS = /* @__PURE__ */ new Set(["POST", "PUT", "PATCH", "DELETE"]);
|
|
565
|
+
function statusForCode(code) {
|
|
566
|
+
switch (code) {
|
|
567
|
+
case "WORK_ITEM_NOT_FOUND":
|
|
568
|
+
return 404;
|
|
569
|
+
case "WORK_ITEM_CONFLICT":
|
|
570
|
+
case "WORK_ITEM_NOT_EDITABLE":
|
|
571
|
+
return 409;
|
|
572
|
+
case "INVALID_INPUT":
|
|
573
|
+
case "INVALID_WORK_ITEM_ID":
|
|
574
|
+
case "INVALID_TRANSITION":
|
|
575
|
+
return 400;
|
|
576
|
+
default:
|
|
577
|
+
return 500;
|
|
578
|
+
}
|
|
579
|
+
}
|
|
259
580
|
async function createAdminServer(opts) {
|
|
260
581
|
const { projectDir, storage, staticDir, host = "127.0.0.1", port = 4173 } = opts;
|
|
261
582
|
const app = Fastify({ logger: false });
|
|
@@ -282,6 +603,15 @@ async function createAdminServer(opts) {
|
|
|
282
603
|
reply.code(401).send({ error: { code: "SESSION_INVALID", message: "Invalid or expired session." } });
|
|
283
604
|
}
|
|
284
605
|
});
|
|
606
|
+
const allowedOrigin = `http://${host}:${port}`;
|
|
607
|
+
app.addHook("onRequest", async (request, reply) => {
|
|
608
|
+
if (!request.url.startsWith("/api/")) return;
|
|
609
|
+
if (!WRITE_METHODS.has(request.method)) return;
|
|
610
|
+
const origin = request.headers.origin;
|
|
611
|
+
if (!origin || origin !== allowedOrigin) {
|
|
612
|
+
reply.code(403).send({ error: { code: "FORBIDDEN_ORIGIN", message: "Cross-origin write requests are not allowed." } });
|
|
613
|
+
}
|
|
614
|
+
});
|
|
285
615
|
app.get("/api/v1/admin/health", async () => ({ status: "ok" }));
|
|
286
616
|
app.get("/api/v1/admin/session", async (_request, reply) => {
|
|
287
617
|
reply.setCookie("kaddo-session", sessionId, {
|
|
@@ -321,6 +651,42 @@ async function createAdminServer(opts) {
|
|
|
321
651
|
}
|
|
322
652
|
}
|
|
323
653
|
);
|
|
654
|
+
const writeHandler = (reply, fn) => {
|
|
655
|
+
try {
|
|
656
|
+
return fn();
|
|
657
|
+
} catch (err) {
|
|
658
|
+
if (err instanceof CoreError) {
|
|
659
|
+
return reply.code(statusForCode(err.code)).send({ error: { code: err.code, message: err.message } });
|
|
660
|
+
}
|
|
661
|
+
throw err;
|
|
662
|
+
}
|
|
663
|
+
};
|
|
664
|
+
app.post("/api/v1/admin/work-items", async (request, reply) => {
|
|
665
|
+
const parsed = WorkItemCreateSchema.safeParse(request.body);
|
|
666
|
+
if (!parsed.success) return reply.code(400).send({ error: { code: "INVALID_INPUT", message: "Intent and type are required." } });
|
|
667
|
+
return writeHandler(reply, () => createWorkItemAdmin(projectDir, parsed.data));
|
|
668
|
+
});
|
|
669
|
+
app.get("/api/v1/admin/work-items/:workItemId/edit", async (request, reply) => {
|
|
670
|
+
return writeHandler(reply, () => getWorkItemEdit(projectDir, request.params.workItemId));
|
|
671
|
+
});
|
|
672
|
+
app.put("/api/v1/admin/work-items/:workItemId", async (request, reply) => {
|
|
673
|
+
const parsed = WorkItemUpdateSchema.safeParse(request.body);
|
|
674
|
+
if (!parsed.success) return reply.code(400).send({ error: { code: "INVALID_INPUT", message: "A Work Item model and expectedRevision are required." } });
|
|
675
|
+
return writeHandler(reply, () => updateWorkItemAdmin(projectDir, request.params.workItemId, parsed.data));
|
|
676
|
+
});
|
|
677
|
+
app.post("/api/v1/admin/work-items/:workItemId/validate", async (request, reply) => {
|
|
678
|
+
return writeHandler(reply, () => validateWorkItemAdmin(projectDir, request.params.workItemId));
|
|
679
|
+
});
|
|
680
|
+
app.post("/api/v1/admin/work-items/:workItemId/transitions/ready", async (request, reply) => {
|
|
681
|
+
const parsed = WorkItemTransitionSchema.safeParse(request.body);
|
|
682
|
+
if (!parsed.success) return reply.code(400).send({ error: { code: "INVALID_INPUT", message: "expectedRevision is required." } });
|
|
683
|
+
return writeHandler(reply, () => transitionWorkItemAdmin(projectDir, request.params.workItemId, "ready", parsed.data.expectedRevision));
|
|
684
|
+
});
|
|
685
|
+
app.post("/api/v1/admin/work-items/:workItemId/transitions/draft", async (request, reply) => {
|
|
686
|
+
const parsed = WorkItemTransitionSchema.safeParse(request.body);
|
|
687
|
+
if (!parsed.success) return reply.code(400).send({ error: { code: "INVALID_INPUT", message: "expectedRevision is required." } });
|
|
688
|
+
return writeHandler(reply, () => transitionWorkItemAdmin(projectDir, request.params.workItemId, "draft", parsed.data.expectedRevision));
|
|
689
|
+
});
|
|
324
690
|
app.get("/api/v1/admin/work-items/:workItemId", async (request, reply) => {
|
|
325
691
|
try {
|
|
326
692
|
return getWorkItemDetail(projectDir, request.params.workItemId);
|
|
@@ -474,206 +840,6 @@ var SQLiteAdminStorage = class {
|
|
|
474
840
|
this.db.close();
|
|
475
841
|
}
|
|
476
842
|
};
|
|
477
|
-
|
|
478
|
-
// src/contracts/schemas.ts
|
|
479
|
-
import { z } from "zod";
|
|
480
|
-
var ProjectSummarySchema = z.object({
|
|
481
|
-
name: z.string(),
|
|
482
|
-
state: z.string(),
|
|
483
|
-
structure: z.string(),
|
|
484
|
-
language: z.string(),
|
|
485
|
-
teamSize: z.string()
|
|
486
|
-
});
|
|
487
|
-
var KnowledgeSummarySchema = z.object({
|
|
488
|
-
layers: z.array(z.object({
|
|
489
|
-
layer: z.string(),
|
|
490
|
-
status: z.string()
|
|
491
|
-
})),
|
|
492
|
-
missing: z.array(z.string())
|
|
493
|
-
});
|
|
494
|
-
var WorkItemSummarySchema = z.object({
|
|
495
|
-
total: z.number(),
|
|
496
|
-
byState: z.record(z.string(), z.number()),
|
|
497
|
-
byType: z.record(z.string(), z.number()),
|
|
498
|
-
items: z.array(z.object({
|
|
499
|
-
id: z.string(),
|
|
500
|
-
title: z.string(),
|
|
501
|
-
type: z.string(),
|
|
502
|
-
lifecycle: z.string(),
|
|
503
|
-
initiative: z.string()
|
|
504
|
-
}))
|
|
505
|
-
});
|
|
506
|
-
var ModuleSummarySchema = z.object({
|
|
507
|
-
modules: z.array(z.object({
|
|
508
|
-
id: z.string(),
|
|
509
|
-
role: z.string(),
|
|
510
|
-
path: z.string().optional(),
|
|
511
|
-
available: z.boolean()
|
|
512
|
-
}))
|
|
513
|
-
});
|
|
514
|
-
var ProjectReadinessSchema = z.object({
|
|
515
|
-
overall: z.string(),
|
|
516
|
-
recommendedNextStep: z.object({
|
|
517
|
-
label: z.string(),
|
|
518
|
-
command: z.string().optional()
|
|
519
|
-
})
|
|
520
|
-
});
|
|
521
|
-
var RouteStepSchema = z.object({
|
|
522
|
-
id: z.string(),
|
|
523
|
-
label: z.string(),
|
|
524
|
-
status: z.string(),
|
|
525
|
-
evidence: z.array(z.string()).optional(),
|
|
526
|
-
reason: z.string().optional(),
|
|
527
|
-
command: z.string().optional()
|
|
528
|
-
});
|
|
529
|
-
var ProjectRouteSchema = z.object({
|
|
530
|
-
type: z.string(),
|
|
531
|
-
completed: z.number(),
|
|
532
|
-
total: z.number(),
|
|
533
|
-
progressPercent: z.number(),
|
|
534
|
-
steps: z.array(RouteStepSchema)
|
|
535
|
-
});
|
|
536
|
-
var FindingsSummarySchema = z.object({
|
|
537
|
-
blocking: z.number(),
|
|
538
|
-
warning: z.number(),
|
|
539
|
-
fyi: z.number(),
|
|
540
|
-
items: z.array(z.object({
|
|
541
|
-
level: z.enum(["blocking", "warning", "fyi"]),
|
|
542
|
-
message: z.string()
|
|
543
|
-
}))
|
|
544
|
-
});
|
|
545
|
-
var ProjectOverviewSchema = z.object({
|
|
546
|
-
project: ProjectSummarySchema,
|
|
547
|
-
knowledge: KnowledgeSummarySchema,
|
|
548
|
-
workItems: WorkItemSummarySchema,
|
|
549
|
-
modules: ModuleSummarySchema,
|
|
550
|
-
readiness: ProjectReadinessSchema,
|
|
551
|
-
route: ProjectRouteSchema,
|
|
552
|
-
findings: FindingsSummarySchema
|
|
553
|
-
});
|
|
554
|
-
var KnowledgeArtifactSummarySchema = z.object({
|
|
555
|
-
id: z.string(),
|
|
556
|
-
title: z.string(),
|
|
557
|
-
layer: z.string(),
|
|
558
|
-
path: z.string(),
|
|
559
|
-
status: z.string(),
|
|
560
|
-
type: z.string().optional()
|
|
561
|
-
});
|
|
562
|
-
var KnowledgeInventoryLayerSchema = z.object({
|
|
563
|
-
id: z.string(),
|
|
564
|
-
label: z.string(),
|
|
565
|
-
status: z.string(),
|
|
566
|
-
artifacts: z.array(KnowledgeArtifactSummarySchema)
|
|
567
|
-
});
|
|
568
|
-
var KnowledgeInventorySchema = z.object({
|
|
569
|
-
layers: z.array(KnowledgeInventoryLayerSchema)
|
|
570
|
-
});
|
|
571
|
-
var KnowledgeArtifactDetailSchema = z.object({
|
|
572
|
-
id: z.string(),
|
|
573
|
-
title: z.string(),
|
|
574
|
-
layer: z.string(),
|
|
575
|
-
path: z.string(),
|
|
576
|
-
status: z.string(),
|
|
577
|
-
format: z.string(),
|
|
578
|
-
content: z.string(),
|
|
579
|
-
type: z.string().optional()
|
|
580
|
-
});
|
|
581
|
-
var WorkItemsSummaryStatsSchema = z.object({
|
|
582
|
-
total: z.number(),
|
|
583
|
-
active: z.number(),
|
|
584
|
-
draft: z.number(),
|
|
585
|
-
ready: z.number(),
|
|
586
|
-
inProgress: z.number(),
|
|
587
|
-
blocked: z.number(),
|
|
588
|
-
completed: z.number(),
|
|
589
|
-
archived: z.number()
|
|
590
|
-
});
|
|
591
|
-
var WorkItemListItemSchema = z.object({
|
|
592
|
-
id: z.string(),
|
|
593
|
-
title: z.string(),
|
|
594
|
-
type: z.string(),
|
|
595
|
-
status: z.string(),
|
|
596
|
-
implementationStatus: z.string().nullable(),
|
|
597
|
-
validationStatus: z.string().nullable(),
|
|
598
|
-
releaseStatus: z.string().nullable(),
|
|
599
|
-
affectedModules: z.array(z.string()),
|
|
600
|
-
scopeConfidenceLevel: z.string().nullable(),
|
|
601
|
-
initiative: z.string().nullable()
|
|
602
|
-
});
|
|
603
|
-
var WorkItemsListSchema = z.object({
|
|
604
|
-
summary: WorkItemsSummaryStatsSchema,
|
|
605
|
-
items: z.array(WorkItemListItemSchema),
|
|
606
|
-
modules: z.array(z.string())
|
|
607
|
-
});
|
|
608
|
-
var CoverageEntrySchema = z.object({ id: z.string(), status: z.string(), reason: z.string().optional() });
|
|
609
|
-
var ImpactEntrySchema = z.object({
|
|
610
|
-
surface: z.string(),
|
|
611
|
-
status: z.string(),
|
|
612
|
-
reason: z.string().optional(),
|
|
613
|
-
question: z.string().optional()
|
|
614
|
-
});
|
|
615
|
-
var AcceptanceCriterionSchema = z.object({ text: z.string(), checked: z.boolean().nullable() });
|
|
616
|
-
var ReleaseGateEntrySchema = z.object({
|
|
617
|
-
id: z.string(),
|
|
618
|
-
status: z.string(),
|
|
619
|
-
reason: z.string().optional(),
|
|
620
|
-
requiredFor: z.string().optional()
|
|
621
|
-
});
|
|
622
|
-
var CompletionExceptionEntrySchema = z.object({
|
|
623
|
-
id: z.string(),
|
|
624
|
-
status: z.string(),
|
|
625
|
-
reason: z.string().optional(),
|
|
626
|
-
category: z.string().optional(),
|
|
627
|
-
impact: z.string().optional()
|
|
628
|
-
});
|
|
629
|
-
var RepoValidationSchema = z.object({ command: z.string(), status: z.string(), reason: z.string().optional() });
|
|
630
|
-
var RepoMigrationSchema = z.object({
|
|
631
|
-
id: z.string(),
|
|
632
|
-
environment: z.string(),
|
|
633
|
-
status: z.string(),
|
|
634
|
-
reason: z.string().optional()
|
|
635
|
-
});
|
|
636
|
-
var EvidenceRepoSchema = z.object({
|
|
637
|
-
module: z.string(),
|
|
638
|
-
role: z.string(),
|
|
639
|
-
status: z.string(),
|
|
640
|
-
changedPaths: z.array(z.string()),
|
|
641
|
-
validations: z.array(RepoValidationSchema),
|
|
642
|
-
migrations: z.array(RepoMigrationSchema)
|
|
643
|
-
});
|
|
644
|
-
var LinkedDecisionSchema = z.object({
|
|
645
|
-
id: z.string(),
|
|
646
|
-
title: z.string().optional(),
|
|
647
|
-
knowledgeId: z.string().optional(),
|
|
648
|
-
knowledgeLayer: z.string().optional()
|
|
649
|
-
});
|
|
650
|
-
var LinkedKnowledgeSchema = z.object({ id: z.string(), title: z.string(), layer: z.string() });
|
|
651
|
-
var WorkItemDetailSchema = WorkItemListItemSchema.extend({
|
|
652
|
-
actor: z.string().nullable(),
|
|
653
|
-
outcome: z.string().nullable(),
|
|
654
|
-
currentBehavior: z.string().nullable(),
|
|
655
|
-
targetBehavior: z.string().nullable(),
|
|
656
|
-
entryPoints: z.string().nullable(),
|
|
657
|
-
endToEndFlow: z.string().nullable(),
|
|
658
|
-
scopeConfidence: z.object({ level: z.string(), reasons: z.array(z.string()) }).nullable(),
|
|
659
|
-
scopeUnknowns: z.array(z.string()),
|
|
660
|
-
moduleCoverage: z.array(CoverageEntrySchema),
|
|
661
|
-
impactAnalysis: z.array(ImpactEntrySchema),
|
|
662
|
-
acceptanceCriteria: z.array(AcceptanceCriterionSchema),
|
|
663
|
-
implementationEvidence: z.array(EvidenceRepoSchema),
|
|
664
|
-
releaseGates: z.array(ReleaseGateEntrySchema),
|
|
665
|
-
completionExceptions: z.array(CompletionExceptionEntrySchema),
|
|
666
|
-
decisions: z.array(LinkedDecisionSchema),
|
|
667
|
-
relatedKnowledge: z.array(LinkedKnowledgeSchema),
|
|
668
|
-
source: z.object({ type: z.string(), id: z.string().optional(), inferred: z.boolean() }).passthrough(),
|
|
669
|
-
path: z.string()
|
|
670
|
-
});
|
|
671
|
-
var ErrorResponseSchema = z.object({
|
|
672
|
-
error: z.object({
|
|
673
|
-
code: z.string(),
|
|
674
|
-
message: z.string()
|
|
675
|
-
})
|
|
676
|
-
});
|
|
677
843
|
export {
|
|
678
844
|
ErrorResponseSchema,
|
|
679
845
|
FindingsSummarySchema,
|
|
@@ -690,9 +856,16 @@ export {
|
|
|
690
856
|
RouteStepSchema,
|
|
691
857
|
SQLiteAdminStorage,
|
|
692
858
|
SessionManager,
|
|
859
|
+
ValidationResultSchema,
|
|
860
|
+
WorkItemCreateSchema,
|
|
693
861
|
WorkItemDetailSchema,
|
|
862
|
+
WorkItemEditModelSchema,
|
|
863
|
+
WorkItemInputSchema,
|
|
694
864
|
WorkItemListItemSchema,
|
|
695
865
|
WorkItemSummarySchema,
|
|
866
|
+
WorkItemTransitionSchema,
|
|
867
|
+
WorkItemUpdateSchema,
|
|
868
|
+
WorkItemWriteResultSchema,
|
|
696
869
|
WorkItemsListSchema,
|
|
697
870
|
WorkItemsSummaryStatsSchema,
|
|
698
871
|
createAdminServer
|