@lucern/graph-primitives 1.0.29 → 1.0.30
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/dist/{beliefDecay-DZ6tkLYq.d.ts → beliefDecay-BmkEk5OJ.d.ts} +3 -3
- package/dist/beliefDecay.d.ts +1 -1
- package/dist/beliefDecay.js +448 -314
- package/dist/beliefDecay.js.map +1 -1
- package/dist/{beliefEvidenceLinks-CWOXxxJg.d.ts → beliefEvidenceLinks-BzfjON_6.d.ts} +13 -13
- package/dist/beliefEvidenceLinks.d.ts +1 -1
- package/dist/beliefEvidenceLinks.js +843 -624
- package/dist/beliefEvidenceLinks.js.map +1 -1
- package/dist/beliefEvidenceLinks.operational.d.ts +7 -5
- package/dist/beliefEvidenceLinks.operational.js +91 -18
- package/dist/beliefEvidenceLinks.operational.js.map +1 -1
- package/dist/beliefLifecycle.js.map +1 -1
- package/dist/confidencePropagationDispatch.d.ts +28 -27
- package/dist/confidencePropagationDispatch.js +157 -99
- package/dist/confidencePropagationDispatch.js.map +1 -1
- package/dist/{contradictions-51VLsESq.d.ts → contradictions-BATPuZTL.d.ts} +10 -10
- package/dist/contradictions.d.ts +1 -1
- package/dist/contradictions.js +395 -225
- package/dist/contradictions.js.map +1 -1
- package/dist/convex.d.ts +65 -30
- package/dist/convex.js +7 -3
- package/dist/convex.js.map +1 -1
- package/dist/debug.js.map +1 -1
- package/dist/edgeValidation.js +293 -85
- package/dist/edgeValidation.js.map +1 -1
- package/dist/edges/contains.d.ts +1 -1
- package/dist/edges/contains.js.map +1 -1
- package/dist/edges/contradicts.d.ts +1 -1
- package/dist/edges/contradicts.js.map +1 -1
- package/dist/edges/{dependsOn.d.ts → depends-on.d.ts} +1 -1
- package/dist/edges/{dependsOn.js → depends-on.js} +4 -4
- package/dist/edges/depends-on.js.map +1 -0
- package/dist/edges/{derivedFrom.d.ts → derived-from.d.ts} +1 -1
- package/dist/edges/{derivedFrom.js → derived-from.js} +3 -3
- package/dist/edges/derived-from.js.map +1 -0
- package/dist/edges/elaborates.d.ts +1 -1
- package/dist/edges/elaborates.js.map +1 -1
- package/dist/edges/index.d.ts +7 -3
- package/dist/edges/index.js +7 -4
- package/dist/edges/index.js.map +1 -1
- package/dist/edges/informs.d.ts +1 -1
- package/dist/edges/informs.js.map +1 -1
- package/dist/edges/{propagationTypes.d.ts → propagation-types.d.ts} +14 -14
- package/dist/edges/{propagationTypes.js → propagation-types.js} +3 -3
- package/dist/edges/propagation-types.js.map +1 -0
- package/dist/edges/refutes.d.ts +1 -1
- package/dist/edges/refutes.js.map +1 -1
- package/dist/edges/supports.d.ts +1 -1
- package/dist/edges/supports.js.map +1 -1
- package/dist/edges/tests.d.ts +1 -1
- package/dist/edges/tests.js.map +1 -1
- package/dist/edges/utils.d.ts +1 -1
- package/dist/edges/utils.js.map +1 -1
- package/dist/embeddingTrigger.d.ts +14 -6
- package/dist/embeddingTrigger.js +11 -14
- package/dist/embeddingTrigger.js.map +1 -1
- package/dist/{entityBridge-DMaKooYn.d.ts → entityBridge-BhVDM3pc.d.ts} +5 -5
- package/dist/entityBridge.d.ts +1 -1
- package/dist/entityBridge.js +602 -225
- package/dist/entityBridge.js.map +1 -1
- package/dist/entityCanonicalMatch.d.ts +14 -12
- package/dist/entityCanonicalMatch.js.map +1 -1
- package/dist/{entityLifecycle-CvgSK5FV.d.ts → entityLifecycle-BsfCz9pS.d.ts} +5 -9
- package/dist/entityLifecycle.d.ts +1 -1
- package/dist/entityLifecycle.js +854 -480
- package/dist/entityLifecycle.js.map +1 -1
- package/dist/{entityValidation-KLZ_Xl2D.d.ts → entityValidation-B1yNEHJx.d.ts} +7 -6
- package/dist/entityValidation.d.ts +3 -1
- package/dist/entityValidation.js +60 -8
- package/dist/entityValidation.js.map +1 -1
- package/dist/{epistemicAnswers-C5ib4z6_.d.ts → epistemicAnswers-f47YMu9U.d.ts} +6 -6
- package/dist/epistemicAnswers.d.ts +1 -1
- package/dist/epistemicAnswers.js +587 -545
- package/dist/epistemicAnswers.js.map +1 -1
- package/dist/epistemicBeliefs.admin.d.ts +8 -8
- package/dist/epistemicBeliefs.admin.js +365 -166
- package/dist/epistemicBeliefs.admin.js.map +1 -1
- package/dist/epistemicBeliefs.backfills.d.ts +8 -8
- package/dist/epistemicBeliefs.backfills.js +655 -289
- package/dist/epistemicBeliefs.backfills.js.map +1 -1
- package/dist/epistemicBeliefs.confidence.d.ts +19 -15
- package/dist/epistemicBeliefs.confidence.js +633 -386
- package/dist/epistemicBeliefs.confidence.js.map +1 -1
- package/dist/epistemicBeliefs.core.d.ts +6 -6
- package/dist/epistemicBeliefs.core.js +717 -371
- package/dist/epistemicBeliefs.core.js.map +1 -1
- package/dist/epistemicBeliefs.d.ts +11 -9
- package/dist/epistemicBeliefs.forkEvidence.d.ts +2 -0
- package/dist/epistemicBeliefs.forkEvidence.js +8 -8
- package/dist/epistemicBeliefs.forkEvidence.js.map +1 -1
- package/dist/epistemicBeliefs.helpers.d.ts +68 -49
- package/dist/epistemicBeliefs.helpers.js +358 -211
- package/dist/epistemicBeliefs.helpers.js.map +1 -1
- package/dist/epistemicBeliefs.internal.d.ts +5 -5
- package/dist/epistemicBeliefs.internal.js +1248 -1026
- package/dist/epistemicBeliefs.internal.js.map +1 -1
- package/dist/epistemicBeliefs.js +4942 -3590
- package/dist/epistemicBeliefs.js.map +1 -1
- package/dist/epistemicBeliefs.lifecycle.d.ts +5 -5
- package/dist/epistemicBeliefs.lifecycle.js +1138 -781
- package/dist/epistemicBeliefs.lifecycle.js.map +1 -1
- package/dist/epistemicBeliefs.links.d.ts +7 -7
- package/dist/epistemicBeliefs.links.js +404 -267
- package/dist/epistemicBeliefs.links.js.map +1 -1
- package/dist/epistemicBeliefs.queries.d.ts +4 -4
- package/dist/epistemicBeliefs.queries.js +175 -20
- package/dist/epistemicBeliefs.queries.js.map +1 -1
- package/dist/epistemicBeliefs.topicAnchor.d.ts +6 -4
- package/dist/epistemicBeliefs.topicAnchor.js +12 -5
- package/dist/epistemicBeliefs.topicAnchor.js.map +1 -1
- package/dist/epistemicContracts.d.ts +28 -3
- package/dist/epistemicContracts.evaluators.d.ts +2 -0
- package/dist/epistemicContracts.evaluators.js +1062 -576
- package/dist/epistemicContracts.evaluators.js.map +1 -1
- package/dist/epistemicContracts.handlers.d.ts +15 -32
- package/dist/epistemicContracts.handlers.js +1829 -1351
- package/dist/epistemicContracts.handlers.js.map +1 -1
- package/dist/epistemicContracts.js +1131 -636
- package/dist/epistemicContracts.js.map +1 -1
- package/dist/epistemicContracts.metrics.d.ts +2 -0
- package/dist/epistemicContracts.metrics.js +375 -158
- package/dist/epistemicContracts.metrics.js.map +1 -1
- package/dist/epistemicContracts.types.d.ts +87 -81
- package/dist/epistemicEdgeCreation.d.ts +2 -0
- package/dist/epistemicEdgeCreation.js +87 -16
- package/dist/epistemicEdgeCreation.js.map +1 -1
- package/dist/{epistemicEdges-BF-cn4i3.d.ts → epistemicEdges-BGBh0QSP.d.ts} +4 -7
- package/dist/epistemicEdges.d.ts +6 -5
- package/dist/epistemicEdges.handlers.d.ts +3 -3
- package/dist/epistemicEdges.handlers.js +129 -24
- package/dist/epistemicEdges.handlers.js.map +1 -1
- package/dist/epistemicEdges.helpers.d.ts +6 -4
- package/dist/epistemicEdges.helpers.js +37 -2
- package/dist/epistemicEdges.helpers.js.map +1 -1
- package/dist/epistemicEdges.js +1966 -1202
- package/dist/epistemicEdges.js.map +1 -1
- package/dist/epistemicEdges.mutations.d.ts +7 -7
- package/dist/epistemicEdges.mutations.js +956 -579
- package/dist/epistemicEdges.mutations.js.map +1 -1
- package/dist/epistemicEdges.queries.d.ts +16 -16
- package/dist/epistemicEdges.queries.js +639 -367
- package/dist/epistemicEdges.queries.js.map +1 -1
- package/dist/epistemicEdges.types.d.ts +10 -8
- package/dist/epistemicEvidence.d.ts +4 -1
- package/dist/epistemicEvidence.js +933 -532
- package/dist/epistemicEvidence.js.map +1 -1
- package/dist/epistemicEvidenceHelpers.d.ts +26 -10
- package/dist/epistemicEvidenceHelpers.js +239 -200
- package/dist/epistemicEvidenceHelpers.js.map +1 -1
- package/dist/epistemicEvidenceMutations.d.ts +8 -8
- package/dist/epistemicEvidenceMutations.js +840 -692
- package/dist/epistemicEvidenceMutations.js.map +1 -1
- package/dist/epistemicEvidenceQueries.d.ts +8 -8
- package/dist/epistemicEvidenceQueries.js +514 -238
- package/dist/epistemicEvidenceQueries.js.map +1 -1
- package/dist/epistemicHelpers.d.ts +4 -2
- package/dist/epistemicHelpers.js +308 -134
- package/dist/epistemicHelpers.js.map +1 -1
- package/dist/epistemicInsert.d.ts +16 -4
- package/dist/epistemicInsert.js +6 -3
- package/dist/epistemicInsert.js.map +1 -1
- package/dist/epistemicLayerRules.d.ts +10 -8
- package/dist/epistemicLayerRules.js +1 -5
- package/dist/epistemicLayerRules.js.map +1 -1
- package/dist/{epistemicLinking-CfE00tHJ.d.ts → epistemicLinking-CsCDv2cN.d.ts} +3 -3
- package/dist/epistemicLinking.d.ts +1 -1
- package/dist/epistemicLinking.js +177 -100
- package/dist/epistemicLinking.js.map +1 -1
- package/dist/epistemicNodeCreation.d.ts +2 -0
- package/dist/epistemicNodeCreation.js +203 -40
- package/dist/epistemicNodeCreation.js.map +1 -1
- package/dist/{epistemicNodes-BCQxpYx_.d.ts → epistemicNodes-CokAgBHg.d.ts} +3 -3
- package/dist/epistemicNodes.d.ts +3 -3
- package/dist/epistemicNodes.helpers.d.ts +24 -15
- package/dist/epistemicNodes.helpers.js.map +1 -1
- package/dist/epistemicNodes.internal.d.ts +6 -6
- package/dist/epistemicNodes.internal.js +389 -319
- package/dist/epistemicNodes.internal.js.map +1 -1
- package/dist/epistemicNodes.js +700 -504
- package/dist/epistemicNodes.js.map +1 -1
- package/dist/epistemicNodes.mutations.d.ts +6 -6
- package/dist/epistemicNodes.mutations.js +560 -463
- package/dist/epistemicNodes.mutations.js.map +1 -1
- package/dist/epistemicNodes.queries.d.ts +8 -8
- package/dist/epistemicNodes.queries.js +311 -314
- package/dist/epistemicNodes.queries.js.map +1 -1
- package/dist/epistemicNodes.validators.d.ts +2 -2
- package/dist/epistemicNodes.validators.js.map +1 -1
- package/dist/epistemicQuestions.conviction.d.ts +8 -8
- package/dist/epistemicQuestions.conviction.js +665 -484
- package/dist/epistemicQuestions.conviction.js.map +1 -1
- package/dist/epistemicQuestions.create.d.ts +4 -4
- package/dist/epistemicQuestions.create.js +640 -612
- package/dist/epistemicQuestions.create.js.map +1 -1
- package/dist/epistemicQuestions.d.ts +8 -5
- package/dist/epistemicQuestions.evidence.d.ts +2 -2
- package/dist/epistemicQuestions.evidence.js +475 -383
- package/dist/epistemicQuestions.evidence.js.map +1 -1
- package/dist/epistemicQuestions.helpers.d.ts +125 -24
- package/dist/epistemicQuestions.helpers.js +240 -209
- package/dist/epistemicQuestions.helpers.js.map +1 -1
- package/dist/epistemicQuestions.js +3474 -2823
- package/dist/epistemicQuestions.js.map +1 -1
- package/dist/epistemicQuestions.lifecycle.d.ts +2 -2
- package/dist/epistemicQuestions.lifecycle.js +607 -546
- package/dist/epistemicQuestions.lifecycle.js.map +1 -1
- package/dist/epistemicQuestions.queries.d.ts +12 -7
- package/dist/epistemicQuestions.queries.js +305 -244
- package/dist/epistemicQuestions.queries.js.map +1 -1
- package/dist/epistemicQuestions.sprint.d.ts +2 -2
- package/dist/epistemicQuestions.sprint.js +600 -394
- package/dist/epistemicQuestions.sprint.js.map +1 -1
- package/dist/epistemicQuestions.tail.d.ts +6 -6
- package/dist/epistemicQuestions.tail.js +572 -433
- package/dist/epistemicQuestions.tail.js.map +1 -1
- package/dist/{epistemicSources-dlKj58Jp.d.ts → epistemicSources-DQtaEkWs.d.ts} +4 -4
- package/dist/epistemicSources.d.ts +1 -1
- package/dist/epistemicSources.js +351 -311
- package/dist/epistemicSources.js.map +1 -1
- package/dist/evaluators/index.d.ts +8 -6
- package/dist/evaluators/index.js +399 -167
- package/dist/evaluators/index.js.map +1 -1
- package/dist/evaluators/lint-checker-evaluator.d.ts +16 -0
- package/dist/evaluators/{lintCheckerEvaluator.js → lint-checker-evaluator.js} +10 -5
- package/dist/evaluators/lint-checker-evaluator.js.map +1 -0
- package/dist/evaluators/{sentryCheckerEvaluator.d.ts → sentry-checker-evaluator.d.ts} +7 -2
- package/dist/evaluators/{sentryCheckerEvaluator.js → sentry-checker-evaluator.js} +3 -3
- package/dist/evaluators/sentry-checker-evaluator.js.map +1 -0
- package/dist/evaluators/shared.d.ts +2 -2
- package/dist/evaluators/shared.js +3 -1
- package/dist/evaluators/shared.js.map +1 -1
- package/dist/evaluators/{testRunnerEvaluator.d.ts → test-runner-evaluator.d.ts} +6 -1
- package/dist/evaluators/{testRunnerEvaluator.js → test-runner-evaluator.js} +6 -4
- package/dist/evaluators/test-runner-evaluator.js.map +1 -0
- package/dist/evaluators/tsc-checker-evaluator.d.ts +16 -0
- package/dist/evaluators/{tscCheckerEvaluator.js → tsc-checker-evaluator.js} +10 -5
- package/dist/evaluators/tsc-checker-evaluator.js.map +1 -0
- package/dist/graphTypes.js +6 -2
- package/dist/graphTypes.js.map +1 -1
- package/dist/helpers.d.ts +2 -0
- package/dist/helpers.js +313 -93
- package/dist/helpers.js.map +1 -1
- package/dist/{index-C-Kyd7hD.d.ts → index-DZxyC9Pb.d.ts} +7 -6
- package/dist/index.d.ts +86 -83
- package/dist/index.js +16914 -11760
- package/dist/index.js.map +1 -1
- package/dist/invariantEnforcement.d.ts +3 -3
- package/dist/invariantEnforcement.js.map +1 -1
- package/dist/logicalRoleInference.d.ts +2 -0
- package/dist/logicalRoleInference.js +1 -1
- package/dist/logicalRoleInference.js.map +1 -1
- package/dist/matcherFeedbackUtils.d.ts +2 -2
- package/dist/matcherFeedbackUtils.js.map +1 -1
- package/dist/{ontology-matching-C6rrz2VP.d.ts → ontology-matching-C-mYFrir.d.ts} +16 -16
- package/dist/ontology-matching.d.ts +1 -1
- package/dist/{ontologyApproval-CFYmqKmk.d.ts → ontologyApproval-BVt0feJi.d.ts} +10 -10
- package/dist/ontologyApproval.d.ts +1 -1
- package/dist/ontologyApproval.js +7 -1
- package/dist/ontologyApproval.js.map +1 -1
- package/dist/ontologyDefinitions.d.ts +14 -24
- package/dist/ontologyDefinitions.js +269 -34
- package/dist/ontologyDefinitions.js.map +1 -1
- package/dist/ontologyHelpers.d.ts +13 -13
- package/dist/ontologyHelpers.js.map +1 -1
- package/dist/{ontologyRegistry-B67rPJ16.d.ts → ontologyRegistry-CljS-ENv.d.ts} +2 -2
- package/dist/ontologyRegistry.d.ts +1 -1
- package/dist/ontologyRegistry.js +34 -6
- package/dist/ontologyRegistry.js.map +1 -1
- package/dist/{projectionReconciliation-jww2fBI0.d.ts → projectionReconciliation-DnrSgHSQ.d.ts} +4 -4
- package/dist/projectionReconciliation.d.ts +1 -1
- package/dist/projectionReconciliation.js +57 -10
- package/dist/projectionReconciliation.js.map +1 -1
- package/dist/{projectionStaleness-CmdbpjVK.d.ts → projectionStaleness-C8ImQ2zP.d.ts} +17 -17
- package/dist/projectionStaleness.d.ts +1 -1
- package/dist/projectionStaleness.js +8 -2
- package/dist/projectionStaleness.js.map +1 -1
- package/dist/proof-attestation.json +1 -1
- package/dist/{questionEvidenceLinks-DFlyPpAj.d.ts → questionEvidenceLinks-_nPRa-LY.d.ts} +10 -10
- package/dist/questionEvidenceLinks.d.ts +1 -1
- package/dist/questionEvidenceLinks.js +564 -347
- package/dist/questionEvidenceLinks.js.map +1 -1
- package/dist/{resolverTypes-CC8Ea2E2.d.ts → resolverTypes-BOXPxLET.d.ts} +8 -7
- package/dist/resolverTypes.d.ts +4 -2
- package/dist/{resolvers-Br1a6eLV.d.ts → resolvers-B1TIBmRO.d.ts} +3 -1
- package/dist/resolvers.d.ts +5 -3
- package/dist/resolvers.js +121 -77
- package/dist/resolvers.js.map +1 -1
- package/dist/scopeResolverCompat.d.ts +10 -7
- package/dist/scopeResolverCompat.js +106 -123
- package/dist/scopeResolverCompat.js.map +1 -1
- package/dist/{text-matching-DNg4M5Wd.d.ts → text-matching-DzFooju6.d.ts} +7 -7
- package/dist/text-matching.d.ts +1 -1
- package/dist/topicOntologyResolver.d.ts +22 -21
- package/dist/topicOntologyResolver.js +54 -32
- package/dist/topicOntologyResolver.js.map +1 -1
- package/dist/topicProjectOverlay.d.ts +30 -20
- package/dist/topicProjectOverlay.js +120 -76
- package/dist/topicProjectOverlay.js.map +1 -1
- package/dist/{topicScope-7zhyeGl7.d.ts → topicScope-DJVa0mLa.d.ts} +22 -7
- package/dist/topicScope.d.ts +3 -1
- package/dist/topicScope.js +104 -119
- package/dist/topicScope.js.map +1 -1
- package/dist/workflowBridge.d.ts +26 -15
- package/dist/workflowBridge.js +140 -144
- package/dist/workflowBridge.js.map +1 -1
- package/dist/workspaceIsolation.d.ts +14 -12
- package/dist/workspaceIsolation.js +108 -122
- package/dist/workspaceIsolation.js.map +1 -1
- package/package.json +4 -4
- package/dist/edges/dependsOn.js.map +0 -1
- package/dist/edges/derivedFrom.js.map +0 -1
- package/dist/edges/propagationTypes.js.map +0 -1
- package/dist/evaluators/lintCheckerEvaluator.d.ts +0 -11
- package/dist/evaluators/lintCheckerEvaluator.js.map +0 -1
- package/dist/evaluators/sentryCheckerEvaluator.js.map +0 -1
- package/dist/evaluators/testRunnerEvaluator.js.map +0 -1
- package/dist/evaluators/tscCheckerEvaluator.d.ts +0 -11
- package/dist/evaluators/tscCheckerEvaluator.js.map +0 -1
- package/dist/{epistemicQuestions-bwHd2FWE.d.ts → epistemicQuestions-Do1fhYm5.d.ts} +4 -4
package/dist/epistemicNodes.js
CHANGED
|
@@ -1,12 +1,105 @@
|
|
|
1
|
-
import { v } from 'convex/values';
|
|
2
1
|
import { checkScopeAccess, requireScopeWriteAccess } from '@lucern/access-control/access';
|
|
3
2
|
import { permissiveReturn } from '@lucern/contracts/schema-helpers/validators';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
3
|
+
import { v } from 'convex/values';
|
|
4
|
+
import { unsafeConvexAnyApi } from '@lucern/contracts/convex/unsafeAnyApi';
|
|
5
|
+
import { componentsGeneric, queryGeneric, internalMutationGeneric, internalQueryGeneric, mutationGeneric } from 'convex/server';
|
|
7
6
|
import '@lucern/contracts';
|
|
7
|
+
import { assertUuidV7Identity } from '@lucern/contracts/ids';
|
|
8
|
+
import { isNodeType, getLayerForNodeType } from '@lucern/contracts/schema-helpers/spine/tables/epistemicNodes';
|
|
9
|
+
|
|
10
|
+
// src/epistemicNodes.queries.ts
|
|
11
|
+
var unsafeApi = unsafeConvexAnyApi(
|
|
12
|
+
"graph-primitives top-level module bundle lacks a committed Convex _generated/api surface"
|
|
13
|
+
);
|
|
14
|
+
var api = unsafeApi;
|
|
15
|
+
componentsGeneric();
|
|
16
|
+
var internal = unsafeApi;
|
|
17
|
+
var internalMutation = internalMutationGeneric;
|
|
18
|
+
var internalQuery = internalQueryGeneric;
|
|
19
|
+
var mutation = mutationGeneric;
|
|
20
|
+
var query = queryGeneric;
|
|
21
|
+
|
|
22
|
+
// src/debug.ts
|
|
23
|
+
function isGraphPrimitiveDebugEnabled() {
|
|
24
|
+
const env = globalThis.process?.env;
|
|
25
|
+
return env?.LUCERN_COMPAT_FALLBACK_DEBUG === "1" || env?.LUCERN_GRAPH_DEBUG === "1";
|
|
26
|
+
}
|
|
27
|
+
function debugGraphPrimitiveFallback(message, context) {
|
|
28
|
+
if (!isGraphPrimitiveDebugEnabled()) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
console.debug(message, context ?? {});
|
|
32
|
+
}
|
|
8
33
|
|
|
9
|
-
// src/epistemicNodes.
|
|
34
|
+
// src/epistemicNodes.helpers.ts
|
|
35
|
+
var DEFAULT_NODE_PAGE_SIZE = 250;
|
|
36
|
+
var MAX_NODE_PAGE_SIZE = 8e3;
|
|
37
|
+
function clampNodeLimit(limit, fallback = DEFAULT_NODE_PAGE_SIZE) {
|
|
38
|
+
if (!Number.isFinite(limit)) {
|
|
39
|
+
return fallback;
|
|
40
|
+
}
|
|
41
|
+
return Math.max(1, Math.min(Math.floor(limit), MAX_NODE_PAGE_SIZE));
|
|
42
|
+
}
|
|
43
|
+
function buildNodeStatusSuccessResult() {
|
|
44
|
+
return { success: true };
|
|
45
|
+
}
|
|
46
|
+
function buildNodeArchivedResult() {
|
|
47
|
+
return {
|
|
48
|
+
success: true,
|
|
49
|
+
effectiveStatus: "archived"
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function buildNodeNotFoundResult() {
|
|
53
|
+
const result = {};
|
|
54
|
+
result.success = false;
|
|
55
|
+
result.error = "Node not found";
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
function buildNodeDeletedResult(deletedEdgeCount) {
|
|
59
|
+
return {
|
|
60
|
+
success: true,
|
|
61
|
+
deletedEdgeCount
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function dedupeWorkspaceNodes(nodes) {
|
|
65
|
+
const seen = /* @__PURE__ */ new Set();
|
|
66
|
+
const deduped = [];
|
|
67
|
+
for (const node of nodes) {
|
|
68
|
+
const key = String(node._id);
|
|
69
|
+
if (seen.has(key)) {
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
seen.add(key);
|
|
73
|
+
deduped.push(node);
|
|
74
|
+
}
|
|
75
|
+
return deduped;
|
|
76
|
+
}
|
|
77
|
+
function nodeMatchesWorkspaceReasoningScope(node, scope) {
|
|
78
|
+
return scope.topicId !== void 0 && node.topicId === scope.topicId || scope.projectId !== void 0 && node.projectId === scope.projectId;
|
|
79
|
+
}
|
|
80
|
+
async function collectScopedNodes(ctx, scope, args) {
|
|
81
|
+
const queries = [];
|
|
82
|
+
if (scope.topicId) {
|
|
83
|
+
queries.push(
|
|
84
|
+
args.nodeType ? ctx.db.query("epistemicNodes").withIndex(
|
|
85
|
+
"by_topic_type",
|
|
86
|
+
(q) => q.eq("topicId", scope.topicId).eq("nodeType", args.nodeType)
|
|
87
|
+
).order("desc").take(args.scanLimit) : ctx.db.query("epistemicNodes").withIndex("by_topic", (q) => q.eq("topicId", scope.topicId)).order("desc").take(args.scanLimit)
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
if (scope.projectId && !scope.topicId) {
|
|
91
|
+
queries.push(
|
|
92
|
+
args.nodeType ? ctx.db.query("epistemicNodes").withIndex(
|
|
93
|
+
"by_topic_type",
|
|
94
|
+
(q) => q.eq("topicId", scope.projectId).eq("nodeType", args.nodeType)
|
|
95
|
+
).order("desc").take(args.scanLimit) : ctx.db.query("epistemicNodes").withIndex("by_topic", (q) => q.eq("topicId", scope.projectId)).order("desc").take(args.scanLimit)
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
const combined = dedupeWorkspaceNodes((await Promise.all(queries)).flat());
|
|
99
|
+
return combined.filter(
|
|
100
|
+
(node) => nodeMatchesWorkspaceReasoningScope(node, scope)
|
|
101
|
+
);
|
|
102
|
+
}
|
|
10
103
|
var epistemicLayerValidator = v.union(
|
|
11
104
|
v.literal("L4"),
|
|
12
105
|
v.literal("L3"),
|
|
@@ -105,25 +198,6 @@ var verificationStatusValidator = v.union(
|
|
|
105
198
|
v.literal("contradicted"),
|
|
106
199
|
v.literal("outdated")
|
|
107
200
|
);
|
|
108
|
-
var api = anyApi;
|
|
109
|
-
componentsGeneric();
|
|
110
|
-
var internal = anyApi;
|
|
111
|
-
var internalMutation = internalMutationGeneric;
|
|
112
|
-
var internalQuery = internalQueryGeneric;
|
|
113
|
-
var mutation = mutationGeneric;
|
|
114
|
-
var query = queryGeneric;
|
|
115
|
-
|
|
116
|
-
// src/debug.ts
|
|
117
|
-
function isGraphPrimitiveDebugEnabled() {
|
|
118
|
-
const env = globalThis.process?.env;
|
|
119
|
-
return env?.LUCERN_COMPAT_FALLBACK_DEBUG === "1" || env?.LUCERN_GRAPH_DEBUG === "1";
|
|
120
|
-
}
|
|
121
|
-
function debugGraphPrimitiveFallback(message, context) {
|
|
122
|
-
if (!isGraphPrimitiveDebugEnabled()) {
|
|
123
|
-
return;
|
|
124
|
-
}
|
|
125
|
-
console.debug(message, context ?? {});
|
|
126
|
-
}
|
|
127
201
|
var LEGACY_SCOPE_FIELD = "graphScopeProjectId";
|
|
128
202
|
async function resolveTopicNodeScopeOrNull(ctx, ref) {
|
|
129
203
|
if (!ctx?.db || typeof ctx.db.query !== "function") {
|
|
@@ -158,13 +232,15 @@ function asMappedProjectId(topic) {
|
|
|
158
232
|
if (!topic) {
|
|
159
233
|
return;
|
|
160
234
|
}
|
|
161
|
-
const directLegacyProjectId = normalizeScopeValue(
|
|
235
|
+
const directLegacyProjectId = normalizeScopeValue(
|
|
236
|
+
topic[LEGACY_SCOPE_FIELD]
|
|
237
|
+
);
|
|
162
238
|
if (directLegacyProjectId) {
|
|
163
239
|
return directLegacyProjectId;
|
|
164
240
|
}
|
|
165
241
|
const metadata = topic.metadata || {};
|
|
166
242
|
const candidate = metadata[LEGACY_SCOPE_FIELD] || metadata.legacyProjectId || metadata.projectId || metadata.scopeProjectId;
|
|
167
|
-
return candidate ? candidate : void 0;
|
|
243
|
+
return typeof candidate === "string" ? normalizeScopeValue(candidate) : void 0;
|
|
168
244
|
}
|
|
169
245
|
function normalizeScopeValue(value) {
|
|
170
246
|
if (typeof value !== "string") {
|
|
@@ -189,8 +265,9 @@ function pickPrimaryTopic(candidates) {
|
|
|
189
265
|
})[0];
|
|
190
266
|
}
|
|
191
267
|
async function findTopicsByScopeAlias(ctx, scopeId) {
|
|
268
|
+
const query2 = ctx.db.query("topics");
|
|
192
269
|
try {
|
|
193
|
-
return await
|
|
270
|
+
return await query2.withIndex(
|
|
194
271
|
"by_graph_scope_project",
|
|
195
272
|
(q) => q.eq(LEGACY_SCOPE_FIELD, scopeId)
|
|
196
273
|
).collect();
|
|
@@ -202,7 +279,7 @@ async function findTopicsByScopeAlias(ctx, scopeId) {
|
|
|
202
279
|
scopeId
|
|
203
280
|
}
|
|
204
281
|
);
|
|
205
|
-
const topics = await
|
|
282
|
+
const topics = await query2.collect();
|
|
206
283
|
return topics.filter((topic) => {
|
|
207
284
|
const normalizedGlobalId = normalizeScopeValue(topic.globalId);
|
|
208
285
|
const mappedProjectId = asMappedProjectId(topic);
|
|
@@ -258,234 +335,163 @@ async function resolveInheritedWorkspaceScope(ctx, topic) {
|
|
|
258
335
|
let current = topic;
|
|
259
336
|
for (let i = 0; i < MAX_DEPTH && current?.parentTopicId; i++) {
|
|
260
337
|
current = await ctx.db.get(current.parentTopicId);
|
|
261
|
-
if (!current)
|
|
338
|
+
if (!current) {
|
|
339
|
+
break;
|
|
340
|
+
}
|
|
262
341
|
if (!tenantId) {
|
|
263
342
|
tenantId = normalizeScopeValue(current.tenantId);
|
|
264
343
|
}
|
|
265
344
|
if (!workspaceId) {
|
|
266
345
|
workspaceId = normalizeScopeValue(current.workspaceId);
|
|
267
346
|
}
|
|
268
|
-
if (tenantId && workspaceId)
|
|
347
|
+
if (tenantId && workspaceId) {
|
|
348
|
+
break;
|
|
349
|
+
}
|
|
269
350
|
}
|
|
270
351
|
return { tenantId, workspaceId };
|
|
271
352
|
}
|
|
272
353
|
async function resolveTopicProjectScope(ctx, args) {
|
|
273
354
|
if (args.topicId) {
|
|
274
|
-
|
|
275
|
-
try {
|
|
276
|
-
topic = await ctx.db.get(
|
|
277
|
-
args.topicId
|
|
278
|
-
);
|
|
279
|
-
} catch (error) {
|
|
280
|
-
debugGraphPrimitiveFallback(
|
|
281
|
-
"[topicScope] Failed to load topic by direct id",
|
|
282
|
-
{
|
|
283
|
-
error,
|
|
284
|
-
topicId: args.topicId
|
|
285
|
-
}
|
|
286
|
-
);
|
|
287
|
-
}
|
|
288
|
-
if (!topic) {
|
|
289
|
-
topic = await tryResolveHostTopicById(ctx, String(args.topicId));
|
|
290
|
-
}
|
|
291
|
-
if (!topic) {
|
|
292
|
-
topic = pickPrimaryTopic(
|
|
293
|
-
await findTopicsByScopeAlias(ctx, String(args.topicId))
|
|
294
|
-
) ?? null;
|
|
295
|
-
}
|
|
296
|
-
if (!topic) {
|
|
297
|
-
const nodeScope = await resolveTopicNodeScopeOrNull(
|
|
298
|
-
ctx,
|
|
299
|
-
String(args.topicId)
|
|
300
|
-
);
|
|
301
|
-
if (nodeScope) {
|
|
302
|
-
return nodeScope;
|
|
303
|
-
}
|
|
304
|
-
throw new Error(`Topic not found: ${String(args.topicId)}`);
|
|
305
|
-
}
|
|
306
|
-
const inherited = await resolveInheritedWorkspaceScope(ctx, topic);
|
|
307
|
-
const mapped = asMappedProjectId(topic);
|
|
308
|
-
if (mapped) {
|
|
309
|
-
return {
|
|
310
|
-
topicId: topic._id,
|
|
311
|
-
projectId: mapped,
|
|
312
|
-
tenantId: inherited.tenantId,
|
|
313
|
-
workspaceId: inherited.workspaceId,
|
|
314
|
-
source: "topic"
|
|
315
|
-
};
|
|
316
|
-
}
|
|
317
|
-
return {
|
|
318
|
-
topicId: topic._id,
|
|
319
|
-
tenantId: inherited.tenantId,
|
|
320
|
-
workspaceId: inherited.workspaceId,
|
|
321
|
-
source: "topic"
|
|
322
|
-
};
|
|
355
|
+
return await resolveScopeFromTopicId(ctx, args.topicId);
|
|
323
356
|
}
|
|
324
357
|
if (args.projectId) {
|
|
325
|
-
|
|
326
|
-
try {
|
|
327
|
-
directTopic = await ctx.db.get(
|
|
328
|
-
args.projectId
|
|
329
|
-
);
|
|
330
|
-
} catch (error) {
|
|
331
|
-
debugGraphPrimitiveFallback(
|
|
332
|
-
"[topicScope] Failed to load direct project topic",
|
|
333
|
-
{
|
|
334
|
-
error,
|
|
335
|
-
projectId: args.projectId
|
|
336
|
-
}
|
|
337
|
-
);
|
|
338
|
-
}
|
|
339
|
-
if (directTopic) {
|
|
340
|
-
const inherited = await resolveInheritedWorkspaceScope(ctx, directTopic);
|
|
341
|
-
const mapped = asMappedProjectId(directTopic);
|
|
342
|
-
return {
|
|
343
|
-
topicId: directTopic._id,
|
|
344
|
-
projectId: mapped ?? args.projectId,
|
|
345
|
-
tenantId: inherited.tenantId,
|
|
346
|
-
workspaceId: inherited.workspaceId,
|
|
347
|
-
source: "topic_inferred"
|
|
348
|
-
};
|
|
349
|
-
}
|
|
350
|
-
directTopic = await tryResolveHostTopicByLegacyScope(ctx, args.projectId);
|
|
351
|
-
if (directTopic) {
|
|
352
|
-
const inherited = await resolveInheritedWorkspaceScope(ctx, directTopic);
|
|
353
|
-
const mapped = asMappedProjectId(directTopic);
|
|
354
|
-
return {
|
|
355
|
-
topicId: directTopic._id,
|
|
356
|
-
projectId: mapped ?? args.projectId,
|
|
357
|
-
tenantId: inherited.tenantId,
|
|
358
|
-
workspaceId: inherited.workspaceId,
|
|
359
|
-
source: "topic_inferred"
|
|
360
|
-
};
|
|
361
|
-
}
|
|
362
|
-
const topics = await findTopicsByScopeAlias(ctx, args.projectId);
|
|
363
|
-
const primary = pickPrimaryTopic(topics);
|
|
364
|
-
if (primary) {
|
|
365
|
-
const inherited = await resolveInheritedWorkspaceScope(ctx, primary);
|
|
366
|
-
return {
|
|
367
|
-
topicId: primary._id,
|
|
368
|
-
projectId: args.projectId,
|
|
369
|
-
tenantId: inherited.tenantId,
|
|
370
|
-
workspaceId: inherited.workspaceId,
|
|
371
|
-
source: "project_mapped_topic"
|
|
372
|
-
};
|
|
373
|
-
}
|
|
374
|
-
const nodeScope = await resolveTopicNodeScopeOrNull(
|
|
375
|
-
ctx,
|
|
376
|
-
String(args.projectId)
|
|
377
|
-
);
|
|
378
|
-
if (nodeScope) {
|
|
379
|
-
return {
|
|
380
|
-
...nodeScope,
|
|
381
|
-
projectId: nodeScope.projectId ?? String(args.projectId)
|
|
382
|
-
};
|
|
383
|
-
}
|
|
384
|
-
throw new Error(
|
|
385
|
-
`Legacy project scope ${String(args.projectId)} has no mapped topic.`
|
|
386
|
-
);
|
|
358
|
+
return await resolveScopeFromLegacyProjectId(ctx, args.projectId);
|
|
387
359
|
}
|
|
388
360
|
throw new Error(
|
|
389
361
|
"Missing scope: provide topicId (preferred) or legacy projectId alias."
|
|
390
362
|
);
|
|
391
363
|
}
|
|
364
|
+
async function resolveScopeFromTopicId(ctx, topicId) {
|
|
365
|
+
const topic = await resolveTopicDocFromTopicId(ctx, topicId);
|
|
366
|
+
if (topic) {
|
|
367
|
+
return await buildTopicScope(ctx, topic, "topic");
|
|
368
|
+
}
|
|
369
|
+
const nodeScope = await resolveTopicNodeScopeOrNull(ctx, String(topicId));
|
|
370
|
+
if (nodeScope) {
|
|
371
|
+
return nodeScope;
|
|
372
|
+
}
|
|
373
|
+
throw new Error(`Topic not found: ${String(topicId)}`);
|
|
374
|
+
}
|
|
375
|
+
async function resolveTopicDocFromTopicId(ctx, topicId) {
|
|
376
|
+
const direct = await tryReadTopicDoc(ctx, topicId, {
|
|
377
|
+
failureLog: "[topicScope] Failed to load topic by direct id",
|
|
378
|
+
idLogKey: "topicId"
|
|
379
|
+
});
|
|
380
|
+
if (direct) {
|
|
381
|
+
return direct;
|
|
382
|
+
}
|
|
383
|
+
const hostTopic = await tryResolveHostTopicById(ctx, String(topicId));
|
|
384
|
+
if (hostTopic) {
|
|
385
|
+
return hostTopic;
|
|
386
|
+
}
|
|
387
|
+
return pickPrimaryTopic(await findTopicsByScopeAlias(ctx, String(topicId))) ?? null;
|
|
388
|
+
}
|
|
389
|
+
async function resolveScopeFromLegacyProjectId(ctx, legacyProjectId) {
|
|
390
|
+
const directTopic = await resolveDirectLegacyProjectTopic(
|
|
391
|
+
ctx,
|
|
392
|
+
legacyProjectId
|
|
393
|
+
);
|
|
394
|
+
if (directTopic) {
|
|
395
|
+
return await buildTopicScope(ctx, directTopic, "topic_inferred", {
|
|
396
|
+
fallbackProjectId: legacyProjectId
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
const primary = pickPrimaryTopic(
|
|
400
|
+
await findTopicsByScopeAlias(ctx, legacyProjectId)
|
|
401
|
+
);
|
|
402
|
+
if (primary) {
|
|
403
|
+
return await buildTopicScope(ctx, primary, "project_mapped_topic", {
|
|
404
|
+
fallbackProjectId: legacyProjectId
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
const nodeScope = await resolveTopicNodeScopeOrNull(ctx, legacyProjectId);
|
|
408
|
+
if (nodeScope) {
|
|
409
|
+
return {
|
|
410
|
+
...nodeScope,
|
|
411
|
+
projectId: nodeScope.projectId ?? legacyProjectId
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
throw new Error(
|
|
415
|
+
`Legacy project scope ${legacyProjectId} has no mapped topic.`
|
|
416
|
+
);
|
|
417
|
+
}
|
|
418
|
+
async function resolveDirectLegacyProjectTopic(ctx, legacyProjectId) {
|
|
419
|
+
const directTopic = await tryReadTopicDoc(ctx, legacyProjectId, {
|
|
420
|
+
failureLog: "[topicScope] Failed to load direct project topic",
|
|
421
|
+
idLogKey: "projectId"
|
|
422
|
+
});
|
|
423
|
+
return directTopic ?? tryResolveHostTopicByLegacyScope(ctx, legacyProjectId);
|
|
424
|
+
}
|
|
425
|
+
async function tryReadTopicDoc(ctx, id, log) {
|
|
426
|
+
try {
|
|
427
|
+
return await ctx.db.get(id);
|
|
428
|
+
} catch (error) {
|
|
429
|
+
debugGraphPrimitiveFallback(log.failureLog, {
|
|
430
|
+
error,
|
|
431
|
+
[log.idLogKey]: id
|
|
432
|
+
});
|
|
433
|
+
return null;
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
async function buildTopicScope(ctx, topic, source, options = {}) {
|
|
437
|
+
const inherited = await resolveInheritedWorkspaceScope(ctx, topic);
|
|
438
|
+
const mapped = asMappedProjectId(topic);
|
|
439
|
+
return {
|
|
440
|
+
topicId: topic._id,
|
|
441
|
+
...mapped || options.fallbackProjectId ? { projectId: mapped ?? options.fallbackProjectId } : {},
|
|
442
|
+
tenantId: inherited.tenantId,
|
|
443
|
+
workspaceId: inherited.workspaceId,
|
|
444
|
+
source
|
|
445
|
+
};
|
|
446
|
+
}
|
|
392
447
|
var optionalScopeArgs = {
|
|
393
448
|
projectId: v.optional(v.string()),
|
|
394
449
|
topicId: v.optional(v.string())
|
|
395
450
|
};
|
|
396
451
|
|
|
397
|
-
// src/epistemicNodes.
|
|
398
|
-
var
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
if (!Number.isFinite(limit)) {
|
|
402
|
-
return fallback;
|
|
403
|
-
}
|
|
404
|
-
return Math.max(1, Math.min(Math.floor(limit), MAX_NODE_PAGE_SIZE));
|
|
452
|
+
// src/epistemicNodes.queries.ts
|
|
453
|
+
var optionalNodeScopeArgs = optionalScopeArgs;
|
|
454
|
+
function asEpistemicNodesQueryCtx(ctx) {
|
|
455
|
+
return ctx;
|
|
405
456
|
}
|
|
406
|
-
function
|
|
407
|
-
return
|
|
457
|
+
function isInScope(node, scope) {
|
|
458
|
+
return nodeMatchesWorkspaceReasoningScope(node, scope);
|
|
408
459
|
}
|
|
409
|
-
function
|
|
410
|
-
return
|
|
411
|
-
success: true,
|
|
412
|
-
effectiveStatus: "archived"
|
|
413
|
-
};
|
|
460
|
+
function isStatus(status) {
|
|
461
|
+
return (node) => node.status === status;
|
|
414
462
|
}
|
|
415
|
-
function
|
|
416
|
-
|
|
417
|
-
result.success = false;
|
|
418
|
-
result.error = "Node not found";
|
|
419
|
-
return result;
|
|
463
|
+
function isStatusInScope(status, scope) {
|
|
464
|
+
return (node) => isStatus(status)(node) && isInScope(node, scope);
|
|
420
465
|
}
|
|
421
|
-
function
|
|
466
|
+
function isNotDeletedInScope(scope) {
|
|
467
|
+
return (node) => node.status !== "deleted" && isInScope(node, scope);
|
|
468
|
+
}
|
|
469
|
+
function toLiteNode(node) {
|
|
422
470
|
return {
|
|
423
|
-
|
|
424
|
-
|
|
471
|
+
_id: node._id,
|
|
472
|
+
globalId: node.globalId,
|
|
473
|
+
nodeType: node.nodeType,
|
|
474
|
+
createdBy: node.createdBy,
|
|
475
|
+
topicId: node.topicId,
|
|
476
|
+
projectId: node.projectId,
|
|
477
|
+
status: node.status,
|
|
478
|
+
epistemicLayer: node.epistemicLayer
|
|
425
479
|
};
|
|
426
480
|
}
|
|
427
|
-
function dedupeWorkspaceNodes(nodes) {
|
|
428
|
-
const seen = /* @__PURE__ */ new Set();
|
|
429
|
-
const deduped = [];
|
|
430
|
-
for (const node of nodes) {
|
|
431
|
-
const key = String(node._id);
|
|
432
|
-
if (seen.has(key)) {
|
|
433
|
-
continue;
|
|
434
|
-
}
|
|
435
|
-
seen.add(key);
|
|
436
|
-
deduped.push(node);
|
|
437
|
-
}
|
|
438
|
-
return deduped;
|
|
439
|
-
}
|
|
440
|
-
function nodeMatchesWorkspaceReasoningScope(node, scope) {
|
|
441
|
-
return scope.topicId !== void 0 && node.topicId === scope.topicId || scope.projectId !== void 0 && node.projectId === scope.projectId;
|
|
442
|
-
}
|
|
443
|
-
async function collectScopedNodes(ctx, scope, args) {
|
|
444
|
-
const queries = [];
|
|
445
|
-
if (scope.topicId) {
|
|
446
|
-
queries.push(
|
|
447
|
-
args.nodeType ? ctx.db.query("epistemicNodes").withIndex(
|
|
448
|
-
"by_topic_type",
|
|
449
|
-
(q) => q.eq("topicId", scope.topicId).eq("nodeType", args.nodeType)
|
|
450
|
-
).order("desc").take(args.scanLimit) : ctx.db.query("epistemicNodes").withIndex("by_topic", (q) => q.eq("topicId", scope.topicId)).order("desc").take(args.scanLimit)
|
|
451
|
-
);
|
|
452
|
-
}
|
|
453
|
-
if (scope.projectId && !scope.topicId) {
|
|
454
|
-
queries.push(
|
|
455
|
-
args.nodeType ? ctx.db.query("epistemicNodes").withIndex(
|
|
456
|
-
"by_topic_type",
|
|
457
|
-
(q) => q.eq("topicId", scope.projectId).eq("nodeType", args.nodeType)
|
|
458
|
-
).order("desc").take(args.scanLimit) : ctx.db.query("epistemicNodes").withIndex("by_topic", (q) => q.eq("topicId", scope.projectId)).order("desc").take(args.scanLimit)
|
|
459
|
-
);
|
|
460
|
-
}
|
|
461
|
-
const combined = dedupeWorkspaceNodes((await Promise.all(queries)).flat());
|
|
462
|
-
return combined.filter(
|
|
463
|
-
(node) => nodeMatchesWorkspaceReasoningScope(node, scope)
|
|
464
|
-
);
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
// src/epistemicNodes.queries.ts
|
|
468
|
-
var optionalNodeScopeArgs = optionalScopeArgs;
|
|
469
481
|
var get = query({
|
|
470
482
|
args: { nodeId: v.id("epistemicNodes") },
|
|
471
483
|
returns: permissiveReturn,
|
|
472
|
-
handler: async (ctx, args) =>
|
|
473
|
-
return await ctx.db.get(args.nodeId);
|
|
474
|
-
}
|
|
484
|
+
handler: async (ctx, args) => await asEpistemicNodesQueryCtx(ctx).db.get(args.nodeId)
|
|
475
485
|
});
|
|
476
486
|
var getByGlobalId = query({
|
|
477
487
|
args: { globalId: v.string() },
|
|
478
488
|
returns: permissiveReturn,
|
|
479
|
-
handler: async (ctx, args) =>
|
|
480
|
-
return await ctx.db.query("epistemicNodes").withIndex("by_globalId", (q) => q.eq("globalId", args.globalId)).first();
|
|
481
|
-
}
|
|
489
|
+
handler: async (ctx, args) => await asEpistemicNodesQueryCtx(ctx).db.query("epistemicNodes").withIndex("by_globalId", (q) => q.eq("globalId", args.globalId)).first()
|
|
482
490
|
});
|
|
483
491
|
var getByContentHash = query({
|
|
484
492
|
args: { contentHash: v.string() },
|
|
485
493
|
returns: permissiveReturn,
|
|
486
|
-
handler: async (ctx, args) =>
|
|
487
|
-
return await ctx.db.query("epistemicNodes").withIndex("by_contentHash", (q) => q.eq("contentHash", args.contentHash)).collect();
|
|
488
|
-
}
|
|
494
|
+
handler: async (ctx, args) => await asEpistemicNodesQueryCtx(ctx).db.query("epistemicNodes").withIndex("by_contentHash", (q) => q.eq("contentHash", args.contentHash)).collect()
|
|
489
495
|
});
|
|
490
496
|
var getByProjectAndType = query({
|
|
491
497
|
args: {
|
|
@@ -496,12 +502,13 @@ var getByProjectAndType = query({
|
|
|
496
502
|
},
|
|
497
503
|
returns: permissiveReturn,
|
|
498
504
|
handler: async (ctx, args) => {
|
|
499
|
-
if (!args.projectId
|
|
505
|
+
if (!(args.projectId || args.topicId)) {
|
|
500
506
|
return [];
|
|
501
507
|
}
|
|
508
|
+
const queryCtx = asEpistemicNodesQueryCtx(ctx);
|
|
502
509
|
let scope;
|
|
503
510
|
try {
|
|
504
|
-
scope = await resolveTopicProjectScope(
|
|
511
|
+
scope = await resolveTopicProjectScope(queryCtx, {
|
|
505
512
|
projectId: args.projectId,
|
|
506
513
|
topicId: args.topicId
|
|
507
514
|
});
|
|
@@ -518,18 +525,14 @@ var getByProjectAndType = query({
|
|
|
518
525
|
}
|
|
519
526
|
const pageSize = clampNodeLimit(args.limit);
|
|
520
527
|
const scanLimit = Math.min(pageSize * 3, MAX_NODE_PAGE_SIZE);
|
|
521
|
-
const nodes = await collectScopedNodes(
|
|
528
|
+
const nodes = await collectScopedNodes(queryCtx, scope, {
|
|
522
529
|
nodeType: args.nodeType,
|
|
523
530
|
scanLimit
|
|
524
531
|
});
|
|
525
532
|
if (args.status) {
|
|
526
|
-
return nodes.filter(
|
|
527
|
-
(n) => n.status === args.status && nodeMatchesWorkspaceReasoningScope(n, scope)
|
|
528
|
-
).slice(0, pageSize);
|
|
533
|
+
return nodes.filter(isStatusInScope(args.status, scope)).slice(0, pageSize);
|
|
529
534
|
}
|
|
530
|
-
return nodes.filter(
|
|
531
|
-
(n) => n.status === "active" && nodeMatchesWorkspaceReasoningScope(n, scope)
|
|
532
|
-
).slice(0, pageSize);
|
|
535
|
+
return nodes.filter(isStatusInScope("active", scope)).slice(0, pageSize);
|
|
533
536
|
}
|
|
534
537
|
});
|
|
535
538
|
var getByProjectAndTypeLite = query({
|
|
@@ -541,12 +544,13 @@ var getByProjectAndTypeLite = query({
|
|
|
541
544
|
},
|
|
542
545
|
returns: permissiveReturn,
|
|
543
546
|
handler: async (ctx, args) => {
|
|
544
|
-
if (!args.projectId
|
|
547
|
+
if (!(args.projectId || args.topicId)) {
|
|
545
548
|
return [];
|
|
546
549
|
}
|
|
550
|
+
const queryCtx = asEpistemicNodesQueryCtx(ctx);
|
|
547
551
|
let scope;
|
|
548
552
|
try {
|
|
549
|
-
scope = await resolveTopicProjectScope(
|
|
553
|
+
scope = await resolveTopicProjectScope(queryCtx, {
|
|
550
554
|
projectId: args.projectId,
|
|
551
555
|
topicId: args.topicId
|
|
552
556
|
});
|
|
@@ -563,23 +567,14 @@ var getByProjectAndTypeLite = query({
|
|
|
563
567
|
}
|
|
564
568
|
const pageSize = clampNodeLimit(args.limit);
|
|
565
569
|
const scanLimit = Math.min(pageSize * 3, MAX_NODE_PAGE_SIZE);
|
|
566
|
-
const
|
|
570
|
+
const nodeQuery = queryCtx.db.query("epistemicNodes").withIndex(
|
|
567
571
|
"by_topic_type",
|
|
568
572
|
(q) => q.eq("topicId", scope.topicId).eq("nodeType", args.nodeType)
|
|
569
573
|
);
|
|
570
|
-
const nodes = await
|
|
571
|
-
const statusFiltered = args.status ? nodes.filter((
|
|
574
|
+
const nodes = await nodeQuery.order("desc").take(scanLimit);
|
|
575
|
+
const statusFiltered = args.status ? nodes.filter(isStatus(args.status)) : nodes.filter(isStatus("active"));
|
|
572
576
|
const capped = statusFiltered.slice(0, pageSize);
|
|
573
|
-
return capped.map(
|
|
574
|
-
_id: n._id,
|
|
575
|
-
globalId: n.globalId,
|
|
576
|
-
nodeType: n.nodeType,
|
|
577
|
-
createdBy: n.createdBy,
|
|
578
|
-
topicId: n.topicId,
|
|
579
|
-
projectId: n.projectId,
|
|
580
|
-
status: n.status,
|
|
581
|
-
epistemicLayer: n.epistemicLayer
|
|
582
|
-
}));
|
|
577
|
+
return capped.map(toLiteNode);
|
|
583
578
|
}
|
|
584
579
|
});
|
|
585
580
|
var getByProject = query({
|
|
@@ -591,23 +586,27 @@ var getByProject = query({
|
|
|
591
586
|
},
|
|
592
587
|
returns: permissiveReturn,
|
|
593
588
|
handler: async (ctx, args) => {
|
|
594
|
-
if (!args.projectId
|
|
589
|
+
if (!(args.projectId || args.topicId)) {
|
|
595
590
|
return [];
|
|
596
591
|
}
|
|
592
|
+
const queryCtx = asEpistemicNodesQueryCtx(ctx);
|
|
597
593
|
const pageSize = clampNodeLimit(args.limit);
|
|
598
594
|
const scanLimit = Math.min(pageSize * 3, MAX_NODE_PAGE_SIZE);
|
|
599
595
|
let scope;
|
|
600
596
|
try {
|
|
601
|
-
scope = await resolveTopicProjectScope(
|
|
597
|
+
scope = await resolveTopicProjectScope(queryCtx, {
|
|
602
598
|
projectId: args.projectId,
|
|
603
599
|
topicId: args.topicId
|
|
604
600
|
});
|
|
605
601
|
} catch (error) {
|
|
606
|
-
debugGraphPrimitiveFallback(
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
602
|
+
debugGraphPrimitiveFallback(
|
|
603
|
+
"[epistemicNodes] Failed to resolve list scope",
|
|
604
|
+
{
|
|
605
|
+
error,
|
|
606
|
+
projectId: args.projectId,
|
|
607
|
+
topicId: args.topicId
|
|
608
|
+
}
|
|
609
|
+
);
|
|
611
610
|
return [];
|
|
612
611
|
}
|
|
613
612
|
if (args.userId) {
|
|
@@ -620,15 +619,11 @@ var getByProject = query({
|
|
|
620
619
|
return [];
|
|
621
620
|
}
|
|
622
621
|
}
|
|
623
|
-
const nodes = await collectScopedNodes(
|
|
622
|
+
const nodes = await collectScopedNodes(queryCtx, scope, { scanLimit });
|
|
624
623
|
if (args.includeArchived) {
|
|
625
|
-
return nodes.filter(
|
|
626
|
-
(n) => n.status !== "deleted" && nodeMatchesWorkspaceReasoningScope(n, scope)
|
|
627
|
-
).slice(0, pageSize);
|
|
624
|
+
return nodes.filter(isNotDeletedInScope(scope)).slice(0, pageSize);
|
|
628
625
|
}
|
|
629
|
-
return nodes.filter(
|
|
630
|
-
(n) => n.status === "active" && nodeMatchesWorkspaceReasoningScope(n, scope)
|
|
631
|
-
).slice(0, pageSize);
|
|
626
|
+
return nodes.filter(isStatusInScope("active", scope)).slice(0, pageSize);
|
|
632
627
|
}
|
|
633
628
|
});
|
|
634
629
|
var listAll = query({
|
|
@@ -637,10 +632,11 @@ var listAll = query({
|
|
|
637
632
|
},
|
|
638
633
|
returns: permissiveReturn,
|
|
639
634
|
handler: async (ctx, args) => {
|
|
635
|
+
const queryCtx = asEpistemicNodesQueryCtx(ctx);
|
|
640
636
|
const pageSize = clampNodeLimit(args.limit ?? 2e3);
|
|
641
637
|
const scanLimit = Math.min(pageSize * 2, MAX_NODE_PAGE_SIZE * 2);
|
|
642
|
-
const nodes = await
|
|
643
|
-
return nodes.filter((
|
|
638
|
+
const nodes = await queryCtx.db.query("epistemicNodes").order("desc").take(scanLimit);
|
|
639
|
+
return nodes.filter(isStatus("active")).slice(0, pageSize);
|
|
644
640
|
}
|
|
645
641
|
});
|
|
646
642
|
var search = query({
|
|
@@ -652,11 +648,12 @@ var search = query({
|
|
|
652
648
|
},
|
|
653
649
|
returns: permissiveReturn,
|
|
654
650
|
handler: async (ctx, args) => {
|
|
651
|
+
const queryCtx = asEpistemicNodesQueryCtx(ctx);
|
|
655
652
|
const pageSize = clampNodeLimit(args.limit, 100);
|
|
656
653
|
let scope;
|
|
657
654
|
if (args.projectId || args.topicId) {
|
|
658
655
|
try {
|
|
659
|
-
scope = await resolveTopicProjectScope(
|
|
656
|
+
scope = await resolveTopicProjectScope(queryCtx, {
|
|
660
657
|
projectId: args.projectId,
|
|
661
658
|
topicId: args.topicId
|
|
662
659
|
});
|
|
@@ -672,7 +669,7 @@ var search = query({
|
|
|
672
669
|
return [];
|
|
673
670
|
}
|
|
674
671
|
}
|
|
675
|
-
const searchResults =
|
|
672
|
+
const searchResults = queryCtx.db.query("epistemicNodes").withSearchIndex("search_canonicalText", (q) => {
|
|
676
673
|
let search2 = q.search("canonicalText", args.searchQuery);
|
|
677
674
|
if (scope?.topicId) {
|
|
678
675
|
search2 = search2.eq("topicId", scope.topicId);
|
|
@@ -687,6 +684,10 @@ var search = query({
|
|
|
687
684
|
return await searchResults.take(pageSize);
|
|
688
685
|
}
|
|
689
686
|
});
|
|
687
|
+
function insertEpistemicNode(ctx, doc) {
|
|
688
|
+
assertUuidV7Identity("epistemicNodes", doc.globalId);
|
|
689
|
+
return ctx.db.insert("epistemicNodes", doc);
|
|
690
|
+
}
|
|
690
691
|
|
|
691
692
|
// src/graphTypes.ts
|
|
692
693
|
function getNodeLayer(nodeType) {
|
|
@@ -951,6 +952,310 @@ function assertOntologicalNodeSupersedeAllowed(args) {
|
|
|
951
952
|
}
|
|
952
953
|
});
|
|
953
954
|
}
|
|
955
|
+
|
|
956
|
+
// src/epistemicNodes.internal.ts
|
|
957
|
+
var optionalNodeScopeArgs2 = optionalScopeArgs;
|
|
958
|
+
var EPISTEMIC_LAYERS = /* @__PURE__ */ new Set([
|
|
959
|
+
"L4",
|
|
960
|
+
"L3",
|
|
961
|
+
"L2",
|
|
962
|
+
"L1",
|
|
963
|
+
"ontological",
|
|
964
|
+
"organizational"
|
|
965
|
+
]);
|
|
966
|
+
function readOptionalString(value) {
|
|
967
|
+
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
968
|
+
}
|
|
969
|
+
function readConvexId(value) {
|
|
970
|
+
const normalized = readOptionalString(value);
|
|
971
|
+
return normalized ? normalized : null;
|
|
972
|
+
}
|
|
973
|
+
function readRecord(value) {
|
|
974
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
975
|
+
}
|
|
976
|
+
function readEpistemicLayer(value) {
|
|
977
|
+
const layer = readOptionalString(value);
|
|
978
|
+
return layer && EPISTEMIC_LAYERS.has(layer) ? layer : void 0;
|
|
979
|
+
}
|
|
980
|
+
function resolveEpistemicLayer(args) {
|
|
981
|
+
return readEpistemicLayer(args.providedLayer) ?? getNodeLayer(args.nodeType);
|
|
982
|
+
}
|
|
983
|
+
function readInternalNodeRow(value) {
|
|
984
|
+
const record = readRecord(value);
|
|
985
|
+
if (!record) {
|
|
986
|
+
return null;
|
|
987
|
+
}
|
|
988
|
+
const id = readConvexId(record._id);
|
|
989
|
+
const nodeType = readOptionalString(record.nodeType);
|
|
990
|
+
if (!(id && nodeType)) {
|
|
991
|
+
return null;
|
|
992
|
+
}
|
|
993
|
+
const node = { _id: id, nodeType };
|
|
994
|
+
const canonicalText = readOptionalString(record.canonicalText);
|
|
995
|
+
if (canonicalText !== void 0) {
|
|
996
|
+
node.canonicalText = canonicalText;
|
|
997
|
+
}
|
|
998
|
+
const globalId = readOptionalString(record.globalId);
|
|
999
|
+
if (globalId !== void 0) {
|
|
1000
|
+
node.globalId = globalId;
|
|
1001
|
+
}
|
|
1002
|
+
const projectId = readOptionalString(record.projectId);
|
|
1003
|
+
if (projectId !== void 0) {
|
|
1004
|
+
node.projectId = projectId;
|
|
1005
|
+
}
|
|
1006
|
+
const status = readOptionalString(record.status);
|
|
1007
|
+
if (status !== void 0) {
|
|
1008
|
+
node.status = status;
|
|
1009
|
+
}
|
|
1010
|
+
const title = readOptionalString(record.title);
|
|
1011
|
+
if (title !== void 0) {
|
|
1012
|
+
node.title = title;
|
|
1013
|
+
}
|
|
1014
|
+
return node;
|
|
1015
|
+
}
|
|
1016
|
+
function readInternalEdgeRow(value) {
|
|
1017
|
+
const record = readRecord(value);
|
|
1018
|
+
if (!record) {
|
|
1019
|
+
return null;
|
|
1020
|
+
}
|
|
1021
|
+
const id = readConvexId(record._id);
|
|
1022
|
+
if (!id) {
|
|
1023
|
+
return null;
|
|
1024
|
+
}
|
|
1025
|
+
const edge = { _id: id };
|
|
1026
|
+
const globalId = readOptionalString(record.globalId);
|
|
1027
|
+
if (globalId !== void 0) {
|
|
1028
|
+
edge.globalId = globalId;
|
|
1029
|
+
}
|
|
1030
|
+
return edge;
|
|
1031
|
+
}
|
|
1032
|
+
var createInternal = internalMutation({
|
|
1033
|
+
args: {
|
|
1034
|
+
...optionalNodeScopeArgs2,
|
|
1035
|
+
globalId: v.string(),
|
|
1036
|
+
nodeType: nodeTypeValidator,
|
|
1037
|
+
subtype: v.optional(v.string()),
|
|
1038
|
+
canonicalText: v.string(),
|
|
1039
|
+
contentHash: v.optional(v.string()),
|
|
1040
|
+
// Optional - will be generated if not provided
|
|
1041
|
+
content: v.optional(v.string()),
|
|
1042
|
+
contentType: v.optional(v.string()),
|
|
1043
|
+
title: v.optional(v.string()),
|
|
1044
|
+
tags: v.optional(v.array(v.string())),
|
|
1045
|
+
domain: v.optional(v.string()),
|
|
1046
|
+
metadata: v.optional(v.any()),
|
|
1047
|
+
externalIds: v.optional(
|
|
1048
|
+
v.object({
|
|
1049
|
+
crunchbase: v.optional(v.string()),
|
|
1050
|
+
linkedin: v.optional(v.string()),
|
|
1051
|
+
pitchbook: v.optional(v.string()),
|
|
1052
|
+
twitter: v.optional(v.string()),
|
|
1053
|
+
website: v.optional(v.string())
|
|
1054
|
+
})
|
|
1055
|
+
),
|
|
1056
|
+
sourceType: v.optional(sourceTypeValidator),
|
|
1057
|
+
aiProvider: v.optional(v.string()),
|
|
1058
|
+
extractedFromNodeId: v.optional(v.id("epistemicNodes")),
|
|
1059
|
+
confidence: v.optional(v.number()),
|
|
1060
|
+
verificationStatus: v.optional(verificationStatusValidator),
|
|
1061
|
+
createdBy: v.string(),
|
|
1062
|
+
// Neo4j sync status tracking
|
|
1063
|
+
syncStatus: v.optional(
|
|
1064
|
+
v.union(
|
|
1065
|
+
v.literal("synced"),
|
|
1066
|
+
v.literal("pending_edges"),
|
|
1067
|
+
v.literal("edge_creation_failed")
|
|
1068
|
+
)
|
|
1069
|
+
),
|
|
1070
|
+
epistemicLayer: v.optional(v.string()),
|
|
1071
|
+
status: v.optional(v.string())
|
|
1072
|
+
},
|
|
1073
|
+
returns: permissiveReturn,
|
|
1074
|
+
handler: async (ctx, args) => {
|
|
1075
|
+
const now = Date.now();
|
|
1076
|
+
const resolvedScope = args.topicId || args.projectId ? await (async () => {
|
|
1077
|
+
try {
|
|
1078
|
+
return await resolveTopicProjectScope(ctx, {
|
|
1079
|
+
topicId: args.topicId,
|
|
1080
|
+
projectId: args.projectId
|
|
1081
|
+
});
|
|
1082
|
+
} catch (error) {
|
|
1083
|
+
debugGraphPrimitiveFallback(
|
|
1084
|
+
"[epistemicNodes] Failed to resolve create scope",
|
|
1085
|
+
{
|
|
1086
|
+
error,
|
|
1087
|
+
topicId: args.topicId,
|
|
1088
|
+
projectId: args.projectId
|
|
1089
|
+
}
|
|
1090
|
+
);
|
|
1091
|
+
return;
|
|
1092
|
+
}
|
|
1093
|
+
})() : void 0;
|
|
1094
|
+
const contentHash = args.contentHash || `${args.nodeType}:${args.canonicalText}`.slice(0, 64);
|
|
1095
|
+
const epistemicLayer = resolveEpistemicLayer({
|
|
1096
|
+
nodeType: args.nodeType,
|
|
1097
|
+
providedLayer: args.epistemicLayer
|
|
1098
|
+
});
|
|
1099
|
+
const nodeId = await insertEpistemicNode(ctx, {
|
|
1100
|
+
globalId: args.globalId,
|
|
1101
|
+
nodeType: args.nodeType,
|
|
1102
|
+
epistemicLayer,
|
|
1103
|
+
subtype: args.subtype,
|
|
1104
|
+
canonicalText: args.canonicalText,
|
|
1105
|
+
contentHash,
|
|
1106
|
+
content: args.content,
|
|
1107
|
+
contentType: args.contentType,
|
|
1108
|
+
title: args.title,
|
|
1109
|
+
tags: args.tags,
|
|
1110
|
+
domain: args.domain,
|
|
1111
|
+
metadata: args.metadata,
|
|
1112
|
+
externalIds: args.externalIds,
|
|
1113
|
+
sourceType: args.sourceType ?? "human",
|
|
1114
|
+
aiProvider: args.aiProvider,
|
|
1115
|
+
extractedFromNodeId: args.extractedFromNodeId,
|
|
1116
|
+
confidence: args.confidence,
|
|
1117
|
+
verificationStatus: args.verificationStatus ?? "unverified",
|
|
1118
|
+
status: args.status ?? "active",
|
|
1119
|
+
topicId: resolvedScope?.topicId ?? args.topicId,
|
|
1120
|
+
projectId: resolvedScope?.projectId ?? args.projectId,
|
|
1121
|
+
createdBy: args.createdBy,
|
|
1122
|
+
createdAt: now,
|
|
1123
|
+
updatedAt: now,
|
|
1124
|
+
// Neo4j sync status
|
|
1125
|
+
syncStatus: args.syncStatus
|
|
1126
|
+
});
|
|
1127
|
+
await ctx.scheduler.runAfter(0, internal.neo4jSync.syncNodeToNeo4j, {
|
|
1128
|
+
nodeId,
|
|
1129
|
+
operation: "upsert"
|
|
1130
|
+
});
|
|
1131
|
+
return nodeId;
|
|
1132
|
+
}
|
|
1133
|
+
});
|
|
1134
|
+
var getInternal = internalQuery({
|
|
1135
|
+
args: {
|
|
1136
|
+
nodeId: v.id("epistemicNodes")
|
|
1137
|
+
},
|
|
1138
|
+
returns: permissiveReturn,
|
|
1139
|
+
handler: async (ctx, args) => await ctx.db.get(args.nodeId)
|
|
1140
|
+
});
|
|
1141
|
+
var updateSyncStatus = internalMutation({
|
|
1142
|
+
args: {
|
|
1143
|
+
nodeId: v.id("epistemicNodes"),
|
|
1144
|
+
syncStatus: v.union(
|
|
1145
|
+
v.literal("synced"),
|
|
1146
|
+
v.literal("pending_edges"),
|
|
1147
|
+
v.literal("edge_creation_failed")
|
|
1148
|
+
),
|
|
1149
|
+
syncError: v.optional(v.string())
|
|
1150
|
+
},
|
|
1151
|
+
returns: permissiveReturn,
|
|
1152
|
+
handler: async (ctx, args) => {
|
|
1153
|
+
const updates = {
|
|
1154
|
+
syncStatus: args.syncStatus,
|
|
1155
|
+
updatedAt: Date.now()
|
|
1156
|
+
};
|
|
1157
|
+
if (args.syncError !== void 0) {
|
|
1158
|
+
updates.syncError = args.syncError;
|
|
1159
|
+
}
|
|
1160
|
+
await ctx.db.patch(args.nodeId, updates);
|
|
1161
|
+
return buildNodeStatusSuccessResult();
|
|
1162
|
+
}
|
|
1163
|
+
});
|
|
1164
|
+
var backfillTopicId = internalMutation({
|
|
1165
|
+
args: {
|
|
1166
|
+
nodeIds: v.array(v.id("epistemicNodes")),
|
|
1167
|
+
newTopicId: v.string()
|
|
1168
|
+
},
|
|
1169
|
+
returns: permissiveReturn,
|
|
1170
|
+
handler: async (ctx, args) => {
|
|
1171
|
+
let patched = 0;
|
|
1172
|
+
for (const nodeId of args.nodeIds) {
|
|
1173
|
+
const node = await ctx.db.get(nodeId);
|
|
1174
|
+
if (!node) {
|
|
1175
|
+
continue;
|
|
1176
|
+
}
|
|
1177
|
+
await ctx.db.patch(nodeId, {
|
|
1178
|
+
topicId: args.newTopicId,
|
|
1179
|
+
updatedAt: Date.now()
|
|
1180
|
+
});
|
|
1181
|
+
patched++;
|
|
1182
|
+
}
|
|
1183
|
+
return { patched, total: args.nodeIds.length };
|
|
1184
|
+
}
|
|
1185
|
+
});
|
|
1186
|
+
var getNodesPendingEdgeSync = internalQuery({
|
|
1187
|
+
args: {
|
|
1188
|
+
limit: v.optional(v.number())
|
|
1189
|
+
},
|
|
1190
|
+
returns: permissiveReturn,
|
|
1191
|
+
handler: async (ctx, args) => {
|
|
1192
|
+
const limit = args.limit ?? 100;
|
|
1193
|
+
return await ctx.db.query("epistemicNodes").withIndex(
|
|
1194
|
+
"by_syncStatus",
|
|
1195
|
+
(q) => q.eq("syncStatus", "edge_creation_failed")
|
|
1196
|
+
).take(limit);
|
|
1197
|
+
}
|
|
1198
|
+
});
|
|
1199
|
+
var hardDelete = internalMutation({
|
|
1200
|
+
args: {
|
|
1201
|
+
nodeId: v.id("epistemicNodes"),
|
|
1202
|
+
reason: v.string(),
|
|
1203
|
+
// Required: document why this is being hard-deleted
|
|
1204
|
+
allowBeliefHardDelete: v.optional(v.boolean())
|
|
1205
|
+
},
|
|
1206
|
+
returns: permissiveReturn,
|
|
1207
|
+
handler: async (ctx, args) => {
|
|
1208
|
+
const node = readInternalNodeRow(await ctx.db.get(args.nodeId));
|
|
1209
|
+
if (!node) {
|
|
1210
|
+
return buildNodeNotFoundResult();
|
|
1211
|
+
}
|
|
1212
|
+
assertBeliefNodeHardDeleteAllowed({
|
|
1213
|
+
node,
|
|
1214
|
+
allowBeliefHardDelete: args.allowBeliefHardDelete ?? false,
|
|
1215
|
+
reason: args.reason,
|
|
1216
|
+
mutationName: "epistemicNodes.hardDelete"
|
|
1217
|
+
});
|
|
1218
|
+
await ctx.db.insert("epistemicAudit", {
|
|
1219
|
+
entityType: "node",
|
|
1220
|
+
entityId: String(args.nodeId),
|
|
1221
|
+
changeType: "deleted",
|
|
1222
|
+
projectId: node.projectId,
|
|
1223
|
+
changedBy: "system:hard_delete",
|
|
1224
|
+
changedAt: Date.now(),
|
|
1225
|
+
isAgent: false,
|
|
1226
|
+
previousState: {
|
|
1227
|
+
nodeType: node.nodeType,
|
|
1228
|
+
title: node.title ?? node.canonicalText?.slice(0, 100),
|
|
1229
|
+
status: node.status
|
|
1230
|
+
},
|
|
1231
|
+
rationale: args.reason
|
|
1232
|
+
});
|
|
1233
|
+
const endpointRefs = [String(args.nodeId), node.globalId].filter(
|
|
1234
|
+
(ref) => typeof ref === "string" && ref.length > 0
|
|
1235
|
+
);
|
|
1236
|
+
const uniqueEdges = /* @__PURE__ */ new Map();
|
|
1237
|
+
for (const endpointRef of endpointRefs) {
|
|
1238
|
+
const fromEdges = await ctx.db.query("epistemicEdges").withIndex("by_from", (q) => q.eq("fromNodeId", endpointRef)).collect();
|
|
1239
|
+
const toEdges = await ctx.db.query("epistemicEdges").withIndex("by_to", (q) => q.eq("toNodeId", endpointRef)).collect();
|
|
1240
|
+
for (const rawEdge of [...fromEdges, ...toEdges]) {
|
|
1241
|
+
const edge = readInternalEdgeRow(rawEdge);
|
|
1242
|
+
if (edge) {
|
|
1243
|
+
uniqueEdges.set(edge.globalId ?? String(edge._id), edge);
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
for (const edge of uniqueEdges.values()) {
|
|
1248
|
+
if (edge.globalId) {
|
|
1249
|
+
await ctx.scheduler.runAfter(0, internal.neo4jEdgeAPI.deleteEdge, {
|
|
1250
|
+
globalId: edge.globalId
|
|
1251
|
+
});
|
|
1252
|
+
}
|
|
1253
|
+
await ctx.db.delete(edge._id);
|
|
1254
|
+
}
|
|
1255
|
+
await ctx.db.delete(args.nodeId);
|
|
1256
|
+
return buildNodeDeletedResult(uniqueEdges.size);
|
|
1257
|
+
}
|
|
1258
|
+
});
|
|
954
1259
|
function normalizeScopeValue2(value) {
|
|
955
1260
|
if (typeof value !== "string") {
|
|
956
1261
|
return;
|
|
@@ -989,7 +1294,7 @@ function assertWorkspaceScopedEpistemicNodeScope(args) {
|
|
|
989
1294
|
});
|
|
990
1295
|
}
|
|
991
1296
|
function resolveRuntimePackMutationContext(args) {
|
|
992
|
-
if (!args.runtimeToolName
|
|
1297
|
+
if (!(args.runtimeToolName || args.runtimePackKey || args.runtimePackInstallScope)) {
|
|
993
1298
|
return;
|
|
994
1299
|
}
|
|
995
1300
|
return {
|
|
@@ -1021,13 +1326,117 @@ function assertTenantPackWorkspaceMutationAllowed(args) {
|
|
|
1021
1326
|
}
|
|
1022
1327
|
});
|
|
1023
1328
|
}
|
|
1024
|
-
async function insertEpistemicNode(ctx, doc) {
|
|
1025
|
-
assertUuidV7Identity("epistemicNodes", doc.globalId);
|
|
1026
|
-
return ctx.db.insert("epistemicNodes", doc);
|
|
1027
|
-
}
|
|
1028
1329
|
|
|
1029
1330
|
// src/epistemicNodes.mutations.ts
|
|
1030
|
-
var
|
|
1331
|
+
var optionalNodeScopeArgs3 = optionalScopeArgs;
|
|
1332
|
+
var EPISTEMIC_LAYERS2 = /* @__PURE__ */ new Set([
|
|
1333
|
+
"L4",
|
|
1334
|
+
"L3",
|
|
1335
|
+
"L2",
|
|
1336
|
+
"L1",
|
|
1337
|
+
"ontological",
|
|
1338
|
+
"organizational"
|
|
1339
|
+
]);
|
|
1340
|
+
function readOptionalString2(value) {
|
|
1341
|
+
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
1342
|
+
}
|
|
1343
|
+
function readOptionalNumber(value) {
|
|
1344
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
1345
|
+
}
|
|
1346
|
+
function readConvexId2(value) {
|
|
1347
|
+
const normalized = readOptionalString2(value);
|
|
1348
|
+
return normalized ? normalized : null;
|
|
1349
|
+
}
|
|
1350
|
+
function readRecord2(value) {
|
|
1351
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
1352
|
+
}
|
|
1353
|
+
function readStringArray(value) {
|
|
1354
|
+
return Array.isArray(value) && value.every((item) => typeof item === "string") ? value : void 0;
|
|
1355
|
+
}
|
|
1356
|
+
function readEpistemicLayer2(value) {
|
|
1357
|
+
const layer = readOptionalString2(value);
|
|
1358
|
+
return layer && EPISTEMIC_LAYERS2.has(layer) ? layer : void 0;
|
|
1359
|
+
}
|
|
1360
|
+
function readEpistemicNodeRow(value) {
|
|
1361
|
+
const record = readRecord2(value);
|
|
1362
|
+
if (!record) {
|
|
1363
|
+
return null;
|
|
1364
|
+
}
|
|
1365
|
+
const id = readConvexId2(record._id);
|
|
1366
|
+
const nodeType = readOptionalString2(record.nodeType);
|
|
1367
|
+
if (!(id && nodeType)) {
|
|
1368
|
+
return null;
|
|
1369
|
+
}
|
|
1370
|
+
const node = { _id: id, nodeType };
|
|
1371
|
+
const canonicalText = readOptionalString2(record.canonicalText);
|
|
1372
|
+
if (canonicalText !== void 0) {
|
|
1373
|
+
node.canonicalText = canonicalText;
|
|
1374
|
+
}
|
|
1375
|
+
const confidence = readOptionalNumber(record.confidence);
|
|
1376
|
+
if (confidence !== void 0) {
|
|
1377
|
+
node.confidence = confidence;
|
|
1378
|
+
}
|
|
1379
|
+
const content = readOptionalString2(record.content);
|
|
1380
|
+
if (content !== void 0) {
|
|
1381
|
+
node.content = content;
|
|
1382
|
+
}
|
|
1383
|
+
const contentType = readOptionalString2(record.contentType);
|
|
1384
|
+
if (contentType !== void 0) {
|
|
1385
|
+
node.contentType = contentType;
|
|
1386
|
+
}
|
|
1387
|
+
const createdBy = readOptionalString2(record.createdBy);
|
|
1388
|
+
if (createdBy !== void 0) {
|
|
1389
|
+
node.createdBy = createdBy;
|
|
1390
|
+
}
|
|
1391
|
+
const epistemicLayer = readEpistemicLayer2(record.epistemicLayer);
|
|
1392
|
+
if (epistemicLayer !== void 0) {
|
|
1393
|
+
node.epistemicLayer = epistemicLayer;
|
|
1394
|
+
}
|
|
1395
|
+
const metadata = readRecord2(record.metadata);
|
|
1396
|
+
if (metadata) {
|
|
1397
|
+
node.metadata = metadata;
|
|
1398
|
+
}
|
|
1399
|
+
const projectId = readOptionalString2(record.projectId);
|
|
1400
|
+
if (projectId !== void 0) {
|
|
1401
|
+
node.projectId = projectId;
|
|
1402
|
+
}
|
|
1403
|
+
const status = readOptionalString2(record.status);
|
|
1404
|
+
if (status !== void 0) {
|
|
1405
|
+
node.status = status;
|
|
1406
|
+
}
|
|
1407
|
+
const tags = readStringArray(record.tags);
|
|
1408
|
+
if (tags !== void 0) {
|
|
1409
|
+
node.tags = tags;
|
|
1410
|
+
}
|
|
1411
|
+
const tenantId = readOptionalString2(record.tenantId);
|
|
1412
|
+
if (tenantId !== void 0) {
|
|
1413
|
+
node.tenantId = tenantId;
|
|
1414
|
+
}
|
|
1415
|
+
const title = readOptionalString2(record.title);
|
|
1416
|
+
if (title !== void 0) {
|
|
1417
|
+
node.title = title;
|
|
1418
|
+
}
|
|
1419
|
+
const topicId = readOptionalString2(record.topicId);
|
|
1420
|
+
if (topicId !== void 0) {
|
|
1421
|
+
node.topicId = topicId;
|
|
1422
|
+
}
|
|
1423
|
+
const verificationStatus = readOptionalString2(record.verificationStatus);
|
|
1424
|
+
if (verificationStatus !== void 0) {
|
|
1425
|
+
node.verificationStatus = verificationStatus;
|
|
1426
|
+
}
|
|
1427
|
+
const workspaceId = readOptionalString2(record.workspaceId);
|
|
1428
|
+
if (workspaceId !== void 0) {
|
|
1429
|
+
node.workspaceId = workspaceId;
|
|
1430
|
+
}
|
|
1431
|
+
return node;
|
|
1432
|
+
}
|
|
1433
|
+
function requireEpistemicNodeRow(value, context) {
|
|
1434
|
+
const node = readEpistemicNodeRow(value);
|
|
1435
|
+
if (!node) {
|
|
1436
|
+
throw new Error(`${context} requires a stored epistemic node.`);
|
|
1437
|
+
}
|
|
1438
|
+
return node;
|
|
1439
|
+
}
|
|
1031
1440
|
var create = mutation({
|
|
1032
1441
|
args: {
|
|
1033
1442
|
globalId: v.string(),
|
|
@@ -1057,7 +1466,7 @@ var create = mutation({
|
|
|
1057
1466
|
extractedFromNodeId: v.optional(v.id("epistemicNodes")),
|
|
1058
1467
|
confidence: v.optional(v.number()),
|
|
1059
1468
|
verificationStatus: v.optional(verificationStatusValidator),
|
|
1060
|
-
...
|
|
1469
|
+
...optionalNodeScopeArgs3,
|
|
1061
1470
|
createdBy: v.string(),
|
|
1062
1471
|
runtimeToolName: v.optional(v.string()),
|
|
1063
1472
|
runtimePackKey: v.optional(v.string()),
|
|
@@ -1073,8 +1482,9 @@ var create = mutation({
|
|
|
1073
1482
|
mutationName: "epistemicNodes.create"
|
|
1074
1483
|
});
|
|
1075
1484
|
const existing = await ctx.db.query("epistemicNodes").withIndex("by_contentHash", (q) => q.eq("contentHash", args.contentHash)).first();
|
|
1076
|
-
|
|
1077
|
-
|
|
1485
|
+
const existingNode = readEpistemicNodeRow(existing);
|
|
1486
|
+
if (existingNode?.status === "active") {
|
|
1487
|
+
return { nodeId: existingNode._id, isDuplicate: true };
|
|
1078
1488
|
}
|
|
1079
1489
|
const epistemicLayer = getNodeLayer(args.nodeType);
|
|
1080
1490
|
const resolvedScope = args.topicId || args.projectId ? await resolveTopicProjectScope(ctx, {
|
|
@@ -1189,10 +1599,10 @@ var update = mutation({
|
|
|
1189
1599
|
returns: permissiveReturn,
|
|
1190
1600
|
handler: async (ctx, args) => {
|
|
1191
1601
|
const { nodeId, userId, ...updates } = args;
|
|
1192
|
-
const node =
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1602
|
+
const node = requireEpistemicNodeRow(
|
|
1603
|
+
await ctx.db.get(nodeId),
|
|
1604
|
+
"Update node"
|
|
1605
|
+
);
|
|
1196
1606
|
if (node.projectId && userId) {
|
|
1197
1607
|
await requireScopeWriteAccess(ctx, node.projectId, userId);
|
|
1198
1608
|
}
|
|
@@ -1221,7 +1631,7 @@ var update = mutation({
|
|
|
1221
1631
|
entityId: String(nodeId),
|
|
1222
1632
|
changeType: "updated",
|
|
1223
1633
|
changedAt: Date.now(),
|
|
1224
|
-
changedBy: userId
|
|
1634
|
+
changedBy: userId ?? node.createdBy ?? "system:update",
|
|
1225
1635
|
isAgent: false,
|
|
1226
1636
|
previousState: {
|
|
1227
1637
|
status: node.status,
|
|
@@ -1250,10 +1660,10 @@ var supersede = mutation({
|
|
|
1250
1660
|
},
|
|
1251
1661
|
returns: permissiveReturn,
|
|
1252
1662
|
handler: async (ctx, args) => {
|
|
1253
|
-
const oldNode =
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1663
|
+
const oldNode = requireEpistemicNodeRow(
|
|
1664
|
+
await ctx.db.get(args.oldNodeId),
|
|
1665
|
+
"Supersede node"
|
|
1666
|
+
);
|
|
1257
1667
|
if (oldNode.projectId) {
|
|
1258
1668
|
await requireScopeWriteAccess(ctx, oldNode.projectId, args.createdBy);
|
|
1259
1669
|
}
|
|
@@ -1285,7 +1695,10 @@ var supersede = mutation({
|
|
|
1285
1695
|
verificationStatus: "unverified",
|
|
1286
1696
|
// New version needs re-verification
|
|
1287
1697
|
status: "active",
|
|
1698
|
+
topicId: oldNode.topicId,
|
|
1288
1699
|
projectId: oldNode.projectId,
|
|
1700
|
+
tenantId: oldNode.tenantId,
|
|
1701
|
+
workspaceId: oldNode.workspaceId,
|
|
1289
1702
|
createdBy: args.createdBy,
|
|
1290
1703
|
createdAt: now,
|
|
1291
1704
|
updatedAt: now
|
|
@@ -1326,10 +1739,10 @@ var archive = mutation({
|
|
|
1326
1739
|
},
|
|
1327
1740
|
returns: permissiveReturn,
|
|
1328
1741
|
handler: async (ctx, args) => {
|
|
1329
|
-
const node =
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1742
|
+
const node = requireEpistemicNodeRow(
|
|
1743
|
+
await ctx.db.get(args.nodeId),
|
|
1744
|
+
"Archive node"
|
|
1745
|
+
);
|
|
1333
1746
|
if (node.projectId && args.userId) {
|
|
1334
1747
|
await requireScopeWriteAccess(ctx, node.projectId, args.userId);
|
|
1335
1748
|
}
|
|
@@ -1351,7 +1764,7 @@ var archive = mutation({
|
|
|
1351
1764
|
entityId: String(args.nodeId),
|
|
1352
1765
|
changeType: "archived",
|
|
1353
1766
|
changedAt: Date.now(),
|
|
1354
|
-
changedBy: args.userId
|
|
1767
|
+
changedBy: args.userId ?? node.createdBy ?? "system:archive",
|
|
1355
1768
|
isAgent: false,
|
|
1356
1769
|
previousState: { status: node.status },
|
|
1357
1770
|
newState: { status: "archived" },
|
|
@@ -1370,10 +1783,10 @@ var verify = mutation({
|
|
|
1370
1783
|
},
|
|
1371
1784
|
returns: permissiveReturn,
|
|
1372
1785
|
handler: async (ctx, args) => {
|
|
1373
|
-
const node =
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1786
|
+
const node = requireEpistemicNodeRow(
|
|
1787
|
+
await ctx.db.get(args.nodeId),
|
|
1788
|
+
"Verify node"
|
|
1789
|
+
);
|
|
1377
1790
|
assertBeliefNodeVerifyAllowed({
|
|
1378
1791
|
node,
|
|
1379
1792
|
confidence: args.confidence,
|
|
@@ -1412,7 +1825,7 @@ var batchCreate = mutation({
|
|
|
1412
1825
|
args: {
|
|
1413
1826
|
nodes: v.array(
|
|
1414
1827
|
v.object({
|
|
1415
|
-
...
|
|
1828
|
+
...optionalNodeScopeArgs3,
|
|
1416
1829
|
globalId: v.string(),
|
|
1417
1830
|
nodeType: nodeTypeValidator,
|
|
1418
1831
|
subtype: v.optional(v.string()),
|
|
@@ -1445,7 +1858,7 @@ var batchCreate = mutation({
|
|
|
1445
1858
|
handler: async (ctx, args) => {
|
|
1446
1859
|
const resolveNodeScope = async (node) => {
|
|
1447
1860
|
if (!(node.topicId || node.projectId)) {
|
|
1448
|
-
return
|
|
1861
|
+
return;
|
|
1449
1862
|
}
|
|
1450
1863
|
try {
|
|
1451
1864
|
return await resolveTopicProjectScope(ctx, {
|
|
@@ -1461,7 +1874,7 @@ var batchCreate = mutation({
|
|
|
1461
1874
|
projectId: node.projectId
|
|
1462
1875
|
}
|
|
1463
1876
|
);
|
|
1464
|
-
return
|
|
1877
|
+
return;
|
|
1465
1878
|
}
|
|
1466
1879
|
};
|
|
1467
1880
|
const now = Date.now();
|
|
@@ -1510,223 +1923,6 @@ var batchCreate = mutation({
|
|
|
1510
1923
|
return { created: results.length, results };
|
|
1511
1924
|
}
|
|
1512
1925
|
});
|
|
1513
|
-
var optionalNodeScopeArgs3 = optionalScopeArgs;
|
|
1514
|
-
var createInternal = internalMutation({
|
|
1515
|
-
args: {
|
|
1516
|
-
...optionalNodeScopeArgs3,
|
|
1517
|
-
globalId: v.string(),
|
|
1518
|
-
nodeType: nodeTypeValidator,
|
|
1519
|
-
subtype: v.optional(v.string()),
|
|
1520
|
-
canonicalText: v.string(),
|
|
1521
|
-
contentHash: v.optional(v.string()),
|
|
1522
|
-
// Optional - will be generated if not provided
|
|
1523
|
-
content: v.optional(v.string()),
|
|
1524
|
-
contentType: v.optional(v.string()),
|
|
1525
|
-
title: v.optional(v.string()),
|
|
1526
|
-
tags: v.optional(v.array(v.string())),
|
|
1527
|
-
domain: v.optional(v.string()),
|
|
1528
|
-
metadata: v.optional(v.any()),
|
|
1529
|
-
externalIds: v.optional(
|
|
1530
|
-
v.object({
|
|
1531
|
-
crunchbase: v.optional(v.string()),
|
|
1532
|
-
linkedin: v.optional(v.string()),
|
|
1533
|
-
pitchbook: v.optional(v.string()),
|
|
1534
|
-
twitter: v.optional(v.string()),
|
|
1535
|
-
website: v.optional(v.string())
|
|
1536
|
-
})
|
|
1537
|
-
),
|
|
1538
|
-
sourceType: v.optional(sourceTypeValidator),
|
|
1539
|
-
aiProvider: v.optional(v.string()),
|
|
1540
|
-
extractedFromNodeId: v.optional(v.id("epistemicNodes")),
|
|
1541
|
-
confidence: v.optional(v.number()),
|
|
1542
|
-
verificationStatus: v.optional(verificationStatusValidator),
|
|
1543
|
-
createdBy: v.string(),
|
|
1544
|
-
// Neo4j sync status tracking
|
|
1545
|
-
syncStatus: v.optional(
|
|
1546
|
-
v.union(
|
|
1547
|
-
v.literal("synced"),
|
|
1548
|
-
v.literal("pending_edges"),
|
|
1549
|
-
v.literal("edge_creation_failed")
|
|
1550
|
-
)
|
|
1551
|
-
),
|
|
1552
|
-
epistemicLayer: v.optional(v.string()),
|
|
1553
|
-
status: v.optional(v.string())
|
|
1554
|
-
},
|
|
1555
|
-
returns: permissiveReturn,
|
|
1556
|
-
handler: async (ctx, args) => {
|
|
1557
|
-
const now = Date.now();
|
|
1558
|
-
const resolvedScope = args.topicId || args.projectId ? await (async () => {
|
|
1559
|
-
try {
|
|
1560
|
-
return await resolveTopicProjectScope(ctx, {
|
|
1561
|
-
topicId: args.topicId,
|
|
1562
|
-
projectId: args.projectId
|
|
1563
|
-
});
|
|
1564
|
-
} catch (error) {
|
|
1565
|
-
debugGraphPrimitiveFallback(
|
|
1566
|
-
"[epistemicNodes] Failed to resolve create scope",
|
|
1567
|
-
{
|
|
1568
|
-
error,
|
|
1569
|
-
topicId: args.topicId,
|
|
1570
|
-
projectId: args.projectId
|
|
1571
|
-
}
|
|
1572
|
-
);
|
|
1573
|
-
return void 0;
|
|
1574
|
-
}
|
|
1575
|
-
})() : void 0;
|
|
1576
|
-
const contentHash = args.contentHash || `${args.nodeType}:${args.canonicalText}`.slice(0, 64);
|
|
1577
|
-
const epistemicLayer = args.epistemicLayer || getNodeLayer(args.nodeType);
|
|
1578
|
-
const nodeId = await insertEpistemicNode(ctx, {
|
|
1579
|
-
globalId: args.globalId,
|
|
1580
|
-
nodeType: args.nodeType,
|
|
1581
|
-
epistemicLayer,
|
|
1582
|
-
subtype: args.subtype,
|
|
1583
|
-
canonicalText: args.canonicalText,
|
|
1584
|
-
contentHash,
|
|
1585
|
-
content: args.content,
|
|
1586
|
-
contentType: args.contentType,
|
|
1587
|
-
title: args.title,
|
|
1588
|
-
tags: args.tags,
|
|
1589
|
-
domain: args.domain,
|
|
1590
|
-
metadata: args.metadata,
|
|
1591
|
-
externalIds: args.externalIds,
|
|
1592
|
-
sourceType: args.sourceType ?? "human",
|
|
1593
|
-
aiProvider: args.aiProvider,
|
|
1594
|
-
extractedFromNodeId: args.extractedFromNodeId,
|
|
1595
|
-
confidence: args.confidence,
|
|
1596
|
-
verificationStatus: args.verificationStatus ?? "unverified",
|
|
1597
|
-
status: args.status ?? "active",
|
|
1598
|
-
topicId: resolvedScope?.topicId ?? args.topicId,
|
|
1599
|
-
projectId: resolvedScope?.projectId ?? args.projectId,
|
|
1600
|
-
createdBy: args.createdBy,
|
|
1601
|
-
createdAt: now,
|
|
1602
|
-
updatedAt: now,
|
|
1603
|
-
// Neo4j sync status
|
|
1604
|
-
syncStatus: args.syncStatus
|
|
1605
|
-
});
|
|
1606
|
-
await ctx.scheduler.runAfter(0, internal.neo4jSync.syncNodeToNeo4j, {
|
|
1607
|
-
nodeId,
|
|
1608
|
-
operation: "upsert"
|
|
1609
|
-
});
|
|
1610
|
-
return nodeId;
|
|
1611
|
-
}
|
|
1612
|
-
});
|
|
1613
|
-
var getInternal = internalQuery({
|
|
1614
|
-
args: {
|
|
1615
|
-
nodeId: v.id("epistemicNodes")
|
|
1616
|
-
},
|
|
1617
|
-
returns: permissiveReturn,
|
|
1618
|
-
handler: async (ctx, args) => {
|
|
1619
|
-
return await ctx.db.get(args.nodeId);
|
|
1620
|
-
}
|
|
1621
|
-
});
|
|
1622
|
-
var updateSyncStatus = internalMutation({
|
|
1623
|
-
args: {
|
|
1624
|
-
nodeId: v.id("epistemicNodes"),
|
|
1625
|
-
syncStatus: v.union(
|
|
1626
|
-
v.literal("synced"),
|
|
1627
|
-
v.literal("pending_edges"),
|
|
1628
|
-
v.literal("edge_creation_failed")
|
|
1629
|
-
),
|
|
1630
|
-
syncError: v.optional(v.string())
|
|
1631
|
-
},
|
|
1632
|
-
returns: permissiveReturn,
|
|
1633
|
-
handler: async (ctx, args) => {
|
|
1634
|
-
const updates = {
|
|
1635
|
-
syncStatus: args.syncStatus,
|
|
1636
|
-
updatedAt: Date.now()
|
|
1637
|
-
};
|
|
1638
|
-
if (args.syncError !== void 0) {
|
|
1639
|
-
updates.syncError = args.syncError;
|
|
1640
|
-
}
|
|
1641
|
-
await ctx.db.patch(args.nodeId, updates);
|
|
1642
|
-
return buildNodeStatusSuccessResult();
|
|
1643
|
-
}
|
|
1644
|
-
});
|
|
1645
|
-
var backfillTopicId = internalMutation({
|
|
1646
|
-
args: {
|
|
1647
|
-
nodeIds: v.array(v.id("epistemicNodes")),
|
|
1648
|
-
newTopicId: v.string()
|
|
1649
|
-
},
|
|
1650
|
-
returns: permissiveReturn,
|
|
1651
|
-
handler: async (ctx, args) => {
|
|
1652
|
-
let patched = 0;
|
|
1653
|
-
for (const nodeId of args.nodeIds) {
|
|
1654
|
-
const node = await ctx.db.get(nodeId);
|
|
1655
|
-
if (!node) {
|
|
1656
|
-
continue;
|
|
1657
|
-
}
|
|
1658
|
-
await ctx.db.patch(nodeId, {
|
|
1659
|
-
topicId: args.newTopicId,
|
|
1660
|
-
updatedAt: Date.now()
|
|
1661
|
-
});
|
|
1662
|
-
patched++;
|
|
1663
|
-
}
|
|
1664
|
-
return { patched, total: args.nodeIds.length };
|
|
1665
|
-
}
|
|
1666
|
-
});
|
|
1667
|
-
var getNodesPendingEdgeSync = internalQuery({
|
|
1668
|
-
args: {
|
|
1669
|
-
limit: v.optional(v.number())
|
|
1670
|
-
},
|
|
1671
|
-
returns: permissiveReturn,
|
|
1672
|
-
handler: async (ctx, args) => {
|
|
1673
|
-
const limit = args.limit ?? 100;
|
|
1674
|
-
return await ctx.db.query("epistemicNodes").withIndex(
|
|
1675
|
-
"by_syncStatus",
|
|
1676
|
-
(q) => q.eq("syncStatus", "edge_creation_failed")
|
|
1677
|
-
).take(limit);
|
|
1678
|
-
}
|
|
1679
|
-
});
|
|
1680
|
-
var hardDelete = internalMutation({
|
|
1681
|
-
args: {
|
|
1682
|
-
nodeId: v.id("epistemicNodes"),
|
|
1683
|
-
reason: v.string(),
|
|
1684
|
-
// Required: document why this is being hard-deleted
|
|
1685
|
-
allowBeliefHardDelete: v.optional(v.boolean())
|
|
1686
|
-
},
|
|
1687
|
-
returns: permissiveReturn,
|
|
1688
|
-
handler: async (ctx, args) => {
|
|
1689
|
-
const node = await ctx.db.get(args.nodeId);
|
|
1690
|
-
if (!node) {
|
|
1691
|
-
return buildNodeNotFoundResult();
|
|
1692
|
-
}
|
|
1693
|
-
assertBeliefNodeHardDeleteAllowed({
|
|
1694
|
-
node,
|
|
1695
|
-
allowBeliefHardDelete: args.allowBeliefHardDelete ?? false,
|
|
1696
|
-
reason: args.reason,
|
|
1697
|
-
mutationName: "epistemicNodes.hardDelete"
|
|
1698
|
-
});
|
|
1699
|
-
await ctx.db.insert("epistemicAudit", {
|
|
1700
|
-
entityType: "node",
|
|
1701
|
-
entityId: args.nodeId,
|
|
1702
|
-
changeType: "deleted",
|
|
1703
|
-
projectId: node.projectId,
|
|
1704
|
-
changedBy: "system:hard_delete",
|
|
1705
|
-
changedAt: Date.now(),
|
|
1706
|
-
isAgent: false,
|
|
1707
|
-
previousState: {
|
|
1708
|
-
nodeType: node.nodeType,
|
|
1709
|
-
title: node.title || node.canonicalText?.slice(0, 100),
|
|
1710
|
-
status: node.status
|
|
1711
|
-
},
|
|
1712
|
-
rationale: args.reason
|
|
1713
|
-
});
|
|
1714
|
-
const fromEdges = await ctx.db.query("epistemicEdges").withIndex("by_from", (q) => q.eq("fromNodeId", args.nodeId)).collect();
|
|
1715
|
-
const toEdges = await ctx.db.query("epistemicEdges").withIndex("by_to", (q) => q.eq("toNodeId", args.nodeId)).collect();
|
|
1716
|
-
const uniqueEdges = /* @__PURE__ */ new Map();
|
|
1717
|
-
for (const edge of [...fromEdges, ...toEdges]) {
|
|
1718
|
-
uniqueEdges.set(edge.globalId, edge);
|
|
1719
|
-
}
|
|
1720
|
-
for (const edge of uniqueEdges.values()) {
|
|
1721
|
-
await ctx.scheduler.runAfter(0, internal.neo4jEdgeAPI.deleteEdge, {
|
|
1722
|
-
globalId: edge.globalId
|
|
1723
|
-
});
|
|
1724
|
-
await ctx.db.delete(edge._id);
|
|
1725
|
-
}
|
|
1726
|
-
await ctx.db.delete(args.nodeId);
|
|
1727
|
-
return buildNodeDeletedResult(uniqueEdges.size);
|
|
1728
|
-
}
|
|
1729
|
-
});
|
|
1730
1926
|
|
|
1731
1927
|
// src/epistemicNodes.ts
|
|
1732
1928
|
var getByTopic = getByProject;
|