@mindflight/mindbrain-personal-studio 0.6.1 → 0.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -8
- package/build/client/_app/immutable/chunks/CIErFlYG.js +1 -0
- package/build/client/_app/immutable/chunks/CIErFlYG.js.br +0 -0
- package/build/client/_app/immutable/chunks/CIErFlYG.js.gz +0 -0
- package/build/client/_app/immutable/entry/{app.CVz6aYsT.js → app.mURYm8o_.js} +2 -2
- package/build/client/_app/immutable/entry/app.mURYm8o_.js.br +0 -0
- package/build/client/_app/immutable/entry/app.mURYm8o_.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.D4M9ZeGO.js +1 -0
- package/build/client/_app/immutable/entry/start.D4M9ZeGO.js.br +2 -0
- package/build/client/_app/immutable/entry/start.D4M9ZeGO.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{1.BBtxY46Q.js → 1.DHKtMeFI.js} +1 -1
- package/build/client/_app/immutable/nodes/1.DHKtMeFI.js.br +1 -0
- package/build/client/_app/immutable/nodes/1.DHKtMeFI.js.gz +0 -0
- package/build/client/_app/version.json +1 -1
- package/build/client/_app/version.json.br +0 -0
- package/build/client/_app/version.json.gz +0 -0
- package/build/handler.js +4 -4
- package/build/index.js +4 -4
- package/build/server/chunks/chunks/{internal.js-D8EA_he2.js → internal.js-C3tV0XXj.js} +2 -2
- package/build/server/chunks/chunks/{internal.js-D8EA_he2.js.map → internal.js-C3tV0XXj.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/graph/schema-registry/{_server.ts.js-Dyfsc-VA.js → _server.ts.js-CAsXxBRq.js} +7 -2
- package/build/server/chunks/entries/endpoints/api/graph/schema-registry/_server.ts.js-CAsXxBRq.js.map +1 -0
- package/build/server/chunks/{handler-BjXBCd1c.js → handler-DlaCCnxx.js} +3 -3
- package/build/server/chunks/{handler-BjXBCd1c.js.map → handler-DlaCCnxx.js.map} +1 -1
- package/build/server/chunks/{index.js-BJYcV8V7.js → index.js-BGfKWHak.js} +2 -2
- package/build/server/chunks/{index.js-BJYcV8V7.js.map → index.js-BGfKWHak.js.map} +1 -1
- package/build/server/chunks/{manifest.js-Ddaot0P4.js → manifest.js-CnmaNf5D.js} +4 -4
- package/build/server/chunks/{manifest.js-Ddaot0P4.js.map → manifest.js-CnmaNf5D.js.map} +1 -1
- package/build/server/chunks/nodes/{1.js-BRigw_9J.js → 1.js-BypjwBYB.js} +2 -2
- package/build/server/chunks/nodes/{1.js-BRigw_9J.js.map → 1.js-BypjwBYB.js.map} +1 -1
- package/examples/immeuble/ACCEPTANCE.yaml +82 -0
- package/examples/immeuble/BIM_LITE.md +15 -0
- package/examples/immeuble/CHECKLIST.md +128 -0
- package/examples/immeuble/README.md +121 -0
- package/examples/immeuble/bundle/immeuble.bundle.json +22786 -0
- package/examples/immeuble/contracts/answer_artifacts.seed.jsonl +34 -0
- package/examples/immeuble/contracts/business_capabilities.seed.jsonl +25 -0
- package/examples/immeuble/contracts/consumer_contract.yaml +131 -0
- package/examples/immeuble/contracts/immeuble_structured_import_model.json +310 -0
- package/examples/immeuble/contracts/mapping_external_to_canonical.json +375 -0
- package/examples/immeuble/contracts/mapping_external_to_canonical.yaml +55 -0
- package/examples/immeuble/contracts/mapping_external_to_canonical_ws.json +65 -0
- package/examples/immeuble/contracts/model_contract.json +943 -0
- package/examples/immeuble/contracts/projection_catalog.yaml +366 -0
- package/examples/immeuble/contracts/scenarios.yaml +27 -0
- package/examples/immeuble/contracts/semantic_proposal.golden.json +1 -0
- package/examples/immeuble/contracts/source_profile.yaml +38 -0
- package/examples/immeuble/fake_data/DeltaFinding.csv +20 -0
- package/examples/immeuble/fake_data/ProjectionResult.csv +13 -0
- package/examples/immeuble/fake_data/ag_meeting.csv +4 -0
- package/examples/immeuble/fake_data/agenda_item.csv +4 -0
- package/examples/immeuble/fake_data/architect.csv +3 -0
- package/examples/immeuble/fake_data/architecture_firm.csv +2 -0
- package/examples/immeuble/fake_data/bank_account.csv +3 -0
- package/examples/immeuble/fake_data/billing_group.csv +41 -0
- package/examples/immeuble/fake_data/block.csv +10 -0
- package/examples/immeuble/fake_data/budget_line.csv +3 -0
- package/examples/immeuble/fake_data/building.csv +6 -0
- package/examples/immeuble/fake_data/cellar.csv +41 -0
- package/examples/immeuble/fake_data/change_order.csv +2 -0
- package/examples/immeuble/fake_data/charge_call.csv +58 -0
- package/examples/immeuble/fake_data/claim.csv +4 -0
- package/examples/immeuble/fake_data/coda_entry.csv +49 -0
- package/examples/immeuble/fake_data/compliance_certificate.csv +10 -0
- package/examples/immeuble/fake_data/contractor.csv +4 -0
- package/examples/immeuble/fake_data/decision.csv +5 -0
- package/examples/immeuble/fake_data/defect_reserve.csv +3 -0
- package/examples/immeuble/fake_data/household.csv +41 -0
- package/examples/immeuble/fake_data/inspection.csv +3 -0
- package/examples/immeuble/fake_data/insurance_policy.csv +4 -0
- package/examples/immeuble/fake_data/intervention.csv +13 -0
- package/examples/immeuble/fake_data/invoice.csv +3 -0
- package/examples/immeuble/fake_data/lease_contract.csv +12 -0
- package/examples/immeuble/fake_data/maintenance_ticket.csv +13 -0
- package/examples/immeuble/fake_data/meter.csv +4 -0
- package/examples/immeuble/fake_data/meter_reading.csv +19 -0
- package/examples/immeuble/fake_data/milestone.csv +3 -0
- package/examples/immeuble/fake_data/organization.csv +12 -0
- package/examples/immeuble/fake_data/parking_space.csv +8 -0
- package/examples/immeuble/fake_data/permit.csv +3 -0
- package/examples/immeuble/fake_data/person.csv +85 -0
- package/examples/immeuble/fake_data/private_garden.csv +7 -0
- package/examples/immeuble/fake_data/progress_event.csv +2 -0
- package/examples/immeuble/fake_data/quote.csv +3 -0
- package/examples/immeuble/fake_data/receipt.csv +2 -0
- package/examples/immeuble/fake_data/reminder.csv +11 -0
- package/examples/immeuble/fake_data/service_contract.csv +4 -0
- package/examples/immeuble/fake_data/shared_equipment.csv +8 -0
- package/examples/immeuble/fake_data/shared_space.csv +10 -0
- package/examples/immeuble/fake_data/unit.csv +41 -0
- package/examples/immeuble/fake_data/work_package.csv +4 -0
- package/examples/immeuble/fake_data/worksite_project.csv +3 -0
- package/examples/immeuble/gap-rules/L0-patrimoine.json +57 -0
- package/examples/immeuble/gap-rules/L1-syndic-naive.json +36 -0
- package/examples/immeuble/gap-rules/L1-syndic.json +61 -0
- package/examples/immeuble/gap-rules/L2-chantier.json +87 -0
- package/examples/immeuble/gap-rules/L2-exploitation.json +87 -0
- package/examples/immeuble/gap-rules/L2-finance.json +48 -0
- package/examples/immeuble/gap-rules/L2-maintenance.json +107 -0
- package/examples/immeuble/gap-rules/L2-syndic-filtered.json +39 -0
- package/examples/immeuble/gap-rules/L3-full.json +332 -0
- package/examples/immeuble/gap-rules/closed-world-contract.md +76 -0
- package/examples/immeuble/gap-rules/demo.json +51 -0
- package/examples/immeuble/gap-rules/expected-findings.yaml +100 -0
- package/examples/immeuble/gap-rules/gap-scenarios.yaml +79 -0
- package/examples/immeuble/gap-rules/motifs.json +38 -0
- package/examples/immeuble/gap-rules/syndic.json +40 -0
- package/examples/immeuble/import_manifest.yaml +25 -0
- package/examples/immeuble/import_ready/graph_edges_import.csv +848 -0
- package/examples/immeuble/import_ready/mfo_facets_import.csv +559 -0
- package/examples/immeuble/index.md +140 -0
- package/examples/immeuble/model/immeuble_model.json +418 -0
- package/examples/immeuble/reports/01-model.validation.json +56 -0
- package/examples/immeuble/reports/02-mapping.validation.json +9 -0
- package/examples/immeuble/reports/acceptance.validation.json +161 -0
- package/examples/immeuble/reports/consumer_contract.validation.json +162 -0
- package/examples/immeuble/reports/graph_edges.jsonl +847 -0
- package/examples/immeuble/reports/graph_nodes.jsonl +558 -0
- package/examples/immeuble/reports/hybrid-compare.json +144 -0
- package/examples/immeuble/reports/immeuble-import-scenario.json +233 -0
- package/examples/immeuble/reports/live-artifacts-refresh.validation.json +51 -0
- package/examples/immeuble/reports/pipeline_audit.json +59 -0
- package/examples/immeuble/reports/projection_audit.json +69 -0
- package/examples/immeuble/reports/projection_audit_immeuble.json +257 -0
- package/examples/immeuble/reports/projection_audit_immeuble.md +122 -0
- package/examples/immeuble/reports/projection_candidates.json +1596 -0
- package/examples/immeuble/reports/projection_candidates.md +117 -0
- package/examples/immeuble/reports/projection_model_validation.md +115 -0
- package/examples/immeuble/reports/reindex.json +4 -0
- package/examples/immeuble/reports/reset-immeuble-workspace.json +32 -0
- package/examples/immeuble/reports/schema-id-prefix-check.json +5 -0
- package/examples/immeuble/scripts/audit-immeuble-projections.mjs +254 -0
- package/examples/immeuble/scripts/build-immeuble-model.mjs +308 -0
- package/examples/immeuble/scripts/compare-immeuble-snapshots.sh +227 -0
- package/examples/immeuble/scripts/enrich-immeuble-demo.mjs +1135 -0
- package/examples/immeuble/scripts/reset-immeuble-workspace.mjs +139 -0
- package/examples/immeuble/scripts/run-immeuble-backend.sh +164 -0
- package/examples/immeuble/scripts/run-immeuble-import.mjs +232 -0
- package/examples/immeuble/scripts/run-immeuble-live-lab.sh +439 -0
- package/examples/immeuble/scripts/seed-immeuble-gap-rules.mjs +69 -0
- package/examples/immeuble/scripts/start-immeuble-demo.sh +52 -0
- package/examples/immeuble/scripts/starterkit/analysis-lenses.mjs +181 -0
- package/examples/immeuble/scripts/starterkit/analyze-projection-candidates.mjs +714 -0
- package/examples/immeuble/scripts/starterkit/audit-ghostcrab-projections.mjs +674 -0
- package/examples/immeuble/scripts/starterkit/facet-prefix.mjs +166 -0
- package/examples/immeuble/scripts/starterkit/sqlite-utils.mjs +131 -0
- package/examples/immeuble/scripts/verify-immeuble-acceptance.mjs +284 -0
- package/examples/immeuble/scripts/verify-immeuble-live-artifacts.mjs +140 -0
- package/examples/immeuble/scripts/yaml-lite.mjs +96 -0
- package/examples/immeuble/sources/agent-prompts/prompts/00-prerequisites-immo-mcp.md +161 -0
- package/examples/immeuble/sources/agent-prompts/prompts/00-prerequisites.md +39 -0
- package/examples/immeuble/sources/agent-prompts/prompts/01-discovery-and-model-proposal.md +42 -0
- package/examples/immeuble/sources/agent-prompts/prompts/02-ontology-register.md +44 -0
- package/examples/immeuble/sources/agent-prompts/prompts/03-gap-rules-design.md +44 -0
- package/examples/immeuble/sources/agent-prompts/prompts/04-document-ingest.md +40 -0
- package/examples/immeuble/sources/agent-prompts/prompts/05-graph-extraction.md +44 -0
- package/examples/immeuble/sources/agent-prompts/prompts/06-validate-and-compare-immo-mcp.md +109 -0
- package/examples/immeuble/sources/agent-prompts/prompts/06-validate-and-compare-test-immo-mcp3.md +30 -0
- package/examples/immeuble/sources/agent-prompts/prompts/06-validate-and-compare.md +63 -0
- package/examples/immeuble/sources/checklists/gap-rules-checklist.md +42 -0
- package/examples/immeuble/sources/checklists/ontology-checklist.md +54 -0
- package/examples/immeuble/sources/documents/README.md +42 -0
- package/examples/immeuble/sources/documents/annexes-caves-garages-jardins.md +8 -0
- package/examples/immeuble/sources/documents/annexes-jardins-garages.md +1 -0
- package/examples/immeuble/sources/documents/baux-erables.md +1 -0
- package/examples/immeuble/sources/documents/baux-locatifs.md +11 -0
- package/examples/immeuble/sources/documents/coda-janvier-2026.md +10 -0
- package/examples/immeuble/sources/documents/composition-menages.md +1 -0
- package/examples/immeuble/sources/documents/composition-occupants.md +18 -0
- package/examples/immeuble/sources/documents/expected-coverage.json +70 -0
- package/examples/immeuble/sources/documents/extrait-coda-janvier-2026.md +1 -0
- package/examples/immeuble/sources/documents/groupes-facturation.md +30 -0
- package/examples/immeuble/sources/documents/manifest.json +79 -0
- package/examples/immeuble/sources/documents/note-architecte-chantier-erables.md +3 -0
- package/examples/immeuble/sources/documents/permis-urbanisme-erables.md +3 -0
- package/examples/immeuble/sources/documents/procedures-operationnelles.md +3 -0
- package/examples/immeuble/sources/documents/pv-ag-budget-2026.md +1 -0
- package/examples/immeuble/sources/documents/pv-reception-reserves-erables.md +3 -0
- package/examples/immeuble/sources/documents/registre-coproprietaires.md +24 -0
- package/examples/immeuble/sources/documents/reglement-copropriete-tilleuls.md +1 -0
- package/examples/immeuble/sources/documents/statuts-erables.md +22 -0
- package/examples/immeuble/sources/documents/statuts-tilleuls.md +19 -0
- package/examples/immeuble/sources/documents/succession-jean-dupont.md +3 -0
- package/examples/immeuble/sources/documents/titre-propriete-tilleuls-a3.md +1 -0
- package/examples/immeuble/sources/documents/trous-pedagogiques.md +3 -0
- package/examples/immeuble/sources/ontology/README.md +1 -0
- package/examples/immeuble/sources/ontology/core.yaml +444 -0
- package/examples/immeuble/success-criteria.yaml +35 -0
- package/fixtures/immeuble-demo.sqlite +0 -0
- package/package.json +16 -3
- package/scripts/lib/sqlite-runtime.mjs +1 -1
- package/scripts/load-immeuble-demo.sh +103 -0
- package/scripts/seed-immeuble-projections.mjs +75 -148
- package/scripts/verify-immeuble-demo-sources.mjs +93 -0
- package/scripts/verify-immeuble-demo.mjs +69 -0
- package/build/client/_app/immutable/chunks/BmeSanva.js +0 -1
- package/build/client/_app/immutable/chunks/BmeSanva.js.br +0 -0
- package/build/client/_app/immutable/chunks/BmeSanva.js.gz +0 -0
- package/build/client/_app/immutable/entry/app.CVz6aYsT.js.br +0 -0
- package/build/client/_app/immutable/entry/app.CVz6aYsT.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.Bt5tVOz8.js +0 -1
- package/build/client/_app/immutable/entry/start.Bt5tVOz8.js.br +0 -2
- package/build/client/_app/immutable/entry/start.Bt5tVOz8.js.gz +0 -0
- package/build/client/_app/immutable/nodes/1.BBtxY46Q.js.br +0 -0
- package/build/client/_app/immutable/nodes/1.BBtxY46Q.js.gz +0 -0
- package/build/server/chunks/entries/endpoints/api/graph/schema-registry/_server.ts.js-Dyfsc-VA.js.map +0 -1
- package/scripts/build-serenity-v6-concept-review-pack.mjs +0 -493
- package/scripts/build-serenity-v6-review-pack.mjs +0 -479
- package/scripts/create-serenity-production-v6.mjs +0 -627
- package/scripts/export-serenity-v6-backup.mjs +0 -178
- package/scripts/import-serenity-v6-user-decisions.mjs +0 -543
- package/scripts/materialize-serenity-v6-snapshots.mjs +0 -675
|
@@ -1,543 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
3
|
-
import { join } from 'node:path';
|
|
4
|
-
import { spawnSync } from 'node:child_process';
|
|
5
|
-
|
|
6
|
-
const WORKSPACE = 'serenity-production-v6';
|
|
7
|
-
const DEFAULT_DB = '/home/dlamotte/.ghostcrab/databases/ghostcrab-serenity-v4-demos.sqlite';
|
|
8
|
-
const OUT_DIR = 'docs/demo/export-audit/2026-06-26/serenity-production-v6-concept-review';
|
|
9
|
-
const args = new Set(process.argv.slice(2));
|
|
10
|
-
const apply = args.has('--apply');
|
|
11
|
-
const dbPath = valueAfter('--db') ?? process.env.GHOSTCRAB_SQLITE_PATH ?? DEFAULT_DB;
|
|
12
|
-
const reportPath = join(OUT_DIR, '06-import-application-report.json');
|
|
13
|
-
|
|
14
|
-
function valueAfter(flag) {
|
|
15
|
-
const index = process.argv.indexOf(flag);
|
|
16
|
-
return index >= 0 ? process.argv[index + 1] : null;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function runSql(sql, { json = false, readonly = false } = {}) {
|
|
20
|
-
const argv = [];
|
|
21
|
-
if (readonly) argv.push('-readonly');
|
|
22
|
-
if (json) argv.push('-json');
|
|
23
|
-
argv.push(dbPath, sql);
|
|
24
|
-
const result = spawnSync('sqlite3', argv, { encoding: 'utf8', maxBuffer: 1024 * 1024 * 64 });
|
|
25
|
-
if (result.status !== 0) {
|
|
26
|
-
throw new Error(result.stderr || result.stdout || `sqlite3 failed for ${sql.slice(0, 120)}`);
|
|
27
|
-
}
|
|
28
|
-
return json ? JSON.parse(result.stdout || '[]') : result.stdout;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function runSqlFile(sql) {
|
|
32
|
-
const result = spawnSync('sqlite3', [dbPath], {
|
|
33
|
-
encoding: 'utf8',
|
|
34
|
-
input: sql,
|
|
35
|
-
maxBuffer: 1024 * 1024 * 64
|
|
36
|
-
});
|
|
37
|
-
if (result.status !== 0) {
|
|
38
|
-
throw new Error(result.stderr || result.stdout || 'sqlite3 transaction failed');
|
|
39
|
-
}
|
|
40
|
-
return result.stdout;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function q(value) {
|
|
44
|
-
if (value === null || value === undefined) return 'NULL';
|
|
45
|
-
if (typeof value === 'number') return Number.isFinite(value) ? String(value) : 'NULL';
|
|
46
|
-
return `'${String(value).replaceAll("'", "''")}'`;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const commonFields = {
|
|
50
|
-
workspace_id: field('string', true),
|
|
51
|
-
copropriete_id: field('string', true),
|
|
52
|
-
record_id: field('string', true),
|
|
53
|
-
source_ref: field('string', true),
|
|
54
|
-
status: field('enum', true),
|
|
55
|
-
previous_status: field('enum', false),
|
|
56
|
-
status_reason: field('string', false),
|
|
57
|
-
status_changed_at: field('datetime', true),
|
|
58
|
-
valid_from: field('datetime', true),
|
|
59
|
-
valid_until: field('datetime', false),
|
|
60
|
-
actor_refs: field('entity_ref[]', true, true),
|
|
61
|
-
evidence_refs: field('entity_ref[]', true, true),
|
|
62
|
-
rule_refs: field('entity_ref[]', true, true)
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
function field(type, required = false, multivalued = false, description = null) {
|
|
66
|
-
return {
|
|
67
|
-
type,
|
|
68
|
-
range: type,
|
|
69
|
-
required,
|
|
70
|
-
multivalued,
|
|
71
|
-
description: description ?? `Operational field`
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
function schemaDefinition({
|
|
76
|
-
module,
|
|
77
|
-
nodeType,
|
|
78
|
-
description,
|
|
79
|
-
statusFacet = 'workflow_status',
|
|
80
|
-
extraFields = {},
|
|
81
|
-
annotations = {}
|
|
82
|
-
}) {
|
|
83
|
-
const fields = { ...commonFields, ...extraFields };
|
|
84
|
-
for (const [name, value] of Object.entries(fields)) {
|
|
85
|
-
value.description = value.description === 'Operational field' ? `Operational field ${name}` : value.description;
|
|
86
|
-
}
|
|
87
|
-
return {
|
|
88
|
-
schema_id: `${WORKSPACE}:${module}:${nodeType}`,
|
|
89
|
-
module,
|
|
90
|
-
node_type: nodeType,
|
|
91
|
-
description,
|
|
92
|
-
version: 1,
|
|
93
|
-
required_fields: Object.entries(fields)
|
|
94
|
-
.filter(([, value]) => value.required)
|
|
95
|
-
.map(([name]) => name),
|
|
96
|
-
status_facet: statusFacet,
|
|
97
|
-
annotations: {
|
|
98
|
-
'ghostcrab.contract_authority': 'ghostcrab_mcp',
|
|
99
|
-
'ghostcrab.linkml_role': 'secondary_synchronized_view',
|
|
100
|
-
'ghostcrab.status_filter_required': true,
|
|
101
|
-
'serenity.review_source': 'user_concept_decisions_2026_06_26',
|
|
102
|
-
...annotations
|
|
103
|
-
},
|
|
104
|
-
fields
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
const schemaAdds = [
|
|
109
|
-
schemaDefinition({
|
|
110
|
-
module: 'administrative',
|
|
111
|
-
nodeType: 'mandataire',
|
|
112
|
-
description:
|
|
113
|
-
'Personne contact representant un ou plusieurs proprietaires, lots ou groupes de lots; contactee avec les proprietaires pour les appels de fonds.',
|
|
114
|
-
extraFields: {
|
|
115
|
-
mandataire_personne_id: field('entity_ref', true, false, 'Personne qui agit comme mandataire.'),
|
|
116
|
-
represented_owner_refs: field('entity_ref[]', false, true, 'Proprietaires representes.'),
|
|
117
|
-
represented_lot_refs: field('entity_ref[]', false, true, 'Lots ou groupes de lots representes.'),
|
|
118
|
-
contact_scope: field('string', false, false, 'Perimetre de contact du mandataire.'),
|
|
119
|
-
receives_fund_calls: field('boolean', false, false, 'Indique si le mandataire recoit les appels de fonds.')
|
|
120
|
-
},
|
|
121
|
-
annotations: {
|
|
122
|
-
'serenity.replaces_candidate': 'administrative:mandat_gestion'
|
|
123
|
-
}
|
|
124
|
-
}),
|
|
125
|
-
schemaDefinition({
|
|
126
|
-
module: 'decisionnel',
|
|
127
|
-
nodeType: 'decision',
|
|
128
|
-
description:
|
|
129
|
-
'Decision metier pouvant generer des effets financiers, des travaux ou autres objets aval.',
|
|
130
|
-
extraFields: {
|
|
131
|
-
meeting_id: field('entity_ref', false, false, 'Assemblee generale ou reunion source.'),
|
|
132
|
-
decision_type: field('string', false, false, 'Type de decision.'),
|
|
133
|
-
financial_impact: field('boolean', false, false, 'Indique si la decision a un impact financier.'),
|
|
134
|
-
execution_status: field('enum', false, false, 'Etat d execution de la decision.'),
|
|
135
|
-
enforceable_at: field('datetime', false, false, 'Date a partir de laquelle la decision est executable.')
|
|
136
|
-
}
|
|
137
|
-
}),
|
|
138
|
-
schemaDefinition({
|
|
139
|
-
module: 'comptabilite',
|
|
140
|
-
nodeType: 'extrait_compte_bancaire',
|
|
141
|
-
description:
|
|
142
|
-
'Extrait bancaire utilise pour les comptes de copropriete, proprietaires et fournisseurs.',
|
|
143
|
-
statusFacet: 'payment_status',
|
|
144
|
-
extraFields: {
|
|
145
|
-
account_id: field('entity_ref', true, false, 'Compte bancaire concerne.'),
|
|
146
|
-
account_owner_type: field('enum', false, false, 'copropriete, proprietaire ou fournisseur.'),
|
|
147
|
-
statement_period_start: field('datetime', false, false, 'Debut de periode de l extrait.'),
|
|
148
|
-
statement_period_end: field('datetime', false, false, 'Fin de periode de l extrait.'),
|
|
149
|
-
opening_balance: field('decimal', false, false, 'Solde initial.'),
|
|
150
|
-
closing_balance: field('decimal', false, false, 'Solde final.'),
|
|
151
|
-
currency: field('string', false, false, 'Devise.'),
|
|
152
|
-
source_document_ref: field('entity_ref', false, false, 'Document source.')
|
|
153
|
-
}
|
|
154
|
-
}),
|
|
155
|
-
schemaDefinition({
|
|
156
|
-
module: 'technique',
|
|
157
|
-
nodeType: 'offre_prix',
|
|
158
|
-
description:
|
|
159
|
-
'Offre de prix ou devis issu d une demande d offres; peut etre retravaille puis accepte.',
|
|
160
|
-
extraFields: {
|
|
161
|
-
demande_travaux_id: field('entity_ref', false, false, 'Demande de travaux source.'),
|
|
162
|
-
fournisseur_id: field('entity_ref', false, false, 'Fournisseur emetteur.'),
|
|
163
|
-
version_ref: field('string', false, false, 'Version ou variante du devis.'),
|
|
164
|
-
option_summary: field('string', false, false, 'Options retenues ou modifiees.'),
|
|
165
|
-
amount_eur: field('decimal', false, false, 'Montant propose.'),
|
|
166
|
-
accepted_at: field('datetime', false, false, 'Date d acceptation.')
|
|
167
|
-
},
|
|
168
|
-
annotations: {
|
|
169
|
-
'serenity.alias': 'devis'
|
|
170
|
-
}
|
|
171
|
-
})
|
|
172
|
-
];
|
|
173
|
-
|
|
174
|
-
const schemaUpdates = [
|
|
175
|
-
{
|
|
176
|
-
schemaId: `${WORKSPACE}:technique:rapport_intervention`,
|
|
177
|
-
extraFields: {
|
|
178
|
-
intervention_id: field('entity_ref', true, false, 'Intervention documentee.'),
|
|
179
|
-
performed_at: field('datetime', false, false, 'Date de realisation.'),
|
|
180
|
-
conclusion: field('string', false, false, 'Conclusion du rapport.'),
|
|
181
|
-
reserves: field('string', false, false, 'Reserves eventuelles.'),
|
|
182
|
-
conformity_status: field('enum', false, false, 'Statut de conformite.'),
|
|
183
|
-
supplier_id: field('entity_ref', false, false, 'Fournisseur intervenant.')
|
|
184
|
-
}
|
|
185
|
-
},
|
|
186
|
-
{
|
|
187
|
-
schemaId: `${WORKSPACE}:administrative:mutation`,
|
|
188
|
-
extraFields: {
|
|
189
|
-
closed_lot_refs: field('entity_ref[]', false, true, 'Lots clotures par la mutation.'),
|
|
190
|
-
created_lot_refs: field('entity_ref[]', false, true, 'Nouveaux lots crees par la mutation.'),
|
|
191
|
-
adapted_relation_refs: field(
|
|
192
|
-
'entity_ref[]',
|
|
193
|
-
false,
|
|
194
|
-
true,
|
|
195
|
-
'Relations proprietaires, localisation ou occupants adaptees par la mutation.'
|
|
196
|
-
)
|
|
197
|
-
}
|
|
198
|
-
},
|
|
199
|
-
{
|
|
200
|
-
schemaId: `${WORKSPACE}:comptabilite:appel_fonds`,
|
|
201
|
-
extraFields: {
|
|
202
|
-
annual_amount_ref: field('entity_ref', false, false, 'Montant annuel ou budget source.'),
|
|
203
|
-
owner_quotites_total: field('decimal', false, false, 'Total quotites du proprietaire.'),
|
|
204
|
-
copropriete_quotites_total: field('decimal', false, false, 'Total quotites de la copropriete.'),
|
|
205
|
-
calculation_formula: field(
|
|
206
|
-
'string',
|
|
207
|
-
false,
|
|
208
|
-
false,
|
|
209
|
-
'total quotites proprietaire / total quotites copropriete * montant annuel'
|
|
210
|
-
),
|
|
211
|
-
mandataire_contact_refs: field('entity_ref[]', false, true, 'Mandataires contactes avec les proprietaires.')
|
|
212
|
-
}
|
|
213
|
-
},
|
|
214
|
-
{
|
|
215
|
-
schemaId: `${WORKSPACE}:decisionnel:assemblee_generale`,
|
|
216
|
-
extraFields: {
|
|
217
|
-
ordre_du_jour_items: field('string[]', false, true, 'Points a l ordre du jour gardes comme section de l AG.')
|
|
218
|
-
}
|
|
219
|
-
},
|
|
220
|
-
{
|
|
221
|
-
schemaId: `${WORKSPACE}:missions:sinistre`,
|
|
222
|
-
extraFields: {
|
|
223
|
-
police_assurance_document_ref: field(
|
|
224
|
-
'entity_ref',
|
|
225
|
-
false,
|
|
226
|
-
false,
|
|
227
|
-
'Police assurance gardee comme document ou preuve liee au sinistre.'
|
|
228
|
-
)
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
];
|
|
232
|
-
|
|
233
|
-
const entityAdds = [
|
|
234
|
-
['serenity-production-v6::administrative', 'mandataire', `${WORKSPACE}:administrative:mandataire`, 'workflow_status'],
|
|
235
|
-
['serenity-production-v6::decisionnel', 'decision', `${WORKSPACE}:decisionnel:decision`, 'workflow_status'],
|
|
236
|
-
[
|
|
237
|
-
'serenity-production-v6::comptabilite',
|
|
238
|
-
'extrait_compte_bancaire',
|
|
239
|
-
`${WORKSPACE}:comptabilite:extrait_compte_bancaire`,
|
|
240
|
-
'payment_status'
|
|
241
|
-
],
|
|
242
|
-
['serenity-production-v6::technique', 'offre_prix', `${WORKSPACE}:technique:offre_prix`, 'workflow_status']
|
|
243
|
-
];
|
|
244
|
-
|
|
245
|
-
const edgeAdds = [
|
|
246
|
-
['serenity-production-v6::administrative', 'MUTATION_CLOSES_LOT', 'mutation', 'lot', 'closes_lot'],
|
|
247
|
-
['serenity-production-v6::administrative', 'MUTATION_CREATES_LOT', 'mutation', 'lot', 'creates_lot'],
|
|
248
|
-
['serenity-production-v6::administrative', 'MUTATION_ADAPTS_OWNER_RELATION', 'mutation', 'compte_coproprietaire_titulaire', 'adapts_owner_relation'],
|
|
249
|
-
['serenity-production-v6::administrative', 'MANDATAIRE_REPRESENTS_PERSON', 'mandataire', 'personne', 'represents_person'],
|
|
250
|
-
['serenity-production-v6::administrative', 'MANDATAIRE_REPRESENTS_LOT', 'mandataire', 'lot', 'represents_lot'],
|
|
251
|
-
['serenity-production-v6::comptabilite', 'APPEL_FONDS_CONTACTS_MANDATAIRE', 'appel_fonds', 'mandataire', 'contacts_mandataire'],
|
|
252
|
-
['serenity-production-v6::comptabilite', 'APPEL_FONDS_CALCULATED_FROM_BUDGET', 'appel_fonds', 'budget', 'calculated_from_budget'],
|
|
253
|
-
['serenity-production-v6::comptabilite', 'APPEL_FONDS_USES_CLE_REPARTITION', 'appel_fonds', 'cle_repartition', 'uses_cle_repartition'],
|
|
254
|
-
['serenity-production-v6::comptabilite', 'EXTRAIT_DOCUMENTS_COMPTE_BANCAIRE', 'extrait_compte_bancaire', 'compte_bancaire', 'documents_account'],
|
|
255
|
-
['serenity-production-v6::decisionnel', 'ASSEMBLEE_GENERALE_ADOPTS_DECISION', 'assemblee_generale', 'decision', 'adopts_decision'],
|
|
256
|
-
['serenity-production-v6::decisionnel', 'DECISION_GENERATES_DEMANDE_TRAVAUX', 'decision', 'demande_travaux', 'generates_work_request'],
|
|
257
|
-
['serenity-production-v6::decisionnel', 'DECISION_GENERATES_APPEL_FONDS', 'decision', 'appel_fonds', 'generates_fund_call'],
|
|
258
|
-
['serenity-production-v6::technique', 'DEMANDE_TRAVAUX_REQUESTS_OFFRE_PRIX', 'demande_travaux', 'offre_prix', 'requests_quote'],
|
|
259
|
-
['serenity-production-v6::technique', 'OFFRE_PRIX_REVISED_AS', 'offre_prix', 'offre_prix', 'revised_as'],
|
|
260
|
-
['serenity-production-v6::technique', 'OFFRE_PRIX_ACCEPTED_AS_BON_COMMANDE', 'offre_prix', 'bon_commande', 'accepted_as_purchase_order']
|
|
261
|
-
];
|
|
262
|
-
|
|
263
|
-
function schemaFactInsert(def, docId) {
|
|
264
|
-
const facets = {
|
|
265
|
-
schema_id: def.schema_id,
|
|
266
|
-
target: 'graph_node',
|
|
267
|
-
module: def.module,
|
|
268
|
-
node_type: def.node_type,
|
|
269
|
-
version: def.version
|
|
270
|
-
};
|
|
271
|
-
const sourceRef = `serenity-production-v6-concept-review/user_concept_decisions.json#${def.schema_id}`;
|
|
272
|
-
return `INSERT INTO agent_facts (id, schema_id, content, facets, facets_json, created_by, workspace_id, source_ref, doc_id)
|
|
273
|
-
VALUES (${q(`schema:${def.schema_id}`)}, 'mindbrain:schema', ${q(JSON.stringify(def))}, ${q(JSON.stringify(facets))}, ${q(JSON.stringify(facets))}, 'codex:serenity-v6-user-decisions', ${q(WORKSPACE)}, ${q(sourceRef)}, ${docId})
|
|
274
|
-
ON CONFLICT(id) DO UPDATE SET
|
|
275
|
-
content=excluded.content,
|
|
276
|
-
facets=excluded.facets,
|
|
277
|
-
facets_json=excluded.facets_json,
|
|
278
|
-
source_ref=excluded.source_ref,
|
|
279
|
-
updated_at=CURRENT_TIMESTAMP,
|
|
280
|
-
updated_at_unix=unixepoch(),
|
|
281
|
-
version=agent_facts.version+1;`;
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
function mergeSchemaContent(existingContent, extraFields) {
|
|
285
|
-
const parsed = JSON.parse(existingContent);
|
|
286
|
-
parsed.fields = parsed.fields && typeof parsed.fields === 'object' ? parsed.fields : {};
|
|
287
|
-
for (const [name, value] of Object.entries(extraFields)) {
|
|
288
|
-
parsed.fields[name] = {
|
|
289
|
-
...value,
|
|
290
|
-
description: value.description === 'Operational field' ? `Operational field ${name}` : value.description
|
|
291
|
-
};
|
|
292
|
-
}
|
|
293
|
-
const required = new Set(Array.isArray(parsed.required_fields) ? parsed.required_fields : []);
|
|
294
|
-
for (const [name, value] of Object.entries(parsed.fields)) {
|
|
295
|
-
if (value?.required) required.add(name);
|
|
296
|
-
}
|
|
297
|
-
parsed.required_fields = [...required];
|
|
298
|
-
parsed.annotations = parsed.annotations && typeof parsed.annotations === 'object' ? parsed.annotations : {};
|
|
299
|
-
parsed.annotations['serenity.review_source'] = 'user_concept_decisions_2026_06_26';
|
|
300
|
-
parsed.version = Math.max(Number(parsed.version || 1), 1);
|
|
301
|
-
return parsed;
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
function entityMetadata(schemaId, schemaFamily, statusFacet) {
|
|
305
|
-
return JSON.stringify({
|
|
306
|
-
ghostcrab: {
|
|
307
|
-
'ghostcrab.schema_id': schemaId,
|
|
308
|
-
'ghostcrab.schema_family': schemaFamily,
|
|
309
|
-
'ghostcrab.status_facet': statusFacet
|
|
310
|
-
},
|
|
311
|
-
serenity: {
|
|
312
|
-
review_source: 'user_concept_decisions_2026_06_26'
|
|
313
|
-
}
|
|
314
|
-
});
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
function edgeMetadata(nativeEdge, source, target) {
|
|
318
|
-
return JSON.stringify({
|
|
319
|
-
source: 'user_concept_decisions_2026_06_26',
|
|
320
|
-
purpose: 'sop_business_structure',
|
|
321
|
-
important: true,
|
|
322
|
-
ghostcrab: {
|
|
323
|
-
'ghostcrab.native_edge_type': nativeEdge,
|
|
324
|
-
'ghostcrab.native_source_type': source,
|
|
325
|
-
'ghostcrab.native_target_type': target
|
|
326
|
-
}
|
|
327
|
-
});
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
function propertyTriples(ontologyId, nodeType, fields, startIndex) {
|
|
331
|
-
const triples = [];
|
|
332
|
-
let tripleIndex = startIndex;
|
|
333
|
-
for (const [fieldName, def] of Object.entries(fields)) {
|
|
334
|
-
const property = `studio:property:${nodeType}.${fieldName}`;
|
|
335
|
-
const range = typeToRdfRange(def.type);
|
|
336
|
-
triples.push({
|
|
337
|
-
ontology_id: ontologyId,
|
|
338
|
-
triple_index: tripleIndex++,
|
|
339
|
-
subject_kind: 'iri',
|
|
340
|
-
subject: property,
|
|
341
|
-
predicate: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type',
|
|
342
|
-
object_kind: 'iri',
|
|
343
|
-
object_value: 'http://www.w3.org/2002/07/owl#DatatypeProperty',
|
|
344
|
-
object_datatype: null,
|
|
345
|
-
object_language: null,
|
|
346
|
-
source_line: `${nodeType}.${fieldName} type`,
|
|
347
|
-
metadata_json: '{}'
|
|
348
|
-
});
|
|
349
|
-
triples.push({
|
|
350
|
-
ontology_id: ontologyId,
|
|
351
|
-
triple_index: tripleIndex++,
|
|
352
|
-
subject_kind: 'iri',
|
|
353
|
-
subject: property,
|
|
354
|
-
predicate: 'http://www.w3.org/2000/01/rdf-schema#domain',
|
|
355
|
-
object_kind: 'iri',
|
|
356
|
-
object_value: nodeType,
|
|
357
|
-
object_datatype: null,
|
|
358
|
-
object_language: null,
|
|
359
|
-
source_line: `${nodeType}.${fieldName} domain`,
|
|
360
|
-
metadata_json: '{}'
|
|
361
|
-
});
|
|
362
|
-
triples.push({
|
|
363
|
-
ontology_id: ontologyId,
|
|
364
|
-
triple_index: tripleIndex++,
|
|
365
|
-
subject_kind: 'iri',
|
|
366
|
-
subject: property,
|
|
367
|
-
predicate: 'http://www.w3.org/2000/01/rdf-schema#range',
|
|
368
|
-
object_kind: 'iri',
|
|
369
|
-
object_value: range,
|
|
370
|
-
object_datatype: null,
|
|
371
|
-
object_language: null,
|
|
372
|
-
source_line: `${nodeType}.${fieldName} range`,
|
|
373
|
-
metadata_json: '{}'
|
|
374
|
-
});
|
|
375
|
-
}
|
|
376
|
-
return triples;
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
function typeToRdfRange(type) {
|
|
380
|
-
if (type === 'datetime') return 'http://www.w3.org/2001/XMLSchema#dateTime';
|
|
381
|
-
if (type === 'decimal') return 'http://www.w3.org/2001/XMLSchema#decimal';
|
|
382
|
-
if (type === 'boolean') return 'http://www.w3.org/2001/XMLSchema#boolean';
|
|
383
|
-
return 'http://www.w3.org/2001/XMLSchema#string';
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
function tripleInsert(triple) {
|
|
387
|
-
return `INSERT INTO ontology_triples_raw (ontology_id, triple_index, subject_kind, subject, predicate, object_kind, object_value, object_datatype, object_language, source_line, metadata_json)
|
|
388
|
-
SELECT ${q(triple.ontology_id)}, ${triple.triple_index}, ${q(triple.subject_kind)}, ${q(triple.subject)}, ${q(triple.predicate)}, ${q(triple.object_kind)}, ${q(triple.object_value)}, ${q(triple.object_datatype)}, ${q(triple.object_language)}, ${q(triple.source_line)}, ${q(triple.metadata_json)}
|
|
389
|
-
WHERE NOT EXISTS (
|
|
390
|
-
SELECT 1 FROM ontology_triples_raw
|
|
391
|
-
WHERE ontology_id=${q(triple.ontology_id)}
|
|
392
|
-
AND subject=${q(triple.subject)}
|
|
393
|
-
AND predicate=${q(triple.predicate)}
|
|
394
|
-
AND object_value=${q(triple.object_value)}
|
|
395
|
-
AND source_line=${q(triple.source_line)}
|
|
396
|
-
);`;
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
function countSnapshot() {
|
|
400
|
-
return {
|
|
401
|
-
workspace: WORKSPACE,
|
|
402
|
-
ontology_entity_types: runSql(
|
|
403
|
-
`SELECT COUNT(*) AS c FROM ontology_entity_types WHERE ontology_id IN (SELECT ontology_id FROM ontologies WHERE workspace_id=${q(WORKSPACE)})`,
|
|
404
|
-
{ json: true, readonly: true }
|
|
405
|
-
)[0].c,
|
|
406
|
-
ontology_edge_types: runSql(
|
|
407
|
-
`SELECT COUNT(*) AS c FROM ontology_edge_types WHERE ontology_id IN (SELECT ontology_id FROM ontologies WHERE workspace_id=${q(WORKSPACE)})`,
|
|
408
|
-
{ json: true, readonly: true }
|
|
409
|
-
)[0].c,
|
|
410
|
-
ontology_triples: runSql(
|
|
411
|
-
`SELECT COUNT(*) AS c FROM ontology_triples_raw WHERE ontology_id IN (SELECT ontology_id FROM ontologies WHERE workspace_id=${q(WORKSPACE)})`,
|
|
412
|
-
{ json: true, readonly: true }
|
|
413
|
-
)[0].c,
|
|
414
|
-
schema_registry: runSql(
|
|
415
|
-
`SELECT COUNT(*) AS c FROM agent_facts WHERE workspace_id=${q(WORKSPACE)} AND schema_id='mindbrain:schema'`,
|
|
416
|
-
{ json: true, readonly: true }
|
|
417
|
-
)[0].c
|
|
418
|
-
};
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
function buildSql() {
|
|
422
|
-
const statements = ['.bail on', 'BEGIN IMMEDIATE;'];
|
|
423
|
-
const maxDocId = runSql(`SELECT COALESCE(MAX(doc_id), 0) AS max_doc_id FROM agent_facts`, {
|
|
424
|
-
json: true,
|
|
425
|
-
readonly: true
|
|
426
|
-
})[0].max_doc_id;
|
|
427
|
-
let nextDocId = Number(maxDocId) + 1;
|
|
428
|
-
|
|
429
|
-
for (const def of schemaAdds) {
|
|
430
|
-
statements.push(schemaFactInsert(def, nextDocId++));
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
for (const update of schemaUpdates) {
|
|
434
|
-
const row = runSql(
|
|
435
|
-
`SELECT content FROM agent_facts WHERE workspace_id=${q(WORKSPACE)} AND schema_id='mindbrain:schema' AND id=${q(`schema:${update.schemaId}`)} LIMIT 1`,
|
|
436
|
-
{ json: true, readonly: true }
|
|
437
|
-
)[0];
|
|
438
|
-
if (!row) continue;
|
|
439
|
-
const merged = mergeSchemaContent(row.content, update.extraFields);
|
|
440
|
-
statements.push(
|
|
441
|
-
`UPDATE agent_facts SET content=${q(JSON.stringify(merged))}, updated_at=CURRENT_TIMESTAMP, updated_at_unix=unixepoch(), version=version+1 WHERE id=${q(`schema:${update.schemaId}`)};`
|
|
442
|
-
);
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
for (const [ontologyId, entityType, schemaId, statusFacet] of entityAdds) {
|
|
446
|
-
const module = ontologyId.slice(`${WORKSPACE}::`.length);
|
|
447
|
-
statements.push(
|
|
448
|
-
`INSERT OR IGNORE INTO ontology_entity_types (ontology_id, entity_type, label, metadata_json) VALUES (${q(ontologyId)}, ${q(entityType)}, ${q(entityType)}, ${q(entityMetadata(schemaId, `${WORKSPACE}:${module}`, statusFacet))});`
|
|
449
|
-
);
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
for (const [ontologyId, edgeType, source, target, nativeEdge] of edgeAdds) {
|
|
453
|
-
statements.push(
|
|
454
|
-
`INSERT OR IGNORE INTO ontology_edge_types (ontology_id, edge_type, directed, source_entity_type, target_entity_type, metadata_json) VALUES (${q(ontologyId)}, ${q(edgeType)}, 1, ${q(source)}, ${q(target)}, ${q(edgeMetadata(nativeEdge, source, target))});`
|
|
455
|
-
);
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
const maxTriples = new Map(
|
|
459
|
-
runSql(
|
|
460
|
-
`SELECT ontology_id, COALESCE(MAX(triple_index), 0) AS max_triple_index FROM ontology_triples_raw WHERE ontology_id LIKE ${q(`${WORKSPACE}::%`)} GROUP BY ontology_id`,
|
|
461
|
-
{ json: true, readonly: true }
|
|
462
|
-
).map((row) => [row.ontology_id, Number(row.max_triple_index)])
|
|
463
|
-
);
|
|
464
|
-
for (const def of schemaAdds) {
|
|
465
|
-
const ontologyId = `${WORKSPACE}::${def.module}`;
|
|
466
|
-
const start = (maxTriples.get(ontologyId) ?? 0) + 1;
|
|
467
|
-
const triples = propertyTriples(ontologyId, def.node_type, def.fields, start);
|
|
468
|
-
maxTriples.set(ontologyId, start + triples.length - 1);
|
|
469
|
-
for (const triple of triples) statements.push(tripleInsert(triple));
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
statements.push('COMMIT;');
|
|
473
|
-
return statements.join('\n');
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
const before = countSnapshot();
|
|
477
|
-
const sql = buildSql();
|
|
478
|
-
|
|
479
|
-
if (!apply) {
|
|
480
|
-
mkdirSync(OUT_DIR, { recursive: true });
|
|
481
|
-
writeFileSync(join(OUT_DIR, '06-import-preview.sql'), `${sql}\n`);
|
|
482
|
-
console.log(
|
|
483
|
-
JSON.stringify(
|
|
484
|
-
{
|
|
485
|
-
mode: 'preview',
|
|
486
|
-
apply_with: `node scripts/import-serenity-v6-user-decisions.mjs --apply --db ${dbPath}`,
|
|
487
|
-
before,
|
|
488
|
-
planned: {
|
|
489
|
-
new_schema_definitions: schemaAdds.map((schema) => schema.schema_id),
|
|
490
|
-
schema_updates: schemaUpdates.map((schema) => schema.schemaId),
|
|
491
|
-
new_entity_types: entityAdds.map(([ontologyId, entityType]) => `${ontologyId}:${entityType}`),
|
|
492
|
-
new_edge_types: edgeAdds.map(([ontologyId, edgeType]) => `${ontologyId}:${edgeType}`)
|
|
493
|
-
}
|
|
494
|
-
},
|
|
495
|
-
null,
|
|
496
|
-
2
|
|
497
|
-
)
|
|
498
|
-
);
|
|
499
|
-
process.exit(0);
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
runSqlFile(sql);
|
|
503
|
-
const after = countSnapshot();
|
|
504
|
-
const verificationRows = runSql(
|
|
505
|
-
`SELECT id, json_extract(content, '$.schema_id') AS schema_id, json_extract(content, '$.description') AS description
|
|
506
|
-
FROM agent_facts
|
|
507
|
-
WHERE workspace_id=${q(WORKSPACE)}
|
|
508
|
-
AND schema_id='mindbrain:schema'
|
|
509
|
-
AND json_extract(content, '$.schema_id') IN (${schemaAdds.map((schema) => q(schema.schema_id)).join(', ')})
|
|
510
|
-
ORDER BY schema_id`,
|
|
511
|
-
{ json: true, readonly: true }
|
|
512
|
-
);
|
|
513
|
-
const edgeRows = runSql(
|
|
514
|
-
`SELECT ontology_id, edge_type, source_entity_type, target_entity_type
|
|
515
|
-
FROM ontology_edge_types
|
|
516
|
-
WHERE ontology_id LIKE ${q(`${WORKSPACE}::%`)}
|
|
517
|
-
AND edge_type IN (${edgeAdds.map(([, edgeType]) => q(edgeType)).join(', ')})
|
|
518
|
-
ORDER BY ontology_id, edge_type`,
|
|
519
|
-
{ json: true, readonly: true }
|
|
520
|
-
);
|
|
521
|
-
const report = {
|
|
522
|
-
generated_at: new Date().toISOString(),
|
|
523
|
-
db_path: dbPath,
|
|
524
|
-
before,
|
|
525
|
-
after,
|
|
526
|
-
delta: Object.fromEntries(
|
|
527
|
-
Object.keys(after).map((key) => [
|
|
528
|
-
key,
|
|
529
|
-
typeof after[key] === 'number' && typeof before[key] === 'number' ? after[key] - before[key] : null
|
|
530
|
-
])
|
|
531
|
-
),
|
|
532
|
-
inserted_or_existing_schema_definitions: verificationRows,
|
|
533
|
-
inserted_or_existing_edge_types: edgeRows,
|
|
534
|
-
skipped_by_user_decision: [
|
|
535
|
-
'administrative:demande_information/transfert_propriete_entrant/cloture_sortant',
|
|
536
|
-
'decisionnel:point_ordre_jour',
|
|
537
|
-
'missions:police_assurance',
|
|
538
|
-
'comptabilite:verification_comptes as persistent schema'
|
|
539
|
-
]
|
|
540
|
-
};
|
|
541
|
-
mkdirSync(OUT_DIR, { recursive: true });
|
|
542
|
-
writeFileSync(reportPath, `${JSON.stringify(report, null, 2)}\n`);
|
|
543
|
-
console.log(JSON.stringify(report, null, 2));
|