@lwelliott/cortex-cli 1.0.3
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/LICENSE +21 -0
- package/README.md +159 -0
- package/dist/cli/audit.d.ts +3 -0
- package/dist/cli/audit.d.ts.map +1 -0
- package/dist/cli/audit.js +78 -0
- package/dist/cli/audit.js.map +1 -0
- package/dist/cli/doc.d.ts +3 -0
- package/dist/cli/doc.d.ts.map +1 -0
- package/dist/cli/doc.js +291 -0
- package/dist/cli/doc.js.map +1 -0
- package/dist/cli/entity.d.ts +3 -0
- package/dist/cli/entity.d.ts.map +1 -0
- package/dist/cli/entity.js +135 -0
- package/dist/cli/entity.js.map +1 -0
- package/dist/cli/format-selector.d.ts +30 -0
- package/dist/cli/format-selector.d.ts.map +1 -0
- package/dist/cli/format-selector.js +101 -0
- package/dist/cli/format-selector.js.map +1 -0
- package/dist/cli/formatters/audit-formatter.d.ts +33 -0
- package/dist/cli/formatters/audit-formatter.d.ts.map +1 -0
- package/dist/cli/formatters/audit-formatter.js +204 -0
- package/dist/cli/formatters/audit-formatter.js.map +1 -0
- package/dist/cli/formatters/json.d.ts +10 -0
- package/dist/cli/formatters/json.d.ts.map +1 -0
- package/dist/cli/formatters/json.js +31 -0
- package/dist/cli/formatters/json.js.map +1 -0
- package/dist/cli/formatters/markdown.d.ts +12 -0
- package/dist/cli/formatters/markdown.d.ts.map +1 -0
- package/dist/cli/formatters/markdown.js +341 -0
- package/dist/cli/formatters/markdown.js.map +1 -0
- package/dist/cli/formatters/quiet.d.ts +15 -0
- package/dist/cli/formatters/quiet.d.ts.map +1 -0
- package/dist/cli/formatters/quiet.js +75 -0
- package/dist/cli/formatters/quiet.js.map +1 -0
- package/dist/cli/formatters/table.d.ts +11 -0
- package/dist/cli/formatters/table.d.ts.map +1 -0
- package/dist/cli/formatters/table.js +726 -0
- package/dist/cli/formatters/table.js.map +1 -0
- package/dist/cli/graph.d.ts +3 -0
- package/dist/cli/graph.d.ts.map +1 -0
- package/dist/cli/graph.js +209 -0
- package/dist/cli/graph.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +144 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/lesson.d.ts +3 -0
- package/dist/cli/lesson.d.ts.map +1 -0
- package/dist/cli/lesson.js +85 -0
- package/dist/cli/lesson.js.map +1 -0
- package/dist/cli/project-resolver.d.ts +17 -0
- package/dist/cli/project-resolver.d.ts.map +1 -0
- package/dist/cli/project-resolver.js +25 -0
- package/dist/cli/project-resolver.js.map +1 -0
- package/dist/cli/project.d.ts +12 -0
- package/dist/cli/project.d.ts.map +1 -0
- package/dist/cli/project.js +169 -0
- package/dist/cli/project.js.map +1 -0
- package/dist/cli/relation.d.ts +3 -0
- package/dist/cli/relation.d.ts.map +1 -0
- package/dist/cli/relation.js +128 -0
- package/dist/cli/relation.js.map +1 -0
- package/dist/cli/review.d.ts +3 -0
- package/dist/cli/review.d.ts.map +1 -0
- package/dist/cli/review.js +131 -0
- package/dist/cli/review.js.map +1 -0
- package/dist/cli/router.d.ts +38 -0
- package/dist/cli/router.d.ts.map +1 -0
- package/dist/cli/router.js +49 -0
- package/dist/cli/router.js.map +1 -0
- package/dist/cli/schema.d.ts +3 -0
- package/dist/cli/schema.d.ts.map +1 -0
- package/dist/cli/schema.js +94 -0
- package/dist/cli/schema.js.map +1 -0
- package/dist/cli/sprint.d.ts +12 -0
- package/dist/cli/sprint.d.ts.map +1 -0
- package/dist/cli/sprint.js +200 -0
- package/dist/cli/sprint.js.map +1 -0
- package/dist/cli/task.d.ts +12 -0
- package/dist/cli/task.d.ts.map +1 -0
- package/dist/cli/task.js +252 -0
- package/dist/cli/task.js.map +1 -0
- package/dist/cli/test-report.d.ts +3 -0
- package/dist/cli/test-report.d.ts.map +1 -0
- package/dist/cli/test-report.js +134 -0
- package/dist/cli/test-report.js.map +1 -0
- package/dist/cli/validate.d.ts +8 -0
- package/dist/cli/validate.d.ts.map +1 -0
- package/dist/cli/validate.js +86 -0
- package/dist/cli/validate.js.map +1 -0
- package/dist/config/config.d.ts +18 -0
- package/dist/config/config.d.ts.map +1 -0
- package/dist/config/config.js +70 -0
- package/dist/config/config.js.map +1 -0
- package/dist/config/registry.d.ts +52 -0
- package/dist/config/registry.d.ts.map +1 -0
- package/dist/config/registry.js +193 -0
- package/dist/config/registry.js.map +1 -0
- package/dist/config/resolver.d.ts +26 -0
- package/dist/config/resolver.d.ts.map +1 -0
- package/dist/config/resolver.js +87 -0
- package/dist/config/resolver.js.map +1 -0
- package/dist/db/builtin-schema-constants.d.ts +109 -0
- package/dist/db/builtin-schema-constants.d.ts.map +1 -0
- package/dist/db/builtin-schema-constants.js +32 -0
- package/dist/db/builtin-schema-constants.js.map +1 -0
- package/dist/db/connection.d.ts +34 -0
- package/dist/db/connection.d.ts.map +1 -0
- package/dist/db/connection.js +140 -0
- package/dist/db/connection.js.map +1 -0
- package/dist/db/generated/schema-types.d.ts +134 -0
- package/dist/db/generated/schema-types.d.ts.map +1 -0
- package/dist/db/generated/schema-types.js +31 -0
- package/dist/db/generated/schema-types.js.map +1 -0
- package/dist/db/locks.d.ts +106 -0
- package/dist/db/locks.d.ts.map +1 -0
- package/dist/db/locks.js +211 -0
- package/dist/db/locks.js.map +1 -0
- package/dist/db/migration.d.ts +65 -0
- package/dist/db/migration.d.ts.map +1 -0
- package/dist/db/migration.js +233 -0
- package/dist/db/migration.js.map +1 -0
- package/dist/db/retry.d.ts +26 -0
- package/dist/db/retry.d.ts.map +1 -0
- package/dist/db/retry.js +71 -0
- package/dist/db/retry.js.map +1 -0
- package/dist/db/schema.d.ts +21 -0
- package/dist/db/schema.d.ts.map +1 -0
- package/dist/db/schema.js +830 -0
- package/dist/db/schema.js.map +1 -0
- package/dist/models/common.d.ts +27 -0
- package/dist/models/common.d.ts.map +1 -0
- package/dist/models/common.js +4 -0
- package/dist/models/common.js.map +1 -0
- package/dist/models/document.d.ts +89 -0
- package/dist/models/document.d.ts.map +1 -0
- package/dist/models/document.js +5 -0
- package/dist/models/document.js.map +1 -0
- package/dist/models/entity-model.d.ts +30 -0
- package/dist/models/entity-model.d.ts.map +1 -0
- package/dist/models/entity-model.js +99 -0
- package/dist/models/entity-model.js.map +1 -0
- package/dist/models/entity.d.ts +88 -0
- package/dist/models/entity.d.ts.map +1 -0
- package/dist/models/entity.js +5 -0
- package/dist/models/entity.js.map +1 -0
- package/dist/models/graph-schema.d.ts +43 -0
- package/dist/models/graph-schema.d.ts.map +1 -0
- package/dist/models/graph-schema.js +76 -0
- package/dist/models/graph-schema.js.map +1 -0
- package/dist/models/project.d.ts +49 -0
- package/dist/models/project.d.ts.map +1 -0
- package/dist/models/project.js +18 -0
- package/dist/models/project.js.map +1 -0
- package/dist/models/relation.d.ts +35 -0
- package/dist/models/relation.d.ts.map +1 -0
- package/dist/models/relation.js +212 -0
- package/dist/models/relation.js.map +1 -0
- package/dist/models/review.d.ts +86 -0
- package/dist/models/review.d.ts.map +1 -0
- package/dist/models/review.js +5 -0
- package/dist/models/review.js.map +1 -0
- package/dist/models/sprint.d.ts +38 -0
- package/dist/models/sprint.d.ts.map +1 -0
- package/dist/models/sprint.js +4 -0
- package/dist/models/sprint.js.map +1 -0
- package/dist/models/task.d.ts +75 -0
- package/dist/models/task.d.ts.map +1 -0
- package/dist/models/task.js +4 -0
- package/dist/models/task.js.map +1 -0
- package/dist/models/validation.d.ts +25 -0
- package/dist/models/validation.d.ts.map +1 -0
- package/dist/models/validation.js +4 -0
- package/dist/models/validation.js.map +1 -0
- package/dist/services/audit-check-service.d.ts +16 -0
- package/dist/services/audit-check-service.d.ts.map +1 -0
- package/dist/services/audit-check-service.js +137 -0
- package/dist/services/audit-check-service.js.map +1 -0
- package/dist/services/audit-checks/dangling-relations-check.d.ts +7 -0
- package/dist/services/audit-checks/dangling-relations-check.d.ts.map +1 -0
- package/dist/services/audit-checks/dangling-relations-check.js +52 -0
- package/dist/services/audit-checks/dangling-relations-check.js.map +1 -0
- package/dist/services/audit-checks/duplicate-ids-check.d.ts +4 -0
- package/dist/services/audit-checks/duplicate-ids-check.d.ts.map +1 -0
- package/dist/services/audit-checks/duplicate-ids-check.js +49 -0
- package/dist/services/audit-checks/duplicate-ids-check.js.map +1 -0
- package/dist/services/audit-checks/fix-engine.d.ts +24 -0
- package/dist/services/audit-checks/fix-engine.d.ts.map +1 -0
- package/dist/services/audit-checks/fix-engine.js +114 -0
- package/dist/services/audit-checks/fix-engine.js.map +1 -0
- package/dist/services/audit-checks/fr-nfr-to-fs-nfs-check.d.ts +9 -0
- package/dist/services/audit-checks/fr-nfr-to-fs-nfs-check.d.ts.map +1 -0
- package/dist/services/audit-checks/fr-nfr-to-fs-nfs-check.js +56 -0
- package/dist/services/audit-checks/fr-nfr-to-fs-nfs-check.js.map +1 -0
- package/dist/services/audit-checks/fs-nfs-to-sad-ad-qa-check.d.ts +10 -0
- package/dist/services/audit-checks/fs-nfs-to-sad-ad-qa-check.d.ts.map +1 -0
- package/dist/services/audit-checks/fs-nfs-to-sad-ad-qa-check.js +57 -0
- package/dist/services/audit-checks/fs-nfs-to-sad-ad-qa-check.js.map +1 -0
- package/dist/services/audit-checks/fs-nfs-to-ts-check.d.ts +9 -0
- package/dist/services/audit-checks/fs-nfs-to-ts-check.d.ts.map +1 -0
- package/dist/services/audit-checks/fs-nfs-to-ts-check.js +56 -0
- package/dist/services/audit-checks/fs-nfs-to-ts-check.js.map +1 -0
- package/dist/services/audit-checks/inverse-consistency-check.d.ts +7 -0
- package/dist/services/audit-checks/inverse-consistency-check.d.ts.map +1 -0
- package/dist/services/audit-checks/inverse-consistency-check.js +54 -0
- package/dist/services/audit-checks/inverse-consistency-check.js.map +1 -0
- package/dist/services/audit-checks/mapping-check.d.ts +4 -0
- package/dist/services/audit-checks/mapping-check.d.ts.map +1 -0
- package/dist/services/audit-checks/mapping-check.js +74 -0
- package/dist/services/audit-checks/mapping-check.js.map +1 -0
- package/dist/services/audit-checks/orphan-documents-check.d.ts +9 -0
- package/dist/services/audit-checks/orphan-documents-check.d.ts.map +1 -0
- package/dist/services/audit-checks/orphan-documents-check.js +54 -0
- package/dist/services/audit-checks/orphan-documents-check.js.map +1 -0
- package/dist/services/audit-checks/orphan-entities-check.d.ts +4 -0
- package/dist/services/audit-checks/orphan-entities-check.d.ts.map +1 -0
- package/dist/services/audit-checks/orphan-entities-check.js +39 -0
- package/dist/services/audit-checks/orphan-entities-check.js.map +1 -0
- package/dist/services/audit-checks/sad-ad-qa-tc-to-src-check.d.ts +9 -0
- package/dist/services/audit-checks/sad-ad-qa-tc-to-src-check.d.ts.map +1 -0
- package/dist/services/audit-checks/sad-ad-qa-tc-to-src-check.js +56 -0
- package/dist/services/audit-checks/sad-ad-qa-tc-to-src-check.js.map +1 -0
- package/dist/services/audit-checks/sprint-consistency-check.d.ts +4 -0
- package/dist/services/audit-checks/sprint-consistency-check.d.ts.map +1 -0
- package/dist/services/audit-checks/sprint-consistency-check.js +80 -0
- package/dist/services/audit-checks/sprint-consistency-check.js.map +1 -0
- package/dist/services/audit-checks/src-filesystem-only-check.d.ts +10 -0
- package/dist/services/audit-checks/src-filesystem-only-check.d.ts.map +1 -0
- package/dist/services/audit-checks/src-filesystem-only-check.js +106 -0
- package/dist/services/audit-checks/src-filesystem-only-check.js.map +1 -0
- package/dist/services/audit-checks/ts-to-tc-check.d.ts +10 -0
- package/dist/services/audit-checks/ts-to-tc-check.d.ts.map +1 -0
- package/dist/services/audit-checks/ts-to-tc-check.js +58 -0
- package/dist/services/audit-checks/ts-to-tc-check.js.map +1 -0
- package/dist/services/audit-checks/type-mismatch-check.d.ts +4 -0
- package/dist/services/audit-checks/type-mismatch-check.d.ts.map +1 -0
- package/dist/services/audit-checks/type-mismatch-check.js +55 -0
- package/dist/services/audit-checks/type-mismatch-check.js.map +1 -0
- package/dist/services/audit-checks/types.d.ts +66 -0
- package/dist/services/audit-checks/types.d.ts.map +1 -0
- package/dist/services/audit-checks/types.js +30 -0
- package/dist/services/audit-checks/types.js.map +1 -0
- package/dist/services/audit-checks/us-to-fr-nfr-check.d.ts +9 -0
- package/dist/services/audit-checks/us-to-fr-nfr-check.d.ts.map +1 -0
- package/dist/services/audit-checks/us-to-fr-nfr-check.js +56 -0
- package/dist/services/audit-checks/us-to-fr-nfr-check.js.map +1 -0
- package/dist/services/doc-entity-mapping.d.ts +19 -0
- package/dist/services/doc-entity-mapping.d.ts.map +1 -0
- package/dist/services/doc-entity-mapping.js +35 -0
- package/dist/services/doc-entity-mapping.js.map +1 -0
- package/dist/services/document-service.d.ts +58 -0
- package/dist/services/document-service.d.ts.map +1 -0
- package/dist/services/document-service.js +409 -0
- package/dist/services/document-service.js.map +1 -0
- package/dist/services/graph-export-service.d.ts +12 -0
- package/dist/services/graph-export-service.d.ts.map +1 -0
- package/dist/services/graph-export-service.js +112 -0
- package/dist/services/graph-export-service.js.map +1 -0
- package/dist/services/graph-service.d.ts +21 -0
- package/dist/services/graph-service.d.ts.map +1 -0
- package/dist/services/graph-service.js +49 -0
- package/dist/services/graph-service.js.map +1 -0
- package/dist/services/graph-validation-service.d.ts +13 -0
- package/dist/services/graph-validation-service.d.ts.map +1 -0
- package/dist/services/graph-validation-service.js +171 -0
- package/dist/services/graph-validation-service.js.map +1 -0
- package/dist/services/project.d.ts +80 -0
- package/dist/services/project.d.ts.map +1 -0
- package/dist/services/project.js +256 -0
- package/dist/services/project.js.map +1 -0
- package/dist/services/review-service.d.ts +81 -0
- package/dist/services/review-service.d.ts.map +1 -0
- package/dist/services/review-service.js +242 -0
- package/dist/services/review-service.js.map +1 -0
- package/dist/services/schema-migration-service.d.ts +44 -0
- package/dist/services/schema-migration-service.d.ts.map +1 -0
- package/dist/services/schema-migration-service.js +894 -0
- package/dist/services/schema-migration-service.js.map +1 -0
- package/dist/services/sprint.d.ts +71 -0
- package/dist/services/sprint.d.ts.map +1 -0
- package/dist/services/sprint.js +238 -0
- package/dist/services/sprint.js.map +1 -0
- package/dist/services/stage-validator.d.ts +36 -0
- package/dist/services/stage-validator.d.ts.map +1 -0
- package/dist/services/stage-validator.js +78 -0
- package/dist/services/stage-validator.js.map +1 -0
- package/dist/services/task.d.ts +75 -0
- package/dist/services/task.d.ts.map +1 -0
- package/dist/services/task.js +487 -0
- package/dist/services/task.js.map +1 -0
- package/dist/services/validation.d.ts +24 -0
- package/dist/services/validation.d.ts.map +1 -0
- package/dist/services/validation.js +53 -0
- package/dist/services/validation.js.map +1 -0
- package/dist/state-machines/sprint-state.d.ts +25 -0
- package/dist/state-machines/sprint-state.d.ts.map +1 -0
- package/dist/state-machines/sprint-state.js +64 -0
- package/dist/state-machines/sprint-state.js.map +1 -0
- package/dist/state-machines/task-state.d.ts +31 -0
- package/dist/state-machines/task-state.d.ts.map +1 -0
- package/dist/state-machines/task-state.js +83 -0
- package/dist/state-machines/task-state.js.map +1 -0
- package/dist/utils/errors.d.ts +673 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +1447 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/format.d.ts +52 -0
- package/dist/utils/format.d.ts.map +1 -0
- package/dist/utils/format.js +65 -0
- package/dist/utils/format.js.map +1 -0
- package/dist/validators/board-integrity.d.ts +25 -0
- package/dist/validators/board-integrity.d.ts.map +1 -0
- package/dist/validators/board-integrity.js +102 -0
- package/dist/validators/board-integrity.js.map +1 -0
- package/dist/validators/board-shape.d.ts +13 -0
- package/dist/validators/board-shape.d.ts.map +1 -0
- package/dist/validators/board-shape.js +74 -0
- package/dist/validators/board-shape.js.map +1 -0
- package/dist/validators/owner-validator.d.ts +30 -0
- package/dist/validators/owner-validator.d.ts.map +1 -0
- package/dist/validators/owner-validator.js +70 -0
- package/dist/validators/owner-validator.js.map +1 -0
- package/dist/validators/spawn-legality.d.ts +19 -0
- package/dist/validators/spawn-legality.d.ts.map +1 -0
- package/dist/validators/spawn-legality.js +77 -0
- package/dist/validators/spawn-legality.js.map +1 -0
- package/dist/validators/state-field-checker.d.ts +8 -0
- package/dist/validators/state-field-checker.d.ts.map +1 -0
- package/dist/validators/state-field-checker.js +47 -0
- package/dist/validators/state-field-checker.js.map +1 -0
- package/dist/validators/state-field-recorder.d.ts +39 -0
- package/dist/validators/state-field-recorder.d.ts.map +1 -0
- package/dist/validators/state-field-recorder.js +62 -0
- package/dist/validators/state-field-recorder.js.map +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1,487 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Task service: orchestrates task/kanban lifecycle
|
|
3
|
+
// Implements AD-0008: Centralized State Machines + Owner Validation
|
|
4
|
+
// + AD-0011: Soft Delete for Task Removal → now permanent delete (FS-SS-005-0007 v3)
|
|
5
|
+
// + AD-0014: Nullable Columns for State-Specific Fields
|
|
6
|
+
// + AD-0031: Stage-Driven Workflow Engine
|
|
7
|
+
// + FS-SS-005-0001..0012
|
|
8
|
+
// + FS-SS-030-0001..0004
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.validateOwnerRole = exports.isValidRole = void 0;
|
|
11
|
+
exports.addTask = addTask;
|
|
12
|
+
exports.moveTask = moveTask;
|
|
13
|
+
exports.updateTask = updateTask;
|
|
14
|
+
exports.removeTask = removeTask;
|
|
15
|
+
exports.showTask = showTask;
|
|
16
|
+
exports.listTasks = listTasks;
|
|
17
|
+
exports.getTaskStatusCounts = getTaskStatusCounts;
|
|
18
|
+
const errors_1 = require("../utils/errors");
|
|
19
|
+
const task_state_1 = require("../state-machines/task-state");
|
|
20
|
+
const owner_validator_1 = require("../validators/owner-validator");
|
|
21
|
+
Object.defineProperty(exports, "validateOwnerRole", { enumerable: true, get: function () { return owner_validator_1.validateOwnerRole; } });
|
|
22
|
+
Object.defineProperty(exports, "isValidRole", { enumerable: true, get: function () { return owner_validator_1.isValidRole; } });
|
|
23
|
+
const state_field_recorder_1 = require("../validators/state-field-recorder");
|
|
24
|
+
const stage_validator_1 = require("./stage-validator");
|
|
25
|
+
const sprint_1 = require("./sprint");
|
|
26
|
+
const locks_1 = require("../db/locks");
|
|
27
|
+
const retry_1 = require("../db/retry");
|
|
28
|
+
/** Valid task type values */
|
|
29
|
+
const VALID_TASK_TYPES = ['Feature', 'Bug', 'Chore'];
|
|
30
|
+
/** Valid task priority values */
|
|
31
|
+
const VALID_PRIORITIES = ['P0', 'P1', 'P2'];
|
|
32
|
+
/**
|
|
33
|
+
* Generate a unique task ID using 4-digit zero-padded format (NNNN).
|
|
34
|
+
* IDs are globally unique across all sprints.
|
|
35
|
+
* FS-SS-028-0002: Task ID format changed from sprint-XXX-N to NNNN.
|
|
36
|
+
*/
|
|
37
|
+
function generateTaskId(db) {
|
|
38
|
+
const row = db.prepare(`SELECT MAX(CAST(id AS INTEGER)) as max_n FROM tasks WHERE id GLOB '[0-9][0-9][0-9][0-9]'`).get();
|
|
39
|
+
const next = (row?.max_n ?? 0) + 1;
|
|
40
|
+
return String(next).padStart(4, '0');
|
|
41
|
+
}
|
|
42
|
+
/** 4-digit zero-padded ID validation regex */
|
|
43
|
+
const FOUR_DIGIT_ID_RE = /^\d{4}$/;
|
|
44
|
+
/**
|
|
45
|
+
* Validate task ID format: /^\d{4}$/
|
|
46
|
+
* @throws TaskBadIdError if invalid
|
|
47
|
+
*/
|
|
48
|
+
function validateTaskIdFormat(taskId) {
|
|
49
|
+
if (!FOUR_DIGIT_ID_RE.test(taskId)) {
|
|
50
|
+
throw new errors_1.TaskBadIdError(taskId);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Validate task type value.
|
|
55
|
+
* @throws TaskInvalidTypeError if invalid
|
|
56
|
+
*/
|
|
57
|
+
function validateTaskType(type) {
|
|
58
|
+
if (!VALID_TASK_TYPES.includes(type)) {
|
|
59
|
+
throw new errors_1.TaskInvalidTypeError(type);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Validate task priority value.
|
|
64
|
+
* @throws TaskInvalidPriorityError if invalid
|
|
65
|
+
*/
|
|
66
|
+
function validatePriority(priority) {
|
|
67
|
+
if (!VALID_PRIORITIES.includes(priority)) {
|
|
68
|
+
throw new errors_1.TaskInvalidPriorityError(priority);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Add a new task to a sprint.
|
|
73
|
+
*
|
|
74
|
+
* @param db - Database connection
|
|
75
|
+
* @param sprintId - Sprint ID
|
|
76
|
+
* @param description - Task description
|
|
77
|
+
* @param owner - Owner role (must be valid, captain-only for Backlog)
|
|
78
|
+
* @param opts - Optional task properties
|
|
79
|
+
* @returns The created task result
|
|
80
|
+
* @throws TaskBadSprintError if sprint doesn't exist or is closed
|
|
81
|
+
* @throws TaskOwnerRequiredError if owner is empty
|
|
82
|
+
* @throws various owner validation errors
|
|
83
|
+
*/
|
|
84
|
+
function addTask(db, sprintId, description, owner, opts) {
|
|
85
|
+
// Validate sprint exists and is not closed
|
|
86
|
+
let sprintStatus;
|
|
87
|
+
try {
|
|
88
|
+
const sprint = (0, sprint_1.resolveSprint)(db, sprintId);
|
|
89
|
+
sprintStatus = sprint.status;
|
|
90
|
+
}
|
|
91
|
+
catch (err) {
|
|
92
|
+
if (err instanceof errors_1.SprintNotFoundError) {
|
|
93
|
+
throw new errors_1.TaskBadSprintError(sprintId, 'sprint not found');
|
|
94
|
+
}
|
|
95
|
+
throw err;
|
|
96
|
+
}
|
|
97
|
+
if (sprintStatus === 'CLOSED') {
|
|
98
|
+
throw new errors_1.TaskBadSprintError(sprintId, 'sprint is closed');
|
|
99
|
+
}
|
|
100
|
+
// Validate owner
|
|
101
|
+
if (!owner || owner.trim().length === 0) {
|
|
102
|
+
throw new errors_1.TaskOwnerRequiredError();
|
|
103
|
+
}
|
|
104
|
+
// Default stage is Planning — captain-only for Planning stage (FS-SS-005-0010, FS-SS-030-0003)
|
|
105
|
+
const stage = opts?.stage ?? 'Planning';
|
|
106
|
+
if (!(0, stage_validator_1.isValidStage)(stage)) {
|
|
107
|
+
throw new errors_1.StageInvalidError(stage);
|
|
108
|
+
}
|
|
109
|
+
(0, owner_validator_1.validateOwnerForStage)(owner.trim(), stage);
|
|
110
|
+
// Validate optional type
|
|
111
|
+
const taskType = opts?.task_type ?? 'Feature';
|
|
112
|
+
if (opts?.task_type) {
|
|
113
|
+
validateTaskType(opts.task_type);
|
|
114
|
+
}
|
|
115
|
+
// Validate optional priority
|
|
116
|
+
const priority = opts?.priority ?? 'P2';
|
|
117
|
+
if (opts?.priority) {
|
|
118
|
+
validatePriority(opts.priority);
|
|
119
|
+
}
|
|
120
|
+
// Validate optional parent
|
|
121
|
+
if (opts?.parent_id) {
|
|
122
|
+
const parent = db.prepare('SELECT id, sprint_id FROM tasks WHERE id = ? AND sprint_id = ? AND removed_at IS NULL').get(opts.parent_id, sprintId);
|
|
123
|
+
if (!parent) {
|
|
124
|
+
throw new errors_1.TaskParentError(opts.parent_id, 'not found or removed');
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
const lockName = `kanban:${sprintId}`;
|
|
128
|
+
const lockOwner = (0, locks_1.generateLockOwner)();
|
|
129
|
+
return (0, locks_1.withLock)(db, { name: lockName, owner: lockOwner }, () => {
|
|
130
|
+
return (0, retry_1.withTransaction)(db, () => {
|
|
131
|
+
// Support explicit task ID (FS-SS-028-0001: positional <id> on task add)
|
|
132
|
+
let taskId;
|
|
133
|
+
if (opts?.task_id) {
|
|
134
|
+
validateTaskIdFormat(opts.task_id);
|
|
135
|
+
// Check for duplicate within the same sprint (per-sprint ID policy)
|
|
136
|
+
const existing = db.prepare('SELECT id FROM tasks WHERE id = ? AND sprint_id = ?').get(opts.task_id, sprintId);
|
|
137
|
+
if (existing) {
|
|
138
|
+
throw new errors_1.TaskDuplicateIdError(opts.task_id);
|
|
139
|
+
}
|
|
140
|
+
taskId = opts.task_id;
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
taskId = generateTaskId(db);
|
|
144
|
+
}
|
|
145
|
+
const now = new Date().toISOString();
|
|
146
|
+
db.prepare(`
|
|
147
|
+
INSERT INTO tasks (id, sprint_id, parent_id, description, task_type, priority, owner, points, status, stage, created_at, updated_at)
|
|
148
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'Backlog', ?, ?, ?)
|
|
149
|
+
`).run(taskId, sprintId, opts?.parent_id ?? null, description.trim(), taskType, priority, owner.trim(), opts?.points ?? 0, stage, now, now);
|
|
150
|
+
return {
|
|
151
|
+
id: taskId,
|
|
152
|
+
sprint_id: sprintId,
|
|
153
|
+
parent_id: opts?.parent_id ?? null,
|
|
154
|
+
description: description.trim(),
|
|
155
|
+
task_type: taskType,
|
|
156
|
+
priority: priority,
|
|
157
|
+
owner: owner.trim(),
|
|
158
|
+
points: opts?.points ?? 0,
|
|
159
|
+
status: 'Backlog',
|
|
160
|
+
stage: stage,
|
|
161
|
+
created_at: now,
|
|
162
|
+
};
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Resolve the active (non-CLOSED) sprint for task move enforcement.
|
|
168
|
+
* Active sprint is the most-recently-created non-CLOSED sprint.
|
|
169
|
+
* @throws TaskNoActiveSprintError if no active sprint exists
|
|
170
|
+
*/
|
|
171
|
+
function resolveActiveSprint(db) {
|
|
172
|
+
const sprint = db.prepare(`SELECT id, status FROM sprints WHERE status != 'CLOSED' ORDER BY created_at DESC LIMIT 1`).get();
|
|
173
|
+
if (!sprint) {
|
|
174
|
+
throw new errors_1.TaskNoActiveSprintError();
|
|
175
|
+
}
|
|
176
|
+
return sprint;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Move a task: status transition, stage transition, or combined.
|
|
180
|
+
*
|
|
181
|
+
* Per AD-0039: stage validation runs before status validation in combined moves.
|
|
182
|
+
* Per FR-URD-034-0004: active sprint is required — no --sprint override.
|
|
183
|
+
*
|
|
184
|
+
* @param db - Database connection
|
|
185
|
+
* @param taskId - Task ID (4-digit NNNN)
|
|
186
|
+
* @param opts - Move options: targetStatus, targetStage, context
|
|
187
|
+
* @returns Updated task result
|
|
188
|
+
*/
|
|
189
|
+
function moveTask(db, taskId, opts) {
|
|
190
|
+
// Validate task ID format
|
|
191
|
+
validateTaskIdFormat(taskId);
|
|
192
|
+
// Resolve sprint for task lookup (per-sprint ID policy)
|
|
193
|
+
const sprintId = opts.sprintId || resolveActiveSprint(db).id;
|
|
194
|
+
// Read task first (pre-lock, for validation)
|
|
195
|
+
const task = db.prepare('SELECT * FROM tasks WHERE id = ? AND sprint_id = ? AND removed_at IS NULL').get(taskId, sprintId);
|
|
196
|
+
if (!task) {
|
|
197
|
+
throw new errors_1.TaskNotFoundError(taskId, sprintId);
|
|
198
|
+
}
|
|
199
|
+
// Active sprint enforcement: task must belong to the active sprint
|
|
200
|
+
const activeSprint = resolveActiveSprint(db);
|
|
201
|
+
if (task.sprint_id !== activeSprint.id) {
|
|
202
|
+
throw new errors_1.TaskNotInActiveSprintError(taskId);
|
|
203
|
+
}
|
|
204
|
+
const targetStatus = opts.targetStatus;
|
|
205
|
+
const targetStage = opts.targetStage;
|
|
206
|
+
// Phase 1: Validate stage progression (runs first per AD-0039)
|
|
207
|
+
if (targetStage !== undefined) {
|
|
208
|
+
if (!(0, stage_validator_1.isValidStage)(targetStage)) {
|
|
209
|
+
throw new errors_1.StageInvalidError(targetStage);
|
|
210
|
+
}
|
|
211
|
+
(0, stage_validator_1.validateProgression)(task.stage, targetStage, task.status);
|
|
212
|
+
// Validate owner for destination stage (captain-only for Planning/Release)
|
|
213
|
+
(0, owner_validator_1.validateOwnerForStage)(task.owner, targetStage);
|
|
214
|
+
}
|
|
215
|
+
// Phase 2: Validate status transition (runs second per AD-0039)
|
|
216
|
+
if (targetStatus !== undefined) {
|
|
217
|
+
if (!(0, task_state_1.isValidTaskStatus)(targetStatus)) {
|
|
218
|
+
throw new errors_1.TaskBadStatusError(targetStatus);
|
|
219
|
+
}
|
|
220
|
+
if (task.status === targetStatus) {
|
|
221
|
+
throw new errors_1.TaskNoopError(taskId, task.status);
|
|
222
|
+
}
|
|
223
|
+
if (!(0, task_state_1.isValidTaskTransition)(task.status, targetStatus)) {
|
|
224
|
+
const allowed = (0, task_state_1.getAllowedTaskTransitions)(task.status).map(s => s);
|
|
225
|
+
throw new errors_1.TaskTransitionError(taskId, task.status, targetStatus, allowed);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
// At least one of targetStatus or targetStage must be provided
|
|
229
|
+
if (targetStatus === undefined && targetStage === undefined) {
|
|
230
|
+
throw new errors_1.TaskNoopError(taskId, task.status);
|
|
231
|
+
}
|
|
232
|
+
// Phase 3: Apply in atomic transaction
|
|
233
|
+
const lockName = `kanban:${task.sprint_id}`;
|
|
234
|
+
const lockOwner = (0, locks_1.generateLockOwner)();
|
|
235
|
+
return (0, locks_1.withLock)(db, { name: lockName, owner: lockOwner }, () => {
|
|
236
|
+
return (0, retry_1.withTransaction)(db, () => {
|
|
237
|
+
// Re-read inside transaction for consistency under lock
|
|
238
|
+
const fresh = db.prepare('SELECT * FROM tasks WHERE id = ? AND sprint_id = ? AND removed_at IS NULL').get(taskId, sprintId);
|
|
239
|
+
if (!fresh) {
|
|
240
|
+
throw new errors_1.TaskNotFoundError(taskId, sprintId);
|
|
241
|
+
}
|
|
242
|
+
const columns = [];
|
|
243
|
+
const values = [];
|
|
244
|
+
const now = new Date().toISOString();
|
|
245
|
+
// Apply stage update if provided
|
|
246
|
+
if (targetStage !== undefined) {
|
|
247
|
+
columns.push('stage = ?');
|
|
248
|
+
values.push(targetStage);
|
|
249
|
+
}
|
|
250
|
+
// Apply status update and record state-specific fields if provided
|
|
251
|
+
if (targetStatus !== undefined) {
|
|
252
|
+
// Record state-specific fields inline
|
|
253
|
+
const stFields = (0, state_field_recorder_1.computeStateFields)(fresh.status, targetStatus, opts.context);
|
|
254
|
+
// build column+value pairs: stFields already includes status + updated_at
|
|
255
|
+
for (let i = 0; i < stFields.columns.length; i++) {
|
|
256
|
+
// Avoid duplicating updated_at
|
|
257
|
+
const col = stFields.columns[i];
|
|
258
|
+
if (col.startsWith('updated_at')) {
|
|
259
|
+
// We'll add updated_at at the end
|
|
260
|
+
continue;
|
|
261
|
+
}
|
|
262
|
+
columns.push(col);
|
|
263
|
+
values.push(stFields.values[i]);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
// Always update updated_at
|
|
267
|
+
columns.push('updated_at = ?');
|
|
268
|
+
values.push(now);
|
|
269
|
+
values.push(taskId);
|
|
270
|
+
values.push(sprintId);
|
|
271
|
+
const sql = `UPDATE tasks SET ${columns.join(', ')} WHERE id = ? AND sprint_id = ?`;
|
|
272
|
+
db.prepare(sql).run(...values);
|
|
273
|
+
// Re-read and return
|
|
274
|
+
const updated = db.prepare('SELECT id, sprint_id, parent_id, description, task_type, priority, owner, points, status, stage, created_at FROM tasks WHERE id = ? AND sprint_id = ?').get(taskId, sprintId);
|
|
275
|
+
return updated;
|
|
276
|
+
});
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Update task metadata (description, type, priority, points, scope, acceptance).
|
|
281
|
+
* Does NOT change task status, stage, owner, or sprint — use moveTask for those.
|
|
282
|
+
*
|
|
283
|
+
* Per AD-0038: rejects stage, owner, sprint fields at the service layer.
|
|
284
|
+
*
|
|
285
|
+
* @throws TaskNotFoundError if task doesn't exist
|
|
286
|
+
* @throws TaskInvalidFieldError if prohibited fields are present
|
|
287
|
+
*/
|
|
288
|
+
function updateTask(db, taskId, fields, sprintId) {
|
|
289
|
+
// Guard clause: reject prohibited fields before any DB access (AD-0038)
|
|
290
|
+
if ('stage' in fields)
|
|
291
|
+
throw new errors_1.TaskInvalidFieldError('stage');
|
|
292
|
+
if ('owner' in fields)
|
|
293
|
+
throw new errors_1.TaskInvalidFieldError('owner');
|
|
294
|
+
if ('sprint' in fields)
|
|
295
|
+
throw new errors_1.TaskInvalidFieldError('sprint');
|
|
296
|
+
// Resolve sprint for task lookup (per-sprint ID policy)
|
|
297
|
+
const resolvedSprintId = sprintId || resolveActiveSprint(db).id;
|
|
298
|
+
// Read task first to resolve sprint ID for per-sprint locking (AD-0015)
|
|
299
|
+
const task = db.prepare('SELECT * FROM tasks WHERE id = ? AND sprint_id = ? AND removed_at IS NULL').get(taskId, resolvedSprintId);
|
|
300
|
+
if (!task) {
|
|
301
|
+
throw new errors_1.TaskNotFoundError(taskId, resolvedSprintId);
|
|
302
|
+
}
|
|
303
|
+
const lockName = `kanban:${task.sprint_id}`;
|
|
304
|
+
const lockOwner = (0, locks_1.generateLockOwner)();
|
|
305
|
+
return (0, locks_1.withLock)(db, { name: lockName, owner: lockOwner }, () => {
|
|
306
|
+
return (0, retry_1.withTransaction)(db, () => {
|
|
307
|
+
// Re-read task inside transaction for consistency under lock
|
|
308
|
+
const fresh = db.prepare('SELECT * FROM tasks WHERE id = ? AND sprint_id = ? AND removed_at IS NULL').get(taskId, resolvedSprintId);
|
|
309
|
+
if (!fresh) {
|
|
310
|
+
throw new errors_1.TaskNotFoundError(taskId, resolvedSprintId);
|
|
311
|
+
}
|
|
312
|
+
const updates = [];
|
|
313
|
+
const params = [];
|
|
314
|
+
// Handle content_file_content: extract description from frontmatter body
|
|
315
|
+
if (fields.content_file_content !== undefined) {
|
|
316
|
+
const raw = fields.content_file_content;
|
|
317
|
+
const frontmatterMatch = raw.match(/^---\s*\n([\s\S]*?)\n---\s*\n?/);
|
|
318
|
+
let bodyContent;
|
|
319
|
+
if (frontmatterMatch) {
|
|
320
|
+
bodyContent = raw.slice(frontmatterMatch[0].length).trim();
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
bodyContent = raw.trim();
|
|
324
|
+
}
|
|
325
|
+
updates.push('description = ?');
|
|
326
|
+
params.push(bodyContent);
|
|
327
|
+
}
|
|
328
|
+
else if (fields.description !== undefined) {
|
|
329
|
+
updates.push('description = ?');
|
|
330
|
+
params.push(fields.description.trim());
|
|
331
|
+
}
|
|
332
|
+
if (fields.task_type !== undefined) {
|
|
333
|
+
validateTaskType(fields.task_type);
|
|
334
|
+
updates.push('task_type = ?');
|
|
335
|
+
params.push(fields.task_type);
|
|
336
|
+
}
|
|
337
|
+
if (fields.priority !== undefined) {
|
|
338
|
+
validatePriority(fields.priority);
|
|
339
|
+
updates.push('priority = ?');
|
|
340
|
+
params.push(fields.priority);
|
|
341
|
+
}
|
|
342
|
+
if (fields.points !== undefined) {
|
|
343
|
+
updates.push('points = ?');
|
|
344
|
+
params.push(fields.points);
|
|
345
|
+
}
|
|
346
|
+
if (fields.scope_in !== undefined) {
|
|
347
|
+
updates.push('scope_in = ?');
|
|
348
|
+
params.push(fields.scope_in || null);
|
|
349
|
+
}
|
|
350
|
+
if (fields.scope_out !== undefined) {
|
|
351
|
+
updates.push('scope_out = ?');
|
|
352
|
+
params.push(fields.scope_out || null);
|
|
353
|
+
}
|
|
354
|
+
if (fields.acceptance !== undefined) {
|
|
355
|
+
updates.push('acceptance = ?');
|
|
356
|
+
params.push(fields.acceptance || null);
|
|
357
|
+
}
|
|
358
|
+
if (fields.decisions !== undefined) {
|
|
359
|
+
updates.push('decisions = ?');
|
|
360
|
+
params.push(fields.decisions || null);
|
|
361
|
+
}
|
|
362
|
+
if (fields.dependencies !== undefined) {
|
|
363
|
+
updates.push('dependencies = ?');
|
|
364
|
+
params.push(fields.dependencies || null);
|
|
365
|
+
}
|
|
366
|
+
if (updates.length === 0) {
|
|
367
|
+
return {
|
|
368
|
+
id: fresh.id,
|
|
369
|
+
sprint_id: fresh.sprint_id,
|
|
370
|
+
parent_id: fresh.parent_id,
|
|
371
|
+
description: fresh.description,
|
|
372
|
+
task_type: fresh.task_type,
|
|
373
|
+
priority: fresh.priority,
|
|
374
|
+
owner: fresh.owner,
|
|
375
|
+
points: fresh.points,
|
|
376
|
+
status: fresh.status,
|
|
377
|
+
stage: fresh.stage,
|
|
378
|
+
created_at: fresh.created_at,
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
updates.push('updated_at = ?');
|
|
382
|
+
params.push(new Date().toISOString());
|
|
383
|
+
params.push(taskId);
|
|
384
|
+
params.push(resolvedSprintId);
|
|
385
|
+
db.prepare(`UPDATE tasks SET ${updates.join(', ')} WHERE id = ? AND sprint_id = ?`).run(...params);
|
|
386
|
+
// Re-read
|
|
387
|
+
const updated = db.prepare('SELECT id, sprint_id, parent_id, description, task_type, priority, owner, points, status, stage, created_at FROM tasks WHERE id = ? AND sprint_id = ?').get(taskId, resolvedSprintId);
|
|
388
|
+
return updated;
|
|
389
|
+
});
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Remove a task (soft delete by default per AD-0011).
|
|
394
|
+
*
|
|
395
|
+
* @param db - Database connection
|
|
396
|
+
* @param taskId - Task ID
|
|
397
|
+
* @throws TaskNotFoundError if task doesn't exist
|
|
398
|
+
*/
|
|
399
|
+
function removeTask(db, taskId, sprintId) {
|
|
400
|
+
// Resolve sprint for task lookup (per-sprint ID policy)
|
|
401
|
+
const resolvedSprintId = sprintId || resolveActiveSprint(db).id;
|
|
402
|
+
// Read task first to resolve sprint ID for per-sprint locking (AD-0015)
|
|
403
|
+
const task = db.prepare('SELECT id, sprint_id FROM tasks WHERE id = ? AND sprint_id = ?').get(taskId, resolvedSprintId);
|
|
404
|
+
if (!task) {
|
|
405
|
+
throw new errors_1.TaskNotFoundError(taskId, resolvedSprintId);
|
|
406
|
+
}
|
|
407
|
+
// FS-SS-005-0007 v3 / AD-0011: Always permanent delete
|
|
408
|
+
const lockName = `kanban:${task.sprint_id}`;
|
|
409
|
+
const owner = (0, locks_1.generateLockOwner)();
|
|
410
|
+
(0, locks_1.withLock)(db, { name: lockName, owner }, () => {
|
|
411
|
+
return (0, retry_1.withTransaction)(db, () => {
|
|
412
|
+
// Re-read inside transaction for consistency under lock
|
|
413
|
+
const fresh = db.prepare('SELECT id FROM tasks WHERE id = ? AND sprint_id = ?').get(taskId, resolvedSprintId);
|
|
414
|
+
if (!fresh) {
|
|
415
|
+
throw new errors_1.TaskNotFoundError(taskId, resolvedSprintId);
|
|
416
|
+
}
|
|
417
|
+
db.prepare('DELETE FROM tasks WHERE id = ? AND sprint_id = ?').run(taskId, resolvedSprintId);
|
|
418
|
+
return;
|
|
419
|
+
});
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
/**
|
|
423
|
+
* Show detailed task information including sprint name and parent description.
|
|
424
|
+
*
|
|
425
|
+
* @param db - Database connection
|
|
426
|
+
* @param taskId - Task ID
|
|
427
|
+
* @param sprintId - Sprint ID (required for sprint-scoped lookup per URD-026)
|
|
428
|
+
* @throws TaskNotFoundError if task doesn't exist or is not in the specified sprint
|
|
429
|
+
*/
|
|
430
|
+
function showTask(db, taskId, sprintId) {
|
|
431
|
+
let sql = `SELECT t.*, s.name as sprint_name, p.description as parent_description
|
|
432
|
+
FROM tasks t
|
|
433
|
+
LEFT JOIN sprints s ON t.sprint_id = s.id
|
|
434
|
+
LEFT JOIN tasks p ON t.parent_id = p.id
|
|
435
|
+
WHERE t.id = ? AND t.removed_at IS NULL`;
|
|
436
|
+
const params = [taskId];
|
|
437
|
+
if (sprintId) {
|
|
438
|
+
sql += ' AND t.sprint_id = ?';
|
|
439
|
+
params.push(sprintId);
|
|
440
|
+
}
|
|
441
|
+
const task = db.prepare(sql).get(...params);
|
|
442
|
+
if (!task) {
|
|
443
|
+
throw new errors_1.TaskNotFoundError(taskId, sprintId);
|
|
444
|
+
}
|
|
445
|
+
return {
|
|
446
|
+
...task,
|
|
447
|
+
sprint_name: task.sprint_name,
|
|
448
|
+
parent_description: task.parent_description,
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* List tasks for a sprint with optional filters.
|
|
453
|
+
*/
|
|
454
|
+
function listTasks(db, sprintId, filters) {
|
|
455
|
+
let sql = 'SELECT * FROM tasks WHERE removed_at IS NULL';
|
|
456
|
+
const params = [];
|
|
457
|
+
// Sprint filter
|
|
458
|
+
sql += ' AND sprint_id = ?';
|
|
459
|
+
params.push(sprintId);
|
|
460
|
+
// Status filter
|
|
461
|
+
if (filters?.status) {
|
|
462
|
+
sql += ' AND status = ?';
|
|
463
|
+
params.push(filters.status);
|
|
464
|
+
}
|
|
465
|
+
// Owner filter
|
|
466
|
+
if (filters?.owner) {
|
|
467
|
+
sql += ' AND owner = ?';
|
|
468
|
+
params.push(filters.owner);
|
|
469
|
+
}
|
|
470
|
+
sql += ' ORDER BY status, created_at';
|
|
471
|
+
return db.prepare(sql).all(...params);
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* Get task status counts for a sprint.
|
|
475
|
+
*/
|
|
476
|
+
function getTaskStatusCounts(db, sprintId) {
|
|
477
|
+
const rows = db.prepare(`SELECT status, COUNT(*) as count
|
|
478
|
+
FROM tasks
|
|
479
|
+
WHERE sprint_id = ? AND removed_at IS NULL
|
|
480
|
+
GROUP BY status`).all(sprintId);
|
|
481
|
+
const counts = {};
|
|
482
|
+
for (const row of rows) {
|
|
483
|
+
counts[row.status] = row.count;
|
|
484
|
+
}
|
|
485
|
+
return counts;
|
|
486
|
+
}
|
|
487
|
+
//# sourceMappingURL=task.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task.js","sourceRoot":"","sources":["../../src/services/task.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type Database from 'better-sqlite3';
|
|
2
|
+
import type { ValidationResult, SpawnResult } from '../models/validation';
|
|
3
|
+
/**
|
|
4
|
+
* Validate the entire board or a specific sprint's board integrity.
|
|
5
|
+
* This is a read-only operation — no locks are acquired.
|
|
6
|
+
*
|
|
7
|
+
* @param db - Database connection
|
|
8
|
+
* @param sprintId - Optional sprint ID (resolves default if omitted)
|
|
9
|
+
* @returns Validation result with all issues found
|
|
10
|
+
*/
|
|
11
|
+
export declare function validateBoard(db: Database.Database, sprintId?: string): ValidationResult;
|
|
12
|
+
/**
|
|
13
|
+
* Validate whether a spawn operation is legal.
|
|
14
|
+
* Read-only — no locks needed.
|
|
15
|
+
*
|
|
16
|
+
* @param db - Database connection
|
|
17
|
+
* @param sprintId - Sprint ID
|
|
18
|
+
* @param taskId - Task ID to spawn from
|
|
19
|
+
* @param stage - Spawn stage (analyst, architect, coder, tester)
|
|
20
|
+
* @param role - Role that will own the spawned task
|
|
21
|
+
* @returns Spawn legality result
|
|
22
|
+
*/
|
|
23
|
+
export declare function validateSpawn(db: Database.Database, sprintId: string, taskId: string, stage: string, role: string): SpawnResult;
|
|
24
|
+
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/services/validation.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAQ1E;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,QAAQ,CAAC,EAAE,MAAM,GAChB,gBAAgB,CAiBlB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAC3B,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,GACX,WAAW,CAGb"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Validation service: orchestrates board integrity and spawn legality checks
|
|
3
|
+
// Read-only diagnostic service — no write locks, no data modifications
|
|
4
|
+
// Implements AD-0009: Validation as Read-Only Snapshot
|
|
5
|
+
// + FS-SS-006-0001..0004
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.validateBoard = validateBoard;
|
|
8
|
+
exports.validateSpawn = validateSpawn;
|
|
9
|
+
const board_integrity_1 = require("../validators/board-integrity");
|
|
10
|
+
const spawn_legality_1 = require("../validators/spawn-legality");
|
|
11
|
+
const state_field_checker_1 = require("../validators/state-field-checker");
|
|
12
|
+
const board_shape_1 = require("../validators/board-shape");
|
|
13
|
+
const sprint_1 = require("./sprint");
|
|
14
|
+
const task_1 = require("./task");
|
|
15
|
+
/**
|
|
16
|
+
* Validate the entire board or a specific sprint's board integrity.
|
|
17
|
+
* This is a read-only operation — no locks are acquired.
|
|
18
|
+
*
|
|
19
|
+
* @param db - Database connection
|
|
20
|
+
* @param sprintId - Optional sprint ID (resolves default if omitted)
|
|
21
|
+
* @returns Validation result with all issues found
|
|
22
|
+
*/
|
|
23
|
+
function validateBoard(db, sprintId) {
|
|
24
|
+
// Read-only: no locks needed per AD-0009
|
|
25
|
+
const sprint = (0, sprint_1.resolveSprint)(db, sprintId);
|
|
26
|
+
const issues = (0, board_integrity_1.checkBoardIntegrity)(db, sprint);
|
|
27
|
+
// State field checks
|
|
28
|
+
issues.push(...(0, state_field_checker_1.checkRequiredFields)(db, sprint.id));
|
|
29
|
+
// Board shape checks
|
|
30
|
+
const taskCounts = (0, task_1.getTaskStatusCounts)(db, sprint.id);
|
|
31
|
+
issues.push(...(0, board_shape_1.checkSprintBoardShape)(sprint, taskCounts));
|
|
32
|
+
return {
|
|
33
|
+
sprint_id: sprint.id,
|
|
34
|
+
isValid: issues.filter(i => i.severity === 'error').length === 0,
|
|
35
|
+
issues,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Validate whether a spawn operation is legal.
|
|
40
|
+
* Read-only — no locks needed.
|
|
41
|
+
*
|
|
42
|
+
* @param db - Database connection
|
|
43
|
+
* @param sprintId - Sprint ID
|
|
44
|
+
* @param taskId - Task ID to spawn from
|
|
45
|
+
* @param stage - Spawn stage (analyst, architect, coder, tester)
|
|
46
|
+
* @param role - Role that will own the spawned task
|
|
47
|
+
* @returns Spawn legality result
|
|
48
|
+
*/
|
|
49
|
+
function validateSpawn(db, sprintId, taskId, stage, role) {
|
|
50
|
+
// Read-only: no locks needed per AD-0009
|
|
51
|
+
return (0, spawn_legality_1.checkSpawnLegality)(db, sprintId, taskId, stage, role);
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/services/validation.ts"],"names":[],"mappings":";AAAA,6EAA6E;AAC7E,uEAAuE;AACvE,uDAAuD;AACvD,yBAAyB;;AAmBzB,sCAoBC;AAaD,sCASC;AAzDD,mEAAoE;AACpE,iEAAkE;AAClE,2EAAwE;AACxE,2DAAkE;AAClE,qCAAyC;AACzC,iCAA6C;AAE7C;;;;;;;GAOG;AACH,SAAgB,aAAa,CAC3B,EAAqB,EACrB,QAAiB;IAEjB,yCAAyC;IACzC,MAAM,MAAM,GAAG,IAAA,sBAAa,EAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,IAAA,qCAAmB,EAAC,EAAE,EAAE,MAAM,CAAC,CAAC;IAE/C,qBAAqB;IACrB,MAAM,CAAC,IAAI,CAAC,GAAG,IAAA,yCAAmB,EAAC,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAEnD,qBAAqB;IACrB,MAAM,UAAU,GAAG,IAAA,0BAAmB,EAAC,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;IACtD,MAAM,CAAC,IAAI,CAAC,GAAG,IAAA,mCAAqB,EAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;IAE1D,OAAO;QACL,SAAS,EAAE,MAAM,CAAC,EAAE;QACpB,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC;QAChE,MAAM;KACP,CAAC;AACJ,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAgB,aAAa,CAC3B,EAAqB,EACrB,QAAgB,EAChB,MAAc,EACd,KAAa,EACb,IAAY;IAEZ,yCAAyC;IACzC,OAAO,IAAA,mCAAkB,EAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;AAC/D,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { SprintStatus } from '../models/common';
|
|
2
|
+
/** Valid sprint status values */
|
|
3
|
+
export declare const VALID_SPRINT_STATUSES: SprintStatus[];
|
|
4
|
+
/**
|
|
5
|
+
* Check if a given string is a valid SprintStatus value.
|
|
6
|
+
*/
|
|
7
|
+
export declare function isValidSprintStatus(status: string): status is SprintStatus;
|
|
8
|
+
/**
|
|
9
|
+
* Get all allowed target statuses from a given current status.
|
|
10
|
+
*/
|
|
11
|
+
export declare function getAllowedSprintTransitions(current: SprintStatus): SprintStatus[];
|
|
12
|
+
/**
|
|
13
|
+
* Check if a transition from current to target is valid.
|
|
14
|
+
*/
|
|
15
|
+
export declare function isValidSprintTransition(current: SprintStatus, target: SprintStatus): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Auto-populate timestamps for sprint status transitions.
|
|
18
|
+
* - PLANNING → IN EXECUTION: set started_at
|
|
19
|
+
* - * → CLOSED: set closed_at
|
|
20
|
+
*/
|
|
21
|
+
export declare function getSprintAutoTimestamps(current: SprintStatus, target: SprintStatus): {
|
|
22
|
+
started_at?: string;
|
|
23
|
+
closed_at?: string;
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=sprint-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sprint-state.d.ts","sourceRoot":"","sources":["../../src/state-machines/sprint-state.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD,iCAAiC;AACjC,eAAO,MAAM,qBAAqB,EAAE,YAAY,EAK/C,CAAC;AAaF;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,IAAI,YAAY,CAE1E;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,YAAY,GAAG,YAAY,EAAE,CAEjF;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,CAE5F;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,YAAY,GACnB;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAa7C"}
|