@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.
Files changed (335) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +159 -0
  3. package/dist/cli/audit.d.ts +3 -0
  4. package/dist/cli/audit.d.ts.map +1 -0
  5. package/dist/cli/audit.js +78 -0
  6. package/dist/cli/audit.js.map +1 -0
  7. package/dist/cli/doc.d.ts +3 -0
  8. package/dist/cli/doc.d.ts.map +1 -0
  9. package/dist/cli/doc.js +291 -0
  10. package/dist/cli/doc.js.map +1 -0
  11. package/dist/cli/entity.d.ts +3 -0
  12. package/dist/cli/entity.d.ts.map +1 -0
  13. package/dist/cli/entity.js +135 -0
  14. package/dist/cli/entity.js.map +1 -0
  15. package/dist/cli/format-selector.d.ts +30 -0
  16. package/dist/cli/format-selector.d.ts.map +1 -0
  17. package/dist/cli/format-selector.js +101 -0
  18. package/dist/cli/format-selector.js.map +1 -0
  19. package/dist/cli/formatters/audit-formatter.d.ts +33 -0
  20. package/dist/cli/formatters/audit-formatter.d.ts.map +1 -0
  21. package/dist/cli/formatters/audit-formatter.js +204 -0
  22. package/dist/cli/formatters/audit-formatter.js.map +1 -0
  23. package/dist/cli/formatters/json.d.ts +10 -0
  24. package/dist/cli/formatters/json.d.ts.map +1 -0
  25. package/dist/cli/formatters/json.js +31 -0
  26. package/dist/cli/formatters/json.js.map +1 -0
  27. package/dist/cli/formatters/markdown.d.ts +12 -0
  28. package/dist/cli/formatters/markdown.d.ts.map +1 -0
  29. package/dist/cli/formatters/markdown.js +341 -0
  30. package/dist/cli/formatters/markdown.js.map +1 -0
  31. package/dist/cli/formatters/quiet.d.ts +15 -0
  32. package/dist/cli/formatters/quiet.d.ts.map +1 -0
  33. package/dist/cli/formatters/quiet.js +75 -0
  34. package/dist/cli/formatters/quiet.js.map +1 -0
  35. package/dist/cli/formatters/table.d.ts +11 -0
  36. package/dist/cli/formatters/table.d.ts.map +1 -0
  37. package/dist/cli/formatters/table.js +726 -0
  38. package/dist/cli/formatters/table.js.map +1 -0
  39. package/dist/cli/graph.d.ts +3 -0
  40. package/dist/cli/graph.d.ts.map +1 -0
  41. package/dist/cli/graph.js +209 -0
  42. package/dist/cli/graph.js.map +1 -0
  43. package/dist/cli/index.d.ts +3 -0
  44. package/dist/cli/index.d.ts.map +1 -0
  45. package/dist/cli/index.js +144 -0
  46. package/dist/cli/index.js.map +1 -0
  47. package/dist/cli/lesson.d.ts +3 -0
  48. package/dist/cli/lesson.d.ts.map +1 -0
  49. package/dist/cli/lesson.js +85 -0
  50. package/dist/cli/lesson.js.map +1 -0
  51. package/dist/cli/project-resolver.d.ts +17 -0
  52. package/dist/cli/project-resolver.d.ts.map +1 -0
  53. package/dist/cli/project-resolver.js +25 -0
  54. package/dist/cli/project-resolver.js.map +1 -0
  55. package/dist/cli/project.d.ts +12 -0
  56. package/dist/cli/project.d.ts.map +1 -0
  57. package/dist/cli/project.js +169 -0
  58. package/dist/cli/project.js.map +1 -0
  59. package/dist/cli/relation.d.ts +3 -0
  60. package/dist/cli/relation.d.ts.map +1 -0
  61. package/dist/cli/relation.js +128 -0
  62. package/dist/cli/relation.js.map +1 -0
  63. package/dist/cli/review.d.ts +3 -0
  64. package/dist/cli/review.d.ts.map +1 -0
  65. package/dist/cli/review.js +131 -0
  66. package/dist/cli/review.js.map +1 -0
  67. package/dist/cli/router.d.ts +38 -0
  68. package/dist/cli/router.d.ts.map +1 -0
  69. package/dist/cli/router.js +49 -0
  70. package/dist/cli/router.js.map +1 -0
  71. package/dist/cli/schema.d.ts +3 -0
  72. package/dist/cli/schema.d.ts.map +1 -0
  73. package/dist/cli/schema.js +94 -0
  74. package/dist/cli/schema.js.map +1 -0
  75. package/dist/cli/sprint.d.ts +12 -0
  76. package/dist/cli/sprint.d.ts.map +1 -0
  77. package/dist/cli/sprint.js +200 -0
  78. package/dist/cli/sprint.js.map +1 -0
  79. package/dist/cli/task.d.ts +12 -0
  80. package/dist/cli/task.d.ts.map +1 -0
  81. package/dist/cli/task.js +252 -0
  82. package/dist/cli/task.js.map +1 -0
  83. package/dist/cli/test-report.d.ts +3 -0
  84. package/dist/cli/test-report.d.ts.map +1 -0
  85. package/dist/cli/test-report.js +134 -0
  86. package/dist/cli/test-report.js.map +1 -0
  87. package/dist/cli/validate.d.ts +8 -0
  88. package/dist/cli/validate.d.ts.map +1 -0
  89. package/dist/cli/validate.js +86 -0
  90. package/dist/cli/validate.js.map +1 -0
  91. package/dist/config/config.d.ts +18 -0
  92. package/dist/config/config.d.ts.map +1 -0
  93. package/dist/config/config.js +70 -0
  94. package/dist/config/config.js.map +1 -0
  95. package/dist/config/registry.d.ts +52 -0
  96. package/dist/config/registry.d.ts.map +1 -0
  97. package/dist/config/registry.js +193 -0
  98. package/dist/config/registry.js.map +1 -0
  99. package/dist/config/resolver.d.ts +26 -0
  100. package/dist/config/resolver.d.ts.map +1 -0
  101. package/dist/config/resolver.js +87 -0
  102. package/dist/config/resolver.js.map +1 -0
  103. package/dist/db/builtin-schema-constants.d.ts +109 -0
  104. package/dist/db/builtin-schema-constants.d.ts.map +1 -0
  105. package/dist/db/builtin-schema-constants.js +32 -0
  106. package/dist/db/builtin-schema-constants.js.map +1 -0
  107. package/dist/db/connection.d.ts +34 -0
  108. package/dist/db/connection.d.ts.map +1 -0
  109. package/dist/db/connection.js +140 -0
  110. package/dist/db/connection.js.map +1 -0
  111. package/dist/db/generated/schema-types.d.ts +134 -0
  112. package/dist/db/generated/schema-types.d.ts.map +1 -0
  113. package/dist/db/generated/schema-types.js +31 -0
  114. package/dist/db/generated/schema-types.js.map +1 -0
  115. package/dist/db/locks.d.ts +106 -0
  116. package/dist/db/locks.d.ts.map +1 -0
  117. package/dist/db/locks.js +211 -0
  118. package/dist/db/locks.js.map +1 -0
  119. package/dist/db/migration.d.ts +65 -0
  120. package/dist/db/migration.d.ts.map +1 -0
  121. package/dist/db/migration.js +233 -0
  122. package/dist/db/migration.js.map +1 -0
  123. package/dist/db/retry.d.ts +26 -0
  124. package/dist/db/retry.d.ts.map +1 -0
  125. package/dist/db/retry.js +71 -0
  126. package/dist/db/retry.js.map +1 -0
  127. package/dist/db/schema.d.ts +21 -0
  128. package/dist/db/schema.d.ts.map +1 -0
  129. package/dist/db/schema.js +830 -0
  130. package/dist/db/schema.js.map +1 -0
  131. package/dist/models/common.d.ts +27 -0
  132. package/dist/models/common.d.ts.map +1 -0
  133. package/dist/models/common.js +4 -0
  134. package/dist/models/common.js.map +1 -0
  135. package/dist/models/document.d.ts +89 -0
  136. package/dist/models/document.d.ts.map +1 -0
  137. package/dist/models/document.js +5 -0
  138. package/dist/models/document.js.map +1 -0
  139. package/dist/models/entity-model.d.ts +30 -0
  140. package/dist/models/entity-model.d.ts.map +1 -0
  141. package/dist/models/entity-model.js +99 -0
  142. package/dist/models/entity-model.js.map +1 -0
  143. package/dist/models/entity.d.ts +88 -0
  144. package/dist/models/entity.d.ts.map +1 -0
  145. package/dist/models/entity.js +5 -0
  146. package/dist/models/entity.js.map +1 -0
  147. package/dist/models/graph-schema.d.ts +43 -0
  148. package/dist/models/graph-schema.d.ts.map +1 -0
  149. package/dist/models/graph-schema.js +76 -0
  150. package/dist/models/graph-schema.js.map +1 -0
  151. package/dist/models/project.d.ts +49 -0
  152. package/dist/models/project.d.ts.map +1 -0
  153. package/dist/models/project.js +18 -0
  154. package/dist/models/project.js.map +1 -0
  155. package/dist/models/relation.d.ts +35 -0
  156. package/dist/models/relation.d.ts.map +1 -0
  157. package/dist/models/relation.js +212 -0
  158. package/dist/models/relation.js.map +1 -0
  159. package/dist/models/review.d.ts +86 -0
  160. package/dist/models/review.d.ts.map +1 -0
  161. package/dist/models/review.js +5 -0
  162. package/dist/models/review.js.map +1 -0
  163. package/dist/models/sprint.d.ts +38 -0
  164. package/dist/models/sprint.d.ts.map +1 -0
  165. package/dist/models/sprint.js +4 -0
  166. package/dist/models/sprint.js.map +1 -0
  167. package/dist/models/task.d.ts +75 -0
  168. package/dist/models/task.d.ts.map +1 -0
  169. package/dist/models/task.js +4 -0
  170. package/dist/models/task.js.map +1 -0
  171. package/dist/models/validation.d.ts +25 -0
  172. package/dist/models/validation.d.ts.map +1 -0
  173. package/dist/models/validation.js +4 -0
  174. package/dist/models/validation.js.map +1 -0
  175. package/dist/services/audit-check-service.d.ts +16 -0
  176. package/dist/services/audit-check-service.d.ts.map +1 -0
  177. package/dist/services/audit-check-service.js +137 -0
  178. package/dist/services/audit-check-service.js.map +1 -0
  179. package/dist/services/audit-checks/dangling-relations-check.d.ts +7 -0
  180. package/dist/services/audit-checks/dangling-relations-check.d.ts.map +1 -0
  181. package/dist/services/audit-checks/dangling-relations-check.js +52 -0
  182. package/dist/services/audit-checks/dangling-relations-check.js.map +1 -0
  183. package/dist/services/audit-checks/duplicate-ids-check.d.ts +4 -0
  184. package/dist/services/audit-checks/duplicate-ids-check.d.ts.map +1 -0
  185. package/dist/services/audit-checks/duplicate-ids-check.js +49 -0
  186. package/dist/services/audit-checks/duplicate-ids-check.js.map +1 -0
  187. package/dist/services/audit-checks/fix-engine.d.ts +24 -0
  188. package/dist/services/audit-checks/fix-engine.d.ts.map +1 -0
  189. package/dist/services/audit-checks/fix-engine.js +114 -0
  190. package/dist/services/audit-checks/fix-engine.js.map +1 -0
  191. package/dist/services/audit-checks/fr-nfr-to-fs-nfs-check.d.ts +9 -0
  192. package/dist/services/audit-checks/fr-nfr-to-fs-nfs-check.d.ts.map +1 -0
  193. package/dist/services/audit-checks/fr-nfr-to-fs-nfs-check.js +56 -0
  194. package/dist/services/audit-checks/fr-nfr-to-fs-nfs-check.js.map +1 -0
  195. package/dist/services/audit-checks/fs-nfs-to-sad-ad-qa-check.d.ts +10 -0
  196. package/dist/services/audit-checks/fs-nfs-to-sad-ad-qa-check.d.ts.map +1 -0
  197. package/dist/services/audit-checks/fs-nfs-to-sad-ad-qa-check.js +57 -0
  198. package/dist/services/audit-checks/fs-nfs-to-sad-ad-qa-check.js.map +1 -0
  199. package/dist/services/audit-checks/fs-nfs-to-ts-check.d.ts +9 -0
  200. package/dist/services/audit-checks/fs-nfs-to-ts-check.d.ts.map +1 -0
  201. package/dist/services/audit-checks/fs-nfs-to-ts-check.js +56 -0
  202. package/dist/services/audit-checks/fs-nfs-to-ts-check.js.map +1 -0
  203. package/dist/services/audit-checks/inverse-consistency-check.d.ts +7 -0
  204. package/dist/services/audit-checks/inverse-consistency-check.d.ts.map +1 -0
  205. package/dist/services/audit-checks/inverse-consistency-check.js +54 -0
  206. package/dist/services/audit-checks/inverse-consistency-check.js.map +1 -0
  207. package/dist/services/audit-checks/mapping-check.d.ts +4 -0
  208. package/dist/services/audit-checks/mapping-check.d.ts.map +1 -0
  209. package/dist/services/audit-checks/mapping-check.js +74 -0
  210. package/dist/services/audit-checks/mapping-check.js.map +1 -0
  211. package/dist/services/audit-checks/orphan-documents-check.d.ts +9 -0
  212. package/dist/services/audit-checks/orphan-documents-check.d.ts.map +1 -0
  213. package/dist/services/audit-checks/orphan-documents-check.js +54 -0
  214. package/dist/services/audit-checks/orphan-documents-check.js.map +1 -0
  215. package/dist/services/audit-checks/orphan-entities-check.d.ts +4 -0
  216. package/dist/services/audit-checks/orphan-entities-check.d.ts.map +1 -0
  217. package/dist/services/audit-checks/orphan-entities-check.js +39 -0
  218. package/dist/services/audit-checks/orphan-entities-check.js.map +1 -0
  219. package/dist/services/audit-checks/sad-ad-qa-tc-to-src-check.d.ts +9 -0
  220. package/dist/services/audit-checks/sad-ad-qa-tc-to-src-check.d.ts.map +1 -0
  221. package/dist/services/audit-checks/sad-ad-qa-tc-to-src-check.js +56 -0
  222. package/dist/services/audit-checks/sad-ad-qa-tc-to-src-check.js.map +1 -0
  223. package/dist/services/audit-checks/sprint-consistency-check.d.ts +4 -0
  224. package/dist/services/audit-checks/sprint-consistency-check.d.ts.map +1 -0
  225. package/dist/services/audit-checks/sprint-consistency-check.js +80 -0
  226. package/dist/services/audit-checks/sprint-consistency-check.js.map +1 -0
  227. package/dist/services/audit-checks/src-filesystem-only-check.d.ts +10 -0
  228. package/dist/services/audit-checks/src-filesystem-only-check.d.ts.map +1 -0
  229. package/dist/services/audit-checks/src-filesystem-only-check.js +106 -0
  230. package/dist/services/audit-checks/src-filesystem-only-check.js.map +1 -0
  231. package/dist/services/audit-checks/ts-to-tc-check.d.ts +10 -0
  232. package/dist/services/audit-checks/ts-to-tc-check.d.ts.map +1 -0
  233. package/dist/services/audit-checks/ts-to-tc-check.js +58 -0
  234. package/dist/services/audit-checks/ts-to-tc-check.js.map +1 -0
  235. package/dist/services/audit-checks/type-mismatch-check.d.ts +4 -0
  236. package/dist/services/audit-checks/type-mismatch-check.d.ts.map +1 -0
  237. package/dist/services/audit-checks/type-mismatch-check.js +55 -0
  238. package/dist/services/audit-checks/type-mismatch-check.js.map +1 -0
  239. package/dist/services/audit-checks/types.d.ts +66 -0
  240. package/dist/services/audit-checks/types.d.ts.map +1 -0
  241. package/dist/services/audit-checks/types.js +30 -0
  242. package/dist/services/audit-checks/types.js.map +1 -0
  243. package/dist/services/audit-checks/us-to-fr-nfr-check.d.ts +9 -0
  244. package/dist/services/audit-checks/us-to-fr-nfr-check.d.ts.map +1 -0
  245. package/dist/services/audit-checks/us-to-fr-nfr-check.js +56 -0
  246. package/dist/services/audit-checks/us-to-fr-nfr-check.js.map +1 -0
  247. package/dist/services/doc-entity-mapping.d.ts +19 -0
  248. package/dist/services/doc-entity-mapping.d.ts.map +1 -0
  249. package/dist/services/doc-entity-mapping.js +35 -0
  250. package/dist/services/doc-entity-mapping.js.map +1 -0
  251. package/dist/services/document-service.d.ts +58 -0
  252. package/dist/services/document-service.d.ts.map +1 -0
  253. package/dist/services/document-service.js +409 -0
  254. package/dist/services/document-service.js.map +1 -0
  255. package/dist/services/graph-export-service.d.ts +12 -0
  256. package/dist/services/graph-export-service.d.ts.map +1 -0
  257. package/dist/services/graph-export-service.js +112 -0
  258. package/dist/services/graph-export-service.js.map +1 -0
  259. package/dist/services/graph-service.d.ts +21 -0
  260. package/dist/services/graph-service.d.ts.map +1 -0
  261. package/dist/services/graph-service.js +49 -0
  262. package/dist/services/graph-service.js.map +1 -0
  263. package/dist/services/graph-validation-service.d.ts +13 -0
  264. package/dist/services/graph-validation-service.d.ts.map +1 -0
  265. package/dist/services/graph-validation-service.js +171 -0
  266. package/dist/services/graph-validation-service.js.map +1 -0
  267. package/dist/services/project.d.ts +80 -0
  268. package/dist/services/project.d.ts.map +1 -0
  269. package/dist/services/project.js +256 -0
  270. package/dist/services/project.js.map +1 -0
  271. package/dist/services/review-service.d.ts +81 -0
  272. package/dist/services/review-service.d.ts.map +1 -0
  273. package/dist/services/review-service.js +242 -0
  274. package/dist/services/review-service.js.map +1 -0
  275. package/dist/services/schema-migration-service.d.ts +44 -0
  276. package/dist/services/schema-migration-service.d.ts.map +1 -0
  277. package/dist/services/schema-migration-service.js +894 -0
  278. package/dist/services/schema-migration-service.js.map +1 -0
  279. package/dist/services/sprint.d.ts +71 -0
  280. package/dist/services/sprint.d.ts.map +1 -0
  281. package/dist/services/sprint.js +238 -0
  282. package/dist/services/sprint.js.map +1 -0
  283. package/dist/services/stage-validator.d.ts +36 -0
  284. package/dist/services/stage-validator.d.ts.map +1 -0
  285. package/dist/services/stage-validator.js +78 -0
  286. package/dist/services/stage-validator.js.map +1 -0
  287. package/dist/services/task.d.ts +75 -0
  288. package/dist/services/task.d.ts.map +1 -0
  289. package/dist/services/task.js +487 -0
  290. package/dist/services/task.js.map +1 -0
  291. package/dist/services/validation.d.ts +24 -0
  292. package/dist/services/validation.d.ts.map +1 -0
  293. package/dist/services/validation.js +53 -0
  294. package/dist/services/validation.js.map +1 -0
  295. package/dist/state-machines/sprint-state.d.ts +25 -0
  296. package/dist/state-machines/sprint-state.d.ts.map +1 -0
  297. package/dist/state-machines/sprint-state.js +64 -0
  298. package/dist/state-machines/sprint-state.js.map +1 -0
  299. package/dist/state-machines/task-state.d.ts +31 -0
  300. package/dist/state-machines/task-state.d.ts.map +1 -0
  301. package/dist/state-machines/task-state.js +83 -0
  302. package/dist/state-machines/task-state.js.map +1 -0
  303. package/dist/utils/errors.d.ts +673 -0
  304. package/dist/utils/errors.d.ts.map +1 -0
  305. package/dist/utils/errors.js +1447 -0
  306. package/dist/utils/errors.js.map +1 -0
  307. package/dist/utils/format.d.ts +52 -0
  308. package/dist/utils/format.d.ts.map +1 -0
  309. package/dist/utils/format.js +65 -0
  310. package/dist/utils/format.js.map +1 -0
  311. package/dist/validators/board-integrity.d.ts +25 -0
  312. package/dist/validators/board-integrity.d.ts.map +1 -0
  313. package/dist/validators/board-integrity.js +102 -0
  314. package/dist/validators/board-integrity.js.map +1 -0
  315. package/dist/validators/board-shape.d.ts +13 -0
  316. package/dist/validators/board-shape.d.ts.map +1 -0
  317. package/dist/validators/board-shape.js +74 -0
  318. package/dist/validators/board-shape.js.map +1 -0
  319. package/dist/validators/owner-validator.d.ts +30 -0
  320. package/dist/validators/owner-validator.d.ts.map +1 -0
  321. package/dist/validators/owner-validator.js +70 -0
  322. package/dist/validators/owner-validator.js.map +1 -0
  323. package/dist/validators/spawn-legality.d.ts +19 -0
  324. package/dist/validators/spawn-legality.d.ts.map +1 -0
  325. package/dist/validators/spawn-legality.js +77 -0
  326. package/dist/validators/spawn-legality.js.map +1 -0
  327. package/dist/validators/state-field-checker.d.ts +8 -0
  328. package/dist/validators/state-field-checker.d.ts.map +1 -0
  329. package/dist/validators/state-field-checker.js +47 -0
  330. package/dist/validators/state-field-checker.js.map +1 -0
  331. package/dist/validators/state-field-recorder.d.ts +39 -0
  332. package/dist/validators/state-field-recorder.d.ts.map +1 -0
  333. package/dist/validators/state-field-recorder.js +62 -0
  334. package/dist/validators/state-field-recorder.js.map +1 -0
  335. package/package.json +53 -0
