@jungjaehoon/mama-core 1.9.0 → 2.1.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/db/migrations/043-add-tool-trace-failure-code.sql +11 -0
- package/dist/agent-graph/alias-write.js +3 -0
- package/dist/agent-graph/entity-resolve.js +3 -7
- package/dist/agent-graph/graph-query.js +5 -4
- package/dist/agent-graph/types.d.ts +30 -0
- package/dist/cases/store.d.ts +0 -4
- package/dist/cases/store.js +0 -66
- package/dist/cases/wiki-page-index.d.ts +0 -13
- package/dist/cases/wiki-page-index.js +0 -153
- package/dist/connectors/event-index.d.ts +1 -22
- package/dist/connectors/event-index.js +0 -157
- package/dist/context-compile/channel-grant.d.ts +46 -0
- package/dist/context-compile/channel-grant.js +66 -0
- package/dist/context-compile/compiler.js +5 -2
- package/dist/context-compile/index.d.ts +1 -0
- package/dist/context-compile/index.js +1 -0
- package/dist/context-compile/packet-store.d.ts +0 -1
- package/dist/context-compile/packet-store.js +0 -16
- package/dist/context-compile/source-readers.d.ts +1 -0
- package/dist/context-compile/source-readers.js +156 -23
- package/dist/context-compile/types.d.ts +17 -0
- package/dist/context-compile/visibility.js +28 -4
- package/dist/db-adapter/node-sqlite-adapter.js +4 -0
- package/dist/db-manager.d.ts +0 -13
- package/dist/db-manager.js +0 -66
- package/dist/decision-formatter.d.ts +0 -11
- package/dist/decision-formatter.js +0 -122
- package/dist/decision-tracker.d.ts +0 -12
- package/dist/decision-tracker.js +0 -50
- package/dist/edges/ref-validation.d.ts +1 -2
- package/dist/edges/ref-validation.js +33 -13
- package/dist/edges/store.d.ts +1 -3
- package/dist/edges/store.js +0 -214
- package/dist/edges/types.d.ts +10 -0
- package/dist/embedding-client.d.ts +0 -17
- package/dist/embedding-client.js +0 -80
- package/dist/embedding-server/mobile/auth.d.ts +1 -10
- package/dist/embedding-server/mobile/auth.js +0 -15
- package/dist/embeddings.d.ts +0 -12
- package/dist/embeddings.js +0 -68
- package/dist/entities/audit-metrics.d.ts +0 -5
- package/dist/entities/audit-metrics.js +0 -4
- package/dist/entities/candidate-generator.d.ts +1 -2
- package/dist/entities/candidate-generator.js +0 -412
- package/dist/entities/entity-list.d.ts +0 -1
- package/dist/entities/entity-list.js +0 -96
- package/dist/entities/entity-orphan-list.d.ts +0 -9
- package/dist/entities/entity-orphan-list.js +0 -88
- package/dist/entities/entity-search.d.ts +0 -1
- package/dist/entities/entity-search.js +0 -147
- package/dist/entities/errors.d.ts +0 -10
- package/dist/entities/errors.js +1 -25
- package/dist/entities/lineage-store.d.ts +0 -23
- package/dist/entities/lineage-store.js +0 -104
- package/dist/entities/policy-store.d.ts +0 -9
- package/dist/entities/policy-store.js +0 -188
- package/dist/entities/provenance-query.d.ts +0 -1
- package/dist/entities/provenance-query.js +0 -164
- package/dist/entities/resolution-engine.d.ts +1 -8
- package/dist/entities/resolution-engine.js +0 -66
- package/dist/entities/rollback-preview.d.ts +0 -4
- package/dist/entities/rollback-preview.js +0 -232
- package/dist/entities/store.d.ts +1 -10
- package/dist/entities/store.js +0 -49
- package/dist/index.d.ts +15 -31
- package/dist/index.js +4 -46
- package/dist/mama-api.d.ts +19 -1
- package/dist/mama-api.js +97 -2
- package/dist/memory/api.d.ts +8 -0
- package/dist/memory/api.js +55 -2
- package/dist/memory/event-store.d.ts +0 -1
- package/dist/memory/event-store.js +0 -15
- package/dist/memory/finding-store.d.ts +0 -1
- package/dist/memory/finding-store.js +0 -12
- package/dist/memory/scope-backfill.d.ts +0 -3
- package/dist/memory/scope-backfill.js +0 -74
- package/dist/memory/scope-store.d.ts +0 -1
- package/dist/memory/scope-store.js +0 -4
- package/dist/memory/truth-store.d.ts +0 -3
- package/dist/memory/truth-store.js +0 -22
- package/dist/memory/types.d.ts +0 -1
- package/dist/memory/types.js +0 -13
- package/dist/memory-store.d.ts +0 -16
- package/dist/memory-store.js +0 -51
- package/dist/model-runs/tool-trace-store.js +9 -5
- package/dist/model-runs/types.d.ts +3 -0
- package/dist/ollama-client.d.ts +0 -9
- package/dist/ollama-client.js +0 -125
- package/dist/outcome-tracker.d.ts +0 -14
- package/dist/outcome-tracker.js +0 -44
- package/dist/progress-indicator.d.ts +0 -4
- package/dist/progress-indicator.js +0 -7
- package/dist/provenance/source-ref.d.ts +0 -9
- package/dist/provenance/source-ref.js +0 -145
- package/dist/query-intent.d.ts +0 -4
- package/dist/query-intent.js +0 -30
- package/dist/relevance-scorer.d.ts +0 -9
- package/dist/relevance-scorer.js +0 -81
- package/dist/search/feedback-store.d.ts +0 -1
- package/dist/search/feedback-store.js +0 -4
- package/dist/search/ranker-rescore.d.ts +0 -3
- package/dist/search/ranker-rescore.js +0 -27
- package/dist/search/ranker-trainer.d.ts +0 -8
- package/dist/search/ranker-trainer.js +0 -376
- package/dist/tier-validator.d.ts +0 -12
- package/dist/tier-validator.js +0 -56
- package/package.json +1 -10
- package/dist/cases/case-links.d.ts +0 -116
- package/dist/cases/case-links.js +0 -794
- package/dist/cases/composition-overrides.d.ts +0 -90
- package/dist/cases/composition-overrides.js +0 -724
- package/dist/cases/corrections.d.ts +0 -156
- package/dist/cases/corrections.js +0 -1045
- package/dist/cases/freshness.d.ts +0 -57
- package/dist/cases/freshness.js +0 -283
- package/dist/cases/live-state.d.ts +0 -48
- package/dist/cases/live-state.js +0 -256
- package/dist/cases/membership-explain.d.ts +0 -56
- package/dist/cases/membership-explain.js +0 -140
- package/dist/cases/membership-matcher.d.ts +0 -23
- package/dist/cases/membership-matcher.js +0 -193
- package/dist/cases/merge-split.d.ts +0 -61
- package/dist/cases/merge-split.js +0 -368
- package/dist/cases/role-inference.d.ts +0 -10
- package/dist/cases/role-inference.js +0 -85
- package/dist/cases/sqlite-transaction.d.ts +0 -10
- package/dist/cases/sqlite-transaction.js +0 -62
- package/dist/cases/target-ref.d.ts +0 -25
- package/dist/cases/target-ref.js +0 -22
- package/dist/cases/tombstone-sweeper.d.ts +0 -13
- package/dist/cases/tombstone-sweeper.js +0 -128
- package/dist/entities/entity-impact.d.ts +0 -41
- package/dist/entities/entity-impact.js +0 -140
- package/dist/entities/exact-merge-backfill.d.ts +0 -11
- package/dist/entities/exact-merge-backfill.js +0 -161
- package/dist/entities/lineage-backfill.d.ts +0 -12
- package/dist/entities/lineage-backfill.js +0 -101
- package/dist/memory-inject.d.ts +0 -24
- package/dist/memory-inject.js +0 -116
|
@@ -1,150 +1,3 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.searchCanonicalEntities = searchCanonicalEntities;
|
|
4
|
-
const db_manager_js_1 = require("../db-manager.js");
|
|
5
|
-
const entity_linked_decision_counts_js_1 = require("./entity-linked-decision-counts.js");
|
|
6
|
-
const store_js_1 = require("./store.js");
|
|
7
|
-
function normalizeSearchLabel(input) {
|
|
8
|
-
return input.normalize('NFKC').trim().replace(/\s+/gu, ' ').toLowerCase();
|
|
9
|
-
}
|
|
10
|
-
function buildSearchCollapseKey(row) {
|
|
11
|
-
return JSON.stringify([
|
|
12
|
-
row.kind,
|
|
13
|
-
row.scope_kind,
|
|
14
|
-
row.scope_id ?? '',
|
|
15
|
-
normalizeSearchLabel(row.preferred_label),
|
|
16
|
-
]);
|
|
17
|
-
}
|
|
18
|
-
function escapeLikeQuery(query) {
|
|
19
|
-
return query.replace(/[\\%_]/g, '\\$&');
|
|
20
|
-
}
|
|
21
|
-
function decodeCursor(cursor) {
|
|
22
|
-
if (!cursor) {
|
|
23
|
-
return 0;
|
|
24
|
-
}
|
|
25
|
-
try {
|
|
26
|
-
const decoded = Number(Buffer.from(cursor, 'base64').toString('utf8'));
|
|
27
|
-
return Number.isFinite(decoded) && decoded >= 0 ? decoded : 0;
|
|
28
|
-
}
|
|
29
|
-
catch {
|
|
30
|
-
return 0;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
function encodeCursor(offset) {
|
|
34
|
-
return Buffer.from(String(offset), 'utf8').toString('base64');
|
|
35
|
-
}
|
|
36
|
-
async function searchCanonicalEntities(input) {
|
|
37
|
-
await (0, db_manager_js_1.initDB)();
|
|
38
|
-
const adapter = (0, db_manager_js_1.getAdapter)();
|
|
39
|
-
const query = input.query.trim();
|
|
40
|
-
if (!query) {
|
|
41
|
-
return { entities: [], next_cursor: null };
|
|
42
|
-
}
|
|
43
|
-
const escaped = escapeLikeQuery(query);
|
|
44
|
-
const normalizedQuery = normalizeSearchLabel(query);
|
|
45
|
-
const rows = adapter
|
|
46
|
-
.prepare(`
|
|
47
|
-
SELECT
|
|
48
|
-
n.id AS matched_id,
|
|
49
|
-
n.preferred_label,
|
|
50
|
-
n.kind,
|
|
51
|
-
n.scope_kind,
|
|
52
|
-
n.scope_id,
|
|
53
|
-
a.label AS alias_label,
|
|
54
|
-
o.surface_form AS observation_surface_form
|
|
55
|
-
FROM entity_nodes n
|
|
56
|
-
LEFT JOIN entity_aliases a ON a.entity_id = n.id
|
|
57
|
-
LEFT JOIN entity_lineage_links l ON l.canonical_entity_id = n.id AND l.status = 'active'
|
|
58
|
-
LEFT JOIN entity_observations o ON o.id = l.entity_observation_id
|
|
59
|
-
WHERE (
|
|
60
|
-
lower(n.preferred_label) LIKE '%' || lower(?) || '%' ESCAPE '\\'
|
|
61
|
-
OR lower(COALESCE(a.label, '')) LIKE '%' || lower(?) || '%' ESCAPE '\\'
|
|
62
|
-
OR lower(COALESCE(o.surface_form, '')) LIKE '%' || lower(?) || '%' ESCAPE '\\'
|
|
63
|
-
)
|
|
64
|
-
`)
|
|
65
|
-
.all(escaped, escaped, escaped);
|
|
66
|
-
const canonicalIdByMatchedId = new Map();
|
|
67
|
-
for (const matchedId of new Set(rows.map((row) => row.matched_id))) {
|
|
68
|
-
try {
|
|
69
|
-
canonicalIdByMatchedId.set(matchedId, (0, store_js_1.resolveCanonicalEntityId)(adapter, matchedId));
|
|
70
|
-
}
|
|
71
|
-
catch (error) {
|
|
72
|
-
if (error instanceof store_js_1.EntityMergeError) {
|
|
73
|
-
continue;
|
|
74
|
-
}
|
|
75
|
-
throw error;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
const canonicalIds = Array.from(new Set(canonicalIdByMatchedId.values()));
|
|
79
|
-
const canonicalLookup = new Map();
|
|
80
|
-
if (canonicalIds.length > 0) {
|
|
81
|
-
const fetched = adapter
|
|
82
|
-
.prepare(`
|
|
83
|
-
SELECT id, kind, preferred_label, scope_kind, scope_id
|
|
84
|
-
FROM entity_nodes
|
|
85
|
-
WHERE id IN (${canonicalIds.map(() => '?').join(', ')})
|
|
86
|
-
AND status = 'active'
|
|
87
|
-
AND merged_into IS NULL
|
|
88
|
-
`)
|
|
89
|
-
.all(...canonicalIds);
|
|
90
|
-
for (const row of fetched) {
|
|
91
|
-
canonicalLookup.set(row.id, row);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
const canonicalRows = new Map();
|
|
95
|
-
for (const row of rows) {
|
|
96
|
-
const canonicalId = canonicalIdByMatchedId.get(row.matched_id);
|
|
97
|
-
const canonical = canonicalId ? canonicalLookup.get(canonicalId) : undefined;
|
|
98
|
-
if (!canonical) {
|
|
99
|
-
continue;
|
|
100
|
-
}
|
|
101
|
-
const score = normalizeSearchLabel(row.preferred_label).includes(normalizedQuery)
|
|
102
|
-
? 3
|
|
103
|
-
: row.alias_label && normalizeSearchLabel(row.alias_label).includes(normalizedQuery)
|
|
104
|
-
? 2
|
|
105
|
-
: 1;
|
|
106
|
-
const existing = canonicalRows.get(canonical.id);
|
|
107
|
-
if (!existing || score > existing.score) {
|
|
108
|
-
canonicalRows.set(canonical.id, {
|
|
109
|
-
id: canonical.id,
|
|
110
|
-
kind: canonical.kind,
|
|
111
|
-
preferred_label: canonical.preferred_label,
|
|
112
|
-
scope_kind: canonical.scope_kind,
|
|
113
|
-
scope_id: canonical.scope_id,
|
|
114
|
-
score,
|
|
115
|
-
linked_decision_count: 0,
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
const collapsedRows = new Map();
|
|
120
|
-
for (const row of canonicalRows.values()) {
|
|
121
|
-
const key = buildSearchCollapseKey(row);
|
|
122
|
-
const existing = collapsedRows.get(key);
|
|
123
|
-
if (!existing ||
|
|
124
|
-
row.score > existing.score ||
|
|
125
|
-
(row.score === existing.score && row.id.localeCompare(existing.id) < 0)) {
|
|
126
|
-
collapsedRows.set(key, row);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
const sorted = Array.from(collapsedRows.values()).sort((left, right) => {
|
|
130
|
-
if (right.score !== left.score) {
|
|
131
|
-
return right.score - left.score;
|
|
132
|
-
}
|
|
133
|
-
const labelCompare = left.preferred_label.localeCompare(right.preferred_label);
|
|
134
|
-
if (labelCompare !== 0) {
|
|
135
|
-
return labelCompare;
|
|
136
|
-
}
|
|
137
|
-
return left.id.localeCompare(right.id);
|
|
138
|
-
});
|
|
139
|
-
const offset = decodeCursor(input.cursor);
|
|
140
|
-
const limit = Math.max(1, input.limit);
|
|
141
|
-
const page = sorted.slice(offset, offset + limit);
|
|
142
|
-
const linkedCounts = (0, entity_linked_decision_counts_js_1.loadLinkedDecisionCounts)(adapter, page.map((row) => row.id));
|
|
143
|
-
const entities = page.map((row) => ({
|
|
144
|
-
...row,
|
|
145
|
-
linked_decision_count: linkedCounts.get(row.id) ?? 0,
|
|
146
|
-
}));
|
|
147
|
-
const next_cursor = offset + limit < sorted.length ? encodeCursor(offset + limit) : null;
|
|
148
|
-
return { entities, next_cursor };
|
|
149
|
-
}
|
|
150
3
|
//# sourceMappingURL=entity-search.js.map
|
|
@@ -33,21 +33,11 @@ export declare class OntologyViolationError extends EntityError {
|
|
|
33
33
|
readonly doc_section = "#ontology-violation";
|
|
34
34
|
constructor(context?: Record<string, unknown>);
|
|
35
35
|
}
|
|
36
|
-
export declare class MergeTargetStaleError extends EntityError {
|
|
37
|
-
readonly code = "entity.merge_target_stale";
|
|
38
|
-
readonly doc_section = "#merge-target-stale";
|
|
39
|
-
constructor(context?: Record<string, unknown>);
|
|
40
|
-
}
|
|
41
36
|
export declare class EntityLabelMissingError extends EntityError {
|
|
42
37
|
readonly code = "entity.label_missing";
|
|
43
38
|
readonly doc_section = "#label-missing";
|
|
44
39
|
constructor(context?: Record<string, unknown>);
|
|
45
40
|
}
|
|
46
|
-
export declare class CandidateStaleError extends EntityError {
|
|
47
|
-
readonly code = "entity.candidate_stale";
|
|
48
|
-
readonly doc_section = "#candidate-stale";
|
|
49
|
-
constructor(context?: Record<string, unknown>);
|
|
50
|
-
}
|
|
51
41
|
export declare class AuditRunInProgressError extends EntityError {
|
|
52
42
|
readonly code = "entity.audit_run_in_progress";
|
|
53
43
|
readonly doc_section = "#audit-run-in-progress";
|
package/dist/entities/errors.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CaseMergeChainCycleError = exports.AuditRunInProgressError = exports.
|
|
3
|
+
exports.CaseMergeChainCycleError = exports.AuditRunInProgressError = exports.EntityLabelMissingError = exports.OntologyViolationError = exports.EmbeddingUnavailableError = exports.InvalidEntityLabelError = exports.EntityError = void 0;
|
|
4
4
|
class EntityError extends Error {
|
|
5
5
|
context;
|
|
6
6
|
hint;
|
|
@@ -61,18 +61,6 @@ class OntologyViolationError extends EntityError {
|
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
exports.OntologyViolationError = OntologyViolationError;
|
|
64
|
-
class MergeTargetStaleError extends EntityError {
|
|
65
|
-
code = 'entity.merge_target_stale';
|
|
66
|
-
doc_section = '#merge-target-stale';
|
|
67
|
-
constructor(context = {}) {
|
|
68
|
-
super({
|
|
69
|
-
message: 'Merge target is stale.',
|
|
70
|
-
context,
|
|
71
|
-
hint: 'Reload the target entity state and retry the merge against the latest version.',
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
exports.MergeTargetStaleError = MergeTargetStaleError;
|
|
76
64
|
class EntityLabelMissingError extends EntityError {
|
|
77
65
|
code = 'entity.label_missing';
|
|
78
66
|
doc_section = '#label-missing';
|
|
@@ -85,18 +73,6 @@ class EntityLabelMissingError extends EntityError {
|
|
|
85
73
|
}
|
|
86
74
|
}
|
|
87
75
|
exports.EntityLabelMissingError = EntityLabelMissingError;
|
|
88
|
-
class CandidateStaleError extends EntityError {
|
|
89
|
-
code = 'entity.candidate_stale';
|
|
90
|
-
doc_section = '#candidate-stale';
|
|
91
|
-
constructor(context = {}) {
|
|
92
|
-
super({
|
|
93
|
-
message: 'Resolution candidate is stale.',
|
|
94
|
-
context,
|
|
95
|
-
hint: 'Refresh the candidate list and review the latest evidence before acting.',
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
exports.CandidateStaleError = CandidateStaleError;
|
|
100
76
|
class AuditRunInProgressError extends EntityError {
|
|
101
77
|
code = 'entity.audit_run_in_progress';
|
|
102
78
|
doc_section = '#audit-run-in-progress';
|
|
@@ -1,18 +1,7 @@
|
|
|
1
1
|
import type { DatabaseAdapter } from '../db-manager.js';
|
|
2
2
|
import type { EntityIngestRun, EntityLineageLink } from './types.js';
|
|
3
3
|
import type { EntityStoreAdapter } from './store.js';
|
|
4
|
-
type CreateEntityIngestRunInput = Omit<EntityIngestRun, 'status' | 'raw_count' | 'observation_count' | 'candidate_count' | 'reviewable_count' | 'audit_run_id' | 'audit_classification' | 'error_reason' | 'created_at' | 'completed_at'> & {
|
|
5
|
-
id?: string;
|
|
6
|
-
};
|
|
7
4
|
type AppendEntityLineageLinkInput = Omit<EntityLineageLink, 'id' | 'status' | 'created_at' | 'superseded_at'>;
|
|
8
|
-
interface CompleteEntityIngestRunInput {
|
|
9
|
-
raw_count: number;
|
|
10
|
-
observation_count: number;
|
|
11
|
-
candidate_count: number;
|
|
12
|
-
reviewable_count: number;
|
|
13
|
-
audit_run_id?: string | null;
|
|
14
|
-
audit_classification?: EntityIngestRun['audit_classification'];
|
|
15
|
-
}
|
|
16
5
|
interface AdoptLineageAfterMergeInput {
|
|
17
6
|
adapter?: LineageMutationAdapter;
|
|
18
7
|
source_entity_id: string;
|
|
@@ -31,19 +20,7 @@ interface AdoptLineageAfterMergeSyncInput extends Omit<AdoptLineageAfterMergeInp
|
|
|
31
20
|
adapter: LineageMutationAdapter;
|
|
32
21
|
}
|
|
33
22
|
export declare function parseEntityIngestRunRow(row: Record<string, unknown>): EntityIngestRun;
|
|
34
|
-
export declare function createEntityIngestRun(input: CreateEntityIngestRunInput): Promise<EntityIngestRun>;
|
|
35
|
-
export declare function completeEntityIngestRun(id: string, input: CompleteEntityIngestRunInput): Promise<EntityIngestRun>;
|
|
36
|
-
export declare function failEntityIngestRun(id: string, errorReason: string): Promise<EntityIngestRun>;
|
|
37
23
|
export declare function appendEntityLineageLink(input: AppendEntityLineageLinkInput): Promise<AppendEntityLineageLinkResult>;
|
|
38
|
-
export declare function supersedeEntityLineageForEntity(entityId: string): Promise<number>;
|
|
39
|
-
export declare function seedLineageForEntityMaterialization(input: {
|
|
40
|
-
canonical_entity_id: string;
|
|
41
|
-
entity_observation_id: string;
|
|
42
|
-
run_id?: string | null;
|
|
43
|
-
confidence?: number;
|
|
44
|
-
capture_mode?: EntityLineageLink['capture_mode'];
|
|
45
|
-
}): Promise<EntityLineageLink>;
|
|
46
|
-
export declare function adoptLineageAfterMerge(input: AdoptLineageAfterMergeInput): Promise<EntityLineageLink[]>;
|
|
47
24
|
export declare function adoptLineageAfterMergeSync(input: AdoptLineageAfterMergeSyncInput): EntityLineageLink[];
|
|
48
25
|
export declare function listActiveEntityLineage(entityId: string, adapter?: EntityStoreAdapter): Promise<EntityLineageLink[]>;
|
|
49
26
|
export declare function listEntityLineageHistory(entityId: string, adapter?: EntityStoreAdapter): Promise<EntityLineageLink[]>;
|
|
@@ -1,13 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.parseEntityIngestRunRow = parseEntityIngestRunRow;
|
|
4
|
-
exports.createEntityIngestRun = createEntityIngestRun;
|
|
5
|
-
exports.completeEntityIngestRun = completeEntityIngestRun;
|
|
6
|
-
exports.failEntityIngestRun = failEntityIngestRun;
|
|
7
4
|
exports.appendEntityLineageLink = appendEntityLineageLink;
|
|
8
|
-
exports.supersedeEntityLineageForEntity = supersedeEntityLineageForEntity;
|
|
9
|
-
exports.seedLineageForEntityMaterialization = seedLineageForEntityMaterialization;
|
|
10
|
-
exports.adoptLineageAfterMerge = adoptLineageAfterMerge;
|
|
11
5
|
exports.adoptLineageAfterMergeSync = adoptLineageAfterMergeSync;
|
|
12
6
|
exports.listActiveEntityLineage = listActiveEntityLineage;
|
|
13
7
|
exports.listEntityLineageHistory = listEntityLineageHistory;
|
|
@@ -55,67 +49,6 @@ function parseEntityLineageLinkRow(row) {
|
|
|
55
49
|
superseded_at: typeof row.superseded_at === 'number' ? row.superseded_at : null,
|
|
56
50
|
};
|
|
57
51
|
}
|
|
58
|
-
async function createEntityIngestRun(input) {
|
|
59
|
-
await (0, db_manager_js_1.initDB)();
|
|
60
|
-
const adapter = (0, db_manager_js_1.getAdapter)();
|
|
61
|
-
const createdAt = now();
|
|
62
|
-
const id = input.id || `eir_${(0, node_crypto_1.randomUUID)()}`;
|
|
63
|
-
adapter
|
|
64
|
-
.prepare(`
|
|
65
|
-
INSERT INTO entity_ingest_runs (
|
|
66
|
-
id, connector, run_kind, status, scope_key, source_window_start, source_window_end,
|
|
67
|
-
raw_count, observation_count, candidate_count, reviewable_count, audit_run_id,
|
|
68
|
-
audit_classification, error_reason, created_at, completed_at
|
|
69
|
-
) VALUES (?, ?, ?, 'running', ?, ?, ?, 0, 0, 0, 0, NULL, NULL, NULL, ?, NULL)
|
|
70
|
-
`)
|
|
71
|
-
.run(id, input.connector, input.run_kind, input.scope_key, input.source_window_start, input.source_window_end, createdAt);
|
|
72
|
-
const row = adapter.prepare(`SELECT * FROM entity_ingest_runs WHERE id = ?`).get(id);
|
|
73
|
-
return parseEntityIngestRunRow(row);
|
|
74
|
-
}
|
|
75
|
-
async function completeEntityIngestRun(id, input) {
|
|
76
|
-
await (0, db_manager_js_1.initDB)();
|
|
77
|
-
const adapter = (0, db_manager_js_1.getAdapter)();
|
|
78
|
-
const completedAt = now();
|
|
79
|
-
const completion = adapter
|
|
80
|
-
.prepare(`
|
|
81
|
-
UPDATE entity_ingest_runs
|
|
82
|
-
SET status = 'complete',
|
|
83
|
-
raw_count = ?,
|
|
84
|
-
observation_count = ?,
|
|
85
|
-
candidate_count = ?,
|
|
86
|
-
reviewable_count = ?,
|
|
87
|
-
audit_run_id = ?,
|
|
88
|
-
audit_classification = ?,
|
|
89
|
-
error_reason = NULL,
|
|
90
|
-
completed_at = ?
|
|
91
|
-
WHERE id = ?
|
|
92
|
-
`)
|
|
93
|
-
.run(input.raw_count, input.observation_count, input.candidate_count, input.reviewable_count, input.audit_run_id ?? null, input.audit_classification ?? null, completedAt, id);
|
|
94
|
-
if (completion.changes !== 1) {
|
|
95
|
-
throw new Error(`Entity ingest run not found: ${id}`);
|
|
96
|
-
}
|
|
97
|
-
const row = adapter.prepare(`SELECT * FROM entity_ingest_runs WHERE id = ?`).get(id);
|
|
98
|
-
return parseEntityIngestRunRow(row);
|
|
99
|
-
}
|
|
100
|
-
async function failEntityIngestRun(id, errorReason) {
|
|
101
|
-
await (0, db_manager_js_1.initDB)();
|
|
102
|
-
const adapter = (0, db_manager_js_1.getAdapter)();
|
|
103
|
-
const completedAt = now();
|
|
104
|
-
const completion = adapter
|
|
105
|
-
.prepare(`
|
|
106
|
-
UPDATE entity_ingest_runs
|
|
107
|
-
SET status = 'failed',
|
|
108
|
-
error_reason = ?,
|
|
109
|
-
completed_at = ?
|
|
110
|
-
WHERE id = ?
|
|
111
|
-
`)
|
|
112
|
-
.run(errorReason, completedAt, id);
|
|
113
|
-
if (completion.changes !== 1) {
|
|
114
|
-
throw new Error(`Entity ingest run not found: ${id}`);
|
|
115
|
-
}
|
|
116
|
-
const row = adapter.prepare(`SELECT * FROM entity_ingest_runs WHERE id = ?`).get(id);
|
|
117
|
-
return parseEntityIngestRunRow(row);
|
|
118
|
-
}
|
|
119
52
|
async function appendEntityLineageLink(input) {
|
|
120
53
|
await (0, db_manager_js_1.initDB)();
|
|
121
54
|
const adapter = (0, db_manager_js_1.getAdapter)();
|
|
@@ -155,35 +88,6 @@ async function appendEntityLineageLink(input) {
|
|
|
155
88
|
created: true,
|
|
156
89
|
};
|
|
157
90
|
}
|
|
158
|
-
async function supersedeEntityLineageForEntity(entityId) {
|
|
159
|
-
await (0, db_manager_js_1.initDB)();
|
|
160
|
-
const adapter = (0, db_manager_js_1.getAdapter)();
|
|
161
|
-
const supersededAt = now();
|
|
162
|
-
const result = adapter
|
|
163
|
-
.prepare(`
|
|
164
|
-
UPDATE entity_lineage_links
|
|
165
|
-
SET status = 'superseded',
|
|
166
|
-
superseded_at = ?
|
|
167
|
-
WHERE canonical_entity_id = ?
|
|
168
|
-
AND status = 'active'
|
|
169
|
-
`)
|
|
170
|
-
.run(supersededAt, entityId);
|
|
171
|
-
return Number(result.changes ?? 0);
|
|
172
|
-
}
|
|
173
|
-
async function seedLineageForEntityMaterialization(input) {
|
|
174
|
-
const result = await appendEntityLineageLink({
|
|
175
|
-
canonical_entity_id: input.canonical_entity_id,
|
|
176
|
-
entity_observation_id: input.entity_observation_id,
|
|
177
|
-
source_entity_id: null,
|
|
178
|
-
contribution_kind: 'seed',
|
|
179
|
-
run_id: input.run_id ?? null,
|
|
180
|
-
candidate_id: null,
|
|
181
|
-
review_action_id: null,
|
|
182
|
-
capture_mode: input.capture_mode ?? 'direct',
|
|
183
|
-
confidence: input.confidence ?? 1,
|
|
184
|
-
});
|
|
185
|
-
return result.link;
|
|
186
|
-
}
|
|
187
91
|
function runLineageTransaction(adapter, fn) {
|
|
188
92
|
const savepoint = `adopt_lineage_${(0, node_crypto_1.randomUUID)().replace(/-/g, '')}`;
|
|
189
93
|
adapter.prepare(`SAVEPOINT ${savepoint}`).run();
|
|
@@ -208,14 +112,6 @@ function runLineageTransaction(adapter, fn) {
|
|
|
208
112
|
throw error;
|
|
209
113
|
}
|
|
210
114
|
}
|
|
211
|
-
async function adoptLineageAfterMerge(input) {
|
|
212
|
-
if (!input.adapter) {
|
|
213
|
-
await (0, db_manager_js_1.initDB)();
|
|
214
|
-
const adapter = (0, db_manager_js_1.getAdapter)();
|
|
215
|
-
return adoptLineageAfterMergeSync({ ...input, adapter });
|
|
216
|
-
}
|
|
217
|
-
return adoptLineageAfterMergeSync(input);
|
|
218
|
-
}
|
|
219
115
|
function adoptLineageAfterMergeSync(input) {
|
|
220
116
|
return runLineageTransaction(input.adapter, () => adoptLineageAfterMergeWithAdapter(input.adapter, input));
|
|
221
117
|
}
|
|
@@ -1,17 +1,8 @@
|
|
|
1
1
|
import type { DatabaseAdapter } from '../db-manager.js';
|
|
2
2
|
import { createDefaultEntityPolicyBootstrap, type EntityPolicyApprovalInput, type EntityPolicyBootstrapDocument, type EntityPolicyKind, type EntityPolicyProposalInput, type EntityPolicyProposalRow, type EntityPolicyRow, type EntityRole, type EntityRoleBinding, type EntityRoleBindingInput } from './policy-types.js';
|
|
3
3
|
type PolicyStoreAdapter = Pick<DatabaseAdapter, 'prepare' | 'transaction'>;
|
|
4
|
-
export declare function ensureEntityPolicyBootstrap(args: {
|
|
5
|
-
bootstrapPath: string;
|
|
6
|
-
now?: () => number;
|
|
7
|
-
}): Promise<void>;
|
|
8
|
-
export declare function listEntityPolicies(adapter?: PolicyStoreAdapter): EntityPolicyRow[];
|
|
9
4
|
export declare function getEntityPolicy(policyKey: string, adapter?: PolicyStoreAdapter): EntityPolicyRow | null;
|
|
10
|
-
export declare function listEntityRoleBindings(adapter?: PolicyStoreAdapter): EntityRoleBinding[];
|
|
11
|
-
export declare function upsertEntityRoleBinding(input: EntityRoleBindingInput, adapter?: PolicyStoreAdapter): void;
|
|
12
5
|
export declare function resolveEntityRoleForActor(actorId: string, adapter?: PolicyStoreAdapter): EntityRole;
|
|
13
|
-
export declare function createEntityPolicyProposal(input: EntityPolicyProposalInput, adapter?: PolicyStoreAdapter): string;
|
|
14
6
|
export declare function getEntityPolicyProposal(proposalId: string, adapter?: PolicyStoreAdapter): EntityPolicyProposalRow | null;
|
|
15
|
-
export declare function approveEntityPolicyProposal(input: EntityPolicyApprovalInput, adapter?: PolicyStoreAdapter): EntityPolicyProposalRow;
|
|
16
7
|
export { createDefaultEntityPolicyBootstrap, type EntityPolicyApprovalInput, type EntityPolicyBootstrapDocument, type EntityPolicyKind, type EntityPolicyProposalInput, type EntityPolicyProposalRow, type EntityPolicyRow, type EntityRole, type EntityRoleBinding, type EntityRoleBindingInput, };
|
|
17
8
|
//# sourceMappingURL=policy-store.d.ts.map
|
|
@@ -1,26 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.createDefaultEntityPolicyBootstrap = void 0;
|
|
7
|
-
exports.ensureEntityPolicyBootstrap = ensureEntityPolicyBootstrap;
|
|
8
|
-
exports.listEntityPolicies = listEntityPolicies;
|
|
9
4
|
exports.getEntityPolicy = getEntityPolicy;
|
|
10
|
-
exports.listEntityRoleBindings = listEntityRoleBindings;
|
|
11
|
-
exports.upsertEntityRoleBinding = upsertEntityRoleBinding;
|
|
12
5
|
exports.resolveEntityRoleForActor = resolveEntityRoleForActor;
|
|
13
|
-
exports.createEntityPolicyProposal = createEntityPolicyProposal;
|
|
14
6
|
exports.getEntityPolicyProposal = getEntityPolicyProposal;
|
|
15
|
-
exports.approveEntityPolicyProposal = approveEntityPolicyProposal;
|
|
16
|
-
const node_crypto_1 = require("node:crypto");
|
|
17
|
-
const node_fs_1 = __importDefault(require("node:fs"));
|
|
18
7
|
const db_manager_js_1 = require("../db-manager.js");
|
|
19
8
|
const policy_types_js_1 = require("./policy-types.js");
|
|
20
9
|
Object.defineProperty(exports, "createDefaultEntityPolicyBootstrap", { enumerable: true, get: function () { return policy_types_js_1.createDefaultEntityPolicyBootstrap; } });
|
|
21
|
-
function now() {
|
|
22
|
-
return Date.now();
|
|
23
|
-
}
|
|
24
10
|
function parseJsonObject(raw, label) {
|
|
25
11
|
const parsed = JSON.parse(raw);
|
|
26
12
|
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
@@ -44,18 +30,6 @@ function parsePolicyRow(row) {
|
|
|
44
30
|
updated_at: Number(row.updated_at),
|
|
45
31
|
};
|
|
46
32
|
}
|
|
47
|
-
function parseRoleBindingRow(row) {
|
|
48
|
-
const role = String(row.role);
|
|
49
|
-
if (!(0, policy_types_js_1.isEntityRole)(role)) {
|
|
50
|
-
throw new Error(`Invalid entity role binding row: role=${role}`);
|
|
51
|
-
}
|
|
52
|
-
return {
|
|
53
|
-
actor_id: String(row.actor_id),
|
|
54
|
-
role,
|
|
55
|
-
created_at: Number(row.created_at),
|
|
56
|
-
updated_at: Number(row.updated_at),
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
33
|
function parseProposalRow(row) {
|
|
60
34
|
const policyKind = String(row.policy_kind);
|
|
61
35
|
if (!(0, policy_types_js_1.isEntityPolicyKind)(policyKind)) {
|
|
@@ -80,184 +54,22 @@ function parseProposalRow(row) {
|
|
|
80
54
|
approved_at: typeof row.approved_at === 'number' ? row.approved_at : null,
|
|
81
55
|
};
|
|
82
56
|
}
|
|
83
|
-
function readBootstrapDocument(bootstrapPath) {
|
|
84
|
-
const raw = node_fs_1.default.readFileSync(bootstrapPath, 'utf-8');
|
|
85
|
-
const parsed = JSON.parse(raw);
|
|
86
|
-
if (!parsed || typeof parsed !== 'object') {
|
|
87
|
-
throw new Error('Entity policy bootstrap must be a JSON object');
|
|
88
|
-
}
|
|
89
|
-
if (typeof parsed.version !== 'number') {
|
|
90
|
-
throw new Error('Entity policy bootstrap must include numeric version');
|
|
91
|
-
}
|
|
92
|
-
if (!Array.isArray(parsed.policies)) {
|
|
93
|
-
throw new Error('Entity policy bootstrap must include policies[]');
|
|
94
|
-
}
|
|
95
|
-
if (!Array.isArray(parsed.role_bindings)) {
|
|
96
|
-
throw new Error('Entity policy bootstrap must include role_bindings[]');
|
|
97
|
-
}
|
|
98
|
-
for (const policy of parsed.policies) {
|
|
99
|
-
if (!policy || typeof policy !== 'object' || Array.isArray(policy)) {
|
|
100
|
-
throw new Error('Entity policy bootstrap policies must be objects');
|
|
101
|
-
}
|
|
102
|
-
if (typeof policy.policy_key !== 'string' ||
|
|
103
|
-
typeof policy.policy_kind !== 'string' ||
|
|
104
|
-
!(0, policy_types_js_1.isEntityPolicyKind)(policy.policy_kind) ||
|
|
105
|
-
!policy.value ||
|
|
106
|
-
typeof policy.value !== 'object' ||
|
|
107
|
-
Array.isArray(policy.value)) {
|
|
108
|
-
throw new Error('Entity policy bootstrap policy rows are invalid');
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
for (const binding of parsed.role_bindings) {
|
|
112
|
-
if (!binding || typeof binding !== 'object' || Array.isArray(binding)) {
|
|
113
|
-
throw new Error('Entity policy bootstrap role_bindings must be objects');
|
|
114
|
-
}
|
|
115
|
-
if (typeof binding.actor_id !== 'string' ||
|
|
116
|
-
typeof binding.role !== 'string' ||
|
|
117
|
-
!(0, policy_types_js_1.isEntityRole)(binding.role)) {
|
|
118
|
-
throw new Error('Entity policy bootstrap role binding rows are invalid');
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
return parsed;
|
|
122
|
-
}
|
|
123
|
-
function countRows(tableName, adapter) {
|
|
124
|
-
const row = adapter.prepare(`SELECT COUNT(*) AS total FROM ${tableName}`).get();
|
|
125
|
-
return Number(row.total ?? 0);
|
|
126
|
-
}
|
|
127
|
-
async function ensureEntityPolicyBootstrap(args) {
|
|
128
|
-
await (0, db_manager_js_1.initDB)();
|
|
129
|
-
const adapter = (0, db_manager_js_1.getAdapter)();
|
|
130
|
-
const document = readBootstrapDocument(args.bootstrapPath);
|
|
131
|
-
const timestamp = args.now?.() ?? now();
|
|
132
|
-
adapter.transaction(() => {
|
|
133
|
-
const policyCount = countRows('entity_policy', adapter);
|
|
134
|
-
const roleBindingCount = countRows('entity_role_bindings', adapter);
|
|
135
|
-
if ((policyCount === 0) !== (roleBindingCount === 0)) {
|
|
136
|
-
throw new Error('Entity policy bootstrap tables are out of sync: entity_policy and entity_role_bindings must be seeded together.');
|
|
137
|
-
}
|
|
138
|
-
if (policyCount === 0 && roleBindingCount === 0) {
|
|
139
|
-
for (const policy of document.policies) {
|
|
140
|
-
adapter
|
|
141
|
-
.prepare(`
|
|
142
|
-
INSERT INTO entity_policy (
|
|
143
|
-
policy_key, policy_kind, value_json, version, created_at, updated_at
|
|
144
|
-
) VALUES (?, ?, ?, 1, ?, ?)
|
|
145
|
-
`)
|
|
146
|
-
.run(policy.policy_key, policy.policy_kind, JSON.stringify(policy.value), timestamp, timestamp);
|
|
147
|
-
}
|
|
148
|
-
for (const binding of document.role_bindings) {
|
|
149
|
-
adapter
|
|
150
|
-
.prepare(`
|
|
151
|
-
INSERT INTO entity_role_bindings (
|
|
152
|
-
actor_id, role, created_at, updated_at
|
|
153
|
-
) VALUES (?, ?, ?, ?)
|
|
154
|
-
`)
|
|
155
|
-
.run(binding.actor_id, binding.role, timestamp, timestamp);
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
function listEntityPolicies(adapter = (0, db_manager_js_1.getAdapter)()) {
|
|
161
|
-
const rows = adapter
|
|
162
|
-
.prepare('SELECT * FROM entity_policy ORDER BY policy_key ASC')
|
|
163
|
-
.all();
|
|
164
|
-
return rows.map(parsePolicyRow);
|
|
165
|
-
}
|
|
166
57
|
function getEntityPolicy(policyKey, adapter = (0, db_manager_js_1.getAdapter)()) {
|
|
167
58
|
const row = adapter
|
|
168
59
|
.prepare('SELECT * FROM entity_policy WHERE policy_key = ? LIMIT 1')
|
|
169
60
|
.get(policyKey);
|
|
170
61
|
return row ? parsePolicyRow(row) : null;
|
|
171
62
|
}
|
|
172
|
-
function listEntityRoleBindings(adapter = (0, db_manager_js_1.getAdapter)()) {
|
|
173
|
-
const rows = adapter
|
|
174
|
-
.prepare('SELECT * FROM entity_role_bindings ORDER BY actor_id ASC')
|
|
175
|
-
.all();
|
|
176
|
-
return rows.map(parseRoleBindingRow);
|
|
177
|
-
}
|
|
178
|
-
function upsertEntityRoleBinding(input, adapter = (0, db_manager_js_1.getAdapter)()) {
|
|
179
|
-
const timestamp = now();
|
|
180
|
-
adapter
|
|
181
|
-
.prepare(`
|
|
182
|
-
INSERT INTO entity_role_bindings (
|
|
183
|
-
actor_id, role, created_at, updated_at
|
|
184
|
-
) VALUES (?, ?, ?, ?)
|
|
185
|
-
ON CONFLICT(actor_id) DO UPDATE SET
|
|
186
|
-
role = excluded.role,
|
|
187
|
-
updated_at = excluded.updated_at
|
|
188
|
-
`)
|
|
189
|
-
.run(input.actor_id, input.role, timestamp, timestamp);
|
|
190
|
-
}
|
|
191
63
|
function resolveEntityRoleForActor(actorId, adapter = (0, db_manager_js_1.getAdapter)()) {
|
|
192
64
|
const row = adapter
|
|
193
65
|
.prepare('SELECT role FROM entity_role_bindings WHERE actor_id = ? LIMIT 1')
|
|
194
66
|
.get(actorId);
|
|
195
67
|
return row?.role && (0, policy_types_js_1.isEntityRole)(row.role) ? row.role : 'viewer';
|
|
196
68
|
}
|
|
197
|
-
function createEntityPolicyProposal(input, adapter = (0, db_manager_js_1.getAdapter)()) {
|
|
198
|
-
const proposalId = input.proposal_id ?? `epol_${(0, node_crypto_1.randomUUID)()}`;
|
|
199
|
-
const createdAt = input.created_at ?? now();
|
|
200
|
-
adapter
|
|
201
|
-
.prepare(`
|
|
202
|
-
INSERT INTO entity_policy_proposals (
|
|
203
|
-
proposal_id, policy_key, policy_kind, proposed_value_json, proposer_actor,
|
|
204
|
-
approver_actor, reason, status, created_at, approved_at
|
|
205
|
-
) VALUES (?, ?, ?, ?, ?, NULL, ?, 'pending', ?, NULL)
|
|
206
|
-
`)
|
|
207
|
-
.run(proposalId, input.policy_key, input.policy_kind, JSON.stringify(input.proposed_value), input.proposer_actor, input.reason, createdAt);
|
|
208
|
-
return proposalId;
|
|
209
|
-
}
|
|
210
69
|
function getEntityPolicyProposal(proposalId, adapter = (0, db_manager_js_1.getAdapter)()) {
|
|
211
70
|
const row = adapter
|
|
212
71
|
.prepare('SELECT * FROM entity_policy_proposals WHERE proposal_id = ? LIMIT 1')
|
|
213
72
|
.get(proposalId);
|
|
214
73
|
return row ? parseProposalRow(row) : null;
|
|
215
74
|
}
|
|
216
|
-
function approveEntityPolicyProposal(input, adapter = (0, db_manager_js_1.getAdapter)()) {
|
|
217
|
-
const approvedAt = input.approved_at ?? now();
|
|
218
|
-
return adapter.transaction(() => {
|
|
219
|
-
const proposal = getEntityPolicyProposal(input.proposal_id, adapter);
|
|
220
|
-
if (!proposal) {
|
|
221
|
-
throw new Error(`Entity policy proposal not found: ${input.proposal_id}`);
|
|
222
|
-
}
|
|
223
|
-
if (proposal.status !== 'pending') {
|
|
224
|
-
throw new Error(`Entity policy proposal is not pending: ${input.proposal_id}`);
|
|
225
|
-
}
|
|
226
|
-
if (proposal.proposer_actor === input.approver_actor) {
|
|
227
|
-
throw new Error('Entity policy proposal requires a different approver');
|
|
228
|
-
}
|
|
229
|
-
const approverRole = resolveEntityRoleForActor(input.approver_actor, adapter);
|
|
230
|
-
if (approverRole !== 'admin') {
|
|
231
|
-
throw new Error('Entity policy proposal approval requires an admin approver');
|
|
232
|
-
}
|
|
233
|
-
const existingPolicy = getEntityPolicy(proposal.policy_key, adapter);
|
|
234
|
-
const version = existingPolicy ? existingPolicy.version + 1 : 1;
|
|
235
|
-
adapter
|
|
236
|
-
.prepare(`
|
|
237
|
-
INSERT INTO entity_policy (
|
|
238
|
-
policy_key, policy_kind, value_json, version, created_at, updated_at
|
|
239
|
-
) VALUES (?, ?, ?, ?, ?, ?)
|
|
240
|
-
ON CONFLICT(policy_key) DO UPDATE SET
|
|
241
|
-
policy_kind = excluded.policy_kind,
|
|
242
|
-
value_json = excluded.value_json,
|
|
243
|
-
version = excluded.version,
|
|
244
|
-
updated_at = excluded.updated_at
|
|
245
|
-
`)
|
|
246
|
-
.run(proposal.policy_key, proposal.policy_kind, proposal.proposed_value_json, version, approvedAt, approvedAt);
|
|
247
|
-
adapter
|
|
248
|
-
.prepare(`
|
|
249
|
-
UPDATE entity_policy_proposals
|
|
250
|
-
SET approver_actor = ?,
|
|
251
|
-
status = 'approved',
|
|
252
|
-
approved_at = ?
|
|
253
|
-
WHERE proposal_id = ?
|
|
254
|
-
`)
|
|
255
|
-
.run(input.approver_actor, approvedAt, input.proposal_id);
|
|
256
|
-
const approved = getEntityPolicyProposal(input.proposal_id, adapter);
|
|
257
|
-
if (!approved) {
|
|
258
|
-
throw new Error(`Failed to reload approved entity policy proposal: ${input.proposal_id}`);
|
|
259
|
-
}
|
|
260
|
-
return approved;
|
|
261
|
-
});
|
|
262
|
-
}
|
|
263
75
|
//# sourceMappingURL=policy-store.js.map
|