@bongos/core 1.19.316 → 1.19.318

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 (42) hide show
  1. package/.bongos-core.json +108 -33
  2. package/modules/economy/cost.js +84 -19
  3. package/modules/lifecycle/db-analytics.js +719 -0
  4. package/modules/lifecycle/db-claim-reads.js +165 -0
  5. package/modules/lifecycle/db-claims.js +934 -0
  6. package/modules/lifecycle/db-deps-criteria.js +441 -0
  7. package/modules/lifecycle/db-goals.js +763 -0
  8. package/modules/lifecycle/db-grade.js +233 -0
  9. package/modules/lifecycle/db-overrides.js +181 -0
  10. package/modules/lifecycle/db-rank-authz.js +446 -0
  11. package/modules/lifecycle/db-shared.js +115 -0
  12. package/modules/lifecycle/db-ship.js +994 -0
  13. package/modules/lifecycle/db-tasks.js +810 -0
  14. package/modules/lifecycle/db-versions.js +118 -0
  15. package/modules/lifecycle/db.js +167 -5564
  16. package/modules/lifecycle/publish-reconciler.js +7 -2
  17. package/package-lock.json +2 -2
  18. package/package.json +1 -1
  19. package/scripts/gds/coreB-carve-proof.sh +18 -9
  20. package/scripts/gds/fitness.js +34 -26
  21. package/scripts/gds/identity-strip.js +75 -0
  22. package/scripts/gds/provision.js +7 -3
  23. package/scripts/gds/run-unit-tests.js +8 -1
  24. package/scripts/gds/session-cost.js +16 -0
  25. package/scripts/gds/session-digest-build.js +261 -0
  26. package/scripts/gds/ship.js +7 -198
  27. package/src/module-api.js +5 -1
  28. package/tests/auto_satisfy_criteria.mjs +3 -2
  29. package/tests/dependencies_migration.mjs +3 -2
  30. package/tests/fitness.mjs +43 -0
  31. package/tests/goal_abuse_matrix.mjs +3 -2
  32. package/tests/goal_advisory.mjs +3 -2
  33. package/tests/government_claim_eligibility.mjs +3 -1
  34. package/tests/government_rank_sync.mjs +9 -2
  35. package/tests/helpers.mjs +19 -0
  36. package/tests/migration_allocation.mjs +3 -1
  37. package/tests/publish_reconciler.mjs +41 -1
  38. package/tests/rank_gate.mjs +3 -1
  39. package/tests/reward_gate.mjs +3 -1
  40. package/tests/session_cost.mjs +64 -0
  41. package/tests/session_cost_row_raise.mjs +139 -0
  42. package/tests/session_records.mjs +72 -0
