@lucern/graph-primitives 1.0.28 → 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 +398 -228
- 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 +857 -515
- 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 +366 -203
- package/dist/epistemicBeliefs.admin.js.map +1 -1
- package/dist/epistemicBeliefs.backfills.d.ts +8 -8
- package/dist/epistemicBeliefs.backfills.js +655 -308
- package/dist/epistemicBeliefs.backfills.js.map +1 -1
- package/dist/epistemicBeliefs.confidence.d.ts +19 -14
- package/dist/epistemicBeliefs.confidence.js +634 -423
- package/dist/epistemicBeliefs.confidence.js.map +1 -1
- package/dist/epistemicBeliefs.core.d.ts +6 -6
- package/dist/epistemicBeliefs.core.js +719 -411
- package/dist/epistemicBeliefs.core.js.map +1 -1
- package/dist/epistemicBeliefs.d.ts +11 -8
- package/dist/epistemicBeliefs.forkEvidence.d.ts +2 -0
- package/dist/epistemicBeliefs.forkEvidence.js +8 -28
- package/dist/epistemicBeliefs.forkEvidence.js.map +1 -1
- package/dist/epistemicBeliefs.helpers.d.ts +69 -74
- package/dist/epistemicBeliefs.helpers.js +359 -248
- package/dist/epistemicBeliefs.helpers.js.map +1 -1
- package/dist/epistemicBeliefs.internal.d.ts +5 -5
- package/dist/epistemicBeliefs.internal.js +1246 -1044
- package/dist/epistemicBeliefs.internal.js.map +1 -1
- package/dist/epistemicBeliefs.js +4922 -3608
- package/dist/epistemicBeliefs.js.map +1 -1
- package/dist/epistemicBeliefs.lifecycle.d.ts +5 -5
- package/dist/epistemicBeliefs.lifecycle.js +1137 -818
- package/dist/epistemicBeliefs.lifecycle.js.map +1 -1
- package/dist/epistemicBeliefs.links.d.ts +7 -7
- package/dist/epistemicBeliefs.links.js +408 -307
- 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 +1063 -613
- package/dist/epistemicContracts.evaluators.js.map +1 -1
- package/dist/epistemicContracts.handlers.d.ts +15 -32
- package/dist/epistemicContracts.handlers.js +2086 -1644
- package/dist/epistemicContracts.handlers.js.map +1 -1
- package/dist/epistemicContracts.js +1131 -672
- 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 +1969 -1205
- package/dist/epistemicEdges.js.map +1 -1
- package/dist/epistemicEdges.mutations.d.ts +7 -7
- package/dist/epistemicEdges.mutations.js +960 -583
- 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 +937 -536
- 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 +844 -696
- 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 +704 -508
- package/dist/epistemicNodes.js.map +1 -1
- package/dist/epistemicNodes.mutations.d.ts +6 -6
- package/dist/epistemicNodes.mutations.js +564 -467
- 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 +352 -312
- 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 +87 -83
- package/dist/index.js +15677 -10594
- 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
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
import { v } from 'convex/values';
|
|
2
1
|
import { permissiveReturn } from '@lucern/contracts/schema-helpers/validators';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { v } from 'convex/values';
|
|
3
|
+
import { unsafeConvexAnyApi } from '@lucern/contracts/convex/unsafeAnyApi';
|
|
4
|
+
import { componentsGeneric, internalMutationGeneric } from 'convex/server';
|
|
5
5
|
import '@lucern/contracts';
|
|
6
|
+
import { generateGlobalId, assertUuidV7Identity } from '@lucern/contracts/ids';
|
|
6
7
|
|
|
7
8
|
// src/epistemicQuestions.evidence.ts
|
|
8
|
-
var
|
|
9
|
+
var unsafeApi = unsafeConvexAnyApi(
|
|
10
|
+
"graph-primitives top-level module bundle lacks a committed Convex _generated/api surface"
|
|
11
|
+
);
|
|
12
|
+
var api = unsafeApi;
|
|
9
13
|
componentsGeneric();
|
|
10
|
-
var internal =
|
|
14
|
+
var internal = unsafeApi;
|
|
11
15
|
var internalMutation = internalMutationGeneric;
|
|
12
16
|
|
|
13
17
|
// src/debug.ts
|
|
@@ -40,278 +44,13 @@ function debugGraphPrimitiveFallback(message, context) {
|
|
|
40
44
|
}
|
|
41
45
|
console.debug(message, context ?? {});
|
|
42
46
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
return null;
|
|
47
|
-
}
|
|
48
|
-
let node = null;
|
|
49
|
-
try {
|
|
50
|
-
const byGlobalId = await ctx.db.query("epistemicNodes").withIndex("by_globalId", (q) => q.eq("globalId", ref)).first();
|
|
51
|
-
if (byGlobalId && byGlobalId.nodeType === "topic") {
|
|
52
|
-
node = byGlobalId;
|
|
53
|
-
}
|
|
54
|
-
} catch (error) {
|
|
55
|
-
debugGraphPrimitiveFallback(
|
|
56
|
-
"[topicScope] topic-node scope lookup by globalId failed",
|
|
57
|
-
{ error, ref }
|
|
58
|
-
);
|
|
59
|
-
}
|
|
60
|
-
if (!node) {
|
|
61
|
-
return null;
|
|
62
|
-
}
|
|
63
|
-
const scopeKey = normalizeScopeValue(node.topicId) ?? normalizeScopeValue(node.globalId);
|
|
64
|
-
if (!scopeKey) {
|
|
65
|
-
return null;
|
|
66
|
-
}
|
|
67
|
-
return {
|
|
68
|
-
topicId: scopeKey,
|
|
69
|
-
projectId: asMappedProjectId(node),
|
|
70
|
-
source: "topic_node"
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
function asMappedProjectId(topic) {
|
|
74
|
-
if (!topic) {
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
const directLegacyProjectId = normalizeScopeValue(topic[LEGACY_SCOPE_FIELD]);
|
|
78
|
-
if (directLegacyProjectId) {
|
|
79
|
-
return directLegacyProjectId;
|
|
80
|
-
}
|
|
81
|
-
const metadata = topic.metadata || {};
|
|
82
|
-
const candidate = metadata[LEGACY_SCOPE_FIELD] || metadata.legacyProjectId || metadata.projectId || metadata.scopeProjectId;
|
|
83
|
-
return candidate ? candidate : void 0;
|
|
84
|
-
}
|
|
85
|
-
function normalizeScopeValue(value) {
|
|
86
|
-
if (typeof value !== "string") {
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
const normalized = value.trim();
|
|
90
|
-
return normalized.length > 0 ? normalized : void 0;
|
|
91
|
-
}
|
|
92
|
-
function pickPrimaryTopic(candidates) {
|
|
93
|
-
return [...candidates].sort((a, b) => {
|
|
94
|
-
const depthA = a.depth ?? 9999;
|
|
95
|
-
const depthB = b.depth ?? 9999;
|
|
96
|
-
if (depthA !== depthB) {
|
|
97
|
-
return depthA - depthB;
|
|
98
|
-
}
|
|
99
|
-
const createdA = a.createdAt ?? Number.MAX_SAFE_INTEGER;
|
|
100
|
-
const createdB = b.createdAt ?? Number.MAX_SAFE_INTEGER;
|
|
101
|
-
if (createdA !== createdB) {
|
|
102
|
-
return createdA - createdB;
|
|
103
|
-
}
|
|
104
|
-
return String(a.name || "").localeCompare(String(b.name || ""));
|
|
105
|
-
})[0];
|
|
106
|
-
}
|
|
107
|
-
async function findTopicsByScopeAlias(ctx, scopeId) {
|
|
108
|
-
try {
|
|
109
|
-
return await ctx.db.query("topics").withIndex(
|
|
110
|
-
"by_graph_scope_project",
|
|
111
|
-
(q) => q.eq(LEGACY_SCOPE_FIELD, scopeId)
|
|
112
|
-
).collect();
|
|
113
|
-
} catch (error) {
|
|
114
|
-
debugGraphPrimitiveFallback(
|
|
115
|
-
"[topicScope] Failed to resolve scope alias via index",
|
|
116
|
-
{
|
|
117
|
-
error,
|
|
118
|
-
scopeId
|
|
119
|
-
}
|
|
120
|
-
);
|
|
121
|
-
const topics = await ctx.db.query("topics").collect();
|
|
122
|
-
return topics.filter((topic) => {
|
|
123
|
-
const normalizedGlobalId = normalizeScopeValue(topic.globalId);
|
|
124
|
-
const mappedProjectId = asMappedProjectId(topic);
|
|
125
|
-
return String(topic._id) === scopeId || normalizedGlobalId === scopeId || mappedProjectId === scopeId;
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
async function tryResolveHostTopicById(ctx, topicId) {
|
|
130
|
-
if (typeof ctx.runQuery !== "function") {
|
|
131
|
-
return null;
|
|
132
|
-
}
|
|
133
|
-
try {
|
|
134
|
-
return await ctx.runQuery(api.topics.get, {
|
|
135
|
-
id: topicId
|
|
136
|
-
}) ?? null;
|
|
137
|
-
} catch (error) {
|
|
138
|
-
debugGraphPrimitiveFallback(
|
|
139
|
-
"[topicScope] Failed to resolve topic by host query",
|
|
140
|
-
{
|
|
141
|
-
error,
|
|
142
|
-
topicId
|
|
143
|
-
}
|
|
144
|
-
);
|
|
145
|
-
return null;
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
async function tryResolveHostTopicByLegacyScope(ctx, legacyScopeId) {
|
|
149
|
-
if (typeof ctx.runQuery !== "function") {
|
|
150
|
-
return null;
|
|
151
|
-
}
|
|
152
|
-
try {
|
|
153
|
-
return await ctx.runQuery(api.topics.getByLegacyScopeId, {
|
|
154
|
-
projectId: legacyScopeId
|
|
155
|
-
}) ?? null;
|
|
156
|
-
} catch (error) {
|
|
157
|
-
debugGraphPrimitiveFallback(
|
|
158
|
-
"[topicScope] Failed to resolve topic by legacy scope",
|
|
159
|
-
{
|
|
160
|
-
error,
|
|
161
|
-
legacyScopeId
|
|
162
|
-
}
|
|
163
|
-
);
|
|
164
|
-
return null;
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
async function resolveInheritedWorkspaceScope(ctx, topic) {
|
|
168
|
-
const MAX_DEPTH = 10;
|
|
169
|
-
let tenantId = normalizeScopeValue(topic.tenantId);
|
|
170
|
-
let workspaceId = normalizeScopeValue(topic.workspaceId);
|
|
171
|
-
if (tenantId && workspaceId) {
|
|
172
|
-
return { tenantId, workspaceId };
|
|
173
|
-
}
|
|
174
|
-
let current = topic;
|
|
175
|
-
for (let i = 0; i < MAX_DEPTH && current?.parentTopicId; i++) {
|
|
176
|
-
current = await ctx.db.get(current.parentTopicId);
|
|
177
|
-
if (!current) break;
|
|
178
|
-
if (!tenantId) {
|
|
179
|
-
tenantId = normalizeScopeValue(current.tenantId);
|
|
180
|
-
}
|
|
181
|
-
if (!workspaceId) {
|
|
182
|
-
workspaceId = normalizeScopeValue(current.workspaceId);
|
|
183
|
-
}
|
|
184
|
-
if (tenantId && workspaceId) break;
|
|
185
|
-
}
|
|
186
|
-
return { tenantId, workspaceId };
|
|
187
|
-
}
|
|
188
|
-
async function resolveTopicProjectScope(ctx, args) {
|
|
189
|
-
if (args.topicId) {
|
|
190
|
-
let topic = null;
|
|
191
|
-
try {
|
|
192
|
-
topic = await ctx.db.get(
|
|
193
|
-
args.topicId
|
|
194
|
-
);
|
|
195
|
-
} catch (error) {
|
|
196
|
-
debugGraphPrimitiveFallback(
|
|
197
|
-
"[topicScope] Failed to load topic by direct id",
|
|
198
|
-
{
|
|
199
|
-
error,
|
|
200
|
-
topicId: args.topicId
|
|
201
|
-
}
|
|
202
|
-
);
|
|
203
|
-
}
|
|
204
|
-
if (!topic) {
|
|
205
|
-
topic = await tryResolveHostTopicById(ctx, String(args.topicId));
|
|
206
|
-
}
|
|
207
|
-
if (!topic) {
|
|
208
|
-
topic = pickPrimaryTopic(
|
|
209
|
-
await findTopicsByScopeAlias(ctx, String(args.topicId))
|
|
210
|
-
) ?? null;
|
|
211
|
-
}
|
|
212
|
-
if (!topic) {
|
|
213
|
-
const nodeScope = await resolveTopicNodeScopeOrNull(
|
|
214
|
-
ctx,
|
|
215
|
-
String(args.topicId)
|
|
216
|
-
);
|
|
217
|
-
if (nodeScope) {
|
|
218
|
-
return nodeScope;
|
|
219
|
-
}
|
|
220
|
-
throw new Error(`Topic not found: ${String(args.topicId)}`);
|
|
221
|
-
}
|
|
222
|
-
const inherited = await resolveInheritedWorkspaceScope(ctx, topic);
|
|
223
|
-
const mapped = asMappedProjectId(topic);
|
|
224
|
-
if (mapped) {
|
|
225
|
-
return {
|
|
226
|
-
topicId: topic._id,
|
|
227
|
-
projectId: mapped,
|
|
228
|
-
tenantId: inherited.tenantId,
|
|
229
|
-
workspaceId: inherited.workspaceId,
|
|
230
|
-
source: "topic"
|
|
231
|
-
};
|
|
232
|
-
}
|
|
233
|
-
return {
|
|
234
|
-
topicId: topic._id,
|
|
235
|
-
tenantId: inherited.tenantId,
|
|
236
|
-
workspaceId: inherited.workspaceId,
|
|
237
|
-
source: "topic"
|
|
238
|
-
};
|
|
239
|
-
}
|
|
240
|
-
if (args.projectId) {
|
|
241
|
-
let directTopic = null;
|
|
242
|
-
try {
|
|
243
|
-
directTopic = await ctx.db.get(
|
|
244
|
-
args.projectId
|
|
245
|
-
);
|
|
246
|
-
} catch (error) {
|
|
247
|
-
debugGraphPrimitiveFallback(
|
|
248
|
-
"[topicScope] Failed to load direct project topic",
|
|
249
|
-
{
|
|
250
|
-
error,
|
|
251
|
-
projectId: args.projectId
|
|
252
|
-
}
|
|
253
|
-
);
|
|
254
|
-
}
|
|
255
|
-
if (directTopic) {
|
|
256
|
-
const inherited = await resolveInheritedWorkspaceScope(ctx, directTopic);
|
|
257
|
-
const mapped = asMappedProjectId(directTopic);
|
|
258
|
-
return {
|
|
259
|
-
topicId: directTopic._id,
|
|
260
|
-
projectId: mapped ?? args.projectId,
|
|
261
|
-
tenantId: inherited.tenantId,
|
|
262
|
-
workspaceId: inherited.workspaceId,
|
|
263
|
-
source: "topic_inferred"
|
|
264
|
-
};
|
|
265
|
-
}
|
|
266
|
-
directTopic = await tryResolveHostTopicByLegacyScope(ctx, args.projectId);
|
|
267
|
-
if (directTopic) {
|
|
268
|
-
const inherited = await resolveInheritedWorkspaceScope(ctx, directTopic);
|
|
269
|
-
const mapped = asMappedProjectId(directTopic);
|
|
270
|
-
return {
|
|
271
|
-
topicId: directTopic._id,
|
|
272
|
-
projectId: mapped ?? args.projectId,
|
|
273
|
-
tenantId: inherited.tenantId,
|
|
274
|
-
workspaceId: inherited.workspaceId,
|
|
275
|
-
source: "topic_inferred"
|
|
276
|
-
};
|
|
277
|
-
}
|
|
278
|
-
const topics = await findTopicsByScopeAlias(ctx, args.projectId);
|
|
279
|
-
const primary = pickPrimaryTopic(topics);
|
|
280
|
-
if (primary) {
|
|
281
|
-
const inherited = await resolveInheritedWorkspaceScope(ctx, primary);
|
|
282
|
-
return {
|
|
283
|
-
topicId: primary._id,
|
|
284
|
-
projectId: args.projectId,
|
|
285
|
-
tenantId: inherited.tenantId,
|
|
286
|
-
workspaceId: inherited.workspaceId,
|
|
287
|
-
source: "project_mapped_topic"
|
|
288
|
-
};
|
|
289
|
-
}
|
|
290
|
-
const nodeScope = await resolveTopicNodeScopeOrNull(
|
|
291
|
-
ctx,
|
|
292
|
-
String(args.projectId)
|
|
293
|
-
);
|
|
294
|
-
if (nodeScope) {
|
|
295
|
-
return {
|
|
296
|
-
...nodeScope,
|
|
297
|
-
projectId: nodeScope.projectId ?? String(args.projectId)
|
|
298
|
-
};
|
|
299
|
-
}
|
|
300
|
-
throw new Error(
|
|
301
|
-
`Legacy project scope ${String(args.projectId)} has no mapped topic.`
|
|
302
|
-
);
|
|
303
|
-
}
|
|
304
|
-
throw new Error(
|
|
305
|
-
"Missing scope: provide topicId (preferred) or legacy projectId alias."
|
|
306
|
-
);
|
|
47
|
+
function insertEpistemicNode(ctx, doc) {
|
|
48
|
+
assertUuidV7Identity("epistemicNodes", doc.globalId);
|
|
49
|
+
return ctx.db.insert("epistemicNodes", doc);
|
|
307
50
|
}
|
|
308
|
-
var optionalScopeArgs = {
|
|
309
|
-
projectId: v.optional(v.string()),
|
|
310
|
-
topicId: v.optional(v.string())
|
|
311
|
-
};
|
|
312
51
|
|
|
313
52
|
// src/topicProjectOverlay.ts
|
|
314
|
-
var
|
|
53
|
+
var LEGACY_SCOPE_FIELD = "graphScopeProjectId";
|
|
315
54
|
function readNonEmptyString(value) {
|
|
316
55
|
if (typeof value !== "string") {
|
|
317
56
|
return;
|
|
@@ -328,11 +67,15 @@ function readStringArray(value) {
|
|
|
328
67
|
function readMetadata(topic) {
|
|
329
68
|
return topic.metadata && typeof topic.metadata === "object" ? topic.metadata : {};
|
|
330
69
|
}
|
|
70
|
+
function omitMetadataKey(metadata, key) {
|
|
71
|
+
const { [key]: _omitted, ...rest } = metadata;
|
|
72
|
+
return rest;
|
|
73
|
+
}
|
|
331
74
|
function readLegacyProjectId(value) {
|
|
332
75
|
if (!value) {
|
|
333
76
|
return;
|
|
334
77
|
}
|
|
335
|
-
return readNonEmptyString(value[
|
|
78
|
+
return readNonEmptyString(value[LEGACY_SCOPE_FIELD]);
|
|
336
79
|
}
|
|
337
80
|
function coerceVisibility(value) {
|
|
338
81
|
return value === "private" || value === "team" || value === "firm" || value === "external" || value === "public" ? value : void 0;
|
|
@@ -408,9 +151,12 @@ async function resolveTopicDoc(ctx, scopeId) {
|
|
|
408
151
|
);
|
|
409
152
|
}
|
|
410
153
|
try {
|
|
411
|
-
const topic = await ctx.runQuery(
|
|
412
|
-
|
|
413
|
-
|
|
154
|
+
const topic = await ctx.runQuery(
|
|
155
|
+
api.topics.getByLegacyScopeId,
|
|
156
|
+
{
|
|
157
|
+
projectId: String(scopeId)
|
|
158
|
+
}
|
|
159
|
+
);
|
|
414
160
|
if (topic?.name !== void 0 && topic?.type !== void 0) {
|
|
415
161
|
return topic;
|
|
416
162
|
}
|
|
@@ -430,8 +176,18 @@ function materializeTopicProjectOverlay(topic, idMode = "legacy") {
|
|
|
430
176
|
const outwardId = idMode === "topic" ? topicId : storageProjectId;
|
|
431
177
|
const visibility = coerceVisibility(topic.visibility) || coerceVisibility(metadata.visibility) || "private";
|
|
432
178
|
const status = coerceStatus(topic.status) || coerceStatus(metadata.status) || "active";
|
|
433
|
-
|
|
434
|
-
|
|
179
|
+
let createdAt = 0;
|
|
180
|
+
if (typeof topic.createdAt === "number") {
|
|
181
|
+
createdAt = topic.createdAt;
|
|
182
|
+
} else if (typeof topic._creationTime === "number") {
|
|
183
|
+
createdAt = topic._creationTime;
|
|
184
|
+
}
|
|
185
|
+
let updatedAt = createdAt;
|
|
186
|
+
if (typeof topic.updatedAt === "number") {
|
|
187
|
+
updatedAt = topic.updatedAt;
|
|
188
|
+
} else if (typeof metadata.updatedAt === "number") {
|
|
189
|
+
updatedAt = metadata.updatedAt;
|
|
190
|
+
}
|
|
435
191
|
return {
|
|
436
192
|
...metadata,
|
|
437
193
|
_id: outwardId,
|
|
@@ -500,90 +256,113 @@ async function patchTopicProjectOverlay(ctx, scopeId, value) {
|
|
|
500
256
|
if (!topic) {
|
|
501
257
|
return null;
|
|
502
258
|
}
|
|
503
|
-
const
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
259
|
+
const plan = buildTopicProjectOverlayPatchPlan(topic, value);
|
|
260
|
+
await applyTopicProjectOverlayPatch(ctx, topic, plan);
|
|
261
|
+
return materializeTopicProjectOverlay({
|
|
262
|
+
...topic,
|
|
263
|
+
...plan.patch,
|
|
264
|
+
metadata: plan.nextMetadata
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
function buildTopicProjectOverlayPatchPlan(topic, value) {
|
|
268
|
+
const plan = {
|
|
269
|
+
nextMetadata: { ...readMetadata(topic) },
|
|
270
|
+
patch: {},
|
|
271
|
+
topicUpdateArgs: {
|
|
272
|
+
id: String(topic._id)
|
|
273
|
+
}
|
|
507
274
|
};
|
|
508
275
|
for (const [key, rawValue] of Object.entries(value)) {
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
delete nextMetadata.projectType;
|
|
549
|
-
}
|
|
550
|
-
break;
|
|
551
|
-
}
|
|
552
|
-
case "updatedAt":
|
|
553
|
-
case "createdAt":
|
|
554
|
-
break;
|
|
555
|
-
default:
|
|
556
|
-
if (rawValue === void 0) {
|
|
557
|
-
delete nextMetadata[key];
|
|
558
|
-
} else {
|
|
559
|
-
nextMetadata[key] = rawValue;
|
|
560
|
-
}
|
|
561
|
-
}
|
|
276
|
+
applyTopicProjectOverlayPatchEntry(plan, key, rawValue);
|
|
277
|
+
}
|
|
278
|
+
plan.patch.updatedAt = Date.now();
|
|
279
|
+
plan.patch.metadata = plan.nextMetadata;
|
|
280
|
+
plan.topicUpdateArgs.metadata = plan.nextMetadata;
|
|
281
|
+
return plan;
|
|
282
|
+
}
|
|
283
|
+
function applyTopicProjectOverlayPatchEntry(plan, key, rawValue) {
|
|
284
|
+
switch (key) {
|
|
285
|
+
case "_id":
|
|
286
|
+
case "projectId":
|
|
287
|
+
case "topicId":
|
|
288
|
+
case "legacyProjectId":
|
|
289
|
+
case "storageProjectId":
|
|
290
|
+
case "updatedAt":
|
|
291
|
+
case "createdAt":
|
|
292
|
+
return;
|
|
293
|
+
case "name":
|
|
294
|
+
case "description":
|
|
295
|
+
plan.patch[key] = rawValue;
|
|
296
|
+
plan.topicUpdateArgs[key] = rawValue;
|
|
297
|
+
return;
|
|
298
|
+
case "tenantId":
|
|
299
|
+
case "workspaceId":
|
|
300
|
+
case "ownerId":
|
|
301
|
+
throw new Error(
|
|
302
|
+
`patchTopicProjectOverlay cannot mutate ${key} via component-owned topics`
|
|
303
|
+
);
|
|
304
|
+
case "status":
|
|
305
|
+
applyTopicStatusPatch(plan, rawValue);
|
|
306
|
+
return;
|
|
307
|
+
case "visibility":
|
|
308
|
+
applyTopicVisibilityPatch(plan, rawValue);
|
|
309
|
+
return;
|
|
310
|
+
case "type":
|
|
311
|
+
applyTopicProjectTypePatch(plan, rawValue);
|
|
312
|
+
return;
|
|
313
|
+
default:
|
|
314
|
+
applyTopicMetadataPatch(plan, key, rawValue);
|
|
562
315
|
}
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
316
|
+
}
|
|
317
|
+
function applyTopicStatusPatch(plan, rawValue) {
|
|
318
|
+
const status = coerceStatus(rawValue);
|
|
319
|
+
if (status) {
|
|
320
|
+
plan.patch.status = status;
|
|
321
|
+
plan.topicUpdateArgs.status = status;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
function applyTopicVisibilityPatch(plan, rawValue) {
|
|
325
|
+
const visibility = coerceVisibility(rawValue);
|
|
326
|
+
if (visibility) {
|
|
327
|
+
plan.patch.visibility = visibility;
|
|
328
|
+
plan.topicUpdateArgs.visibility = visibility;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
function applyTopicProjectTypePatch(plan, rawValue) {
|
|
332
|
+
const projectType = readNonEmptyString(rawValue);
|
|
333
|
+
if (projectType) {
|
|
334
|
+
plan.nextMetadata.projectType = projectType;
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
plan.nextMetadata = omitMetadataKey(plan.nextMetadata, "projectType");
|
|
338
|
+
}
|
|
339
|
+
function applyTopicMetadataPatch(plan, key, rawValue) {
|
|
340
|
+
if (rawValue === void 0) {
|
|
341
|
+
plan.nextMetadata = omitMetadataKey(plan.nextMetadata, key);
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
plan.nextMetadata[key] = rawValue;
|
|
345
|
+
}
|
|
346
|
+
async function applyTopicProjectOverlayPatch(ctx, topic, plan) {
|
|
566
347
|
if (typeof ctx.runMutation === "function") {
|
|
567
348
|
try {
|
|
568
|
-
await ctx.runMutation(api.topics.update, topicUpdateArgs);
|
|
349
|
+
await ctx.runMutation(api.topics.update, plan.topicUpdateArgs);
|
|
569
350
|
} catch (error) {
|
|
570
|
-
if (!
|
|
351
|
+
if (!canPatchTopicViaLocalDb(ctx, error)) {
|
|
571
352
|
throw error;
|
|
572
353
|
}
|
|
573
|
-
await ctx.db.patch(
|
|
354
|
+
await ctx.db.patch(topic._id, plan.patch);
|
|
574
355
|
}
|
|
575
356
|
} else if (ctx?.db && typeof ctx.db.patch === "function") {
|
|
576
|
-
await ctx.db.patch(
|
|
357
|
+
await ctx.db.patch(topic._id, plan.patch);
|
|
577
358
|
} else {
|
|
578
359
|
throw new Error(
|
|
579
360
|
"Cannot patch topic without component adapter (ctx.runMutation unavailable)"
|
|
580
361
|
);
|
|
581
362
|
}
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
metadata: nextMetadata
|
|
586
|
-
});
|
|
363
|
+
}
|
|
364
|
+
function canPatchTopicViaLocalDb(ctx, error) {
|
|
365
|
+
return isMissingLucernChildComponentError(error) && Boolean(ctx?.db) && typeof ctx.db?.patch === "function";
|
|
587
366
|
}
|
|
588
367
|
|
|
589
368
|
// src/resolvers.ts
|
|
@@ -611,7 +390,7 @@ async function patchProjectWithTolerance(ctx, projectId, value) {
|
|
|
611
390
|
try {
|
|
612
391
|
await patchTopicProjectOverlay(ctx, projectId, value);
|
|
613
392
|
} catch (error) {
|
|
614
|
-
if (!isAdvisoryTopicPatch(value)
|
|
393
|
+
if (!(isAdvisoryTopicPatch(value) && isMissingLucernChildComponentError2(error))) {
|
|
615
394
|
throw error;
|
|
616
395
|
}
|
|
617
396
|
console.warn(
|
|
@@ -644,12 +423,263 @@ function resolveGraphPrimitivesAppResolvers(_ctx) {
|
|
|
644
423
|
...resolverOverrides
|
|
645
424
|
};
|
|
646
425
|
}
|
|
426
|
+
var LEGACY_SCOPE_FIELD2 = "graphScopeProjectId";
|
|
427
|
+
async function resolveTopicNodeScopeOrNull(ctx, ref) {
|
|
428
|
+
if (!ctx?.db || typeof ctx.db.query !== "function") {
|
|
429
|
+
return null;
|
|
430
|
+
}
|
|
431
|
+
let node = null;
|
|
432
|
+
try {
|
|
433
|
+
const byGlobalId = await ctx.db.query("epistemicNodes").withIndex("by_globalId", (q) => q.eq("globalId", ref)).first();
|
|
434
|
+
if (byGlobalId && byGlobalId.nodeType === "topic") {
|
|
435
|
+
node = byGlobalId;
|
|
436
|
+
}
|
|
437
|
+
} catch (error) {
|
|
438
|
+
debugGraphPrimitiveFallback(
|
|
439
|
+
"[topicScope] topic-node scope lookup by globalId failed",
|
|
440
|
+
{ error, ref }
|
|
441
|
+
);
|
|
442
|
+
}
|
|
443
|
+
if (!node) {
|
|
444
|
+
return null;
|
|
445
|
+
}
|
|
446
|
+
const scopeKey = normalizeScopeValue(node.topicId) ?? normalizeScopeValue(node.globalId);
|
|
447
|
+
if (!scopeKey) {
|
|
448
|
+
return null;
|
|
449
|
+
}
|
|
450
|
+
return {
|
|
451
|
+
topicId: scopeKey,
|
|
452
|
+
projectId: asMappedProjectId(node),
|
|
453
|
+
source: "topic_node"
|
|
454
|
+
};
|
|
455
|
+
}
|
|
456
|
+
function asMappedProjectId(topic) {
|
|
457
|
+
if (!topic) {
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
const directLegacyProjectId = normalizeScopeValue(
|
|
461
|
+
topic[LEGACY_SCOPE_FIELD2]
|
|
462
|
+
);
|
|
463
|
+
if (directLegacyProjectId) {
|
|
464
|
+
return directLegacyProjectId;
|
|
465
|
+
}
|
|
466
|
+
const metadata = topic.metadata || {};
|
|
467
|
+
const candidate = metadata[LEGACY_SCOPE_FIELD2] || metadata.legacyProjectId || metadata.projectId || metadata.scopeProjectId;
|
|
468
|
+
return typeof candidate === "string" ? normalizeScopeValue(candidate) : void 0;
|
|
469
|
+
}
|
|
470
|
+
function normalizeScopeValue(value) {
|
|
471
|
+
if (typeof value !== "string") {
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
const normalized = value.trim();
|
|
475
|
+
return normalized.length > 0 ? normalized : void 0;
|
|
476
|
+
}
|
|
477
|
+
function pickPrimaryTopic(candidates) {
|
|
478
|
+
return [...candidates].sort((a, b) => {
|
|
479
|
+
const depthA = a.depth ?? 9999;
|
|
480
|
+
const depthB = b.depth ?? 9999;
|
|
481
|
+
if (depthA !== depthB) {
|
|
482
|
+
return depthA - depthB;
|
|
483
|
+
}
|
|
484
|
+
const createdA = a.createdAt ?? Number.MAX_SAFE_INTEGER;
|
|
485
|
+
const createdB = b.createdAt ?? Number.MAX_SAFE_INTEGER;
|
|
486
|
+
if (createdA !== createdB) {
|
|
487
|
+
return createdA - createdB;
|
|
488
|
+
}
|
|
489
|
+
return String(a.name || "").localeCompare(String(b.name || ""));
|
|
490
|
+
})[0];
|
|
491
|
+
}
|
|
492
|
+
async function findTopicsByScopeAlias(ctx, scopeId) {
|
|
493
|
+
const query2 = ctx.db.query("topics");
|
|
494
|
+
try {
|
|
495
|
+
return await query2.withIndex(
|
|
496
|
+
"by_graph_scope_project",
|
|
497
|
+
(q) => q.eq(LEGACY_SCOPE_FIELD2, scopeId)
|
|
498
|
+
).collect();
|
|
499
|
+
} catch (error) {
|
|
500
|
+
debugGraphPrimitiveFallback(
|
|
501
|
+
"[topicScope] Failed to resolve scope alias via index",
|
|
502
|
+
{
|
|
503
|
+
error,
|
|
504
|
+
scopeId
|
|
505
|
+
}
|
|
506
|
+
);
|
|
507
|
+
const topics = await query2.collect();
|
|
508
|
+
return topics.filter((topic) => {
|
|
509
|
+
const normalizedGlobalId = normalizeScopeValue(topic.globalId);
|
|
510
|
+
const mappedProjectId = asMappedProjectId(topic);
|
|
511
|
+
return String(topic._id) === scopeId || normalizedGlobalId === scopeId || mappedProjectId === scopeId;
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
async function tryResolveHostTopicById(ctx, topicId) {
|
|
516
|
+
if (typeof ctx.runQuery !== "function") {
|
|
517
|
+
return null;
|
|
518
|
+
}
|
|
519
|
+
try {
|
|
520
|
+
return await ctx.runQuery(api.topics.get, {
|
|
521
|
+
id: topicId
|
|
522
|
+
}) ?? null;
|
|
523
|
+
} catch (error) {
|
|
524
|
+
debugGraphPrimitiveFallback(
|
|
525
|
+
"[topicScope] Failed to resolve topic by host query",
|
|
526
|
+
{
|
|
527
|
+
error,
|
|
528
|
+
topicId
|
|
529
|
+
}
|
|
530
|
+
);
|
|
531
|
+
return null;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
async function tryResolveHostTopicByLegacyScope(ctx, legacyScopeId) {
|
|
535
|
+
if (typeof ctx.runQuery !== "function") {
|
|
536
|
+
return null;
|
|
537
|
+
}
|
|
538
|
+
try {
|
|
539
|
+
return await ctx.runQuery(api.topics.getByLegacyScopeId, {
|
|
540
|
+
projectId: legacyScopeId
|
|
541
|
+
}) ?? null;
|
|
542
|
+
} catch (error) {
|
|
543
|
+
debugGraphPrimitiveFallback(
|
|
544
|
+
"[topicScope] Failed to resolve topic by legacy scope",
|
|
545
|
+
{
|
|
546
|
+
error,
|
|
547
|
+
legacyScopeId
|
|
548
|
+
}
|
|
549
|
+
);
|
|
550
|
+
return null;
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
async function resolveInheritedWorkspaceScope(ctx, topic) {
|
|
554
|
+
const MAX_DEPTH = 10;
|
|
555
|
+
let tenantId = normalizeScopeValue(topic.tenantId);
|
|
556
|
+
let workspaceId = normalizeScopeValue(topic.workspaceId);
|
|
557
|
+
if (tenantId && workspaceId) {
|
|
558
|
+
return { tenantId, workspaceId };
|
|
559
|
+
}
|
|
560
|
+
let current = topic;
|
|
561
|
+
for (let i = 0; i < MAX_DEPTH && current?.parentTopicId; i++) {
|
|
562
|
+
current = await ctx.db.get(current.parentTopicId);
|
|
563
|
+
if (!current) {
|
|
564
|
+
break;
|
|
565
|
+
}
|
|
566
|
+
if (!tenantId) {
|
|
567
|
+
tenantId = normalizeScopeValue(current.tenantId);
|
|
568
|
+
}
|
|
569
|
+
if (!workspaceId) {
|
|
570
|
+
workspaceId = normalizeScopeValue(current.workspaceId);
|
|
571
|
+
}
|
|
572
|
+
if (tenantId && workspaceId) {
|
|
573
|
+
break;
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
return { tenantId, workspaceId };
|
|
577
|
+
}
|
|
578
|
+
async function resolveTopicProjectScope(ctx, args) {
|
|
579
|
+
if (args.topicId) {
|
|
580
|
+
return await resolveScopeFromTopicId(ctx, args.topicId);
|
|
581
|
+
}
|
|
582
|
+
if (args.projectId) {
|
|
583
|
+
return await resolveScopeFromLegacyProjectId(ctx, args.projectId);
|
|
584
|
+
}
|
|
585
|
+
throw new Error(
|
|
586
|
+
"Missing scope: provide topicId (preferred) or legacy projectId alias."
|
|
587
|
+
);
|
|
588
|
+
}
|
|
589
|
+
async function resolveScopeFromTopicId(ctx, topicId) {
|
|
590
|
+
const topic = await resolveTopicDocFromTopicId(ctx, topicId);
|
|
591
|
+
if (topic) {
|
|
592
|
+
return await buildTopicScope(ctx, topic, "topic");
|
|
593
|
+
}
|
|
594
|
+
const nodeScope = await resolveTopicNodeScopeOrNull(ctx, String(topicId));
|
|
595
|
+
if (nodeScope) {
|
|
596
|
+
return nodeScope;
|
|
597
|
+
}
|
|
598
|
+
throw new Error(`Topic not found: ${String(topicId)}`);
|
|
599
|
+
}
|
|
600
|
+
async function resolveTopicDocFromTopicId(ctx, topicId) {
|
|
601
|
+
const direct = await tryReadTopicDoc(ctx, topicId, {
|
|
602
|
+
failureLog: "[topicScope] Failed to load topic by direct id",
|
|
603
|
+
idLogKey: "topicId"
|
|
604
|
+
});
|
|
605
|
+
if (direct) {
|
|
606
|
+
return direct;
|
|
607
|
+
}
|
|
608
|
+
const hostTopic = await tryResolveHostTopicById(ctx, String(topicId));
|
|
609
|
+
if (hostTopic) {
|
|
610
|
+
return hostTopic;
|
|
611
|
+
}
|
|
612
|
+
return pickPrimaryTopic(await findTopicsByScopeAlias(ctx, String(topicId))) ?? null;
|
|
613
|
+
}
|
|
614
|
+
async function resolveScopeFromLegacyProjectId(ctx, legacyProjectId) {
|
|
615
|
+
const directTopic = await resolveDirectLegacyProjectTopic(
|
|
616
|
+
ctx,
|
|
617
|
+
legacyProjectId
|
|
618
|
+
);
|
|
619
|
+
if (directTopic) {
|
|
620
|
+
return await buildTopicScope(ctx, directTopic, "topic_inferred", {
|
|
621
|
+
fallbackProjectId: legacyProjectId
|
|
622
|
+
});
|
|
623
|
+
}
|
|
624
|
+
const primary = pickPrimaryTopic(
|
|
625
|
+
await findTopicsByScopeAlias(ctx, legacyProjectId)
|
|
626
|
+
);
|
|
627
|
+
if (primary) {
|
|
628
|
+
return await buildTopicScope(ctx, primary, "project_mapped_topic", {
|
|
629
|
+
fallbackProjectId: legacyProjectId
|
|
630
|
+
});
|
|
631
|
+
}
|
|
632
|
+
const nodeScope = await resolveTopicNodeScopeOrNull(ctx, legacyProjectId);
|
|
633
|
+
if (nodeScope) {
|
|
634
|
+
return {
|
|
635
|
+
...nodeScope,
|
|
636
|
+
projectId: nodeScope.projectId ?? legacyProjectId
|
|
637
|
+
};
|
|
638
|
+
}
|
|
639
|
+
throw new Error(
|
|
640
|
+
`Legacy project scope ${legacyProjectId} has no mapped topic.`
|
|
641
|
+
);
|
|
642
|
+
}
|
|
643
|
+
async function resolveDirectLegacyProjectTopic(ctx, legacyProjectId) {
|
|
644
|
+
const directTopic = await tryReadTopicDoc(ctx, legacyProjectId, {
|
|
645
|
+
failureLog: "[topicScope] Failed to load direct project topic",
|
|
646
|
+
idLogKey: "projectId"
|
|
647
|
+
});
|
|
648
|
+
return directTopic ?? tryResolveHostTopicByLegacyScope(ctx, legacyProjectId);
|
|
649
|
+
}
|
|
650
|
+
async function tryReadTopicDoc(ctx, id, log) {
|
|
651
|
+
try {
|
|
652
|
+
return await ctx.db.get(id);
|
|
653
|
+
} catch (error) {
|
|
654
|
+
debugGraphPrimitiveFallback(log.failureLog, {
|
|
655
|
+
error,
|
|
656
|
+
[log.idLogKey]: id
|
|
657
|
+
});
|
|
658
|
+
return null;
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
async function buildTopicScope(ctx, topic, source, options = {}) {
|
|
662
|
+
const inherited = await resolveInheritedWorkspaceScope(ctx, topic);
|
|
663
|
+
const mapped = asMappedProjectId(topic);
|
|
664
|
+
return {
|
|
665
|
+
topicId: topic._id,
|
|
666
|
+
...mapped || options.fallbackProjectId ? { projectId: mapped ?? options.fallbackProjectId } : {},
|
|
667
|
+
tenantId: inherited.tenantId,
|
|
668
|
+
workspaceId: inherited.workspaceId,
|
|
669
|
+
source
|
|
670
|
+
};
|
|
671
|
+
}
|
|
672
|
+
var optionalScopeArgs = {
|
|
673
|
+
projectId: v.optional(v.string()),
|
|
674
|
+
topicId: v.optional(v.string())
|
|
675
|
+
};
|
|
647
676
|
|
|
648
677
|
// src/epistemicQuestions.helpers.ts
|
|
649
678
|
async function markProjectGraphDirty(ctx, projectId, topicId) {
|
|
679
|
+
const markCacheStaleByTopic = internal.graphAnalysisCache.markCacheStaleByTopic;
|
|
650
680
|
const normalizedProjectId = typeof projectId === "string" && projectId.trim().length > 0 ? projectId : void 0;
|
|
651
681
|
const normalizedTopicId = typeof topicId === "string" && topicId.trim().length > 0 ? topicId : void 0;
|
|
652
|
-
if (!normalizedProjectId
|
|
682
|
+
if (!(normalizedProjectId || normalizedTopicId)) {
|
|
653
683
|
return;
|
|
654
684
|
}
|
|
655
685
|
if (normalizedProjectId) {
|
|
@@ -662,17 +692,17 @@ async function markProjectGraphDirty(ctx, projectId, topicId) {
|
|
|
662
692
|
);
|
|
663
693
|
}
|
|
664
694
|
if (normalizedTopicId) {
|
|
665
|
-
await ctx.scheduler.runAfter(
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
695
|
+
await ctx.scheduler.runAfter(0, markCacheStaleByTopic, {
|
|
696
|
+
topicId: normalizedTopicId
|
|
697
|
+
});
|
|
698
|
+
}
|
|
699
|
+
const resolvedProjectId = normalizedTopicId ?? normalizedProjectId;
|
|
700
|
+
if (!resolvedProjectId) {
|
|
701
|
+
return;
|
|
672
702
|
}
|
|
673
703
|
await resolveGraphPrimitivesAppResolvers().patchProject(
|
|
674
704
|
ctx,
|
|
675
|
-
|
|
705
|
+
resolvedProjectId,
|
|
676
706
|
{
|
|
677
707
|
lastActivityAt: Date.now()
|
|
678
708
|
}
|
|
@@ -695,7 +725,7 @@ function normalizeQuestionTopicId(topicId) {
|
|
|
695
725
|
return typeof topicId === "string" && topicId.trim().length > 0 ? topicId : void 0;
|
|
696
726
|
}
|
|
697
727
|
async function resolveQuestionScopeOrNull(ctx, args) {
|
|
698
|
-
if (!args.projectId
|
|
728
|
+
if (!(args.projectId || args.topicId)) {
|
|
699
729
|
return null;
|
|
700
730
|
}
|
|
701
731
|
try {
|
|
@@ -730,12 +760,62 @@ async function getQuestionNodesForScope(ctx, scope, args) {
|
|
|
730
760
|
function questionMatchesScope(node, scope) {
|
|
731
761
|
return scope.topicId !== void 0 && node.topicId === scope.topicId || scope.projectId !== void 0 && node.projectId === scope.projectId;
|
|
732
762
|
}
|
|
733
|
-
async function insertEpistemicNode(ctx, doc) {
|
|
734
|
-
assertUuidV7Identity("epistemicNodes", doc.globalId);
|
|
735
|
-
return ctx.db.insert("epistemicNodes", doc);
|
|
736
|
-
}
|
|
737
763
|
|
|
738
764
|
// src/epistemicQuestions.evidence.ts
|
|
765
|
+
function readOptionalString(value) {
|
|
766
|
+
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
767
|
+
}
|
|
768
|
+
function readConvexId(value) {
|
|
769
|
+
const normalized = readOptionalString(value);
|
|
770
|
+
return normalized ? normalized : null;
|
|
771
|
+
}
|
|
772
|
+
function readRecord(value) {
|
|
773
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
774
|
+
}
|
|
775
|
+
function readStringArray2(value) {
|
|
776
|
+
return Array.isArray(value) && value.every((item) => typeof item === "string") ? value : [];
|
|
777
|
+
}
|
|
778
|
+
function readFiniteNumber(value) {
|
|
779
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
780
|
+
}
|
|
781
|
+
function readQuestionEvidenceNodeRow(value) {
|
|
782
|
+
const record = readRecord(value);
|
|
783
|
+
if (!record) {
|
|
784
|
+
return null;
|
|
785
|
+
}
|
|
786
|
+
const id = readConvexId(record._id);
|
|
787
|
+
const nodeType = readOptionalString(record.nodeType);
|
|
788
|
+
if (!(id && nodeType)) {
|
|
789
|
+
return null;
|
|
790
|
+
}
|
|
791
|
+
const row = {
|
|
792
|
+
_id: id,
|
|
793
|
+
metadata: readRecord(record.metadata) ?? {},
|
|
794
|
+
nodeType
|
|
795
|
+
};
|
|
796
|
+
const canonicalText = readOptionalString(record.canonicalText);
|
|
797
|
+
if (canonicalText !== void 0) {
|
|
798
|
+
row.canonicalText = canonicalText;
|
|
799
|
+
}
|
|
800
|
+
const globalId = readOptionalString(record.globalId);
|
|
801
|
+
if (globalId !== void 0) {
|
|
802
|
+
row.globalId = globalId;
|
|
803
|
+
}
|
|
804
|
+
return row;
|
|
805
|
+
}
|
|
806
|
+
function readBeliefNodeRow(value) {
|
|
807
|
+
const record = readRecord(value);
|
|
808
|
+
if (!record) {
|
|
809
|
+
return null;
|
|
810
|
+
}
|
|
811
|
+
const id = readConvexId(record._id);
|
|
812
|
+
const globalId = readOptionalString(record.globalId);
|
|
813
|
+
const nodeType = readOptionalString(record.nodeType);
|
|
814
|
+
return id && globalId && nodeType ? { _id: id, globalId, nodeType } : null;
|
|
815
|
+
}
|
|
816
|
+
function resolveCanonicalEdgeTopicId(args) {
|
|
817
|
+
return normalizeQuestionTopicId(args.topicId) ?? args.projectId;
|
|
818
|
+
}
|
|
739
819
|
var createEvidenceFromScoredQuestion = internalMutation({
|
|
740
820
|
args: {
|
|
741
821
|
questionNodeId: v.id("epistemicNodes"),
|
|
@@ -751,14 +831,25 @@ var createEvidenceFromScoredQuestion = internalMutation({
|
|
|
751
831
|
returns: permissiveReturn,
|
|
752
832
|
handler: async (ctx, args) => {
|
|
753
833
|
const now = Date.now();
|
|
754
|
-
const questionNode =
|
|
834
|
+
const questionNode = readQuestionEvidenceNodeRow(
|
|
835
|
+
await ctx.db.get(args.questionNodeId)
|
|
836
|
+
);
|
|
755
837
|
if (!questionNode) {
|
|
756
838
|
return;
|
|
757
839
|
}
|
|
758
|
-
|
|
840
|
+
if (questionNode.nodeType !== "question") {
|
|
841
|
+
return;
|
|
842
|
+
}
|
|
843
|
+
if (!questionNode.globalId) {
|
|
844
|
+
throw new Error(
|
|
845
|
+
"Question node missing globalId; cannot create canonical evidence provenance edge"
|
|
846
|
+
);
|
|
847
|
+
}
|
|
848
|
+
const qMeta = questionNode.metadata;
|
|
759
849
|
if (qMeta.evidenceNodeId) {
|
|
760
850
|
return;
|
|
761
851
|
}
|
|
852
|
+
const edgeTopicId = resolveCanonicalEdgeTopicId(args);
|
|
762
853
|
const evidenceText = `Q: ${args.questionText}
|
|
763
854
|
|
|
764
855
|
A: ${args.answerText}`;
|
|
@@ -805,7 +896,8 @@ A: ${args.answerText}`;
|
|
|
805
896
|
const weight = args.conviction >= 0.5 ? args.conviction : -(1 - args.conviction);
|
|
806
897
|
async function resolveBeliefNode(bId) {
|
|
807
898
|
try {
|
|
808
|
-
const
|
|
899
|
+
const beliefNodeId = readConvexId(bId);
|
|
900
|
+
const node = beliefNodeId ? readBeliefNodeRow(await ctx.db.get(beliefNodeId)) : null;
|
|
809
901
|
if (node?.nodeType === "belief") {
|
|
810
902
|
return node;
|
|
811
903
|
}
|
|
@@ -836,7 +928,7 @@ A: ${args.answerText}`;
|
|
|
836
928
|
confidence: Math.abs(weight),
|
|
837
929
|
context: `origin=sprint_question_scoring | relation=${weight >= 0 ? "supports" : "contradicts"} | sourceQuestionId=${String(args.questionNodeId)}`,
|
|
838
930
|
createdBy: args.userId,
|
|
839
|
-
topicId:
|
|
931
|
+
topicId: edgeTopicId,
|
|
840
932
|
fromNodeType: "evidence",
|
|
841
933
|
toNodeType: "belief",
|
|
842
934
|
fromLayer: "L2",
|
|
@@ -853,7 +945,7 @@ A: ${args.answerText}`;
|
|
|
853
945
|
confidence: 1,
|
|
854
946
|
context: `origin=sprint_question_scoring | sourceQuestionId=${String(args.questionNodeId)}`,
|
|
855
947
|
createdBy: args.userId,
|
|
856
|
-
topicId:
|
|
948
|
+
topicId: edgeTopicId,
|
|
857
949
|
fromNodeType: "evidence",
|
|
858
950
|
toNodeType: "question",
|
|
859
951
|
fromLayer: "L2",
|
|
@@ -904,23 +996,23 @@ var backfillScoredQuestionEvidence = internalMutation({
|
|
|
904
996
|
candidates: []
|
|
905
997
|
};
|
|
906
998
|
}
|
|
907
|
-
const allQuestions = await getQuestionNodesForScope(ctx, scope);
|
|
999
|
+
const allQuestions = (await getQuestionNodesForScope(ctx, scope)).map(readQuestionEvidenceNodeRow).filter((node) => node !== null);
|
|
908
1000
|
const candidates = allQuestions.filter((n) => {
|
|
909
|
-
const meta = n.metadata
|
|
910
|
-
return meta.convictionStage === "scored" && meta.answer && !meta.evidenceNodeId && (meta.linkedBeliefId || meta.beliefId);
|
|
1001
|
+
const meta = n.metadata;
|
|
1002
|
+
return meta.convictionStage === "scored" && readOptionalString(meta.answer) && !meta.evidenceNodeId && (readOptionalString(meta.linkedBeliefId) || readOptionalString(meta.beliefId));
|
|
911
1003
|
});
|
|
912
1004
|
if (dryRun) {
|
|
913
1005
|
return {
|
|
914
1006
|
dryRun: true,
|
|
915
1007
|
candidateCount: candidates.length,
|
|
916
1008
|
candidates: candidates.map((n) => {
|
|
917
|
-
const meta = n.metadata
|
|
1009
|
+
const meta = n.metadata;
|
|
918
1010
|
return {
|
|
919
1011
|
questionId: n._id,
|
|
920
1012
|
questionText: n.canonicalText?.slice(0, 80),
|
|
921
|
-
beliefId: meta.linkedBeliefId
|
|
922
|
-
conviction: meta.conviction,
|
|
923
|
-
hasAnswer:
|
|
1013
|
+
beliefId: readOptionalString(meta.linkedBeliefId) ?? readOptionalString(meta.beliefId),
|
|
1014
|
+
conviction: readFiniteNumber(meta.conviction),
|
|
1015
|
+
hasAnswer: readOptionalString(meta.answer) !== void 0
|
|
924
1016
|
};
|
|
925
1017
|
})
|
|
926
1018
|
};
|
|
@@ -928,11 +1020,11 @@ var backfillScoredQuestionEvidence = internalMutation({
|
|
|
928
1020
|
let created = 0;
|
|
929
1021
|
let skipped = 0;
|
|
930
1022
|
for (const questionNode of candidates) {
|
|
931
|
-
const meta = questionNode.metadata
|
|
932
|
-
const beliefId = meta.linkedBeliefId ?? meta.beliefId;
|
|
933
|
-
const answerText = meta.answer;
|
|
934
|
-
const conviction = meta.conviction ?? 0.5;
|
|
935
|
-
if (!beliefId
|
|
1023
|
+
const meta = questionNode.metadata;
|
|
1024
|
+
const beliefId = readOptionalString(meta.linkedBeliefId) ?? readOptionalString(meta.beliefId);
|
|
1025
|
+
const answerText = readOptionalString(meta.answer);
|
|
1026
|
+
const conviction = readFiniteNumber(meta.conviction) ?? 0.5;
|
|
1027
|
+
if (!(beliefId && answerText)) {
|
|
936
1028
|
skipped++;
|
|
937
1029
|
continue;
|
|
938
1030
|
}
|
|
@@ -945,9 +1037,9 @@ var backfillScoredQuestionEvidence = internalMutation({
|
|
|
945
1037
|
questionText: questionNode.canonicalText || "",
|
|
946
1038
|
answerText,
|
|
947
1039
|
beliefId,
|
|
948
|
-
relatedBeliefIds: meta.relatedBeliefIds
|
|
1040
|
+
relatedBeliefIds: readStringArray2(meta.relatedBeliefIds),
|
|
949
1041
|
conviction,
|
|
950
|
-
rationale: meta.convictionRationale
|
|
1042
|
+
rationale: readOptionalString(meta.convictionRationale) ?? "",
|
|
951
1043
|
projectId: scope.projectId,
|
|
952
1044
|
topicId: normalizeQuestionTopicId(scope.topicId),
|
|
953
1045
|
userId: args.userId
|