@soddong/agentic-domain-methodology 0.11.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/.tbls.yml +64 -0
- package/CHANGELOG.md +97 -0
- package/README.md +501 -0
- package/dist/database.d.ts +8 -0
- package/dist/database.d.ts.map +1 -0
- package/dist/database.js +76 -0
- package/dist/database.js.map +1 -0
- package/dist/fixtures.d.ts +13 -0
- package/dist/fixtures.d.ts.map +1 -0
- package/dist/fixtures.js +413 -0
- package/dist/fixtures.js.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/repositories.d.ts +54 -0
- package/dist/repositories.d.ts.map +1 -0
- package/dist/repositories.js +652 -0
- package/dist/repositories.js.map +1 -0
- package/dist/seed-apply.d.ts +20 -0
- package/dist/seed-apply.d.ts.map +1 -0
- package/dist/seed-apply.js +728 -0
- package/dist/seed-apply.js.map +1 -0
- package/dist/service.d.ts +107 -0
- package/dist/service.d.ts.map +1 -0
- package/dist/service.js +225 -0
- package/dist/service.js.map +1 -0
- package/dist/types.d.ts +356 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/validators.d.ts +17 -0
- package/dist/validators.d.ts.map +1 -0
- package/dist/validators.js +297 -0
- package/dist/validators.js.map +1 -0
- package/docs/build.md +47 -0
- package/docs/configuration.md +33 -0
- package/docs/delivery.md +52 -0
- package/docs/operations.md +55 -0
- package/docs/publishing.md +84 -0
- package/docs/schema/generated/README.md +39 -0
- package/docs/schema/generated/methodology_activities.md +121 -0
- package/docs/schema/generated/methodology_activities.svg +143 -0
- package/docs/schema/generated/methodology_activity_artifact_requirements.md +129 -0
- package/docs/schema/generated/methodology_activity_artifact_requirements.svg +52 -0
- package/docs/schema/generated/methodology_activity_criteria.md +112 -0
- package/docs/schema/generated/methodology_activity_criteria.svg +52 -0
- package/docs/schema/generated/methodology_baseline_requirements.md +103 -0
- package/docs/schema/generated/methodology_baseline_requirements.svg +27 -0
- package/docs/schema/generated/methodology_code_groups.md +70 -0
- package/docs/schema/generated/methodology_code_groups.svg +49 -0
- package/docs/schema/generated/methodology_codes.md +88 -0
- package/docs/schema/generated/methodology_codes.svg +49 -0
- package/docs/schema/generated/methodology_common_blueprint_policies.md +104 -0
- package/docs/schema/generated/methodology_common_blueprint_policies.svg +72 -0
- package/docs/schema/generated/methodology_common_blueprint_policy_nodes.md +118 -0
- package/docs/schema/generated/methodology_common_blueprint_policy_nodes.svg +59 -0
- package/docs/schema/generated/methodology_handoff_requirements.md +130 -0
- package/docs/schema/generated/methodology_handoff_requirements.svg +27 -0
- package/docs/schema/generated/methodology_lifecycles.md +105 -0
- package/docs/schema/generated/methodology_lifecycles.svg +71 -0
- package/docs/schema/generated/methodology_methodologies.md +92 -0
- package/docs/schema/generated/methodology_methodologies.svg +92 -0
- package/docs/schema/generated/methodology_phase_processes.md +106 -0
- package/docs/schema/generated/methodology_phase_processes.svg +77 -0
- package/docs/schema/generated/methodology_phases.md +107 -0
- package/docs/schema/generated/methodology_phases.svg +77 -0
- package/docs/schema/generated/methodology_processes.md +98 -0
- package/docs/schema/generated/methodology_processes.svg +118 -0
- package/docs/schema/generated/methodology_schema_migrations.md +52 -0
- package/docs/schema/generated/methodology_schema_migrations.svg +27 -0
- package/docs/schema/generated/methodology_stage_activities.md +106 -0
- package/docs/schema/generated/methodology_stage_activities.svg +77 -0
- package/docs/schema/generated/methodology_stage_artifact_requirements.md +109 -0
- package/docs/schema/generated/methodology_stage_artifact_requirements.svg +52 -0
- package/docs/schema/generated/methodology_stage_criteria.md +112 -0
- package/docs/schema/generated/methodology_stage_criteria.svg +52 -0
- package/docs/schema/generated/methodology_stages.md +117 -0
- package/docs/schema/generated/methodology_stages.svg +121 -0
- package/docs/schema/generated/methodology_steps.md +105 -0
- package/docs/schema/generated/methodology_steps.svg +52 -0
- package/docs/schema/generated/methodology_trace_policies.md +121 -0
- package/docs/schema/generated/methodology_trace_policies.svg +27 -0
- package/docs/schema/generated/schema.json +4253 -0
- package/docs/schema/generated/schema.mmd +296 -0
- package/docs/schema/generated/schema.svg +446 -0
- package/docs/schema/migrations.md +24 -0
- package/docs/usage.md +39 -0
- package/package.json +29 -0
- package/src/database/migrations/0001_methodology_base.sql +1190 -0
|
@@ -0,0 +1,728 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { MethodologyService } from "./service.js";
|
|
3
|
+
import { openMethodologyDatabase } from "./database.js";
|
|
4
|
+
function isRecord(value) {
|
|
5
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6
|
+
}
|
|
7
|
+
function camelRow(row) {
|
|
8
|
+
if (row === undefined) {
|
|
9
|
+
return undefined;
|
|
10
|
+
}
|
|
11
|
+
return {
|
|
12
|
+
...row,
|
|
13
|
+
methodologyId: row.methodology_id,
|
|
14
|
+
lifecycleId: row.lifecycle_id,
|
|
15
|
+
phaseId: row.phase_id,
|
|
16
|
+
processId: row.process_id,
|
|
17
|
+
stageId: row.stage_id,
|
|
18
|
+
activityId: row.activity_id,
|
|
19
|
+
sortOrder: row.sort_order
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function asArray(value) {
|
|
23
|
+
if (!Array.isArray(value)) {
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
return value.filter(isRecord);
|
|
27
|
+
}
|
|
28
|
+
function stringValue(value, key) {
|
|
29
|
+
const raw = value[key];
|
|
30
|
+
return typeof raw === "string" && raw.length > 0 ? raw : undefined;
|
|
31
|
+
}
|
|
32
|
+
function numberValue(value, key) {
|
|
33
|
+
const raw = value[key];
|
|
34
|
+
return typeof raw === "number" && Number.isFinite(raw) ? raw : undefined;
|
|
35
|
+
}
|
|
36
|
+
function boolValue(value, key, fallback) {
|
|
37
|
+
const raw = value[key];
|
|
38
|
+
return typeof raw === "boolean" ? raw : fallback;
|
|
39
|
+
}
|
|
40
|
+
function normalizeHandoffTypeCode(value) {
|
|
41
|
+
switch (value) {
|
|
42
|
+
case "artifact":
|
|
43
|
+
case "issue":
|
|
44
|
+
case "risk":
|
|
45
|
+
case "decision":
|
|
46
|
+
case "constraint":
|
|
47
|
+
case "approval":
|
|
48
|
+
case "context":
|
|
49
|
+
return value;
|
|
50
|
+
case "stage_gate":
|
|
51
|
+
return "context";
|
|
52
|
+
default:
|
|
53
|
+
return "context";
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function sourceMetadata(input, payload) {
|
|
57
|
+
return {
|
|
58
|
+
seedSourcePackageName: input.sourcePackageName,
|
|
59
|
+
seedSourcePackageVersion: input.sourcePackageVersion,
|
|
60
|
+
seedBundleCode: input.bundleCode,
|
|
61
|
+
seedBundleVersion: input.bundleVersion,
|
|
62
|
+
seedSourceSection: input.sourceSection,
|
|
63
|
+
seedTargetOperation: input.targetOperation,
|
|
64
|
+
seedItemKey: input.itemKey,
|
|
65
|
+
seedPayload: payload
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function methodologyVersion(input) {
|
|
69
|
+
return input.bundleVersion;
|
|
70
|
+
}
|
|
71
|
+
function findMethodology(db, methodologyCode, version) {
|
|
72
|
+
const row = db
|
|
73
|
+
.prepare(`SELECT *
|
|
74
|
+
FROM methodology_methodologies
|
|
75
|
+
WHERE methodology_code = ?
|
|
76
|
+
AND methodology_version = ?`)
|
|
77
|
+
.get(methodologyCode, version);
|
|
78
|
+
return camelRow(row);
|
|
79
|
+
}
|
|
80
|
+
function findLifecycle(db, methodologyId, lifecycleCode) {
|
|
81
|
+
const row = db
|
|
82
|
+
.prepare(`SELECT *
|
|
83
|
+
FROM methodology_lifecycles
|
|
84
|
+
WHERE methodology_id = ?
|
|
85
|
+
AND lifecycle_code = ?`)
|
|
86
|
+
.get(methodologyId, lifecycleCode);
|
|
87
|
+
return camelRow(row);
|
|
88
|
+
}
|
|
89
|
+
function findPhase(db, lifecycleId, phaseCode) {
|
|
90
|
+
const row = db
|
|
91
|
+
.prepare(`SELECT *
|
|
92
|
+
FROM methodology_phases
|
|
93
|
+
WHERE lifecycle_id = ?
|
|
94
|
+
AND phase_code = ?`)
|
|
95
|
+
.get(lifecycleId, phaseCode);
|
|
96
|
+
return camelRow(row);
|
|
97
|
+
}
|
|
98
|
+
function findPhaseByCode(db, methodologyId, phaseCode) {
|
|
99
|
+
const row = db
|
|
100
|
+
.prepare(`SELECT p.*
|
|
101
|
+
FROM methodology_phases p
|
|
102
|
+
JOIN methodology_lifecycles l ON l.lifecycle_id = p.lifecycle_id
|
|
103
|
+
WHERE l.methodology_id = ?
|
|
104
|
+
AND p.phase_code = ?
|
|
105
|
+
ORDER BY p.sort_order
|
|
106
|
+
LIMIT 1`)
|
|
107
|
+
.get(methodologyId, phaseCode);
|
|
108
|
+
return camelRow(row);
|
|
109
|
+
}
|
|
110
|
+
function findProcess(db, methodologyId, processCode) {
|
|
111
|
+
const row = db
|
|
112
|
+
.prepare(`SELECT *
|
|
113
|
+
FROM methodology_processes
|
|
114
|
+
WHERE methodology_id = ?
|
|
115
|
+
AND process_code = ?`)
|
|
116
|
+
.get(methodologyId, processCode);
|
|
117
|
+
return camelRow(row);
|
|
118
|
+
}
|
|
119
|
+
function findStage(db, processId, stageCode) {
|
|
120
|
+
const row = db
|
|
121
|
+
.prepare(`SELECT *
|
|
122
|
+
FROM methodology_stages
|
|
123
|
+
WHERE process_id = ?
|
|
124
|
+
AND stage_code = ?`)
|
|
125
|
+
.get(processId, stageCode);
|
|
126
|
+
return camelRow(row);
|
|
127
|
+
}
|
|
128
|
+
function findStageByCode(db, methodologyId, stageCode) {
|
|
129
|
+
const row = db
|
|
130
|
+
.prepare(`SELECT s.*
|
|
131
|
+
FROM methodology_stages s
|
|
132
|
+
JOIN methodology_processes p ON p.process_id = s.process_id
|
|
133
|
+
WHERE p.methodology_id = ?
|
|
134
|
+
AND s.stage_code = ?
|
|
135
|
+
ORDER BY s.sort_order
|
|
136
|
+
LIMIT 1`)
|
|
137
|
+
.get(methodologyId, stageCode);
|
|
138
|
+
return camelRow(row);
|
|
139
|
+
}
|
|
140
|
+
function findActivity(db, processId, activityCode) {
|
|
141
|
+
const row = db
|
|
142
|
+
.prepare(`SELECT *
|
|
143
|
+
FROM methodology_activities
|
|
144
|
+
WHERE process_id = ?
|
|
145
|
+
AND activity_code = ?`)
|
|
146
|
+
.get(processId, activityCode);
|
|
147
|
+
return camelRow(row);
|
|
148
|
+
}
|
|
149
|
+
function findActivityByCode(db, methodologyId, activityCode) {
|
|
150
|
+
const row = db
|
|
151
|
+
.prepare(`SELECT a.*
|
|
152
|
+
FROM methodology_activities a
|
|
153
|
+
JOIN methodology_processes p ON p.process_id = a.process_id
|
|
154
|
+
WHERE p.methodology_id = ?
|
|
155
|
+
AND a.activity_code = ?
|
|
156
|
+
ORDER BY a.sort_order
|
|
157
|
+
LIMIT 1`)
|
|
158
|
+
.get(methodologyId, activityCode);
|
|
159
|
+
return camelRow(row);
|
|
160
|
+
}
|
|
161
|
+
function createActivityCriteria(db, input) {
|
|
162
|
+
const activityCriteriaId = randomUUID();
|
|
163
|
+
db.prepare(`INSERT INTO methodology_activity_criteria
|
|
164
|
+
(activity_criteria_id, activity_id, criteria_type_code, criteria_name, criteria_text,
|
|
165
|
+
is_required, validation_required, severity_code, sort_order, metadata_json)
|
|
166
|
+
VALUES (?, ?, ?, ?, ?, 1, 1, ?, ?, ?)`).run(activityCriteriaId, input.activityId, input.criteriaTypeCode, input.criteriaName, input.criteriaText, input.severityCode ?? "error", input.sortOrder ?? 0, input.metadata === undefined ? null : JSON.stringify(input.metadata));
|
|
167
|
+
return activityCriteriaId;
|
|
168
|
+
}
|
|
169
|
+
function hasPhaseProcess(db, phaseId, processId) {
|
|
170
|
+
const row = db
|
|
171
|
+
.prepare(`SELECT phase_process_id
|
|
172
|
+
FROM methodology_phase_processes
|
|
173
|
+
WHERE phase_id = ?
|
|
174
|
+
AND process_id = ?`)
|
|
175
|
+
.get(phaseId, processId);
|
|
176
|
+
return row !== undefined;
|
|
177
|
+
}
|
|
178
|
+
function hasStageActivity(db, stageId, activityId) {
|
|
179
|
+
const row = db
|
|
180
|
+
.prepare(`SELECT stage_activity_id
|
|
181
|
+
FROM methodology_stage_activities
|
|
182
|
+
WHERE stage_id = ?
|
|
183
|
+
AND activity_id = ?`)
|
|
184
|
+
.get(stageId, activityId);
|
|
185
|
+
return row !== undefined;
|
|
186
|
+
}
|
|
187
|
+
function processGlobalActivitySortOrder(stage, payload) {
|
|
188
|
+
const localSortOrder = numberValue(payload, "sortOrder");
|
|
189
|
+
if (localSortOrder === undefined) {
|
|
190
|
+
return undefined;
|
|
191
|
+
}
|
|
192
|
+
return (stage.sortOrder * 1000) + localSortOrder;
|
|
193
|
+
}
|
|
194
|
+
function getCurrentMethodology(ctx) {
|
|
195
|
+
const methodologyCode = ctx.input.methodologyCode;
|
|
196
|
+
if (methodologyCode === undefined) {
|
|
197
|
+
return undefined;
|
|
198
|
+
}
|
|
199
|
+
return findMethodology(ctx.db, methodologyCode, methodologyVersion(ctx.input));
|
|
200
|
+
}
|
|
201
|
+
function blocked(message) {
|
|
202
|
+
return {
|
|
203
|
+
status: "blocked",
|
|
204
|
+
message
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
function applied(targetRefs, skippedCount) {
|
|
208
|
+
if (targetRefs.length === 0 && skippedCount > 0) {
|
|
209
|
+
return {
|
|
210
|
+
status: "skipped",
|
|
211
|
+
message: `All ${skippedCount} seed item(s) already exist.`
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
return {
|
|
215
|
+
status: "applied",
|
|
216
|
+
targetRefs,
|
|
217
|
+
message: skippedCount > 0 ? `${skippedCount} seed item(s) already existed.` : undefined
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
function applyMethodology(ctx) {
|
|
221
|
+
if (!isRecord(ctx.input.itemPayload)) {
|
|
222
|
+
return {
|
|
223
|
+
status: "failed",
|
|
224
|
+
message: "methodology payload must be an object."
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
const payload = ctx.input.itemPayload;
|
|
228
|
+
const methodologyCode = stringValue(payload, "methodologyCode");
|
|
229
|
+
const methodologyName = stringValue(payload, "methodologyName");
|
|
230
|
+
const methodologyVersionValue = methodologyVersion(ctx.input);
|
|
231
|
+
if (methodologyCode === undefined || methodologyName === undefined) {
|
|
232
|
+
return {
|
|
233
|
+
status: "failed",
|
|
234
|
+
message: "methodologyCode and methodologyName are required."
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
const existing = findMethodology(ctx.db, methodologyCode, methodologyVersionValue);
|
|
238
|
+
if (existing !== undefined) {
|
|
239
|
+
return applied([], 1);
|
|
240
|
+
}
|
|
241
|
+
const created = ctx.service.createMethodology({
|
|
242
|
+
methodologyCode,
|
|
243
|
+
methodologyName,
|
|
244
|
+
methodologyVersion: methodologyVersionValue,
|
|
245
|
+
methodologyStatusCode: stringValue(payload, "methodologyStatusCode"),
|
|
246
|
+
description: stringValue(payload, "description"),
|
|
247
|
+
metadata: sourceMetadata(ctx.input, payload)
|
|
248
|
+
});
|
|
249
|
+
return applied([`methodology:${created.methodologyCode}`], 0);
|
|
250
|
+
}
|
|
251
|
+
function applyLifecycle(ctx) {
|
|
252
|
+
if (!isRecord(ctx.input.itemPayload)) {
|
|
253
|
+
return {
|
|
254
|
+
status: "failed",
|
|
255
|
+
message: "lifecycle payload must be an object."
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
const methodology = getCurrentMethodology(ctx);
|
|
259
|
+
if (methodology === undefined) {
|
|
260
|
+
return blocked("Target methodology was not found for lifecycle seed.");
|
|
261
|
+
}
|
|
262
|
+
const payload = ctx.input.itemPayload;
|
|
263
|
+
const lifecycleCode = stringValue(payload, "lifecycleCode");
|
|
264
|
+
const lifecycleName = stringValue(payload, "lifecycleName");
|
|
265
|
+
if (lifecycleCode === undefined || lifecycleName === undefined) {
|
|
266
|
+
return {
|
|
267
|
+
status: "failed",
|
|
268
|
+
message: "lifecycleCode and lifecycleName are required."
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
if (findLifecycle(ctx.db, methodology.methodologyId, lifecycleCode) !== undefined) {
|
|
272
|
+
return applied([], 1);
|
|
273
|
+
}
|
|
274
|
+
const created = ctx.service.createLifecycle({
|
|
275
|
+
methodologyId: methodology.methodologyId,
|
|
276
|
+
lifecycleCode,
|
|
277
|
+
lifecycleName,
|
|
278
|
+
lifecycleTypeCode: stringValue(payload, "lifecycleTypeCode"),
|
|
279
|
+
description: stringValue(payload, "description"),
|
|
280
|
+
sortOrder: numberValue(payload, "lifecycleOrder"),
|
|
281
|
+
metadata: sourceMetadata(ctx.input, payload)
|
|
282
|
+
});
|
|
283
|
+
return applied([`lifecycle:${created.lifecycleCode}`], 0);
|
|
284
|
+
}
|
|
285
|
+
function applyPhases(ctx) {
|
|
286
|
+
const methodology = getCurrentMethodology(ctx);
|
|
287
|
+
if (methodology === undefined) {
|
|
288
|
+
return blocked("Target methodology was not found for phase seed.");
|
|
289
|
+
}
|
|
290
|
+
const targetRefs = [];
|
|
291
|
+
let skippedCount = 0;
|
|
292
|
+
for (const payload of asArray(ctx.input.itemPayload)) {
|
|
293
|
+
const lifecycleCode = stringValue(payload, "lifecycleCode");
|
|
294
|
+
const phaseCode = stringValue(payload, "phaseCode");
|
|
295
|
+
const phaseName = stringValue(payload, "phaseName");
|
|
296
|
+
if (lifecycleCode === undefined || phaseCode === undefined || phaseName === undefined) {
|
|
297
|
+
return {
|
|
298
|
+
status: "failed",
|
|
299
|
+
message: "phase seed requires lifecycleCode, phaseCode, and phaseName."
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
const lifecycle = findLifecycle(ctx.db, methodology.methodologyId, lifecycleCode);
|
|
303
|
+
if (lifecycle === undefined) {
|
|
304
|
+
return blocked(`Lifecycle was not found for phase seed: ${lifecycleCode}`);
|
|
305
|
+
}
|
|
306
|
+
if (findPhase(ctx.db, lifecycle.lifecycleId, phaseCode) !== undefined) {
|
|
307
|
+
skippedCount += 1;
|
|
308
|
+
continue;
|
|
309
|
+
}
|
|
310
|
+
const created = ctx.service.createPhase({
|
|
311
|
+
lifecycleId: lifecycle.lifecycleId,
|
|
312
|
+
phaseCode,
|
|
313
|
+
phaseName,
|
|
314
|
+
phasePurpose: stringValue(payload, "description"),
|
|
315
|
+
sortOrder: numberValue(payload, "phaseOrder"),
|
|
316
|
+
metadata: {
|
|
317
|
+
...sourceMetadata(ctx.input, payload),
|
|
318
|
+
phaseTypeCode: stringValue(payload, "phaseTypeCode")
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
targetRefs.push(`phase:${created.phaseCode}`);
|
|
322
|
+
}
|
|
323
|
+
return applied(targetRefs, skippedCount);
|
|
324
|
+
}
|
|
325
|
+
function applyProcesses(ctx) {
|
|
326
|
+
const methodology = getCurrentMethodology(ctx);
|
|
327
|
+
if (methodology === undefined) {
|
|
328
|
+
return blocked("Target methodology was not found for process seed.");
|
|
329
|
+
}
|
|
330
|
+
const targetRefs = [];
|
|
331
|
+
let skippedCount = 0;
|
|
332
|
+
for (const payload of asArray(ctx.input.itemPayload)) {
|
|
333
|
+
const processCode = stringValue(payload, "processCode");
|
|
334
|
+
const processName = stringValue(payload, "processName");
|
|
335
|
+
const phaseCode = stringValue(payload, "phaseCode");
|
|
336
|
+
if (processCode === undefined || processName === undefined || phaseCode === undefined) {
|
|
337
|
+
return {
|
|
338
|
+
status: "failed",
|
|
339
|
+
message: "process seed requires processCode, processName, and phaseCode."
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
const phase = findPhaseByCode(ctx.db, methodology.methodologyId, phaseCode);
|
|
343
|
+
if (phase === undefined) {
|
|
344
|
+
return blocked(`Phase was not found for process seed: ${phaseCode}`);
|
|
345
|
+
}
|
|
346
|
+
const existing = findProcess(ctx.db, methodology.methodologyId, processCode);
|
|
347
|
+
const process = existing ?? ctx.service.createProcess({
|
|
348
|
+
methodologyId: methodology.methodologyId,
|
|
349
|
+
processCode,
|
|
350
|
+
processName,
|
|
351
|
+
processPurpose: stringValue(payload, "description"),
|
|
352
|
+
processTypeCode: stringValue(payload, "processTypeCode"),
|
|
353
|
+
metadata: sourceMetadata(ctx.input, payload)
|
|
354
|
+
});
|
|
355
|
+
if (!hasPhaseProcess(ctx.db, phase.phaseId, process.processId)) {
|
|
356
|
+
ctx.service.assignProcessToPhase({
|
|
357
|
+
phaseId: phase.phaseId,
|
|
358
|
+
processId: process.processId,
|
|
359
|
+
sortOrder: numberValue(payload, "processOrder"),
|
|
360
|
+
metadata: sourceMetadata(ctx.input, payload)
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
if (existing === undefined) {
|
|
364
|
+
targetRefs.push(`process:${process.processCode}`);
|
|
365
|
+
}
|
|
366
|
+
else {
|
|
367
|
+
skippedCount += 1;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
return applied(targetRefs, skippedCount);
|
|
371
|
+
}
|
|
372
|
+
function applyStages(ctx) {
|
|
373
|
+
const methodology = getCurrentMethodology(ctx);
|
|
374
|
+
if (methodology === undefined) {
|
|
375
|
+
return blocked("Target methodology was not found for stage seed.");
|
|
376
|
+
}
|
|
377
|
+
const targetRefs = [];
|
|
378
|
+
let skippedCount = 0;
|
|
379
|
+
for (const payload of asArray(ctx.input.itemPayload)) {
|
|
380
|
+
const processCode = stringValue(payload, "processCode");
|
|
381
|
+
const stageCode = stringValue(payload, "stageCode");
|
|
382
|
+
const stageName = stringValue(payload, "stageName");
|
|
383
|
+
if (processCode === undefined || stageCode === undefined || stageName === undefined) {
|
|
384
|
+
return {
|
|
385
|
+
status: "failed",
|
|
386
|
+
message: "stage seed requires processCode, stageCode, and stageName."
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
const process = findProcess(ctx.db, methodology.methodologyId, processCode);
|
|
390
|
+
if (process === undefined) {
|
|
391
|
+
return blocked(`Process was not found for stage seed: ${processCode}`);
|
|
392
|
+
}
|
|
393
|
+
if (findStage(ctx.db, process.processId, stageCode) !== undefined) {
|
|
394
|
+
skippedCount += 1;
|
|
395
|
+
continue;
|
|
396
|
+
}
|
|
397
|
+
const created = ctx.service.createStage({
|
|
398
|
+
processId: process.processId,
|
|
399
|
+
stageCode,
|
|
400
|
+
stageName,
|
|
401
|
+
stageObjective: stringValue(payload, "description"),
|
|
402
|
+
stageTypeCode: stringValue(payload, "stageTypeCode"),
|
|
403
|
+
sortOrder: numberValue(payload, "stageOrder"),
|
|
404
|
+
metadata: sourceMetadata(ctx.input, payload)
|
|
405
|
+
});
|
|
406
|
+
targetRefs.push(`stage:${created.stageCode}`);
|
|
407
|
+
}
|
|
408
|
+
return applied(targetRefs, skippedCount);
|
|
409
|
+
}
|
|
410
|
+
function applyActivities(ctx) {
|
|
411
|
+
const methodology = getCurrentMethodology(ctx);
|
|
412
|
+
if (methodology === undefined) {
|
|
413
|
+
return blocked("Target methodology was not found for activity seed.");
|
|
414
|
+
}
|
|
415
|
+
const targetRefs = [];
|
|
416
|
+
let skippedCount = 0;
|
|
417
|
+
for (const payload of asArray(ctx.input.itemPayload)) {
|
|
418
|
+
const stageCode = stringValue(payload, "stageCode");
|
|
419
|
+
const activityCode = stringValue(payload, "activityCode");
|
|
420
|
+
const activityName = stringValue(payload, "activityName");
|
|
421
|
+
if (stageCode === undefined || activityCode === undefined || activityName === undefined) {
|
|
422
|
+
return {
|
|
423
|
+
status: "failed",
|
|
424
|
+
message: "activity seed requires stageCode, activityCode, and activityName."
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
const stage = findStageByCode(ctx.db, methodology.methodologyId, stageCode);
|
|
428
|
+
if (stage === undefined) {
|
|
429
|
+
return blocked(`Stage was not found for activity seed: ${stageCode}`);
|
|
430
|
+
}
|
|
431
|
+
const existing = findActivity(ctx.db, stage.processId, activityCode);
|
|
432
|
+
const activity = existing ?? ctx.service.createActivity({
|
|
433
|
+
processId: stage.processId,
|
|
434
|
+
activityCode,
|
|
435
|
+
activityName,
|
|
436
|
+
activityPurpose: stringValue(payload, "description"),
|
|
437
|
+
activityTypeCode: stringValue(payload, "activityTypeCode"),
|
|
438
|
+
sortOrder: processGlobalActivitySortOrder(stage, payload),
|
|
439
|
+
metadata: {
|
|
440
|
+
...sourceMetadata(ctx.input, payload),
|
|
441
|
+
stageLocalSortOrder: numberValue(payload, "sortOrder")
|
|
442
|
+
}
|
|
443
|
+
});
|
|
444
|
+
if (!hasStageActivity(ctx.db, stage.stageId, activity.activityId)) {
|
|
445
|
+
ctx.service.assignActivityToStage({
|
|
446
|
+
stageId: stage.stageId,
|
|
447
|
+
activityId: activity.activityId,
|
|
448
|
+
sortOrder: numberValue(payload, "sortOrder"),
|
|
449
|
+
metadata: sourceMetadata(ctx.input, payload)
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
if (existing === undefined) {
|
|
453
|
+
targetRefs.push(`activity:${activity.activityCode}`);
|
|
454
|
+
}
|
|
455
|
+
else {
|
|
456
|
+
skippedCount += 1;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
return applied(targetRefs, skippedCount);
|
|
460
|
+
}
|
|
461
|
+
function applyActivityArtifactRequirements(ctx) {
|
|
462
|
+
const methodology = getCurrentMethodology(ctx);
|
|
463
|
+
if (methodology === undefined) {
|
|
464
|
+
return blocked("Target methodology was not found for activity artifact requirement seed.");
|
|
465
|
+
}
|
|
466
|
+
const targetRefs = [];
|
|
467
|
+
let skippedCount = 0;
|
|
468
|
+
for (const payload of asArray(ctx.input.itemPayload)) {
|
|
469
|
+
const activityCode = stringValue(payload, "activityCode");
|
|
470
|
+
const artifactStandardCode = stringValue(payload, "artifactStandardCode");
|
|
471
|
+
const artifactStandardVersion = stringValue(payload, "artifactStandardVersion");
|
|
472
|
+
const requirementRoleCode = stringValue(payload, "requirementRoleCode");
|
|
473
|
+
if (activityCode === undefined ||
|
|
474
|
+
artifactStandardCode === undefined ||
|
|
475
|
+
artifactStandardVersion === undefined ||
|
|
476
|
+
requirementRoleCode === undefined) {
|
|
477
|
+
return {
|
|
478
|
+
status: "failed",
|
|
479
|
+
message: "activity artifact requirement seed requires activityCode, artifactStandardCode, artifactStandardVersion, and requirementRoleCode."
|
|
480
|
+
};
|
|
481
|
+
}
|
|
482
|
+
const activity = findActivityByCode(ctx.db, methodology.methodologyId, activityCode);
|
|
483
|
+
if (activity === undefined) {
|
|
484
|
+
return blocked(`Activity was not found for artifact requirement seed: ${activityCode}`);
|
|
485
|
+
}
|
|
486
|
+
const artifactComponentCode = stringValue(payload, "artifactComponentCode");
|
|
487
|
+
const existing = ctx.db
|
|
488
|
+
.prepare(`SELECT activity_artifact_requirement_id
|
|
489
|
+
FROM methodology_activity_artifact_requirements
|
|
490
|
+
WHERE activity_id = ?
|
|
491
|
+
AND artifact_standard_code = ?
|
|
492
|
+
AND artifact_standard_version = ?
|
|
493
|
+
AND requirement_role_code = ?
|
|
494
|
+
AND COALESCE(artifact_component_code, '') = ?`)
|
|
495
|
+
.get(activity.activityId, artifactStandardCode, artifactStandardVersion, requirementRoleCode, artifactComponentCode ?? "");
|
|
496
|
+
if (existing !== undefined) {
|
|
497
|
+
skippedCount += 1;
|
|
498
|
+
continue;
|
|
499
|
+
}
|
|
500
|
+
const created = ctx.service.addActivityArtifactRequirement({
|
|
501
|
+
activityId: activity.activityId,
|
|
502
|
+
artifactStandardCode,
|
|
503
|
+
artifactStandardVersion,
|
|
504
|
+
artifactComponentCode,
|
|
505
|
+
artifactComponentRoleCode: stringValue(payload, "artifactComponentRoleCode"),
|
|
506
|
+
requirementRoleCode: requirementRoleCode,
|
|
507
|
+
isPrimary: boolValue(payload, "isPrimary", false),
|
|
508
|
+
validationRequired: boolValue(payload, "validationRequired", false),
|
|
509
|
+
sortOrder: numberValue(payload, "sortOrder"),
|
|
510
|
+
metadata: {
|
|
511
|
+
...sourceMetadata(ctx.input, payload),
|
|
512
|
+
requirementCode: stringValue(payload, "requirementCode"),
|
|
513
|
+
description: stringValue(payload, "description")
|
|
514
|
+
}
|
|
515
|
+
});
|
|
516
|
+
targetRefs.push(`activityArtifactRequirement:${created.activityArtifactRequirementId}`);
|
|
517
|
+
}
|
|
518
|
+
return applied(targetRefs, skippedCount);
|
|
519
|
+
}
|
|
520
|
+
function applyCriteria(ctx) {
|
|
521
|
+
const methodology = getCurrentMethodology(ctx);
|
|
522
|
+
if (methodology === undefined) {
|
|
523
|
+
return blocked("Target methodology was not found for criteria seed.");
|
|
524
|
+
}
|
|
525
|
+
const targetRefs = [];
|
|
526
|
+
let skippedCount = 0;
|
|
527
|
+
for (const payload of asArray(ctx.input.itemPayload)) {
|
|
528
|
+
const scopeTypeCode = stringValue(payload, "scopeTypeCode");
|
|
529
|
+
const scopeCode = stringValue(payload, "scopeCode");
|
|
530
|
+
const criteriaTypeCode = stringValue(payload, "criteriaTypeCode");
|
|
531
|
+
const criteriaName = stringValue(payload, "criteriaName");
|
|
532
|
+
if (scopeCode === undefined || criteriaTypeCode === undefined || criteriaName === undefined) {
|
|
533
|
+
return {
|
|
534
|
+
status: "failed",
|
|
535
|
+
message: "criteria seed requires scopeCode, criteriaTypeCode, and criteriaName."
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
if (scopeTypeCode === "activity") {
|
|
539
|
+
const activity = findActivityByCode(ctx.db, methodology.methodologyId, scopeCode);
|
|
540
|
+
if (activity === undefined) {
|
|
541
|
+
return blocked(`Activity was not found for criteria seed: ${scopeCode}`);
|
|
542
|
+
}
|
|
543
|
+
const sortOrder = numberValue(payload, "sortOrder") ?? 0;
|
|
544
|
+
const existing = ctx.db
|
|
545
|
+
.prepare(`SELECT activity_criteria_id
|
|
546
|
+
FROM methodology_activity_criteria
|
|
547
|
+
WHERE activity_id = ?
|
|
548
|
+
AND sort_order = ?`)
|
|
549
|
+
.get(activity.activityId, sortOrder);
|
|
550
|
+
if (existing !== undefined) {
|
|
551
|
+
skippedCount += 1;
|
|
552
|
+
continue;
|
|
553
|
+
}
|
|
554
|
+
const activityCriteriaId = createActivityCriteria(ctx.db, {
|
|
555
|
+
activityId: activity.activityId,
|
|
556
|
+
criteriaTypeCode,
|
|
557
|
+
criteriaName,
|
|
558
|
+
criteriaText: stringValue(payload, "description") ?? criteriaName,
|
|
559
|
+
severityCode: stringValue(payload, "severityCode"),
|
|
560
|
+
sortOrder,
|
|
561
|
+
metadata: {
|
|
562
|
+
...sourceMetadata(ctx.input, payload),
|
|
563
|
+
criteriaCode: stringValue(payload, "criteriaCode"),
|
|
564
|
+
scopeTypeCode
|
|
565
|
+
}
|
|
566
|
+
});
|
|
567
|
+
targetRefs.push(`activityCriteria:${activityCriteriaId}`);
|
|
568
|
+
continue;
|
|
569
|
+
}
|
|
570
|
+
if (scopeTypeCode !== undefined && scopeTypeCode !== "stage") {
|
|
571
|
+
return blocked(`Unsupported criteria scope type for seed apply: ${scopeTypeCode}`);
|
|
572
|
+
}
|
|
573
|
+
const stage = findStageByCode(ctx.db, methodology.methodologyId, scopeCode);
|
|
574
|
+
if (stage === undefined) {
|
|
575
|
+
return blocked(`Stage was not found for criteria seed: ${scopeCode}`);
|
|
576
|
+
}
|
|
577
|
+
const sortOrder = numberValue(payload, "sortOrder") ?? 0;
|
|
578
|
+
const existing = ctx.db
|
|
579
|
+
.prepare(`SELECT stage_criteria_id
|
|
580
|
+
FROM methodology_stage_criteria
|
|
581
|
+
WHERE stage_id = ?
|
|
582
|
+
AND criteria_type_code = ?
|
|
583
|
+
AND sort_order = ?`)
|
|
584
|
+
.get(stage.stageId, criteriaTypeCode, sortOrder);
|
|
585
|
+
if (existing !== undefined) {
|
|
586
|
+
skippedCount += 1;
|
|
587
|
+
continue;
|
|
588
|
+
}
|
|
589
|
+
const created = ctx.service.createStageCriteria({
|
|
590
|
+
stageId: stage.stageId,
|
|
591
|
+
criteriaTypeCode: criteriaTypeCode,
|
|
592
|
+
criteriaName,
|
|
593
|
+
criteriaText: stringValue(payload, "description") ?? criteriaName,
|
|
594
|
+
validationRequired: true,
|
|
595
|
+
severityCode: stringValue(payload, "severityCode"),
|
|
596
|
+
sortOrder,
|
|
597
|
+
metadata: {
|
|
598
|
+
...sourceMetadata(ctx.input, payload),
|
|
599
|
+
criteriaCode: stringValue(payload, "criteriaCode"),
|
|
600
|
+
scopeTypeCode: stringValue(payload, "scopeTypeCode")
|
|
601
|
+
}
|
|
602
|
+
});
|
|
603
|
+
targetRefs.push(`criteria:${created.stageCriteriaId}`);
|
|
604
|
+
}
|
|
605
|
+
return applied(targetRefs, skippedCount);
|
|
606
|
+
}
|
|
607
|
+
function applyHandoffs(ctx) {
|
|
608
|
+
const methodology = getCurrentMethodology(ctx);
|
|
609
|
+
if (methodology === undefined) {
|
|
610
|
+
return blocked("Target methodology was not found for handoff seed.");
|
|
611
|
+
}
|
|
612
|
+
const targetRefs = [];
|
|
613
|
+
let skippedCount = 0;
|
|
614
|
+
for (const payload of asArray(ctx.input.itemPayload)) {
|
|
615
|
+
const sourceScopeCode = stringValue(payload, "sourceScopeCode");
|
|
616
|
+
const sourceCode = stringValue(payload, "sourceCode");
|
|
617
|
+
const targetScopeCode = stringValue(payload, "targetScopeCode");
|
|
618
|
+
const targetCode = stringValue(payload, "targetCode");
|
|
619
|
+
const handoffItemName = stringValue(payload, "handoffItemName");
|
|
620
|
+
if (sourceScopeCode === undefined ||
|
|
621
|
+
sourceCode === undefined ||
|
|
622
|
+
targetScopeCode === undefined ||
|
|
623
|
+
targetCode === undefined ||
|
|
624
|
+
handoffItemName === undefined) {
|
|
625
|
+
return {
|
|
626
|
+
status: "failed",
|
|
627
|
+
message: "handoff seed requires sourceScopeCode, sourceCode, targetScopeCode, targetCode, and handoffItemName."
|
|
628
|
+
};
|
|
629
|
+
}
|
|
630
|
+
if (sourceScopeCode !== "stage" || targetScopeCode !== "stage") {
|
|
631
|
+
return blocked(`Methodology seed apply currently supports stage-to-stage handoff only: ${sourceScopeCode} -> ${targetScopeCode}`);
|
|
632
|
+
}
|
|
633
|
+
const sourceStage = findStageByCode(ctx.db, methodology.methodologyId, sourceCode);
|
|
634
|
+
const targetStage = findStageByCode(ctx.db, methodology.methodologyId, targetCode);
|
|
635
|
+
if (sourceStage === undefined || targetStage === undefined) {
|
|
636
|
+
return blocked(`Stage was not found for handoff seed: ${sourceCode} -> ${targetCode}`);
|
|
637
|
+
}
|
|
638
|
+
const sortOrder = numberValue(payload, "sortOrder") ?? 0;
|
|
639
|
+
const existing = ctx.db
|
|
640
|
+
.prepare(`SELECT handoff_requirement_id
|
|
641
|
+
FROM methodology_handoff_requirements
|
|
642
|
+
WHERE source_scope_code = ?
|
|
643
|
+
AND source_ref_id = ?
|
|
644
|
+
AND target_scope_code = ?
|
|
645
|
+
AND target_ref_id = ?
|
|
646
|
+
AND sort_order = ?`)
|
|
647
|
+
.get(sourceScopeCode, sourceStage.stageId, targetScopeCode, targetStage.stageId, sortOrder);
|
|
648
|
+
if (existing !== undefined) {
|
|
649
|
+
skippedCount += 1;
|
|
650
|
+
continue;
|
|
651
|
+
}
|
|
652
|
+
const requiredArtifactStandardCodes = Array.isArray(payload.requiredArtifactStandardCodes)
|
|
653
|
+
? payload.requiredArtifactStandardCodes.filter((item) => typeof item === "string")
|
|
654
|
+
: [];
|
|
655
|
+
const created = ctx.service.createHandoffRequirement({
|
|
656
|
+
sourceScopeCode: sourceScopeCode,
|
|
657
|
+
sourceRefId: sourceStage.stageId,
|
|
658
|
+
targetScopeCode: targetScopeCode,
|
|
659
|
+
targetRefId: targetStage.stageId,
|
|
660
|
+
handoffTypeCode: normalizeHandoffTypeCode(stringValue(payload, "handoffTypeCode")),
|
|
661
|
+
handoffItemName,
|
|
662
|
+
handoffDescription: stringValue(payload, "description"),
|
|
663
|
+
artifactStandardCode: requiredArtifactStandardCodes[0],
|
|
664
|
+
artifactStandardVersion: requiredArtifactStandardCodes.length > 0 ? "1.0.0" : undefined,
|
|
665
|
+
validationRequired: true,
|
|
666
|
+
sortOrder,
|
|
667
|
+
metadata: {
|
|
668
|
+
...sourceMetadata(ctx.input, payload),
|
|
669
|
+
handoffCode: stringValue(payload, "handoffCode"),
|
|
670
|
+
requiredArtifactStandardCodes,
|
|
671
|
+
requiredResultRefs: Array.isArray(payload.requiredResultRefs) ? payload.requiredResultRefs : []
|
|
672
|
+
}
|
|
673
|
+
});
|
|
674
|
+
targetRefs.push(`handoff:${created.handoffRequirementId}`);
|
|
675
|
+
}
|
|
676
|
+
return applied(targetRefs, skippedCount);
|
|
677
|
+
}
|
|
678
|
+
export async function applyAgenticSeed(input) {
|
|
679
|
+
if (input.mode !== "apply") {
|
|
680
|
+
return {
|
|
681
|
+
status: "failed",
|
|
682
|
+
message: "agentic-domain-methodology only supports apply mode."
|
|
683
|
+
};
|
|
684
|
+
}
|
|
685
|
+
const db = openMethodologyDatabase();
|
|
686
|
+
try {
|
|
687
|
+
const service = new MethodologyService(db);
|
|
688
|
+
const ctx = { input, db, service };
|
|
689
|
+
const applyInTransaction = db.transaction(() => {
|
|
690
|
+
switch (input.sourceSection) {
|
|
691
|
+
case "methodology":
|
|
692
|
+
return applyMethodology(ctx);
|
|
693
|
+
case "lifecycle":
|
|
694
|
+
return applyLifecycle(ctx);
|
|
695
|
+
case "phases":
|
|
696
|
+
return applyPhases(ctx);
|
|
697
|
+
case "processes":
|
|
698
|
+
return applyProcesses(ctx);
|
|
699
|
+
case "stages":
|
|
700
|
+
return applyStages(ctx);
|
|
701
|
+
case "activities":
|
|
702
|
+
return applyActivities(ctx);
|
|
703
|
+
case "activityArtifactRequirements":
|
|
704
|
+
return applyActivityArtifactRequirements(ctx);
|
|
705
|
+
case "criteria":
|
|
706
|
+
return applyCriteria(ctx);
|
|
707
|
+
case "handoffs":
|
|
708
|
+
return applyHandoffs(ctx);
|
|
709
|
+
default:
|
|
710
|
+
return {
|
|
711
|
+
status: "blocked",
|
|
712
|
+
message: `Unsupported methodology seed section: ${input.sourceSection}`
|
|
713
|
+
};
|
|
714
|
+
}
|
|
715
|
+
});
|
|
716
|
+
return applyInTransaction();
|
|
717
|
+
}
|
|
718
|
+
catch (error) {
|
|
719
|
+
return {
|
|
720
|
+
status: "failed",
|
|
721
|
+
message: error instanceof Error ? error.message : String(error)
|
|
722
|
+
};
|
|
723
|
+
}
|
|
724
|
+
finally {
|
|
725
|
+
db.close();
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
//# sourceMappingURL=seed-apply.js.map
|