@@ -0,0 +1,118 @@
1
+ // modules/lifecycle/db-versions.js — version rows + version progress.
2
+ //
3
+ // Carved out of modules/lifecycle/db.js by task 1003204 (goal 1000079, the R03
4
+ // de-monolith plan) — a STRUCTURAL move, not a rewrite: the code below is the
5
+ // original db.js lines 561-656 unchanged. db.js remains the facade that
6
+ // re-exports every name, so every existing db call site is unchanged.
7
+ //
8
+ // THE BOUNDARY (ADR 0093 §1): this file reaches core ONLY through the published
9
+ // doorway ../../src/module-api.js — never a core internal, never a sibling module.
10
+
11
+ 'use strict';
12
+
13
+ const api = require('../../src/module-api');
14
+ const { pool, withTx } = api;
15
+ const doneWhen = require('./done-when.js');
16
+
17
+ async function listVersions() {
18
+ const { rows } = await pool.query(
19
+ `SELECT id, name, track, status, scope_doc_path, started_at, shipped_at, done_when
20
+ FROM versions
21
+ ORDER BY started_at`
22
+ );
23
+ return rows;
24
+ }
25
+
26
+
27
+ async function getVersion(id) {
28
+ const { rows } = await pool.query(
29
+ `SELECT id, name, track, status, scope_doc_path, started_at, shipped_at, done_when
30
+ FROM versions WHERE id = $1`,
31
+ [id]
32
+ );
33
+ return rows[0] ?? null;
34
+ }
35
+
36
+
37
+ async function versionProgress() {
38
+ // Joins the rolled-up progress view (any of completed/confirmed/shipped counts
39
+ // as "done") with the per-state breakdown view from migration 012 so the
40
+ // public dashboard can render a stacked three-segment progress bar.
41
+ //
42
+ // Also surfaces two version-level fields the Works-in-Progress surfaces need
43
+ // (task 938): `done_when` (the senate-voice short description rendered as the
44
+ // version's blurb on both the status mirror and the work board) and
45
+ // `criteria_count` (how many done_when_criteria are seeded). The status mirror
46
+ // uses criteria_count > 0 to tell a genuinely-active version from a freshly
47
+ // stubbed "future placeholder" (e.g. a next-version row created by
48
+ // version-close that has no criteria seeded yet) without needing a schema flag.
49
+ const { rows } = await pool.query(
50
+ `SELECT vp.version_id, vp.name, vp.status,
51
+ vp.shipped_count, vp.total_count, vp.shipped_weight, vp.total_weight,
52
+ v.done_when,
53
+ COALESCE(dwc.criteria_count, 0) AS criteria_count,
54
+ COALESCE(vlb.completed_count, 0) AS lifecycle_completed_count,
55
+ COALESCE(vlb.confirmed_count, 0) AS lifecycle_confirmed_count,
56
+ COALESCE(vlb.shipped_count, 0) AS lifecycle_shipped_count
57
+ FROM version_progress vp
58
+ LEFT JOIN version_lifecycle_breakdown vlb ON vlb.version_id = vp.version_id
59
+ LEFT JOIN versions v ON v.id = vp.version_id
60
+ LEFT JOIN (
61
+ SELECT version_id, count(*) AS criteria_count
62
+ FROM done_when_criteria
63
+ GROUP BY version_id
64
+ ) dwc ON dwc.version_id = vp.version_id
65
+ ORDER BY vp.version_id`
66
+ );
67
+ return rows.map((r) => ({
68
+ ...r,
69
+ criteria_count: Number(r.criteria_count),
70
+ lifecycle_completed_count: Number(r.lifecycle_completed_count),
71
+ lifecycle_confirmed_count: Number(r.lifecycle_confirmed_count),
72
+ lifecycle_shipped_count: Number(r.lifecycle_shipped_count),
73
+ percent_complete:
74
+ r.total_weight > 0 ? Math.round((Number(r.shipped_weight) / Number(r.total_weight)) * 100) : 0,
75
+ }));
76
+ }
77
+
78
+ // Create a version + (optionally) its done-when criteria in one atomic write —
79
+ // the seed primitive `bongos init` uses so a fresh instance needs no hand-written
80
+ // seed-*.js script (task 1204 / R65). Atomic: the version and all its criteria
81
+ // commit together, so a bad criterion leaves nothing half-created. Criteria are
82
+ // idempotent on (version_id, criterion_id) so a re-run can't double-insert.
83
+
84
+ async function createVersion({ id, name, status = 'planning', track = 'product', scopeDocPath = null, doneWhen = null, criteria = [] }) {
85
+ // versions.track is NOT NULL with no DB default (migration 003) — omitting it
86
+ // here made every create 500. An instance's first version is its product
87
+ // track, so that's the default; 'internal' is the platform's own track.
88
+ return withTx(async (client) => {
89
+ const { rows } = await client.query(
90
+ `INSERT INTO versions (id, name, status, track, scope_doc_path, done_when)
91
+ VALUES ($1, $2, $3, $4, $5, $6)
92
+ RETURNING id, name, status, track, scope_doc_path, started_at, shipped_at, done_when`,
93
+ [id, name, status, track, scopeDocPath, doneWhen]
94
+ );
95
+ const version = rows[0];
96
+ const createdCriteria = [];
97
+ let i = 0;
98
+ for (const c of (criteria || [])) {
99
+ const { rows: cr } = await client.query(
100
+ `INSERT INTO done_when_criteria (version_id, criterion_id, criterion_md, sort_order)
101
+ VALUES ($1, $2, $3, $4)
102
+ ON CONFLICT (version_id, criterion_id) DO NOTHING
103
+ RETURNING id, version_id, criterion_id, criterion_md, sort_order, satisfied`,
104
+ [id, c.criterion_id, c.criterion_md, Number.isFinite(c.sort_order) ? c.sort_order : (i + 1) * 10]
105
+ );
106
+ if (cr[0]) createdCriteria.push(cr[0]);
107
+ i++;
108
+ }
109
+ return { version, criteria: createdCriteria };
110
+ });
111
+ }
112
+
113
+ module.exports = {
114
+ createVersion,
115
+ getVersion,
116
+ listVersions,
117
+ versionProgress,
118
+ };