@lucern/graph-primitives 1.0.29 → 1.0.31
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/beliefDecay.js
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getAccessibleProjectIds } from '@lucern/access-control/access';
|
|
2
2
|
import { getRescoringSchedule } from '@lucern/confidence';
|
|
3
3
|
export { DEADLINE_URGENCY, DECAY_TIERS, bayesianUpdate, computeBaseDecay, computeDeadlineUrgency, computeEffectiveDecay, getRescoringSchedule } from '@lucern/confidence';
|
|
4
|
-
import { getAccessibleProjectIds } from '@lucern/access-control/access';
|
|
5
4
|
import { permissiveReturn } from '@lucern/contracts/schema-helpers/validators';
|
|
6
|
-
import {
|
|
5
|
+
import { v } from 'convex/values';
|
|
6
|
+
import { unsafeConvexAnyApi } from '@lucern/contracts/convex/unsafeAnyApi';
|
|
7
|
+
import { componentsGeneric, queryGeneric } from 'convex/server';
|
|
7
8
|
|
|
8
9
|
// src/beliefDecay.ts
|
|
9
|
-
var
|
|
10
|
+
var unsafeApi = unsafeConvexAnyApi(
|
|
11
|
+
"graph-primitives top-level module bundle lacks a committed Convex _generated/api surface"
|
|
12
|
+
);
|
|
13
|
+
var api = unsafeApi;
|
|
10
14
|
componentsGeneric();
|
|
11
15
|
var query = queryGeneric;
|
|
12
16
|
|
|
@@ -40,6 +44,10 @@ function readStringArray(value) {
|
|
|
40
44
|
function readMetadata(topic) {
|
|
41
45
|
return topic.metadata && typeof topic.metadata === "object" ? topic.metadata : {};
|
|
42
46
|
}
|
|
47
|
+
function omitMetadataKey(metadata, key) {
|
|
48
|
+
const { [key]: _omitted, ...rest } = metadata;
|
|
49
|
+
return rest;
|
|
50
|
+
}
|
|
43
51
|
function readLegacyProjectId(value) {
|
|
44
52
|
if (!value) {
|
|
45
53
|
return;
|
|
@@ -120,9 +128,12 @@ async function resolveTopicDoc(ctx, scopeId) {
|
|
|
120
128
|
);
|
|
121
129
|
}
|
|
122
130
|
try {
|
|
123
|
-
const topic = await ctx.runQuery(
|
|
124
|
-
|
|
125
|
-
|
|
131
|
+
const topic = await ctx.runQuery(
|
|
132
|
+
api.topics.getByLegacyScopeId,
|
|
133
|
+
{
|
|
134
|
+
projectId: String(scopeId)
|
|
135
|
+
}
|
|
136
|
+
);
|
|
126
137
|
if (topic?.name !== void 0 && topic?.type !== void 0) {
|
|
127
138
|
return topic;
|
|
128
139
|
}
|
|
@@ -142,8 +153,18 @@ function materializeTopicProjectOverlay(topic, idMode = "legacy") {
|
|
|
142
153
|
const outwardId = idMode === "topic" ? topicId : storageProjectId;
|
|
143
154
|
const visibility = coerceVisibility(topic.visibility) || coerceVisibility(metadata.visibility) || "private";
|
|
144
155
|
const status = coerceStatus(topic.status) || coerceStatus(metadata.status) || "active";
|
|
145
|
-
|
|
146
|
-
|
|
156
|
+
let createdAt = 0;
|
|
157
|
+
if (typeof topic.createdAt === "number") {
|
|
158
|
+
createdAt = topic.createdAt;
|
|
159
|
+
} else if (typeof topic._creationTime === "number") {
|
|
160
|
+
createdAt = topic._creationTime;
|
|
161
|
+
}
|
|
162
|
+
let updatedAt = createdAt;
|
|
163
|
+
if (typeof topic.updatedAt === "number") {
|
|
164
|
+
updatedAt = topic.updatedAt;
|
|
165
|
+
} else if (typeof metadata.updatedAt === "number") {
|
|
166
|
+
updatedAt = metadata.updatedAt;
|
|
167
|
+
}
|
|
147
168
|
return {
|
|
148
169
|
...metadata,
|
|
149
170
|
_id: outwardId,
|
|
@@ -212,90 +233,113 @@ async function patchTopicProjectOverlay(ctx, scopeId, value) {
|
|
|
212
233
|
if (!topic) {
|
|
213
234
|
return null;
|
|
214
235
|
}
|
|
215
|
-
const
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
236
|
+
const plan = buildTopicProjectOverlayPatchPlan(topic, value);
|
|
237
|
+
await applyTopicProjectOverlayPatch(ctx, topic, plan);
|
|
238
|
+
return materializeTopicProjectOverlay({
|
|
239
|
+
...topic,
|
|
240
|
+
...plan.patch,
|
|
241
|
+
metadata: plan.nextMetadata
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
function buildTopicProjectOverlayPatchPlan(topic, value) {
|
|
245
|
+
const plan = {
|
|
246
|
+
nextMetadata: { ...readMetadata(topic) },
|
|
247
|
+
patch: {},
|
|
248
|
+
topicUpdateArgs: {
|
|
249
|
+
id: String(topic._id)
|
|
250
|
+
}
|
|
219
251
|
};
|
|
220
252
|
for (const [key, rawValue] of Object.entries(value)) {
|
|
221
|
-
|
|
222
|
-
case "_id":
|
|
223
|
-
case "projectId":
|
|
224
|
-
case "topicId":
|
|
225
|
-
case "legacyProjectId":
|
|
226
|
-
case "storageProjectId":
|
|
227
|
-
break;
|
|
228
|
-
case "name":
|
|
229
|
-
case "description":
|
|
230
|
-
patch[key] = rawValue;
|
|
231
|
-
topicUpdateArgs[key] = rawValue;
|
|
232
|
-
break;
|
|
233
|
-
case "tenantId":
|
|
234
|
-
case "workspaceId":
|
|
235
|
-
case "ownerId":
|
|
236
|
-
throw new Error(
|
|
237
|
-
`patchTopicProjectOverlay cannot mutate ${key} via component-owned topics`
|
|
238
|
-
);
|
|
239
|
-
case "status": {
|
|
240
|
-
const status = coerceStatus(rawValue);
|
|
241
|
-
if (status) {
|
|
242
|
-
patch.status = status;
|
|
243
|
-
topicUpdateArgs.status = status;
|
|
244
|
-
}
|
|
245
|
-
break;
|
|
246
|
-
}
|
|
247
|
-
case "visibility": {
|
|
248
|
-
const visibility = coerceVisibility(rawValue);
|
|
249
|
-
if (visibility) {
|
|
250
|
-
patch.visibility = visibility;
|
|
251
|
-
topicUpdateArgs.visibility = visibility;
|
|
252
|
-
}
|
|
253
|
-
break;
|
|
254
|
-
}
|
|
255
|
-
case "type": {
|
|
256
|
-
const projectType = readNonEmptyString(rawValue);
|
|
257
|
-
if (projectType) {
|
|
258
|
-
nextMetadata.projectType = projectType;
|
|
259
|
-
} else {
|
|
260
|
-
delete nextMetadata.projectType;
|
|
261
|
-
}
|
|
262
|
-
break;
|
|
263
|
-
}
|
|
264
|
-
case "updatedAt":
|
|
265
|
-
case "createdAt":
|
|
266
|
-
break;
|
|
267
|
-
default:
|
|
268
|
-
if (rawValue === void 0) {
|
|
269
|
-
delete nextMetadata[key];
|
|
270
|
-
} else {
|
|
271
|
-
nextMetadata[key] = rawValue;
|
|
272
|
-
}
|
|
273
|
-
}
|
|
253
|
+
applyTopicProjectOverlayPatchEntry(plan, key, rawValue);
|
|
274
254
|
}
|
|
275
|
-
patch.updatedAt = Date.now();
|
|
276
|
-
patch.metadata = nextMetadata;
|
|
277
|
-
topicUpdateArgs.metadata = nextMetadata;
|
|
255
|
+
plan.patch.updatedAt = Date.now();
|
|
256
|
+
plan.patch.metadata = plan.nextMetadata;
|
|
257
|
+
plan.topicUpdateArgs.metadata = plan.nextMetadata;
|
|
258
|
+
return plan;
|
|
259
|
+
}
|
|
260
|
+
function applyTopicProjectOverlayPatchEntry(plan, key, rawValue) {
|
|
261
|
+
switch (key) {
|
|
262
|
+
case "_id":
|
|
263
|
+
case "projectId":
|
|
264
|
+
case "topicId":
|
|
265
|
+
case "legacyProjectId":
|
|
266
|
+
case "storageProjectId":
|
|
267
|
+
case "updatedAt":
|
|
268
|
+
case "createdAt":
|
|
269
|
+
return;
|
|
270
|
+
case "name":
|
|
271
|
+
case "description":
|
|
272
|
+
plan.patch[key] = rawValue;
|
|
273
|
+
plan.topicUpdateArgs[key] = rawValue;
|
|
274
|
+
return;
|
|
275
|
+
case "tenantId":
|
|
276
|
+
case "workspaceId":
|
|
277
|
+
case "ownerId":
|
|
278
|
+
throw new Error(
|
|
279
|
+
`patchTopicProjectOverlay cannot mutate ${key} via component-owned topics`
|
|
280
|
+
);
|
|
281
|
+
case "status":
|
|
282
|
+
applyTopicStatusPatch(plan, rawValue);
|
|
283
|
+
return;
|
|
284
|
+
case "visibility":
|
|
285
|
+
applyTopicVisibilityPatch(plan, rawValue);
|
|
286
|
+
return;
|
|
287
|
+
case "type":
|
|
288
|
+
applyTopicProjectTypePatch(plan, rawValue);
|
|
289
|
+
return;
|
|
290
|
+
default:
|
|
291
|
+
applyTopicMetadataPatch(plan, key, rawValue);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
function applyTopicStatusPatch(plan, rawValue) {
|
|
295
|
+
const status = coerceStatus(rawValue);
|
|
296
|
+
if (status) {
|
|
297
|
+
plan.patch.status = status;
|
|
298
|
+
plan.topicUpdateArgs.status = status;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
function applyTopicVisibilityPatch(plan, rawValue) {
|
|
302
|
+
const visibility = coerceVisibility(rawValue);
|
|
303
|
+
if (visibility) {
|
|
304
|
+
plan.patch.visibility = visibility;
|
|
305
|
+
plan.topicUpdateArgs.visibility = visibility;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
function applyTopicProjectTypePatch(plan, rawValue) {
|
|
309
|
+
const projectType = readNonEmptyString(rawValue);
|
|
310
|
+
if (projectType) {
|
|
311
|
+
plan.nextMetadata.projectType = projectType;
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
plan.nextMetadata = omitMetadataKey(plan.nextMetadata, "projectType");
|
|
315
|
+
}
|
|
316
|
+
function applyTopicMetadataPatch(plan, key, rawValue) {
|
|
317
|
+
if (rawValue === void 0) {
|
|
318
|
+
plan.nextMetadata = omitMetadataKey(plan.nextMetadata, key);
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
plan.nextMetadata[key] = rawValue;
|
|
322
|
+
}
|
|
323
|
+
async function applyTopicProjectOverlayPatch(ctx, topic, plan) {
|
|
278
324
|
if (typeof ctx.runMutation === "function") {
|
|
279
325
|
try {
|
|
280
|
-
await ctx.runMutation(api.topics.update, topicUpdateArgs);
|
|
326
|
+
await ctx.runMutation(api.topics.update, plan.topicUpdateArgs);
|
|
281
327
|
} catch (error) {
|
|
282
|
-
if (!
|
|
328
|
+
if (!canPatchTopicViaLocalDb(ctx, error)) {
|
|
283
329
|
throw error;
|
|
284
330
|
}
|
|
285
|
-
await ctx.db.patch(
|
|
331
|
+
await ctx.db.patch(topic._id, plan.patch);
|
|
286
332
|
}
|
|
287
333
|
} else if (ctx?.db && typeof ctx.db.patch === "function") {
|
|
288
|
-
await ctx.db.patch(
|
|
334
|
+
await ctx.db.patch(topic._id, plan.patch);
|
|
289
335
|
} else {
|
|
290
336
|
throw new Error(
|
|
291
337
|
"Cannot patch topic without component adapter (ctx.runMutation unavailable)"
|
|
292
338
|
);
|
|
293
339
|
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
metadata: nextMetadata
|
|
298
|
-
});
|
|
340
|
+
}
|
|
341
|
+
function canPatchTopicViaLocalDb(ctx, error) {
|
|
342
|
+
return isMissingLucernChildComponentError(error) && Boolean(ctx?.db) && typeof ctx.db?.patch === "function";
|
|
299
343
|
}
|
|
300
344
|
|
|
301
345
|
// src/resolvers.ts
|
|
@@ -323,7 +367,7 @@ async function patchProjectWithTolerance(ctx, projectId, value) {
|
|
|
323
367
|
try {
|
|
324
368
|
await patchTopicProjectOverlay(ctx, projectId, value);
|
|
325
369
|
} catch (error) {
|
|
326
|
-
if (!isAdvisoryTopicPatch(value)
|
|
370
|
+
if (!(isAdvisoryTopicPatch(value) && isMissingLucernChildComponentError2(error))) {
|
|
327
371
|
throw error;
|
|
328
372
|
}
|
|
329
373
|
console.warn(
|
|
@@ -390,13 +434,15 @@ function asMappedProjectId(topic) {
|
|
|
390
434
|
if (!topic) {
|
|
391
435
|
return;
|
|
392
436
|
}
|
|
393
|
-
const directLegacyProjectId = normalizeScopeValue(
|
|
437
|
+
const directLegacyProjectId = normalizeScopeValue(
|
|
438
|
+
topic[LEGACY_SCOPE_FIELD2]
|
|
439
|
+
);
|
|
394
440
|
if (directLegacyProjectId) {
|
|
395
441
|
return directLegacyProjectId;
|
|
396
442
|
}
|
|
397
443
|
const metadata = topic.metadata || {};
|
|
398
444
|
const candidate = metadata[LEGACY_SCOPE_FIELD2] || metadata.legacyProjectId || metadata.projectId || metadata.scopeProjectId;
|
|
399
|
-
return candidate ? candidate : void 0;
|
|
445
|
+
return typeof candidate === "string" ? normalizeScopeValue(candidate) : void 0;
|
|
400
446
|
}
|
|
401
447
|
function normalizeScopeValue(value) {
|
|
402
448
|
if (typeof value !== "string") {
|
|
@@ -421,8 +467,9 @@ function pickPrimaryTopic(candidates) {
|
|
|
421
467
|
})[0];
|
|
422
468
|
}
|
|
423
469
|
async function findTopicsByScopeAlias(ctx, scopeId) {
|
|
470
|
+
const query2 = ctx.db.query("topics");
|
|
424
471
|
try {
|
|
425
|
-
return await
|
|
472
|
+
return await query2.withIndex(
|
|
426
473
|
"by_graph_scope_project",
|
|
427
474
|
(q) => q.eq(LEGACY_SCOPE_FIELD2, scopeId)
|
|
428
475
|
).collect();
|
|
@@ -434,7 +481,7 @@ async function findTopicsByScopeAlias(ctx, scopeId) {
|
|
|
434
481
|
scopeId
|
|
435
482
|
}
|
|
436
483
|
);
|
|
437
|
-
const topics = await
|
|
484
|
+
const topics = await query2.collect();
|
|
438
485
|
return topics.filter((topic) => {
|
|
439
486
|
const normalizedGlobalId = normalizeScopeValue(topic.globalId);
|
|
440
487
|
const mappedProjectId = asMappedProjectId(topic);
|
|
@@ -490,143 +537,195 @@ async function resolveInheritedWorkspaceScope(ctx, topic) {
|
|
|
490
537
|
let current = topic;
|
|
491
538
|
for (let i = 0; i < MAX_DEPTH && current?.parentTopicId; i++) {
|
|
492
539
|
current = await ctx.db.get(current.parentTopicId);
|
|
493
|
-
if (!current)
|
|
540
|
+
if (!current) {
|
|
541
|
+
break;
|
|
542
|
+
}
|
|
494
543
|
if (!tenantId) {
|
|
495
544
|
tenantId = normalizeScopeValue(current.tenantId);
|
|
496
545
|
}
|
|
497
546
|
if (!workspaceId) {
|
|
498
547
|
workspaceId = normalizeScopeValue(current.workspaceId);
|
|
499
548
|
}
|
|
500
|
-
if (tenantId && workspaceId)
|
|
549
|
+
if (tenantId && workspaceId) {
|
|
550
|
+
break;
|
|
551
|
+
}
|
|
501
552
|
}
|
|
502
553
|
return { tenantId, workspaceId };
|
|
503
554
|
}
|
|
504
555
|
async function resolveTopicProjectScope(ctx, args) {
|
|
505
556
|
if (args.topicId) {
|
|
506
|
-
|
|
507
|
-
try {
|
|
508
|
-
topic = await ctx.db.get(
|
|
509
|
-
args.topicId
|
|
510
|
-
);
|
|
511
|
-
} catch (error) {
|
|
512
|
-
debugGraphPrimitiveFallback(
|
|
513
|
-
"[topicScope] Failed to load topic by direct id",
|
|
514
|
-
{
|
|
515
|
-
error,
|
|
516
|
-
topicId: args.topicId
|
|
517
|
-
}
|
|
518
|
-
);
|
|
519
|
-
}
|
|
520
|
-
if (!topic) {
|
|
521
|
-
topic = await tryResolveHostTopicById(ctx, String(args.topicId));
|
|
522
|
-
}
|
|
523
|
-
if (!topic) {
|
|
524
|
-
topic = pickPrimaryTopic(
|
|
525
|
-
await findTopicsByScopeAlias(ctx, String(args.topicId))
|
|
526
|
-
) ?? null;
|
|
527
|
-
}
|
|
528
|
-
if (!topic) {
|
|
529
|
-
const nodeScope = await resolveTopicNodeScopeOrNull(
|
|
530
|
-
ctx,
|
|
531
|
-
String(args.topicId)
|
|
532
|
-
);
|
|
533
|
-
if (nodeScope) {
|
|
534
|
-
return nodeScope;
|
|
535
|
-
}
|
|
536
|
-
throw new Error(`Topic not found: ${String(args.topicId)}`);
|
|
537
|
-
}
|
|
538
|
-
const inherited = await resolveInheritedWorkspaceScope(ctx, topic);
|
|
539
|
-
const mapped = asMappedProjectId(topic);
|
|
540
|
-
if (mapped) {
|
|
541
|
-
return {
|
|
542
|
-
topicId: topic._id,
|
|
543
|
-
projectId: mapped,
|
|
544
|
-
tenantId: inherited.tenantId,
|
|
545
|
-
workspaceId: inherited.workspaceId,
|
|
546
|
-
source: "topic"
|
|
547
|
-
};
|
|
548
|
-
}
|
|
549
|
-
return {
|
|
550
|
-
topicId: topic._id,
|
|
551
|
-
tenantId: inherited.tenantId,
|
|
552
|
-
workspaceId: inherited.workspaceId,
|
|
553
|
-
source: "topic"
|
|
554
|
-
};
|
|
557
|
+
return await resolveScopeFromTopicId(ctx, args.topicId);
|
|
555
558
|
}
|
|
556
559
|
if (args.projectId) {
|
|
557
|
-
|
|
558
|
-
try {
|
|
559
|
-
directTopic = await ctx.db.get(
|
|
560
|
-
args.projectId
|
|
561
|
-
);
|
|
562
|
-
} catch (error) {
|
|
563
|
-
debugGraphPrimitiveFallback(
|
|
564
|
-
"[topicScope] Failed to load direct project topic",
|
|
565
|
-
{
|
|
566
|
-
error,
|
|
567
|
-
projectId: args.projectId
|
|
568
|
-
}
|
|
569
|
-
);
|
|
570
|
-
}
|
|
571
|
-
if (directTopic) {
|
|
572
|
-
const inherited = await resolveInheritedWorkspaceScope(ctx, directTopic);
|
|
573
|
-
const mapped = asMappedProjectId(directTopic);
|
|
574
|
-
return {
|
|
575
|
-
topicId: directTopic._id,
|
|
576
|
-
projectId: mapped ?? args.projectId,
|
|
577
|
-
tenantId: inherited.tenantId,
|
|
578
|
-
workspaceId: inherited.workspaceId,
|
|
579
|
-
source: "topic_inferred"
|
|
580
|
-
};
|
|
581
|
-
}
|
|
582
|
-
directTopic = await tryResolveHostTopicByLegacyScope(ctx, args.projectId);
|
|
583
|
-
if (directTopic) {
|
|
584
|
-
const inherited = await resolveInheritedWorkspaceScope(ctx, directTopic);
|
|
585
|
-
const mapped = asMappedProjectId(directTopic);
|
|
586
|
-
return {
|
|
587
|
-
topicId: directTopic._id,
|
|
588
|
-
projectId: mapped ?? args.projectId,
|
|
589
|
-
tenantId: inherited.tenantId,
|
|
590
|
-
workspaceId: inherited.workspaceId,
|
|
591
|
-
source: "topic_inferred"
|
|
592
|
-
};
|
|
593
|
-
}
|
|
594
|
-
const topics = await findTopicsByScopeAlias(ctx, args.projectId);
|
|
595
|
-
const primary = pickPrimaryTopic(topics);
|
|
596
|
-
if (primary) {
|
|
597
|
-
const inherited = await resolveInheritedWorkspaceScope(ctx, primary);
|
|
598
|
-
return {
|
|
599
|
-
topicId: primary._id,
|
|
600
|
-
projectId: args.projectId,
|
|
601
|
-
tenantId: inherited.tenantId,
|
|
602
|
-
workspaceId: inherited.workspaceId,
|
|
603
|
-
source: "project_mapped_topic"
|
|
604
|
-
};
|
|
605
|
-
}
|
|
606
|
-
const nodeScope = await resolveTopicNodeScopeOrNull(
|
|
607
|
-
ctx,
|
|
608
|
-
String(args.projectId)
|
|
609
|
-
);
|
|
610
|
-
if (nodeScope) {
|
|
611
|
-
return {
|
|
612
|
-
...nodeScope,
|
|
613
|
-
projectId: nodeScope.projectId ?? String(args.projectId)
|
|
614
|
-
};
|
|
615
|
-
}
|
|
616
|
-
throw new Error(
|
|
617
|
-
`Legacy project scope ${String(args.projectId)} has no mapped topic.`
|
|
618
|
-
);
|
|
560
|
+
return await resolveScopeFromLegacyProjectId(ctx, args.projectId);
|
|
619
561
|
}
|
|
620
562
|
throw new Error(
|
|
621
563
|
"Missing scope: provide topicId (preferred) or legacy projectId alias."
|
|
622
564
|
);
|
|
623
565
|
}
|
|
566
|
+
async function resolveScopeFromTopicId(ctx, topicId) {
|
|
567
|
+
const topic = await resolveTopicDocFromTopicId(ctx, topicId);
|
|
568
|
+
if (topic) {
|
|
569
|
+
return await buildTopicScope(ctx, topic, "topic");
|
|
570
|
+
}
|
|
571
|
+
const nodeScope = await resolveTopicNodeScopeOrNull(ctx, String(topicId));
|
|
572
|
+
if (nodeScope) {
|
|
573
|
+
return nodeScope;
|
|
574
|
+
}
|
|
575
|
+
throw new Error(`Topic not found: ${String(topicId)}`);
|
|
576
|
+
}
|
|
577
|
+
async function resolveTopicDocFromTopicId(ctx, topicId) {
|
|
578
|
+
const direct = await tryReadTopicDoc(ctx, topicId, {
|
|
579
|
+
failureLog: "[topicScope] Failed to load topic by direct id",
|
|
580
|
+
idLogKey: "topicId"
|
|
581
|
+
});
|
|
582
|
+
if (direct) {
|
|
583
|
+
return direct;
|
|
584
|
+
}
|
|
585
|
+
const hostTopic = await tryResolveHostTopicById(ctx, String(topicId));
|
|
586
|
+
if (hostTopic) {
|
|
587
|
+
return hostTopic;
|
|
588
|
+
}
|
|
589
|
+
return pickPrimaryTopic(await findTopicsByScopeAlias(ctx, String(topicId))) ?? null;
|
|
590
|
+
}
|
|
591
|
+
async function resolveScopeFromLegacyProjectId(ctx, legacyProjectId) {
|
|
592
|
+
const directTopic = await resolveDirectLegacyProjectTopic(
|
|
593
|
+
ctx,
|
|
594
|
+
legacyProjectId
|
|
595
|
+
);
|
|
596
|
+
if (directTopic) {
|
|
597
|
+
return await buildTopicScope(ctx, directTopic, "topic_inferred", {
|
|
598
|
+
fallbackProjectId: legacyProjectId
|
|
599
|
+
});
|
|
600
|
+
}
|
|
601
|
+
const primary = pickPrimaryTopic(
|
|
602
|
+
await findTopicsByScopeAlias(ctx, legacyProjectId)
|
|
603
|
+
);
|
|
604
|
+
if (primary) {
|
|
605
|
+
return await buildTopicScope(ctx, primary, "project_mapped_topic", {
|
|
606
|
+
fallbackProjectId: legacyProjectId
|
|
607
|
+
});
|
|
608
|
+
}
|
|
609
|
+
const nodeScope = await resolveTopicNodeScopeOrNull(ctx, legacyProjectId);
|
|
610
|
+
if (nodeScope) {
|
|
611
|
+
return {
|
|
612
|
+
...nodeScope,
|
|
613
|
+
projectId: nodeScope.projectId ?? legacyProjectId
|
|
614
|
+
};
|
|
615
|
+
}
|
|
616
|
+
throw new Error(
|
|
617
|
+
`Legacy project scope ${legacyProjectId} has no mapped topic.`
|
|
618
|
+
);
|
|
619
|
+
}
|
|
620
|
+
async function resolveDirectLegacyProjectTopic(ctx, legacyProjectId) {
|
|
621
|
+
const directTopic = await tryReadTopicDoc(ctx, legacyProjectId, {
|
|
622
|
+
failureLog: "[topicScope] Failed to load direct project topic",
|
|
623
|
+
idLogKey: "projectId"
|
|
624
|
+
});
|
|
625
|
+
return directTopic ?? tryResolveHostTopicByLegacyScope(ctx, legacyProjectId);
|
|
626
|
+
}
|
|
627
|
+
async function tryReadTopicDoc(ctx, id, log) {
|
|
628
|
+
try {
|
|
629
|
+
return await ctx.db.get(id);
|
|
630
|
+
} catch (error) {
|
|
631
|
+
debugGraphPrimitiveFallback(log.failureLog, {
|
|
632
|
+
error,
|
|
633
|
+
[log.idLogKey]: id
|
|
634
|
+
});
|
|
635
|
+
return null;
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
async function buildTopicScope(ctx, topic, source, options = {}) {
|
|
639
|
+
const inherited = await resolveInheritedWorkspaceScope(ctx, topic);
|
|
640
|
+
const mapped = asMappedProjectId(topic);
|
|
641
|
+
return {
|
|
642
|
+
topicId: topic._id,
|
|
643
|
+
...mapped || options.fallbackProjectId ? { projectId: mapped ?? options.fallbackProjectId } : {},
|
|
644
|
+
tenantId: inherited.tenantId,
|
|
645
|
+
workspaceId: inherited.workspaceId,
|
|
646
|
+
source
|
|
647
|
+
};
|
|
648
|
+
}
|
|
624
649
|
var optionalScopeArgs = {
|
|
625
650
|
projectId: v.optional(v.string()),
|
|
626
651
|
topicId: v.optional(v.string())
|
|
627
652
|
};
|
|
628
|
-
|
|
629
|
-
|
|
653
|
+
function isRecord(value) {
|
|
654
|
+
return typeof value === "object" && value !== null;
|
|
655
|
+
}
|
|
656
|
+
function readConvexId(value) {
|
|
657
|
+
return typeof value === "string" && value.length > 0 ? value : null;
|
|
658
|
+
}
|
|
659
|
+
function readOptionalNumber(value) {
|
|
660
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
661
|
+
}
|
|
662
|
+
function readOptionalString(value) {
|
|
663
|
+
return typeof value === "string" ? value : void 0;
|
|
664
|
+
}
|
|
665
|
+
function readBeliefMetadata(value) {
|
|
666
|
+
if (!isRecord(value)) {
|
|
667
|
+
return null;
|
|
668
|
+
}
|
|
669
|
+
return {
|
|
670
|
+
beliefStatus: readOptionalString(value.beliefStatus),
|
|
671
|
+
confidence: readOptionalNumber(value.confidence)
|
|
672
|
+
};
|
|
673
|
+
}
|
|
674
|
+
function readPredictionMeta(value) {
|
|
675
|
+
if (!isRecord(value)) {
|
|
676
|
+
return null;
|
|
677
|
+
}
|
|
678
|
+
return {
|
|
679
|
+
expectedBy: readOptionalNumber(value.expectedBy)
|
|
680
|
+
};
|
|
681
|
+
}
|
|
682
|
+
function readBeliefRecord(value) {
|
|
683
|
+
if (!isRecord(value)) {
|
|
684
|
+
return null;
|
|
685
|
+
}
|
|
686
|
+
const id = readConvexId(value._id);
|
|
687
|
+
if (!id || typeof value.canonicalText !== "string") {
|
|
688
|
+
return null;
|
|
689
|
+
}
|
|
690
|
+
return {
|
|
691
|
+
_creationTime: readOptionalNumber(value._creationTime),
|
|
692
|
+
_id: id,
|
|
693
|
+
beliefStatus: readOptionalString(value.beliefStatus) ?? null,
|
|
694
|
+
canonicalText: value.canonicalText,
|
|
695
|
+
confidence: readOptionalNumber(value.confidence),
|
|
696
|
+
createdAt: readOptionalNumber(value.createdAt),
|
|
697
|
+
metadata: readBeliefMetadata(value.metadata),
|
|
698
|
+
predictionMeta: readPredictionMeta(value.predictionMeta),
|
|
699
|
+
status: readOptionalString(value.status),
|
|
700
|
+
temporalNature: readOptionalString(value.temporalNature) ?? null,
|
|
701
|
+
updatedAt: readOptionalNumber(value.updatedAt)
|
|
702
|
+
};
|
|
703
|
+
}
|
|
704
|
+
function readConfidenceEntry(value) {
|
|
705
|
+
if (!isRecord(value)) {
|
|
706
|
+
return null;
|
|
707
|
+
}
|
|
708
|
+
const assessedAt = readOptionalNumber(value.assessedAt);
|
|
709
|
+
if (assessedAt === void 0) {
|
|
710
|
+
return null;
|
|
711
|
+
}
|
|
712
|
+
return {
|
|
713
|
+
assessedAt,
|
|
714
|
+
confidence: readOptionalNumber(value.confidence) ?? null
|
|
715
|
+
};
|
|
716
|
+
}
|
|
717
|
+
function readRowList(values, reader) {
|
|
718
|
+
return values.flatMap((value) => {
|
|
719
|
+
const row = reader(value);
|
|
720
|
+
return row ? [row] : [];
|
|
721
|
+
});
|
|
722
|
+
}
|
|
723
|
+
var PRIORITY_RANK = {
|
|
724
|
+
critical: 4,
|
|
725
|
+
high: 3,
|
|
726
|
+
medium: 2,
|
|
727
|
+
low: 1
|
|
728
|
+
};
|
|
630
729
|
var identifyBeliefsNeedingRescore = query({
|
|
631
730
|
args: {
|
|
632
731
|
...optionalScopeArgs,
|
|
@@ -661,17 +760,14 @@ var identifyBeliefsNeedingRescore = query({
|
|
|
661
760
|
if (!scope) {
|
|
662
761
|
return [];
|
|
663
762
|
}
|
|
664
|
-
const
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
"by_topic_type",
|
|
673
|
-
(q) => q.eq("topicId", scope.topicId).eq("nodeType", "belief")
|
|
674
|
-
).collect();
|
|
763
|
+
const minRank = PRIORITY_RANK[minPriority] ?? 2;
|
|
764
|
+
const beliefs = readRowList(
|
|
765
|
+
await ctx.db.query("epistemicNodes").withIndex(
|
|
766
|
+
"by_topic_type",
|
|
767
|
+
(q) => q.eq("topicId", scope.topicId).eq("nodeType", "belief")
|
|
768
|
+
).collect(),
|
|
769
|
+
readBeliefRecord
|
|
770
|
+
);
|
|
675
771
|
const activeBeliefs = beliefs.filter((b) => b.status === "active");
|
|
676
772
|
const results = [];
|
|
677
773
|
for (const belief of activeBeliefs) {
|
|
@@ -679,10 +775,13 @@ var identifyBeliefsNeedingRescore = query({
|
|
|
679
775
|
const predictionMeta = belief.predictionMeta ?? void 0;
|
|
680
776
|
const temporalNature = belief.temporalNature === "forecast" || belief.temporalNature === "factual" ? belief.temporalNature : "unknown";
|
|
681
777
|
const beliefStatus = belief.beliefStatus ?? metadata.beliefStatus ?? null;
|
|
682
|
-
const confidenceHistory =
|
|
683
|
-
"
|
|
684
|
-
|
|
685
|
-
|
|
778
|
+
const confidenceHistory = readRowList(
|
|
779
|
+
await ctx.db.query("beliefConfidence").withIndex(
|
|
780
|
+
"by_beliefId",
|
|
781
|
+
(q) => q.eq("beliefId", belief._id)
|
|
782
|
+
).collect(),
|
|
783
|
+
readConfidenceEntry
|
|
784
|
+
);
|
|
686
785
|
const sorted = confidenceHistory.sort(
|
|
687
786
|
(a, b) => b.assessedAt - a.assessedAt
|
|
688
787
|
);
|
|
@@ -697,7 +796,7 @@ var identifyBeliefsNeedingRescore = query({
|
|
|
697
796
|
confidence,
|
|
698
797
|
beliefStatus
|
|
699
798
|
});
|
|
700
|
-
if (
|
|
799
|
+
if (PRIORITY_RANK[schedule.priority] >= minRank) {
|
|
701
800
|
results.push({
|
|
702
801
|
beliefId: belief._id,
|
|
703
802
|
beliefText: belief.canonicalText,
|
|
@@ -712,7 +811,7 @@ var identifyBeliefsNeedingRescore = query({
|
|
|
712
811
|
}
|
|
713
812
|
}
|
|
714
813
|
results.sort((a, b) => {
|
|
715
|
-
const rankDiff =
|
|
814
|
+
const rankDiff = PRIORITY_RANK[b.schedule.priority] - PRIORITY_RANK[a.schedule.priority];
|
|
716
815
|
if (rankDiff !== 0) {
|
|
717
816
|
return rankDiff;
|
|
718
817
|
}
|
|
@@ -749,108 +848,137 @@ var getGlobalBeliefHealth = query({
|
|
|
749
848
|
returns: permissiveReturn,
|
|
750
849
|
handler: async (ctx, args) => {
|
|
751
850
|
const { clerkId, maxResults = 30, minPriority = "medium" } = args;
|
|
752
|
-
const
|
|
753
|
-
|
|
754
|
-
high: 3,
|
|
755
|
-
medium: 2,
|
|
756
|
-
low: 1
|
|
757
|
-
};
|
|
758
|
-
const minRank = priorityRank[minPriority] ?? 2;
|
|
759
|
-
const allProjects = await resolveGraphPrimitivesAppResolvers().listTopics(ctx);
|
|
851
|
+
const minRank = PRIORITY_RANK[minPriority] ?? 2;
|
|
852
|
+
const allProjects = await listGraphPrimitiveTopics(ctx);
|
|
760
853
|
const accessibleProjectIds = await getAccessibleProjectIds(ctx, clerkId);
|
|
761
|
-
const accessibleProjects = allProjects.filter(
|
|
762
|
-
|
|
854
|
+
const accessibleProjects = allProjects.filter((project) => accessibleProjectIds.has(project._id)).slice(0, 20);
|
|
855
|
+
const allResults = sortGlobalHealthResults(
|
|
856
|
+
await collectGlobalHealthResults(ctx, accessibleProjects, minRank)
|
|
763
857
|
);
|
|
764
|
-
const allResults = [];
|
|
765
|
-
for (const project of accessibleProjects.slice(0, 20)) {
|
|
766
|
-
let scope;
|
|
767
|
-
try {
|
|
768
|
-
scope = await resolveTopicProjectScope(ctx, {
|
|
769
|
-
projectId: String(project._id)
|
|
770
|
-
});
|
|
771
|
-
} catch (error) {
|
|
772
|
-
debugGraphPrimitiveFallback(
|
|
773
|
-
"[beliefDecay] Failed to resolve project scope in health query",
|
|
774
|
-
{
|
|
775
|
-
error,
|
|
776
|
-
projectId: String(project._id)
|
|
777
|
-
}
|
|
778
|
-
);
|
|
779
|
-
continue;
|
|
780
|
-
}
|
|
781
|
-
if (!scope) {
|
|
782
|
-
continue;
|
|
783
|
-
}
|
|
784
|
-
const beliefs = await ctx.db.query("epistemicNodes").withIndex(
|
|
785
|
-
"by_topic_type",
|
|
786
|
-
(q) => q.eq("topicId", scope.topicId).eq("nodeType", "belief")
|
|
787
|
-
).collect();
|
|
788
|
-
const activeBeliefs = beliefs.filter((b) => b.status === "active");
|
|
789
|
-
for (const belief of activeBeliefs) {
|
|
790
|
-
const metadata = belief.metadata ?? {};
|
|
791
|
-
const predictionMeta = belief.predictionMeta ?? void 0;
|
|
792
|
-
const temporalNature = belief.temporalNature === "forecast" || belief.temporalNature === "factual" ? belief.temporalNature : "unknown";
|
|
793
|
-
const confidence = belief.confidence ?? metadata.confidence ?? 0.5;
|
|
794
|
-
const lastScoredAt = belief.updatedAt ?? belief.createdAt ?? belief._creationTime ?? Date.now();
|
|
795
|
-
const schedule = getRescoringSchedule({
|
|
796
|
-
lastScoredAt,
|
|
797
|
-
temporalNature,
|
|
798
|
-
expectedBy: predictionMeta?.expectedBy ?? null,
|
|
799
|
-
predictionMeta: predictionMeta ?? null,
|
|
800
|
-
confidence,
|
|
801
|
-
beliefStatus: belief.beliefStatus ?? metadata.beliefStatus ?? null
|
|
802
|
-
});
|
|
803
|
-
if (priorityRank[schedule.priority] >= minRank) {
|
|
804
|
-
allResults.push({
|
|
805
|
-
projectId: project._id,
|
|
806
|
-
projectName: project.name,
|
|
807
|
-
beliefId: belief._id,
|
|
808
|
-
beliefText: belief.canonicalText,
|
|
809
|
-
confidence,
|
|
810
|
-
temporalNature,
|
|
811
|
-
expectedBy: predictionMeta?.expectedBy ?? null,
|
|
812
|
-
daysSinceScoring: Math.round(schedule.decay.ageDays),
|
|
813
|
-
priority: schedule.priority,
|
|
814
|
-
reason: schedule.reason,
|
|
815
|
-
deadlineUrgency: schedule.decay.urgency?.urgencyTier.label ?? null
|
|
816
|
-
});
|
|
817
|
-
}
|
|
818
|
-
}
|
|
819
|
-
}
|
|
820
|
-
allResults.sort((a, b) => {
|
|
821
|
-
const rankDiff = priorityRank[b.priority] - priorityRank[a.priority];
|
|
822
|
-
if (rankDiff !== 0) {
|
|
823
|
-
return rankDiff;
|
|
824
|
-
}
|
|
825
|
-
return b.daysSinceScoring - a.daysSinceScoring;
|
|
826
|
-
});
|
|
827
858
|
const results = allResults.slice(0, maxResults);
|
|
828
|
-
const projectGroups = /* @__PURE__ */ new Map();
|
|
829
|
-
for (const r of allResults) {
|
|
830
|
-
projectGroups.set(
|
|
831
|
-
r.projectName,
|
|
832
|
-
(projectGroups.get(r.projectName) || 0) + 1
|
|
833
|
-
);
|
|
834
|
-
}
|
|
835
859
|
return {
|
|
836
860
|
beliefs: results,
|
|
837
|
-
summary:
|
|
838
|
-
total: allResults.length,
|
|
839
|
-
critical: allResults.filter((r) => r.priority === "critical").length,
|
|
840
|
-
high: allResults.filter((r) => r.priority === "high").length,
|
|
841
|
-
medium: allResults.filter((r) => r.priority === "medium").length,
|
|
842
|
-
projectsAffected: projectGroups.size,
|
|
843
|
-
forecastsApproaching: allResults.filter(
|
|
844
|
-
(r) => r.temporalNature === "forecast" && r.deadlineUrgency && r.deadlineUrgency !== "distant"
|
|
845
|
-
).length,
|
|
846
|
-
byProject: Array.from(projectGroups.entries()).map(([name, count]) => ({
|
|
847
|
-
projectName: name,
|
|
848
|
-
count
|
|
849
|
-
}))
|
|
850
|
-
}
|
|
861
|
+
summary: summarizeGlobalHealthResults(allResults)
|
|
851
862
|
};
|
|
852
863
|
}
|
|
853
864
|
});
|
|
865
|
+
async function listGraphPrimitiveTopics(ctx) {
|
|
866
|
+
return await resolveGraphPrimitivesAppResolvers().listTopics(ctx);
|
|
867
|
+
}
|
|
868
|
+
async function collectGlobalHealthResults(ctx, accessibleProjects, minRank) {
|
|
869
|
+
const results = [];
|
|
870
|
+
for (const project of accessibleProjects) {
|
|
871
|
+
results.push(...await collectProjectHealthResults(ctx, project, minRank));
|
|
872
|
+
}
|
|
873
|
+
return results;
|
|
874
|
+
}
|
|
875
|
+
async function collectProjectHealthResults(ctx, project, minRank) {
|
|
876
|
+
const scope = await resolveHealthProjectScope(ctx, project);
|
|
877
|
+
if (!scope) {
|
|
878
|
+
return [];
|
|
879
|
+
}
|
|
880
|
+
const beliefs = await readActiveTopicBeliefs(ctx, scope.topicId);
|
|
881
|
+
return beliefs.flatMap(
|
|
882
|
+
(belief) => buildGlobalHealthResult(project, belief, minRank)
|
|
883
|
+
);
|
|
884
|
+
}
|
|
885
|
+
async function resolveHealthProjectScope(ctx, project) {
|
|
886
|
+
try {
|
|
887
|
+
return await resolveTopicProjectScope(ctx, {
|
|
888
|
+
projectId: String(project._id)
|
|
889
|
+
});
|
|
890
|
+
} catch (error) {
|
|
891
|
+
debugGraphPrimitiveFallback(
|
|
892
|
+
"[beliefDecay] Failed to resolve project scope in health query",
|
|
893
|
+
{
|
|
894
|
+
error,
|
|
895
|
+
projectId: String(project._id)
|
|
896
|
+
}
|
|
897
|
+
);
|
|
898
|
+
return null;
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
async function readActiveTopicBeliefs(ctx, topicId) {
|
|
902
|
+
const beliefs = readRowList(
|
|
903
|
+
await ctx.db.query("epistemicNodes").withIndex(
|
|
904
|
+
"by_topic_type",
|
|
905
|
+
(q) => q.eq("topicId", topicId).eq("nodeType", "belief")
|
|
906
|
+
).collect(),
|
|
907
|
+
readBeliefRecord
|
|
908
|
+
);
|
|
909
|
+
return beliefs.filter((belief) => belief.status === "active");
|
|
910
|
+
}
|
|
911
|
+
function buildGlobalHealthResult(project, belief, minRank) {
|
|
912
|
+
const metadata = belief.metadata ?? {};
|
|
913
|
+
const predictionMeta = belief.predictionMeta ?? void 0;
|
|
914
|
+
const temporalNature = normalizeTemporalNature(belief.temporalNature);
|
|
915
|
+
const confidence = belief.confidence ?? metadata.confidence ?? 0.5;
|
|
916
|
+
const lastScoredAt = belief.updatedAt ?? belief.createdAt ?? belief._creationTime ?? Date.now();
|
|
917
|
+
const schedule = getRescoringSchedule({
|
|
918
|
+
lastScoredAt,
|
|
919
|
+
temporalNature,
|
|
920
|
+
expectedBy: predictionMeta?.expectedBy ?? null,
|
|
921
|
+
predictionMeta: predictionMeta ?? null,
|
|
922
|
+
confidence,
|
|
923
|
+
beliefStatus: belief.beliefStatus ?? metadata.beliefStatus ?? null
|
|
924
|
+
});
|
|
925
|
+
if (PRIORITY_RANK[schedule.priority] < minRank) {
|
|
926
|
+
return [];
|
|
927
|
+
}
|
|
928
|
+
return [
|
|
929
|
+
{
|
|
930
|
+
projectId: project._id,
|
|
931
|
+
projectName: project.name,
|
|
932
|
+
beliefId: belief._id,
|
|
933
|
+
beliefText: belief.canonicalText,
|
|
934
|
+
confidence,
|
|
935
|
+
temporalNature,
|
|
936
|
+
expectedBy: predictionMeta?.expectedBy ?? null,
|
|
937
|
+
daysSinceScoring: Math.round(schedule.decay.ageDays),
|
|
938
|
+
priority: schedule.priority,
|
|
939
|
+
reason: schedule.reason,
|
|
940
|
+
deadlineUrgency: schedule.decay.urgency?.urgencyTier.label ?? null
|
|
941
|
+
}
|
|
942
|
+
];
|
|
943
|
+
}
|
|
944
|
+
function normalizeTemporalNature(value) {
|
|
945
|
+
return value === "forecast" || value === "factual" ? value : "unknown";
|
|
946
|
+
}
|
|
947
|
+
function sortGlobalHealthResults(results) {
|
|
948
|
+
return [...results].sort((a, b) => {
|
|
949
|
+
const rankDiff = PRIORITY_RANK[b.priority] - PRIORITY_RANK[a.priority];
|
|
950
|
+
if (rankDiff !== 0) {
|
|
951
|
+
return rankDiff;
|
|
952
|
+
}
|
|
953
|
+
return b.daysSinceScoring - a.daysSinceScoring;
|
|
954
|
+
});
|
|
955
|
+
}
|
|
956
|
+
function summarizeGlobalHealthResults(allResults) {
|
|
957
|
+
const projectGroups = /* @__PURE__ */ new Map();
|
|
958
|
+
for (const result of allResults) {
|
|
959
|
+
projectGroups.set(
|
|
960
|
+
result.projectName,
|
|
961
|
+
(projectGroups.get(result.projectName) || 0) + 1
|
|
962
|
+
);
|
|
963
|
+
}
|
|
964
|
+
return {
|
|
965
|
+
total: allResults.length,
|
|
966
|
+
critical: allResults.filter((result) => result.priority === "critical").length,
|
|
967
|
+
high: allResults.filter((result) => result.priority === "high").length,
|
|
968
|
+
medium: allResults.filter((result) => result.priority === "medium").length,
|
|
969
|
+
projectsAffected: projectGroups.size,
|
|
970
|
+
forecastsApproaching: allResults.filter(isApproachingForecast).length,
|
|
971
|
+
byProject: Array.from(projectGroups.entries()).map(
|
|
972
|
+
([projectName, count]) => ({
|
|
973
|
+
projectName,
|
|
974
|
+
count
|
|
975
|
+
})
|
|
976
|
+
)
|
|
977
|
+
};
|
|
978
|
+
}
|
|
979
|
+
function isApproachingForecast(result) {
|
|
980
|
+
return result.temporalNature === "forecast" && result.deadlineUrgency !== null && result.deadlineUrgency !== "distant";
|
|
981
|
+
}
|
|
854
982
|
var getBeliefDecayInfo = query({
|
|
855
983
|
args: {
|
|
856
984
|
beliefId: v.id("epistemicNodes")
|
|
@@ -861,14 +989,20 @@ var getBeliefDecayInfo = query({
|
|
|
861
989
|
if (!belief) {
|
|
862
990
|
return null;
|
|
863
991
|
}
|
|
864
|
-
const beliefRecord = belief;
|
|
992
|
+
const beliefRecord = readBeliefRecord(belief);
|
|
993
|
+
if (!beliefRecord) {
|
|
994
|
+
return null;
|
|
995
|
+
}
|
|
865
996
|
const metadata = beliefRecord.metadata ?? {};
|
|
866
997
|
const predictionMeta = beliefRecord.predictionMeta ?? void 0;
|
|
867
998
|
const temporalNature = beliefRecord.temporalNature === "forecast" || beliefRecord.temporalNature === "factual" ? beliefRecord.temporalNature : "unknown";
|
|
868
|
-
const confidenceHistory =
|
|
869
|
-
"
|
|
870
|
-
|
|
871
|
-
|
|
999
|
+
const confidenceHistory = readRowList(
|
|
1000
|
+
await ctx.db.query("beliefConfidence").withIndex(
|
|
1001
|
+
"by_beliefId",
|
|
1002
|
+
(q) => q.eq("beliefId", args.beliefId)
|
|
1003
|
+
).collect(),
|
|
1004
|
+
readConfidenceEntry
|
|
1005
|
+
);
|
|
872
1006
|
const sorted = confidenceHistory.sort(
|
|
873
1007
|
(a, b) => b.assessedAt - a.assessedAt
|
|
874
1008
|
);
|