@promptowl/contextnest-community 1.5.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONFIGURATION.md +60 -2
- package/README.md +13 -0
- package/dist/adapter.postgres-YOODX2BI.js +71 -0
- package/dist/{chunk-EMOE53KX.js → chunk-2TUMMVBG.js} +352 -263
- package/dist/{chunk-RMU3LOPH.js → chunk-7V33Z6CS.js} +258 -69
- package/dist/{chunk-IWA2UDAT.js → chunk-MZGFKBOK.js} +116 -90
- package/dist/chunk-SLTQACJW.js +8 -0
- package/dist/{chunk-HIH7I232.js → chunk-T5L4LYU4.js} +69 -53
- package/dist/index.js +752 -592
- package/dist/migrations.postgres-NVJAGBSF.js +273 -0
- package/dist/{review-service-XNXHF6Q7.js → review-service-QJ3FBOML.js} +5 -4
- package/dist/{stewardship-service-P4M5UEJW.js → stewardship-service-VIKF3VZB.js} +3 -2
- package/dist/{version-service-REGL5CUT.js → version-service-MUZYTYMW.js} +3 -2
- package/dist/web3/assets/{index-DEKnE-ty.js → index-C2Tf2ZFz.js} +97 -97
- package/dist/web3/index.html +1 -1
- package/package.json +3 -1
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createVersion,
|
|
3
3
|
setApprovedVersion
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-T5L4LYU4.js";
|
|
5
5
|
import {
|
|
6
6
|
buildTitleMap,
|
|
7
7
|
canUserApprove,
|
|
8
8
|
engineCache,
|
|
9
9
|
resolveStewardsForNode
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-2TUMMVBG.js";
|
|
11
11
|
import {
|
|
12
|
-
getDb
|
|
13
|
-
|
|
12
|
+
getDb,
|
|
13
|
+
insertOrReplace,
|
|
14
|
+
nowExpr
|
|
15
|
+
} from "./chunk-7V33Z6CS.js";
|
|
14
16
|
|
|
15
17
|
// src/governance/review-service.ts
|
|
16
18
|
import { v4 as uuid } from "uuid";
|
|
@@ -43,43 +45,47 @@ function stripUndefinedDeep(value) {
|
|
|
43
45
|
}
|
|
44
46
|
|
|
45
47
|
// src/governance/review-service.ts
|
|
46
|
-
function submitForReview(params) {
|
|
48
|
+
async function submitForReview(params) {
|
|
47
49
|
const db = getDb();
|
|
48
|
-
const existing = db.
|
|
49
|
-
"SELECT id FROM review_requests WHERE nest_id = ? AND node_id = ? AND status = 'pending'"
|
|
50
|
-
|
|
50
|
+
const existing = await db.get(
|
|
51
|
+
"SELECT id FROM review_requests WHERE nest_id = ? AND node_id = ? AND status = 'pending'",
|
|
52
|
+
[params.nestId, params.nodeId]
|
|
53
|
+
);
|
|
51
54
|
if (existing) {
|
|
52
55
|
throw new Error("A review is already pending for this node");
|
|
53
56
|
}
|
|
54
57
|
const id = uuid();
|
|
55
|
-
db.
|
|
58
|
+
await db.run(
|
|
56
59
|
`INSERT INTO review_requests
|
|
57
60
|
(id, nest_id, node_id, version, requested_by, request_note, priority)
|
|
58
|
-
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
61
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)`,
|
|
62
|
+
[
|
|
63
|
+
id,
|
|
64
|
+
params.nestId,
|
|
65
|
+
params.nodeId,
|
|
66
|
+
params.version,
|
|
67
|
+
params.requestedBy,
|
|
68
|
+
params.note || null,
|
|
69
|
+
params.priority || "normal"
|
|
70
|
+
]
|
|
71
|
+
);
|
|
72
|
+
await db.run(
|
|
73
|
+
"UPDATE node_versions SET status = 'pending_review' WHERE nest_id = ? AND node_id = ? AND version = ?",
|
|
74
|
+
[params.nestId, params.nodeId, params.version]
|
|
67
75
|
);
|
|
68
|
-
|
|
69
|
-
"UPDATE node_versions SET status = 'pending_review' WHERE nest_id = ? AND node_id = ? AND version = ?"
|
|
70
|
-
).run(params.nestId, params.nodeId, params.version);
|
|
71
|
-
return getReviewRequest(id);
|
|
76
|
+
return await getReviewRequest(id);
|
|
72
77
|
}
|
|
73
78
|
async function approve(params) {
|
|
74
79
|
const db = getDb();
|
|
75
|
-
const pending = db.
|
|
76
|
-
"SELECT * FROM review_requests WHERE nest_id = ? AND node_id = ? AND status = 'pending' ORDER BY requested_at DESC LIMIT 1"
|
|
77
|
-
|
|
80
|
+
const pending = await db.get(
|
|
81
|
+
"SELECT * FROM review_requests WHERE nest_id = ? AND node_id = ? AND status = 'pending' ORDER BY requested_at DESC LIMIT 1",
|
|
82
|
+
[params.nestId, params.nodeId]
|
|
83
|
+
);
|
|
78
84
|
if (!pending) {
|
|
79
85
|
throw new Error("No pending review for this node");
|
|
80
86
|
}
|
|
81
87
|
if (!params.override) {
|
|
82
|
-
const check = canUserApprove(
|
|
88
|
+
const check = await canUserApprove(
|
|
83
89
|
params.nestId,
|
|
84
90
|
params.nodeId,
|
|
85
91
|
params.approvedBy
|
|
@@ -88,26 +94,29 @@ async function approve(params) {
|
|
|
88
94
|
throw new Error(check.reason);
|
|
89
95
|
}
|
|
90
96
|
}
|
|
91
|
-
db.
|
|
97
|
+
await db.run(
|
|
92
98
|
`UPDATE review_requests
|
|
93
|
-
SET status = 'approved', resolved_by = ?, resolved_at =
|
|
99
|
+
SET status = 'approved', resolved_by = ?, resolved_at = ${nowExpr(db)},
|
|
94
100
|
resolution_note = ?, is_override = ?
|
|
95
|
-
WHERE id =
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
+
WHERE id = ?`,
|
|
102
|
+
[params.approvedBy, params.note || null, params.override ? 1 : 0, pending.id]
|
|
103
|
+
);
|
|
104
|
+
await db.run(
|
|
105
|
+
"UPDATE node_versions SET status = 'published' WHERE nest_id = ? AND node_id = ? AND version = ?",
|
|
106
|
+
[params.nestId, params.nodeId, params.version]
|
|
107
|
+
);
|
|
108
|
+
await db.run(
|
|
109
|
+
insertOrReplace(
|
|
110
|
+
db,
|
|
111
|
+
`INSERT INTO approved_versions (nest_id, node_id, approved_version, approved_by)
|
|
112
|
+
VALUES (?, ?, ?, ?)`,
|
|
113
|
+
["nest_id", "node_id"],
|
|
114
|
+
`approved_version = excluded.approved_version, approved_by = excluded.approved_by, approved_at = ${nowExpr(db)}`
|
|
115
|
+
),
|
|
116
|
+
[params.nestId, params.nodeId, params.version, params.approvedBy]
|
|
101
117
|
);
|
|
102
|
-
db.prepare(
|
|
103
|
-
"UPDATE node_versions SET status = 'published' WHERE nest_id = ? AND node_id = ? AND version = ?"
|
|
104
|
-
).run(params.nestId, params.nodeId, params.version);
|
|
105
|
-
db.prepare(
|
|
106
|
-
`INSERT OR REPLACE INTO approved_versions (nest_id, node_id, approved_version, approved_by)
|
|
107
|
-
VALUES (?, ?, ?, ?)`
|
|
108
|
-
).run(params.nestId, params.nodeId, params.version, params.approvedBy);
|
|
109
118
|
try {
|
|
110
|
-
const { storage } = engineCache.get(params.nestId);
|
|
119
|
+
const { storage } = await engineCache.get(params.nestId);
|
|
111
120
|
const result = await safePublishDocument(storage, params.nodeId, {
|
|
112
121
|
editedBy: params.approvedBy,
|
|
113
122
|
note: params.note || `Approved review request ${pending.id}`
|
|
@@ -116,7 +125,7 @@ async function approve(params) {
|
|
|
116
125
|
if (engineVersion !== params.version) {
|
|
117
126
|
const node = result.node;
|
|
118
127
|
const tags = node.frontmatter.tags || [];
|
|
119
|
-
createVersion({
|
|
128
|
+
await createVersion({
|
|
120
129
|
nestId: params.nestId,
|
|
121
130
|
nodeId: params.nodeId,
|
|
122
131
|
version: engineVersion,
|
|
@@ -126,7 +135,7 @@ async function approve(params) {
|
|
|
126
135
|
tags,
|
|
127
136
|
changeNote: params.note || `Approved review request ${pending.id}`
|
|
128
137
|
});
|
|
129
|
-
setApprovedVersion(
|
|
138
|
+
await setApprovedVersion(
|
|
130
139
|
params.nestId,
|
|
131
140
|
params.nodeId,
|
|
132
141
|
engineVersion,
|
|
@@ -139,17 +148,18 @@ async function approve(params) {
|
|
|
139
148
|
err
|
|
140
149
|
);
|
|
141
150
|
}
|
|
142
|
-
return getReviewRequest(pending.id);
|
|
151
|
+
return await getReviewRequest(pending.id);
|
|
143
152
|
}
|
|
144
|
-
function reject(params) {
|
|
153
|
+
async function reject(params) {
|
|
145
154
|
const db = getDb();
|
|
146
|
-
const pending = db.
|
|
147
|
-
"SELECT * FROM review_requests WHERE nest_id = ? AND node_id = ? AND status = 'pending' ORDER BY requested_at DESC LIMIT 1"
|
|
148
|
-
|
|
155
|
+
const pending = await db.get(
|
|
156
|
+
"SELECT * FROM review_requests WHERE nest_id = ? AND node_id = ? AND status = 'pending' ORDER BY requested_at DESC LIMIT 1",
|
|
157
|
+
[params.nestId, params.nodeId]
|
|
158
|
+
);
|
|
149
159
|
if (!pending) {
|
|
150
160
|
throw new Error("No pending review for this node");
|
|
151
161
|
}
|
|
152
|
-
const check = canUserApprove(
|
|
162
|
+
const check = await canUserApprove(
|
|
153
163
|
params.nestId,
|
|
154
164
|
params.nodeId,
|
|
155
165
|
params.rejectedBy
|
|
@@ -157,31 +167,36 @@ function reject(params) {
|
|
|
157
167
|
if (!check.allowed) {
|
|
158
168
|
throw new Error(check.reason);
|
|
159
169
|
}
|
|
160
|
-
db.
|
|
170
|
+
await db.run(
|
|
161
171
|
`UPDATE review_requests
|
|
162
|
-
SET status = 'rejected', resolved_by = ?, resolved_at =
|
|
163
|
-
WHERE id =
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
172
|
+
SET status = 'rejected', resolved_by = ?, resolved_at = ${nowExpr(db)}, resolution_note = ?
|
|
173
|
+
WHERE id = ?`,
|
|
174
|
+
[params.rejectedBy, params.note, pending.id]
|
|
175
|
+
);
|
|
176
|
+
await db.run(
|
|
177
|
+
"UPDATE node_versions SET status = 'rejected' WHERE nest_id = ? AND node_id = ? AND version = ?",
|
|
178
|
+
[params.nestId, params.nodeId, params.version]
|
|
179
|
+
);
|
|
180
|
+
return await getReviewRequest(pending.id);
|
|
169
181
|
}
|
|
170
|
-
function cancelReview(params) {
|
|
182
|
+
async function cancelReview(params) {
|
|
171
183
|
const db = getDb();
|
|
172
|
-
const pending = db.
|
|
173
|
-
"SELECT * FROM review_requests WHERE nest_id = ? AND node_id = ? AND status = 'pending' ORDER BY requested_at DESC LIMIT 1"
|
|
174
|
-
|
|
184
|
+
const pending = await db.get(
|
|
185
|
+
"SELECT * FROM review_requests WHERE nest_id = ? AND node_id = ? AND status = 'pending' ORDER BY requested_at DESC LIMIT 1",
|
|
186
|
+
[params.nestId, params.nodeId]
|
|
187
|
+
);
|
|
175
188
|
if (!pending) return null;
|
|
176
|
-
db.
|
|
189
|
+
await db.run(
|
|
177
190
|
`UPDATE review_requests
|
|
178
|
-
SET status = 'cancelled', resolved_by = ?, resolved_at =
|
|
179
|
-
WHERE id =
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
191
|
+
SET status = 'cancelled', resolved_by = ?, resolved_at = ${nowExpr(db)}
|
|
192
|
+
WHERE id = ?`,
|
|
193
|
+
[params.cancelledBy, pending.id]
|
|
194
|
+
);
|
|
195
|
+
await db.run(
|
|
196
|
+
"UPDATE node_versions SET status = 'draft' WHERE nest_id = ? AND node_id = ? AND version = ?",
|
|
197
|
+
[params.nestId, params.nodeId, pending.version]
|
|
198
|
+
);
|
|
199
|
+
return await getReviewRequest(pending.id);
|
|
185
200
|
}
|
|
186
201
|
async function getReviewQueue(params) {
|
|
187
202
|
const db = getDb();
|
|
@@ -199,24 +214,30 @@ async function getReviewQueue(params) {
|
|
|
199
214
|
args.push(...statuses);
|
|
200
215
|
}
|
|
201
216
|
const where = whereClauses.length > 0 ? `WHERE ${whereClauses.join(" AND ")}` : "";
|
|
202
|
-
const total =
|
|
217
|
+
const total = (await db.get(
|
|
218
|
+
`SELECT COUNT(*) as c FROM review_requests ${where}`,
|
|
219
|
+
args
|
|
220
|
+
)).c;
|
|
203
221
|
const limit = params.limit || 50;
|
|
204
222
|
const offset = params.offset || 0;
|
|
205
|
-
const rows = db.
|
|
223
|
+
const rows = await db.all(
|
|
206
224
|
`SELECT * FROM review_requests ${where}
|
|
207
225
|
ORDER BY
|
|
208
226
|
CASE priority WHEN 'urgent' THEN 0 WHEN 'high' THEN 1 WHEN 'normal' THEN 2 ELSE 3 END,
|
|
209
227
|
requested_at DESC
|
|
210
|
-
LIMIT ? OFFSET
|
|
211
|
-
|
|
228
|
+
LIMIT ? OFFSET ?`,
|
|
229
|
+
[...args, limit, offset]
|
|
230
|
+
);
|
|
212
231
|
let requests = rows.map(rowToReviewRequest);
|
|
213
232
|
if (params.stewardEmail) {
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
233
|
+
const filtered = [];
|
|
234
|
+
for (const r of requests) {
|
|
235
|
+
const stewards = await resolveStewardsForNode(r.nestId, r.nodeId);
|
|
236
|
+
if (stewards.some((s) => s.steward.userEmail === params.stewardEmail)) {
|
|
237
|
+
filtered.push(r);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
requests = filtered;
|
|
220
241
|
}
|
|
221
242
|
const titleMapsByNest = /* @__PURE__ */ new Map();
|
|
222
243
|
const nestIds = new Set(requests.map((r) => r.nestId));
|
|
@@ -229,23 +250,28 @@ async function getReviewQueue(params) {
|
|
|
229
250
|
}));
|
|
230
251
|
return { requests, total };
|
|
231
252
|
}
|
|
232
|
-
function getReviewHistory(nestId, nodeId) {
|
|
253
|
+
async function getReviewHistory(nestId, nodeId) {
|
|
233
254
|
const db = getDb();
|
|
234
|
-
const rows = db.
|
|
235
|
-
"SELECT * FROM review_requests WHERE nest_id = ? AND node_id = ? ORDER BY requested_at DESC"
|
|
236
|
-
|
|
255
|
+
const rows = await db.all(
|
|
256
|
+
"SELECT * FROM review_requests WHERE nest_id = ? AND node_id = ? ORDER BY requested_at DESC",
|
|
257
|
+
[nestId, nodeId]
|
|
258
|
+
);
|
|
237
259
|
return rows.map(rowToReviewRequest);
|
|
238
260
|
}
|
|
239
|
-
function getPendingReview(nestId, nodeId) {
|
|
261
|
+
async function getPendingReview(nestId, nodeId) {
|
|
240
262
|
const db = getDb();
|
|
241
|
-
const row = db.
|
|
242
|
-
"SELECT * FROM review_requests WHERE nest_id = ? AND node_id = ? AND status = 'pending' ORDER BY requested_at DESC LIMIT 1"
|
|
243
|
-
|
|
263
|
+
const row = await db.get(
|
|
264
|
+
"SELECT * FROM review_requests WHERE nest_id = ? AND node_id = ? AND status = 'pending' ORDER BY requested_at DESC LIMIT 1",
|
|
265
|
+
[nestId, nodeId]
|
|
266
|
+
);
|
|
244
267
|
return row ? rowToReviewRequest(row) : null;
|
|
245
268
|
}
|
|
246
|
-
function getReviewRequest(id) {
|
|
269
|
+
async function getReviewRequest(id) {
|
|
247
270
|
const db = getDb();
|
|
248
|
-
const row = db.
|
|
271
|
+
const row = await db.get(
|
|
272
|
+
"SELECT * FROM review_requests WHERE id = ?",
|
|
273
|
+
[id]
|
|
274
|
+
);
|
|
249
275
|
return row ? rowToReviewRequest(row) : null;
|
|
250
276
|
}
|
|
251
277
|
function rowToReviewRequest(row) {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
|
-
getDb
|
|
3
|
-
|
|
2
|
+
getDb,
|
|
3
|
+
insertOrReplace,
|
|
4
|
+
nowExpr
|
|
5
|
+
} from "./chunk-7V33Z6CS.js";
|
|
4
6
|
|
|
5
7
|
// src/governance/version-service.ts
|
|
6
8
|
import { createHash } from "crypto";
|
|
@@ -11,21 +13,22 @@ var SYSTEM_AUTHOR_PREFIX = "system:auto-publish:";
|
|
|
11
13
|
function systemAuthor(email) {
|
|
12
14
|
return `${SYSTEM_AUTHOR_PREFIX}${email}`;
|
|
13
15
|
}
|
|
14
|
-
function createVersion(params) {
|
|
16
|
+
async function createVersion(params) {
|
|
15
17
|
const db = getDb();
|
|
16
18
|
const contentHash = hashContent(params.content);
|
|
17
|
-
db.
|
|
19
|
+
await db.run(
|
|
18
20
|
`INSERT INTO node_versions (nest_id, node_id, version, content_hash, author, status, change_note, tags_json)
|
|
19
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
21
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
22
|
+
[
|
|
23
|
+
params.nestId,
|
|
24
|
+
params.nodeId,
|
|
25
|
+
params.version,
|
|
26
|
+
contentHash,
|
|
27
|
+
params.author,
|
|
28
|
+
params.status,
|
|
29
|
+
params.changeNote || null,
|
|
30
|
+
params.tags ? JSON.stringify(params.tags) : null
|
|
31
|
+
]
|
|
29
32
|
);
|
|
30
33
|
return {
|
|
31
34
|
version: params.version,
|
|
@@ -36,53 +39,62 @@ function createVersion(params) {
|
|
|
36
39
|
status: params.status
|
|
37
40
|
};
|
|
38
41
|
}
|
|
39
|
-
function getVersions(nestId, nodeId) {
|
|
42
|
+
async function getVersions(nestId, nodeId) {
|
|
40
43
|
const db = getDb();
|
|
41
|
-
const rows = db.
|
|
42
|
-
"SELECT * FROM node_versions WHERE nest_id = ? AND node_id = ? ORDER BY version DESC"
|
|
43
|
-
|
|
44
|
+
const rows = await db.all(
|
|
45
|
+
"SELECT * FROM node_versions WHERE nest_id = ? AND node_id = ? ORDER BY version DESC",
|
|
46
|
+
[nestId, nodeId]
|
|
47
|
+
);
|
|
44
48
|
return rows.map(rowToVersion);
|
|
45
49
|
}
|
|
46
|
-
function getVersion(nestId, nodeId, version) {
|
|
50
|
+
async function getVersion(nestId, nodeId, version) {
|
|
47
51
|
const db = getDb();
|
|
48
|
-
const row = db.
|
|
49
|
-
"SELECT * FROM node_versions WHERE nest_id = ? AND node_id = ? AND version = ?"
|
|
50
|
-
|
|
52
|
+
const row = await db.get(
|
|
53
|
+
"SELECT * FROM node_versions WHERE nest_id = ? AND node_id = ? AND version = ?",
|
|
54
|
+
[nestId, nodeId, version]
|
|
55
|
+
);
|
|
51
56
|
return row ? rowToVersion(row) : null;
|
|
52
57
|
}
|
|
53
|
-
function getCurrentVersion(nestId, nodeId) {
|
|
58
|
+
async function getCurrentVersion(nestId, nodeId) {
|
|
54
59
|
const db = getDb();
|
|
55
|
-
const row = db.
|
|
60
|
+
const row = await db.get(
|
|
56
61
|
`SELECT MAX(version) as v FROM node_versions
|
|
57
62
|
WHERE nest_id = ? AND node_id = ?
|
|
58
|
-
AND author NOT LIKE
|
|
59
|
-
|
|
63
|
+
AND author NOT LIKE ?`,
|
|
64
|
+
[nestId, nodeId, `${SYSTEM_AUTHOR_PREFIX}%`]
|
|
65
|
+
);
|
|
60
66
|
return row?.v || 0;
|
|
61
67
|
}
|
|
62
|
-
function getApprovedVersion(nestId, nodeId) {
|
|
68
|
+
async function getApprovedVersion(nestId, nodeId) {
|
|
63
69
|
const db = getDb();
|
|
64
|
-
const row = db.
|
|
65
|
-
"SELECT approved_version FROM approved_versions WHERE nest_id = ? AND node_id = ?"
|
|
66
|
-
|
|
70
|
+
const row = await db.get(
|
|
71
|
+
"SELECT approved_version FROM approved_versions WHERE nest_id = ? AND node_id = ?",
|
|
72
|
+
[nestId, nodeId]
|
|
73
|
+
);
|
|
67
74
|
return row?.approved_version ?? null;
|
|
68
75
|
}
|
|
69
|
-
function setApprovedVersion(nestId, nodeId, version, approvedBy) {
|
|
76
|
+
async function setApprovedVersion(nestId, nodeId, version, approvedBy) {
|
|
70
77
|
const db = getDb();
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
78
|
+
const sql = insertOrReplace(
|
|
79
|
+
db,
|
|
80
|
+
`INSERT INTO approved_versions (nest_id, node_id, approved_version, approved_by)
|
|
81
|
+
VALUES (?, ?, ?, ?)`,
|
|
82
|
+
["nest_id", "node_id"],
|
|
83
|
+
`approved_version = excluded.approved_version, approved_by = excluded.approved_by, approved_at = ${nowExpr(db)}`
|
|
84
|
+
);
|
|
85
|
+
await db.run(sql, [nestId, nodeId, version, approvedBy]);
|
|
75
86
|
}
|
|
76
|
-
function checkConflict(nestId, nodeId, baseVersion) {
|
|
87
|
+
async function checkConflict(nestId, nodeId, baseVersion) {
|
|
77
88
|
const db = getDb();
|
|
78
|
-
const current = db.
|
|
89
|
+
const current = await db.get(
|
|
79
90
|
`SELECT version, content_hash, author, created_at
|
|
80
91
|
FROM node_versions
|
|
81
92
|
WHERE nest_id = ? AND node_id = ?
|
|
82
93
|
AND author NOT LIKE ?
|
|
83
94
|
ORDER BY version DESC
|
|
84
|
-
LIMIT 1
|
|
85
|
-
|
|
95
|
+
LIMIT 1`,
|
|
96
|
+
[nestId, nodeId, `${SYSTEM_AUTHOR_PREFIX}%`]
|
|
97
|
+
);
|
|
86
98
|
if (!current) {
|
|
87
99
|
return { conflict: false, currentVersion: 0, currentHash: "" };
|
|
88
100
|
}
|
|
@@ -101,11 +113,12 @@ function checkConflict(nestId, nodeId, baseVersion) {
|
|
|
101
113
|
currentHash: current.content_hash
|
|
102
114
|
};
|
|
103
115
|
}
|
|
104
|
-
function getNodeTags(nestId, nodeId) {
|
|
116
|
+
async function getNodeTags(nestId, nodeId) {
|
|
105
117
|
const db = getDb();
|
|
106
|
-
const row = db.
|
|
107
|
-
"SELECT tags_json FROM node_versions WHERE nest_id = ? AND node_id = ? ORDER BY version DESC LIMIT 1"
|
|
108
|
-
|
|
118
|
+
const row = await db.get(
|
|
119
|
+
"SELECT tags_json FROM node_versions WHERE nest_id = ? AND node_id = ? ORDER BY version DESC LIMIT 1",
|
|
120
|
+
[nestId, nodeId]
|
|
121
|
+
);
|
|
109
122
|
if (!row?.tags_json) return [];
|
|
110
123
|
try {
|
|
111
124
|
return JSON.parse(row.tags_json);
|
|
@@ -113,22 +126,25 @@ function getNodeTags(nestId, nodeId) {
|
|
|
113
126
|
return [];
|
|
114
127
|
}
|
|
115
128
|
}
|
|
116
|
-
function getDisplayStatus(nestId, nodeId) {
|
|
129
|
+
async function getDisplayStatus(nestId, nodeId) {
|
|
117
130
|
const db = getDb();
|
|
118
|
-
const pending = db.
|
|
119
|
-
"SELECT 1 FROM review_requests WHERE nest_id = ? AND node_id = ? AND status = 'pending' LIMIT 1"
|
|
120
|
-
|
|
131
|
+
const pending = await db.get(
|
|
132
|
+
"SELECT 1 FROM review_requests WHERE nest_id = ? AND node_id = ? AND status = 'pending' LIMIT 1",
|
|
133
|
+
[nestId, nodeId]
|
|
134
|
+
);
|
|
121
135
|
if (pending) return "pending_review";
|
|
122
|
-
const current = db.
|
|
136
|
+
const current = await db.get(
|
|
123
137
|
`SELECT version, status FROM node_versions
|
|
124
138
|
WHERE nest_id = ? AND node_id = ?
|
|
125
|
-
ORDER BY version DESC LIMIT 1
|
|
126
|
-
|
|
139
|
+
ORDER BY version DESC LIMIT 1`,
|
|
140
|
+
[nestId, nodeId]
|
|
141
|
+
);
|
|
127
142
|
if (!current) return "draft";
|
|
128
143
|
if (current.status === "published" || current.status === "approved") {
|
|
129
|
-
const approved = db.
|
|
130
|
-
"SELECT approved_version FROM approved_versions WHERE nest_id = ? AND node_id = ?"
|
|
131
|
-
|
|
144
|
+
const approved = await db.get(
|
|
145
|
+
"SELECT approved_version FROM approved_versions WHERE nest_id = ? AND node_id = ?",
|
|
146
|
+
[nestId, nodeId]
|
|
147
|
+
);
|
|
132
148
|
if (approved?.approved_version === current.version) {
|
|
133
149
|
return current.status === "published" ? "published" : "approved";
|
|
134
150
|
}
|