@@ -0,0 +1,13 @@
1
+ import type Database from 'better-sqlite3';
2
+ import type { ValidationResult } from '../models/entity';
3
+ /**
4
+ * Validate the entire graph for integrity violations.
5
+ * Read-only: does not modify any data.
6
+ *
7
+ * Checks:
8
+ * 1. Dangling relations (from_id or to_id references non-existent document)
9
+ * 2. Type constraint violations (doc type not in relation type's from_types/to_types)
10
+ * 3. Cardinality violations (one_to_one/one_to_many/many_to_one exceeded)
11
+ */
12
+ export declare function validateGraph(db: Database.Database): ValidationResult;
13
+ //# sourceMappingURL=graph-validation-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph-validation-service.d.ts","sourceRoot":"","sources":["../../src/services/graph-validation-service.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,EAAE,gBAAgB,EAA2B,MAAM,kBAAkB,CAAC;AAElF;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,gBAAgB,CA2JrE"}
@@ -0,0 +1,171 @@
1
+ "use strict";
2
+ // Graph validation service: read-only graph integrity checks
3
+ // SAD-0003: MOD-011 Graph Validation
4
+ // AD-0009: Validation services are read-only
5
+ // SAD-0035: Updated to use documents(id) instead of entities(id)
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.validateGraph = validateGraph;
8
+ /**
9
+ * Validate the entire graph for integrity violations.
10
+ * Read-only: does not modify any data.
11
+ *
12
+ * Checks:
13
+ * 1. Dangling relations (from_id or to_id references non-existent document)
14
+ * 2. Type constraint violations (doc type not in relation type's from_types/to_types)
15
+ * 3. Cardinality violations (one_to_one/one_to_many/many_to_one exceeded)
16
+ */
17
+ function validateGraph(db) {
18
+ const violations = [];
19
+ // 1. Check for dangling relations (SAD-0035: use documents instead of entities)
20
+ const danglingFrom = db.prepare(`
21
+ SELECT r.id, r.from_id, r.rel_type, r.to_id
22
+ FROM relations r
23
+ LEFT JOIN documents d ON r.from_id = d.id
24
+ WHERE d.id IS NULL
25
+ `).all();
26
+ for (const rel of danglingFrom) {
27
+ violations.push({
28
+ type: 'dangling',
29
+ relationId: rel.id,
30
+ fromId: rel.from_id,
31
+ relType: rel.rel_type,
32
+ toId: rel.to_id,
33
+ message: `Relation ${rel.id}: from_id "${rel.from_id}" references non-existent document`,
34
+ });
35
+ }
36
+ const danglingTo = db.prepare(`
37
+ SELECT r.id, r.from_id, r.rel_type, r.to_id
38
+ FROM relations r
39
+ LEFT JOIN documents d ON r.to_id = d.id
40
+ WHERE d.id IS NULL
41
+ `).all();
42
+ for (const rel of danglingTo) {
43
+ violations.push({
44
+ type: 'dangling',
45
+ relationId: rel.id,
46
+ fromId: rel.from_id,
47
+ relType: rel.rel_type,
48
+ toId: rel.to_id,
49
+ message: `Relation ${rel.id}: to_id "${rel.to_id}" references non-existent document`,
50
+ });
51
+ }
52
+ // 2. Check type constraint violations (SAD-0035: use documents instead of entities)
53
+ const relationTypes = db.prepare('SELECT * FROM relation_types').all();
54
+ const relations = db.prepare('SELECT r.id, r.from_id, r.rel_type, r.to_id, d_from.type as from_type, d_to.type as to_type FROM relations r LEFT JOIN documents d_from ON r.from_id = d_from.id LEFT JOIN documents d_to ON r.to_id = d_to.id').all();
55
+ for (const rel of relations) {
56
+ const rt = relationTypes.find(t => t.name === rel.rel_type);
57
+ if (!rt)
58
+ continue;
59
+ const fromTypes = safeParseJson(rt.from_types, []);
60
+ const toTypes = safeParseJson(rt.to_types, []);
61
+ if (fromTypes.length > 0 && rel.from_type && !fromTypes.includes(rel.from_type)) {
62
+ violations.push({
63
+ type: 'type_constraint',
64
+ relationId: rel.id,
65
+ fromId: rel.from_id,
66
+ relType: rel.rel_type,
67
+ toId: rel.to_id,
68
+ message: `Relation ${rel.id}: from entity type "${rel.from_type}" not in allowed types [${fromTypes.join(', ')}]`,
69
+ });
70
+ }
71
+ if (toTypes.length > 0 && rel.to_type && !toTypes.includes(rel.to_type)) {
72
+ violations.push({
73
+ type: 'type_constraint',
74
+ relationId: rel.id,
75
+ fromId: rel.from_id,
76
+ relType: rel.rel_type,
77
+ toId: rel.to_id,
78
+ message: `Relation ${rel.id}: to entity type "${rel.to_type}" not in allowed types [${toTypes.join(', ')}]`,
79
+ });
80
+ }
81
+ }
82
+ // 3. Check cardinality violations
83
+ for (const rt of relationTypes) {
84
+ const cardinality = (rt.cardinality ?? 'many_to_many');
85
+ if (cardinality === 'many_to_many')
86
+ continue;
87
+ if (cardinality === 'one_to_one') {
88
+ const violators = db.prepare(`
89
+ SELECT from_id, rel_type, COUNT(*) as cnt
90
+ FROM relations WHERE rel_type = ?
91
+ GROUP BY from_id HAVING cnt > 1
92
+ `).all(rt.name);
93
+ for (const v of violators) {
94
+ violations.push({
95
+ type: 'cardinality',
96
+ relationId: 0,
97
+ fromId: v.from_id,
98
+ relType: v.rel_type,
99
+ toId: '',
100
+ message: `Cardinality one_to_one violated: entity "${v.from_id}" has ${v.cnt} outgoing "${v.rel_type}" relations`,
101
+ });
102
+ }
103
+ const violatorsTo = db.prepare(`
104
+ SELECT to_id, rel_type, COUNT(*) as cnt
105
+ FROM relations WHERE rel_type = ?
106
+ GROUP BY to_id HAVING cnt > 1
107
+ `).all(rt.name);
108
+ for (const v of violatorsTo) {
109
+ violations.push({
110
+ type: 'cardinality',
111
+ relationId: 0,
112
+ fromId: '',
113
+ relType: v.rel_type,
114
+ toId: v.to_id,
115
+ message: `Cardinality one_to_one violated: entity "${v.to_id}" has ${v.cnt} incoming "${v.rel_type}" relations`,
116
+ });
117
+ }
118
+ }
119
+ if (cardinality === 'one_to_many') {
120
+ // one_to_many: each target (to_id) can have at most one incoming relation of this type
121
+ const violatorsTo = db.prepare(`
122
+ SELECT to_id, rel_type, COUNT(*) as cnt
123
+ FROM relations WHERE rel_type = ?
124
+ GROUP BY to_id HAVING cnt > 1
125
+ `).all(rt.name);
126
+ for (const v of violatorsTo) {
127
+ violations.push({
128
+ type: 'cardinality',
129
+ relationId: 0,
130
+ fromId: '',
131
+ relType: v.rel_type,
132
+ toId: v.to_id,
133
+ message: `Cardinality one_to_many violated: entity "${v.to_id}" has ${v.cnt} incoming "${v.rel_type}" relations`,
134
+ });
135
+ }
136
+ }
137
+ if (cardinality === 'many_to_one') {
138
+ // many_to_one: each source (from_id) can have at most one outgoing relation of this type
139
+ const violators = db.prepare(`
140
+ SELECT from_id, rel_type, COUNT(*) as cnt
141
+ FROM relations WHERE rel_type = ?
142
+ GROUP BY from_id HAVING cnt > 1
143
+ `).all(rt.name);
144
+ for (const v of violators) {
145
+ violations.push({
146
+ type: 'cardinality',
147
+ relType: v.rel_type,
148
+ relationId: 0,
149
+ fromId: v.from_id,
150
+ toId: '',
151
+ message: `Cardinality many_to_one violated: entity "${v.from_id}" has ${v.cnt} outgoing "${v.rel_type}" relations`,
152
+ });
153
+ }
154
+ }
155
+ }
156
+ return {
157
+ valid: violations.length === 0,
158
+ violations,
159
+ };
160
+ }
161
+ function safeParseJson(raw, fallback) {
162
+ if (!raw)
163
+ return fallback;
164
+ try {
165
+ return JSON.parse(raw);
166
+ }
167
+ catch {
168
+ return fallback;
169
+ }
170
+ }
171
+ //# sourceMappingURL=graph-validation-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph-validation-service.js","sourceRoot":"","sources":["../../src/services/graph-validation-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ import type { ProjectResult, ProjectInfo, ProjectsRegistry } from '../models/project';
2
+ import { resolveProject } from '../config/resolver';
3
+ /** Options for project operations */
4
+ export interface ProjectServiceOptions {
5
+ /** Override registry path (for testing) */
6
+ registryPath?: string;
7
+ /** Override cwd for resolution (for testing) */
8
+ cwd?: string;
9
+ }
10
+ /**
11
+ * Validate project name format per FR-URD-002-0011:
12
+ * - Lowercase alphanumeric and hyphens only
13
+ * - Starts with a letter
14
+ * - Ends with a letter or digit
15
+ * - No consecutive hyphens
16
+ * - 1–64 characters
17
+ *
18
+ * @throws ProjectEmptyNameError (ERR-PROJ-003) if name is empty/whitespace
19
+ * @throws ProjectInvalidNameError (ERR-PROJ-008) if name format is invalid
20
+ */
21
+ export declare function validateProjectName(name: string): void;
22
+ /**
23
+ * Create a new project: make the folder, initialize pmp/project.db,
24
+ * register in ~/.config/cortex-cli/registry.json.
25
+ *
26
+ * @throws ProjectEmptyNameError (ERR-PROJ-003) if name is empty
27
+ * @throws ProjectInvalidNameError (ERR-PROJ-008) if name format is invalid
28
+ * @throws DuplicateProjectError (ERR-PROJ-001) if the project name already exists
29
+ * @throws ProjectPathExistsError (ERR-PROJ-002) if the folder path already exists (directory)
30
+ * @throws ProjectPathNotDirectoryError (ERR-PROJ-013) if the path exists as a file/symlink
31
+ */
32
+ export declare function createProject(name: string, folder: string, opts?: ProjectServiceOptions): ProjectResult;
33
+ /**
34
+ * Register an existing project folder.
35
+ * Creates pmp/project.db if it doesn't exist.
36
+ * Adds to ~/.config/cortex-cli/registry.json.
37
+ *
38
+ * @throws ProjectEmptyNameError (ERR-PROJ-003) if name is empty
39
+ * @throws ProjectInvalidNameError (ERR-PROJ-008) if name format is invalid
40
+ * @throws DuplicateProjectError (ERR-PROJ-001) if the project name already exists
41
+ * @throws ProjectFolderNotFoundError (ERR-PROJ-005) if the folder doesn't exist
42
+ */
43
+ export declare function registerProject(name: string, folder: string, opts?: ProjectServiceOptions): ProjectResult;
44
+ /**
45
+ * Remove a project from the global registry.
46
+ * Does NOT delete the project folder or database.
47
+ *
48
+ * @throws ProjectNotFoundError (ERR-PROJ-007) if the project doesn't exist
49
+ */
50
+ export declare function removeProject(name: string, opts?: ProjectServiceOptions): {
51
+ name: string;
52
+ folder: string;
53
+ dbPath: string;
54
+ };
55
+ /**
56
+ * List all registered projects.
57
+ */
58
+ export declare function listAllProjects(opts?: ProjectServiceOptions): ProjectsRegistry;
59
+ /**
60
+ * Set the default project.
61
+ *
62
+ * @throws ProjectNotFoundError (ERR-PROJ-007) if the project doesn't exist
63
+ */
64
+ export declare function setProjectDefault(name: string, opts?: ProjectServiceOptions): void;
65
+ /**
66
+ * Get the current default project name.
67
+ */
68
+ export declare function getDefaultProjectName(opts?: ProjectServiceOptions): string | null;
69
+ /**
70
+ * Show project details: folder, database path, sprint summary, entity counts.
71
+ *
72
+ * @throws ProjectNotFoundError (ERR-PROJ-007) if the project doesn't exist
73
+ */
74
+ export declare function getProjectInfo(name: string, opts?: ProjectServiceOptions): ProjectInfo;
75
+ /**
76
+ * Resolve the project to use for a command.
77
+ * Delegates to ProjectResolver.
78
+ */
79
+ export declare function resolveProjectForCommand(opts?: ProjectServiceOptions): ReturnType<typeof resolveProject>;
80
+ //# sourceMappingURL=project.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../src/services/project.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAWtF,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAYpD,qCAAqC;AACrC,MAAM,WAAW,qBAAqB;IACpC,2CAA2C;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gDAAgD;IAChD,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CA4BtD;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,qBAAqB,GAAG,aAAa,CA2DvG;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,qBAAqB,GAAG,aAAa,CA2CzG;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,qBAAqB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAS1H;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,CAAC,EAAE,qBAAqB,GAAG,gBAAgB,CAE9E;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,qBAAqB,GAAG,IAAI,CAElF;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,CAAC,EAAE,qBAAqB,GAAG,MAAM,GAAG,IAAI,CAGjF;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,qBAAqB,GAAG,WAAW,CAmCtF;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,CAAC,EAAE,qBAAqB,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAKxG"}
@@ -0,0 +1,256 @@
1
+ "use strict";
2
+ // Project service: orchestrates database and registry
3
+ // Implements AD-0004: ProjectService Orchestrates Database and Registry
4
+ // + FS-SS-002-0001 (create), FS-SS-002-0002 (register)
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.validateProjectName = validateProjectName;
7
+ exports.createProject = createProject;
8
+ exports.registerProject = registerProject;
9
+ exports.removeProject = removeProject;
10
+ exports.listAllProjects = listAllProjects;
11
+ exports.setProjectDefault = setProjectDefault;
12
+ exports.getDefaultProjectName = getDefaultProjectName;
13
+ exports.getProjectInfo = getProjectInfo;
14
+ exports.resolveProjectForCommand = resolveProjectForCommand;
15
+ const fs_1 = require("fs");
16
+ const path_1 = require("path");
17
+ const connection_1 = require("../db/connection");
18
+ const migration_1 = require("../db/migration");
19
+ const registry_1 = require("../config/registry");
20
+ const resolver_1 = require("../config/resolver");
21
+ const errors_1 = require("../utils/errors");
22
+ /**
23
+ * Validate project name format per FR-URD-002-0011:
24
+ * - Lowercase alphanumeric and hyphens only
25
+ * - Starts with a letter
26
+ * - Ends with a letter or digit
27
+ * - No consecutive hyphens
28
+ * - 1–64 characters
29
+ *
30
+ * @throws ProjectEmptyNameError (ERR-PROJ-003) if name is empty/whitespace
31
+ * @throws ProjectInvalidNameError (ERR-PROJ-008) if name format is invalid
32
+ */
33
+ function validateProjectName(name) {
34
+ if (!name || name.trim().length === 0) {
35
+ throw new errors_1.ProjectEmptyNameError();
36
+ }
37
+ // Single character: just needs to be a lowercase letter
38
+ if (name.length === 1) {
39
+ if (!/^[a-z]$/.test(name)) {
40
+ throw new errors_1.ProjectInvalidNameError(name);
41
+ }
42
+ return;
43
+ }
44
+ // Multi-character: full regex
45
+ // /^[a-z][a-z0-9-]{0,62}[a-z0-9]$/ plus no consecutive hyphens
46
+ if (!/^[a-z][a-z0-9-]{0,62}[a-z0-9]$/.test(name)) {
47
+ throw new errors_1.ProjectInvalidNameError(name);
48
+ }
49
+ // Check for consecutive hyphens
50
+ if (name.includes('--')) {
51
+ throw new errors_1.ProjectInvalidNameError(name);
52
+ }
53
+ // Check total length (1-64)
54
+ if (name.length > 64) {
55
+ throw new errors_1.ProjectInvalidNameError(name);
56
+ }
57
+ }
58
+ /**
59
+ * Create a new project: make the folder, initialize pmp/project.db,
60
+ * register in ~/.config/cortex-cli/registry.json.
61
+ *
62
+ * @throws ProjectEmptyNameError (ERR-PROJ-003) if name is empty
63
+ * @throws ProjectInvalidNameError (ERR-PROJ-008) if name format is invalid
64
+ * @throws DuplicateProjectError (ERR-PROJ-001) if the project name already exists
65
+ * @throws ProjectPathExistsError (ERR-PROJ-002) if the folder path already exists (directory)
66
+ * @throws ProjectPathNotDirectoryError (ERR-PROJ-013) if the path exists as a file/symlink
67
+ */
68
+ function createProject(name, folder, opts) {
69
+ // Validate name format (FS-SS-002-0001 VR-003/VR-006)
70
+ validateProjectName(name);
71
+ // Check for duplicate name
72
+ try {
73
+ const existing = (0, registry_1.getProject)(name, opts?.registryPath);
74
+ if (existing) {
75
+ throw new errors_1.DuplicateProjectError(name);
76
+ }
77
+ }
78
+ catch (err) {
79
+ // ProjectNotFoundError is expected if name doesn't exist yet
80
+ if (!(err instanceof errors_1.ProjectNotFoundError))
81
+ throw err;
82
+ }
83
+ const absoluteFolder = (0, path_1.resolve)(folder);
84
+ // Check if path already exists (FS-SS-002-0001 VR-002)
85
+ if ((0, fs_1.existsSync)(absoluteFolder)) {
86
+ const stat = (0, fs_1.lstatSync)(absoluteFolder);
87
+ if (stat.isDirectory()) {
88
+ throw new errors_1.ProjectPathExistsError(absoluteFolder);
89
+ }
90
+ else {
91
+ throw new errors_1.ProjectPathNotDirectoryError(absoluteFolder);
92
+ }
93
+ }
94
+ // Create the project folder
95
+ try {
96
+ (0, fs_1.mkdirSync)(absoluteFolder, { recursive: true });
97
+ }
98
+ catch (err) {
99
+ throw new errors_1.ProjectFolderCreateError(absoluteFolder, err instanceof Error ? err.message : String(err));
100
+ }
101
+ const dbPath = `${absoluteFolder}/pmp/project.db`;
102
+ const dbExisted = (0, fs_1.existsSync)(dbPath);
103
+ // Initialize the database
104
+ const db = (0, connection_1.openConnection)(dbPath);
105
+ try {
106
+ (0, migration_1.initializeSchema)(db);
107
+ }
108
+ finally {
109
+ db.close();
110
+ }
111
+ // Register in global registry
112
+ const registry = (0, registry_1.addProject)(name, absoluteFolder, opts?.registryPath);
113
+ const isDefault = registry.default === name;
114
+ return {
115
+ name,
116
+ folder: absoluteFolder,
117
+ dbPath,
118
+ isNew: !dbExisted,
119
+ isDefault,
120
+ };
121
+ }
122
+ /**
123
+ * Register an existing project folder.
124
+ * Creates pmp/project.db if it doesn't exist.
125
+ * Adds to ~/.config/cortex-cli/registry.json.
126
+ *
127
+ * @throws ProjectEmptyNameError (ERR-PROJ-003) if name is empty
128
+ * @throws ProjectInvalidNameError (ERR-PROJ-008) if name format is invalid
129
+ * @throws DuplicateProjectError (ERR-PROJ-001) if the project name already exists
130
+ * @throws ProjectFolderNotFoundError (ERR-PROJ-005) if the folder doesn't exist
131
+ */
132
+ function registerProject(name, folder, opts) {
133
+ // Validate name format (FS-SS-002-0002 VR-005)
134
+ validateProjectName(name);
135
+ // Check for duplicate name
136
+ try {
137
+ const existing = (0, registry_1.getProject)(name, opts?.registryPath);
138
+ if (existing) {
139
+ throw new errors_1.DuplicateProjectError(name);
140
+ }
141
+ }
142
+ catch (err) {
143
+ if (!(err instanceof errors_1.ProjectNotFoundError))
144
+ throw err;
145
+ }
146
+ const absoluteFolder = (0, path_1.resolve)(folder);
147
+ // Verify folder exists (FS-SS-002-0002 VR-001)
148
+ if (!(0, fs_1.existsSync)(absoluteFolder)) {
149
+ throw new errors_1.ProjectFolderNotFoundError(absoluteFolder);
150
+ }
151
+ const dbPath = `${absoluteFolder}/pmp/project.db`;
152
+ const dbExisted = (0, fs_1.existsSync)(dbPath);
153
+ // Initialize the database
154
+ const db = (0, connection_1.openConnection)(dbPath);
155
+ try {
156
+ (0, migration_1.initializeSchema)(db);
157
+ }
158
+ finally {
159
+ db.close();
160
+ }
161
+ // Register in global registry
162
+ const registry = (0, registry_1.addProject)(name, absoluteFolder, opts?.registryPath);
163
+ const isDefault = registry.default === name;
164
+ return {
165
+ name,
166
+ folder: absoluteFolder,
167
+ dbPath,
168
+ isNew: !dbExisted,
169
+ isDefault,
170
+ };
171
+ }
172
+ /**
173
+ * Remove a project from the global registry.
174
+ * Does NOT delete the project folder or database.
175
+ *
176
+ * @throws ProjectNotFoundError (ERR-PROJ-007) if the project doesn't exist
177
+ */
178
+ function removeProject(name, opts) {
179
+ const entry = (0, registry_1.getProject)(name, opts?.registryPath);
180
+ (0, registry_1.removeProject)(name, opts?.registryPath);
181
+ return {
182
+ name,
183
+ folder: entry.folder,
184
+ dbPath: `${entry.folder}/pmp/project.db`,
185
+ };
186
+ }
187
+ /**
188
+ * List all registered projects.
189
+ */
190
+ function listAllProjects(opts) {
191
+ return (0, registry_1.listProjects)(opts?.registryPath);
192
+ }
193
+ /**
194
+ * Set the default project.
195
+ *
196
+ * @throws ProjectNotFoundError (ERR-PROJ-007) if the project doesn't exist
197
+ */
198
+ function setProjectDefault(name, opts) {
199
+ (0, registry_1.setDefaultProject)(name, opts?.registryPath);
200
+ }
201
+ /**
202
+ * Get the current default project name.
203
+ */
204
+ function getDefaultProjectName(opts) {
205
+ const registry = (0, registry_1.loadRegistry)(opts?.registryPath);
206
+ return registry.default;
207
+ }
208
+ /**
209
+ * Show project details: folder, database path, sprint summary, entity counts.
210
+ *
211
+ * @throws ProjectNotFoundError (ERR-PROJ-007) if the project doesn't exist
212
+ */
213
+ function getProjectInfo(name, opts) {
214
+ const entry = (0, registry_1.getProject)(name, opts?.registryPath);
215
+ const registry = (0, registry_1.loadRegistry)(opts?.registryPath);
216
+ const dbPath = `${entry.folder}/pmp/project.db`;
217
+ const isDefault = registry.default === name;
218
+ // Query the database for summary counts
219
+ let sprintCount = 0;
220
+ let activeSprintCount = 0;
221
+ let docCount = 0;
222
+ let taskCount = 0;
223
+ if ((0, fs_1.existsSync)(dbPath)) {
224
+ const db = (0, connection_1.openConnection)(dbPath);
225
+ try {
226
+ sprintCount = db.prepare('SELECT COUNT(*) as c FROM sprints').get().c;
227
+ activeSprintCount = db.prepare("SELECT COUNT(*) as c FROM sprints WHERE status IN ('PLANNING','IN EXECUTION','CLOSING')").get().c;
228
+ docCount = db.prepare('SELECT COUNT(*) as c FROM documents').get().c;
229
+ taskCount = db.prepare('SELECT COUNT(*) as c FROM tasks').get().c;
230
+ }
231
+ finally {
232
+ db.close();
233
+ }
234
+ }
235
+ return {
236
+ name,
237
+ folder: entry.folder,
238
+ dbPath,
239
+ isDefault,
240
+ sprintCount,
241
+ activeSprintCount,
242
+ docCount,
243
+ taskCount,
244
+ };
245
+ }
246
+ /**
247
+ * Resolve the project to use for a command.
248
+ * Delegates to ProjectResolver.
249
+ */
250
+ function resolveProjectForCommand(opts) {
251
+ return (0, resolver_1.resolveProject)({
252
+ registryPath: opts?.registryPath,
253
+ cwd: opts?.cwd,
254
+ });
255
+ }
256
+ //# sourceMappingURL=project.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project.js","sourceRoot":"","sources":["../../src/services/project.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,81 @@
1
+ import type Database from 'better-sqlite3';
2
+ import type { Review, ReviewDetail, ReviewAddOptions, TestReport, TestReportAddOptions, Lesson, LessonAddOptions, LessonResult, LessonUpdateFields } from '../models/review';
3
+ /**
4
+ * Add a review with explicit caller-provided 4-digit ID.
5
+ * Content must be provided (from --content-file).
6
+ *
7
+ * SAD-0031 Part A: No advisory lock — caller provides explicit ID.
8
+ * Duplicate validation via EXISTS on composite index (sprint_id, review_num).
9
+ */
10
+ export declare function addReview(db: Database.Database, sprintId: string, reviewId: string, reviewType: string, verdict: string, content: string, opts?: ReviewAddOptions): Review;
11
+ /**
12
+ * List reviews for a sprint.
13
+ */
14
+ export declare function listReviews(db: Database.Database, sprintId: string, filters?: {
15
+ type?: string;
16
+ verdict?: string;
17
+ }): Review[];
18
+ /**
19
+ * Get a review by review number within a sprint (SAD-0010 Part C).
20
+ * Both reviewNum and sprintId are required.
21
+ *
22
+ * @param db - Database connection
23
+ * @param reviewNum - Review number (1-based, displayed to user)
24
+ * @param sprintId - Sprint ID (required)
25
+ * @returns Review detail
26
+ * @throws ReviewNotInSprintError if review not found in the specified sprint
27
+ */
28
+ export declare function getReview(db: Database.Database, reviewNum: number, sprintId: string): ReviewDetail;
29
+ /**
30
+ * Add a test report with explicit caller-provided 4-digit ID.
31
+ * SAD-0031 Part A: No advisory lock, no task association.
32
+ * Duplicate validation via EXISTS on composite index (sprint_id, id).
33
+ */
34
+ export declare function addTestReport(db: Database.Database, sprintId: string, testReportId: string, total: number, passed: number, failed: number, opts?: TestReportAddOptions): TestReport;
35
+ /**
36
+ * List test reports. Task filter removed per SAD-0031 Part B.
37
+ */
38
+ export declare function listTestReports(db: Database.Database, sprintId?: string): TestReport[];
39
+ /**
40
+ * Get a single test report by caller-provided ID and sprint.
41
+ * SAD-0031 Part A: sprint-scoped lookup by explicit ID string.
42
+ *
43
+ * @param db - Database connection
44
+ * @param testReportId - Caller-provided test report ID (e.g., "0001")
45
+ * @param sprintId - Sprint ID (required per URD-026)
46
+ * @returns Test report
47
+ * @throws error with ERR-TESTREPORT-004 if not found
48
+ */
49
+ export declare function getTestReport(db: Database.Database, testReportId: string, sprintId: string): TestReport;
50
+ /**
51
+ * Add a lesson (retained for internal use, e.g., sprint lessons-data export).
52
+ * Not CLI-facing — the CLI exposes only show and update.
53
+ * Post-URD-026: metadata removed, content-only.
54
+ */
55
+ export declare function addLesson(db: Database.Database, _sprintId: string, _title: string, description: string, _category: string, _opts?: LessonAddOptions): Lesson;
56
+ /**
57
+ * List lessons (retained for internal use; post-URD-026 no longer sprint-scoped).
58
+ * Not CLI-facing.
59
+ */
60
+ export declare function listLessons(db: Database.Database, _sprintId?: string): Lesson[];
61
+ /**
62
+ * Get the project's single lesson (singleton pattern, SAD-0010 Part B).
63
+ * No ID argument — exactly one lesson per project.
64
+ *
65
+ * @param db - Database connection
66
+ * @returns LessonResult
67
+ * @throws LessonNotFoundError (ERR-LESSON-001) if no lesson exists
68
+ */
69
+ export declare function getLesson(db: Database.Database): LessonResult;
70
+ /**
71
+ * Update the project's single lesson (singleton pattern, post-URD-026).
72
+ * Upsert semantics per AD-0029: creates if absent, updates if exists.
73
+ * Content-only — all metadata fields removed (URD-026 Part B).
74
+ *
75
+ * @param db - Database connection
76
+ * @param updates - Fields to update; content required
77
+ * @returns Updated LessonResult
78
+ * @throws LessonNoUpdateFieldsError if content is empty/missing
79
+ */
80
+ export declare function updateLesson(db: Database.Database, updates: LessonUpdateFields): LessonResult;
81
+ //# sourceMappingURL=review-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-service.d.ts","sourceRoot":"","sources":["../../src/services/review-service.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,gBAAgB,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,EAAE,gBAAgB,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAiC7K;;;;;;GAMG;AACH,wBAAgB,SAAS,CACvB,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,gBAAgB,GACtB,MAAM,CAuCR;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5C,MAAM,EAAE,CAUV;AAWD;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,YAAY,CAalG;AAID;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE,oBAAoB,GAC1B,UAAU,CAsCZ;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,QAAQ,CAAC,EAAE,MAAM,GAChB,UAAU,EAAE,CAOd;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU,CAQvG;AAcD;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,KAAK,CAAC,EAAE,gBAAgB,GACvB,MAAM,CAgBR;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAE/E;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,YAAY,CAM7D;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAC1B,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,OAAO,EAAE,kBAAkB,GAC1B,YAAY,CA2Bd"}