@lucern/graph-primitives 1.0.29 → 1.0.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{beliefDecay-DZ6tkLYq.d.ts → beliefDecay-BmkEk5OJ.d.ts} +3 -3
- package/dist/beliefDecay.d.ts +1 -1
- package/dist/beliefDecay.js +448 -314
- package/dist/beliefDecay.js.map +1 -1
- package/dist/{beliefEvidenceLinks-CWOXxxJg.d.ts → beliefEvidenceLinks-BzfjON_6.d.ts} +13 -13
- package/dist/beliefEvidenceLinks.d.ts +1 -1
- package/dist/beliefEvidenceLinks.js +843 -624
- package/dist/beliefEvidenceLinks.js.map +1 -1
- package/dist/beliefEvidenceLinks.operational.d.ts +7 -5
- package/dist/beliefEvidenceLinks.operational.js +91 -18
- package/dist/beliefEvidenceLinks.operational.js.map +1 -1
- package/dist/beliefLifecycle.js.map +1 -1
- package/dist/confidencePropagationDispatch.d.ts +28 -27
- package/dist/confidencePropagationDispatch.js +157 -99
- package/dist/confidencePropagationDispatch.js.map +1 -1
- package/dist/{contradictions-51VLsESq.d.ts → contradictions-BATPuZTL.d.ts} +10 -10
- package/dist/contradictions.d.ts +1 -1
- package/dist/contradictions.js +395 -225
- package/dist/contradictions.js.map +1 -1
- package/dist/convex.d.ts +65 -30
- package/dist/convex.js +7 -3
- package/dist/convex.js.map +1 -1
- package/dist/debug.js.map +1 -1
- package/dist/edgeValidation.js +293 -85
- package/dist/edgeValidation.js.map +1 -1
- package/dist/edges/contains.d.ts +1 -1
- package/dist/edges/contains.js.map +1 -1
- package/dist/edges/contradicts.d.ts +1 -1
- package/dist/edges/contradicts.js.map +1 -1
- package/dist/edges/{dependsOn.d.ts → depends-on.d.ts} +1 -1
- package/dist/edges/{dependsOn.js → depends-on.js} +4 -4
- package/dist/edges/depends-on.js.map +1 -0
- package/dist/edges/{derivedFrom.d.ts → derived-from.d.ts} +1 -1
- package/dist/edges/{derivedFrom.js → derived-from.js} +3 -3
- package/dist/edges/derived-from.js.map +1 -0
- package/dist/edges/elaborates.d.ts +1 -1
- package/dist/edges/elaborates.js.map +1 -1
- package/dist/edges/index.d.ts +7 -3
- package/dist/edges/index.js +7 -4
- package/dist/edges/index.js.map +1 -1
- package/dist/edges/informs.d.ts +1 -1
- package/dist/edges/informs.js.map +1 -1
- package/dist/edges/{propagationTypes.d.ts → propagation-types.d.ts} +14 -14
- package/dist/edges/{propagationTypes.js → propagation-types.js} +3 -3
- package/dist/edges/propagation-types.js.map +1 -0
- package/dist/edges/refutes.d.ts +1 -1
- package/dist/edges/refutes.js.map +1 -1
- package/dist/edges/supports.d.ts +1 -1
- package/dist/edges/supports.js.map +1 -1
- package/dist/edges/tests.d.ts +1 -1
- package/dist/edges/tests.js.map +1 -1
- package/dist/edges/utils.d.ts +1 -1
- package/dist/edges/utils.js.map +1 -1
- package/dist/embeddingTrigger.d.ts +14 -6
- package/dist/embeddingTrigger.js +11 -14
- package/dist/embeddingTrigger.js.map +1 -1
- package/dist/{entityBridge-DMaKooYn.d.ts → entityBridge-BhVDM3pc.d.ts} +5 -5
- package/dist/entityBridge.d.ts +1 -1
- package/dist/entityBridge.js +602 -225
- package/dist/entityBridge.js.map +1 -1
- package/dist/entityCanonicalMatch.d.ts +14 -12
- package/dist/entityCanonicalMatch.js.map +1 -1
- package/dist/{entityLifecycle-CvgSK5FV.d.ts → entityLifecycle-BsfCz9pS.d.ts} +5 -9
- package/dist/entityLifecycle.d.ts +1 -1
- package/dist/entityLifecycle.js +854 -480
- package/dist/entityLifecycle.js.map +1 -1
- package/dist/{entityValidation-KLZ_Xl2D.d.ts → entityValidation-B1yNEHJx.d.ts} +7 -6
- package/dist/entityValidation.d.ts +3 -1
- package/dist/entityValidation.js +60 -8
- package/dist/entityValidation.js.map +1 -1
- package/dist/{epistemicAnswers-C5ib4z6_.d.ts → epistemicAnswers-f47YMu9U.d.ts} +6 -6
- package/dist/epistemicAnswers.d.ts +1 -1
- package/dist/epistemicAnswers.js +587 -545
- package/dist/epistemicAnswers.js.map +1 -1
- package/dist/epistemicBeliefs.admin.d.ts +8 -8
- package/dist/epistemicBeliefs.admin.js +365 -166
- package/dist/epistemicBeliefs.admin.js.map +1 -1
- package/dist/epistemicBeliefs.backfills.d.ts +8 -8
- package/dist/epistemicBeliefs.backfills.js +655 -289
- package/dist/epistemicBeliefs.backfills.js.map +1 -1
- package/dist/epistemicBeliefs.confidence.d.ts +19 -15
- package/dist/epistemicBeliefs.confidence.js +633 -386
- package/dist/epistemicBeliefs.confidence.js.map +1 -1
- package/dist/epistemicBeliefs.core.d.ts +6 -6
- package/dist/epistemicBeliefs.core.js +717 -371
- package/dist/epistemicBeliefs.core.js.map +1 -1
- package/dist/epistemicBeliefs.d.ts +11 -9
- package/dist/epistemicBeliefs.forkEvidence.d.ts +2 -0
- package/dist/epistemicBeliefs.forkEvidence.js +8 -8
- package/dist/epistemicBeliefs.forkEvidence.js.map +1 -1
- package/dist/epistemicBeliefs.helpers.d.ts +68 -49
- package/dist/epistemicBeliefs.helpers.js +358 -211
- package/dist/epistemicBeliefs.helpers.js.map +1 -1
- package/dist/epistemicBeliefs.internal.d.ts +5 -5
- package/dist/epistemicBeliefs.internal.js +1248 -1026
- package/dist/epistemicBeliefs.internal.js.map +1 -1
- package/dist/epistemicBeliefs.js +4942 -3590
- package/dist/epistemicBeliefs.js.map +1 -1
- package/dist/epistemicBeliefs.lifecycle.d.ts +5 -5
- package/dist/epistemicBeliefs.lifecycle.js +1138 -781
- package/dist/epistemicBeliefs.lifecycle.js.map +1 -1
- package/dist/epistemicBeliefs.links.d.ts +7 -7
- package/dist/epistemicBeliefs.links.js +404 -267
- package/dist/epistemicBeliefs.links.js.map +1 -1
- package/dist/epistemicBeliefs.queries.d.ts +4 -4
- package/dist/epistemicBeliefs.queries.js +175 -20
- package/dist/epistemicBeliefs.queries.js.map +1 -1
- package/dist/epistemicBeliefs.topicAnchor.d.ts +6 -4
- package/dist/epistemicBeliefs.topicAnchor.js +12 -5
- package/dist/epistemicBeliefs.topicAnchor.js.map +1 -1
- package/dist/epistemicContracts.d.ts +28 -3
- package/dist/epistemicContracts.evaluators.d.ts +2 -0
- package/dist/epistemicContracts.evaluators.js +1062 -576
- package/dist/epistemicContracts.evaluators.js.map +1 -1
- package/dist/epistemicContracts.handlers.d.ts +15 -32
- package/dist/epistemicContracts.handlers.js +1829 -1351
- package/dist/epistemicContracts.handlers.js.map +1 -1
- package/dist/epistemicContracts.js +1131 -636
- package/dist/epistemicContracts.js.map +1 -1
- package/dist/epistemicContracts.metrics.d.ts +2 -0
- package/dist/epistemicContracts.metrics.js +375 -158
- package/dist/epistemicContracts.metrics.js.map +1 -1
- package/dist/epistemicContracts.types.d.ts +87 -81
- package/dist/epistemicEdgeCreation.d.ts +2 -0
- package/dist/epistemicEdgeCreation.js +87 -16
- package/dist/epistemicEdgeCreation.js.map +1 -1
- package/dist/{epistemicEdges-BF-cn4i3.d.ts → epistemicEdges-BGBh0QSP.d.ts} +4 -7
- package/dist/epistemicEdges.d.ts +6 -5
- package/dist/epistemicEdges.handlers.d.ts +3 -3
- package/dist/epistemicEdges.handlers.js +129 -24
- package/dist/epistemicEdges.handlers.js.map +1 -1
- package/dist/epistemicEdges.helpers.d.ts +6 -4
- package/dist/epistemicEdges.helpers.js +37 -2
- package/dist/epistemicEdges.helpers.js.map +1 -1
- package/dist/epistemicEdges.js +1966 -1202
- package/dist/epistemicEdges.js.map +1 -1
- package/dist/epistemicEdges.mutations.d.ts +7 -7
- package/dist/epistemicEdges.mutations.js +956 -579
- package/dist/epistemicEdges.mutations.js.map +1 -1
- package/dist/epistemicEdges.queries.d.ts +16 -16
- package/dist/epistemicEdges.queries.js +639 -367
- package/dist/epistemicEdges.queries.js.map +1 -1
- package/dist/epistemicEdges.types.d.ts +10 -8
- package/dist/epistemicEvidence.d.ts +4 -1
- package/dist/epistemicEvidence.js +933 -532
- package/dist/epistemicEvidence.js.map +1 -1
- package/dist/epistemicEvidenceHelpers.d.ts +26 -10
- package/dist/epistemicEvidenceHelpers.js +239 -200
- package/dist/epistemicEvidenceHelpers.js.map +1 -1
- package/dist/epistemicEvidenceMutations.d.ts +8 -8
- package/dist/epistemicEvidenceMutations.js +840 -692
- package/dist/epistemicEvidenceMutations.js.map +1 -1
- package/dist/epistemicEvidenceQueries.d.ts +8 -8
- package/dist/epistemicEvidenceQueries.js +514 -238
- package/dist/epistemicEvidenceQueries.js.map +1 -1
- package/dist/epistemicHelpers.d.ts +4 -2
- package/dist/epistemicHelpers.js +308 -134
- package/dist/epistemicHelpers.js.map +1 -1
- package/dist/epistemicInsert.d.ts +16 -4
- package/dist/epistemicInsert.js +6 -3
- package/dist/epistemicInsert.js.map +1 -1
- package/dist/epistemicLayerRules.d.ts +10 -8
- package/dist/epistemicLayerRules.js +1 -5
- package/dist/epistemicLayerRules.js.map +1 -1
- package/dist/{epistemicLinking-CfE00tHJ.d.ts → epistemicLinking-CsCDv2cN.d.ts} +3 -3
- package/dist/epistemicLinking.d.ts +1 -1
- package/dist/epistemicLinking.js +177 -100
- package/dist/epistemicLinking.js.map +1 -1
- package/dist/epistemicNodeCreation.d.ts +2 -0
- package/dist/epistemicNodeCreation.js +203 -40
- package/dist/epistemicNodeCreation.js.map +1 -1
- package/dist/{epistemicNodes-BCQxpYx_.d.ts → epistemicNodes-CokAgBHg.d.ts} +3 -3
- package/dist/epistemicNodes.d.ts +3 -3
- package/dist/epistemicNodes.helpers.d.ts +24 -15
- package/dist/epistemicNodes.helpers.js.map +1 -1
- package/dist/epistemicNodes.internal.d.ts +6 -6
- package/dist/epistemicNodes.internal.js +389 -319
- package/dist/epistemicNodes.internal.js.map +1 -1
- package/dist/epistemicNodes.js +700 -504
- package/dist/epistemicNodes.js.map +1 -1
- package/dist/epistemicNodes.mutations.d.ts +6 -6
- package/dist/epistemicNodes.mutations.js +560 -463
- package/dist/epistemicNodes.mutations.js.map +1 -1
- package/dist/epistemicNodes.queries.d.ts +8 -8
- package/dist/epistemicNodes.queries.js +311 -314
- package/dist/epistemicNodes.queries.js.map +1 -1
- package/dist/epistemicNodes.validators.d.ts +2 -2
- package/dist/epistemicNodes.validators.js.map +1 -1
- package/dist/epistemicQuestions.conviction.d.ts +8 -8
- package/dist/epistemicQuestions.conviction.js +665 -484
- package/dist/epistemicQuestions.conviction.js.map +1 -1
- package/dist/epistemicQuestions.create.d.ts +4 -4
- package/dist/epistemicQuestions.create.js +640 -612
- package/dist/epistemicQuestions.create.js.map +1 -1
- package/dist/epistemicQuestions.d.ts +8 -5
- package/dist/epistemicQuestions.evidence.d.ts +2 -2
- package/dist/epistemicQuestions.evidence.js +475 -383
- package/dist/epistemicQuestions.evidence.js.map +1 -1
- package/dist/epistemicQuestions.helpers.d.ts +125 -24
- package/dist/epistemicQuestions.helpers.js +240 -209
- package/dist/epistemicQuestions.helpers.js.map +1 -1
- package/dist/epistemicQuestions.js +3474 -2823
- package/dist/epistemicQuestions.js.map +1 -1
- package/dist/epistemicQuestions.lifecycle.d.ts +2 -2
- package/dist/epistemicQuestions.lifecycle.js +607 -546
- package/dist/epistemicQuestions.lifecycle.js.map +1 -1
- package/dist/epistemicQuestions.queries.d.ts +12 -7
- package/dist/epistemicQuestions.queries.js +305 -244
- package/dist/epistemicQuestions.queries.js.map +1 -1
- package/dist/epistemicQuestions.sprint.d.ts +2 -2
- package/dist/epistemicQuestions.sprint.js +600 -394
- package/dist/epistemicQuestions.sprint.js.map +1 -1
- package/dist/epistemicQuestions.tail.d.ts +6 -6
- package/dist/epistemicQuestions.tail.js +572 -433
- package/dist/epistemicQuestions.tail.js.map +1 -1
- package/dist/{epistemicSources-dlKj58Jp.d.ts → epistemicSources-DQtaEkWs.d.ts} +4 -4
- package/dist/epistemicSources.d.ts +1 -1
- package/dist/epistemicSources.js +351 -311
- package/dist/epistemicSources.js.map +1 -1
- package/dist/evaluators/index.d.ts +8 -6
- package/dist/evaluators/index.js +399 -167
- package/dist/evaluators/index.js.map +1 -1
- package/dist/evaluators/lint-checker-evaluator.d.ts +16 -0
- package/dist/evaluators/{lintCheckerEvaluator.js → lint-checker-evaluator.js} +10 -5
- package/dist/evaluators/lint-checker-evaluator.js.map +1 -0
- package/dist/evaluators/{sentryCheckerEvaluator.d.ts → sentry-checker-evaluator.d.ts} +7 -2
- package/dist/evaluators/{sentryCheckerEvaluator.js → sentry-checker-evaluator.js} +3 -3
- package/dist/evaluators/sentry-checker-evaluator.js.map +1 -0
- package/dist/evaluators/shared.d.ts +2 -2
- package/dist/evaluators/shared.js +3 -1
- package/dist/evaluators/shared.js.map +1 -1
- package/dist/evaluators/{testRunnerEvaluator.d.ts → test-runner-evaluator.d.ts} +6 -1
- package/dist/evaluators/{testRunnerEvaluator.js → test-runner-evaluator.js} +6 -4
- package/dist/evaluators/test-runner-evaluator.js.map +1 -0
- package/dist/evaluators/tsc-checker-evaluator.d.ts +16 -0
- package/dist/evaluators/{tscCheckerEvaluator.js → tsc-checker-evaluator.js} +10 -5
- package/dist/evaluators/tsc-checker-evaluator.js.map +1 -0
- package/dist/graphTypes.js +6 -2
- package/dist/graphTypes.js.map +1 -1
- package/dist/helpers.d.ts +2 -0
- package/dist/helpers.js +313 -93
- package/dist/helpers.js.map +1 -1
- package/dist/{index-C-Kyd7hD.d.ts → index-DZxyC9Pb.d.ts} +7 -6
- package/dist/index.d.ts +86 -83
- package/dist/index.js +16914 -11760
- package/dist/index.js.map +1 -1
- package/dist/invariantEnforcement.d.ts +3 -3
- package/dist/invariantEnforcement.js.map +1 -1
- package/dist/logicalRoleInference.d.ts +2 -0
- package/dist/logicalRoleInference.js +1 -1
- package/dist/logicalRoleInference.js.map +1 -1
- package/dist/matcherFeedbackUtils.d.ts +2 -2
- package/dist/matcherFeedbackUtils.js.map +1 -1
- package/dist/{ontology-matching-C6rrz2VP.d.ts → ontology-matching-C-mYFrir.d.ts} +16 -16
- package/dist/ontology-matching.d.ts +1 -1
- package/dist/{ontologyApproval-CFYmqKmk.d.ts → ontologyApproval-BVt0feJi.d.ts} +10 -10
- package/dist/ontologyApproval.d.ts +1 -1
- package/dist/ontologyApproval.js +7 -1
- package/dist/ontologyApproval.js.map +1 -1
- package/dist/ontologyDefinitions.d.ts +14 -24
- package/dist/ontologyDefinitions.js +269 -34
- package/dist/ontologyDefinitions.js.map +1 -1
- package/dist/ontologyHelpers.d.ts +13 -13
- package/dist/ontologyHelpers.js.map +1 -1
- package/dist/{ontologyRegistry-B67rPJ16.d.ts → ontologyRegistry-CljS-ENv.d.ts} +2 -2
- package/dist/ontologyRegistry.d.ts +1 -1
- package/dist/ontologyRegistry.js +34 -6
- package/dist/ontologyRegistry.js.map +1 -1
- package/dist/{projectionReconciliation-jww2fBI0.d.ts → projectionReconciliation-DnrSgHSQ.d.ts} +4 -4
- package/dist/projectionReconciliation.d.ts +1 -1
- package/dist/projectionReconciliation.js +57 -10
- package/dist/projectionReconciliation.js.map +1 -1
- package/dist/{projectionStaleness-CmdbpjVK.d.ts → projectionStaleness-C8ImQ2zP.d.ts} +17 -17
- package/dist/projectionStaleness.d.ts +1 -1
- package/dist/projectionStaleness.js +8 -2
- package/dist/projectionStaleness.js.map +1 -1
- package/dist/proof-attestation.json +1 -1
- package/dist/{questionEvidenceLinks-DFlyPpAj.d.ts → questionEvidenceLinks-_nPRa-LY.d.ts} +10 -10
- package/dist/questionEvidenceLinks.d.ts +1 -1
- package/dist/questionEvidenceLinks.js +564 -347
- package/dist/questionEvidenceLinks.js.map +1 -1
- package/dist/{resolverTypes-CC8Ea2E2.d.ts → resolverTypes-BOXPxLET.d.ts} +8 -7
- package/dist/resolverTypes.d.ts +4 -2
- package/dist/{resolvers-Br1a6eLV.d.ts → resolvers-B1TIBmRO.d.ts} +3 -1
- package/dist/resolvers.d.ts +5 -3
- package/dist/resolvers.js +121 -77
- package/dist/resolvers.js.map +1 -1
- package/dist/scopeResolverCompat.d.ts +10 -7
- package/dist/scopeResolverCompat.js +106 -123
- package/dist/scopeResolverCompat.js.map +1 -1
- package/dist/{text-matching-DNg4M5Wd.d.ts → text-matching-DzFooju6.d.ts} +7 -7
- package/dist/text-matching.d.ts +1 -1
- package/dist/topicOntologyResolver.d.ts +22 -21
- package/dist/topicOntologyResolver.js +54 -32
- package/dist/topicOntologyResolver.js.map +1 -1
- package/dist/topicProjectOverlay.d.ts +30 -20
- package/dist/topicProjectOverlay.js +120 -76
- package/dist/topicProjectOverlay.js.map +1 -1
- package/dist/{topicScope-7zhyeGl7.d.ts → topicScope-DJVa0mLa.d.ts} +22 -7
- package/dist/topicScope.d.ts +3 -1
- package/dist/topicScope.js +104 -119
- package/dist/topicScope.js.map +1 -1
- package/dist/workflowBridge.d.ts +26 -15
- package/dist/workflowBridge.js +140 -144
- package/dist/workflowBridge.js.map +1 -1
- package/dist/workspaceIsolation.d.ts +14 -12
- package/dist/workspaceIsolation.js +108 -122
- package/dist/workspaceIsolation.js.map +1 -1
- package/package.json +4 -4
- package/dist/edges/dependsOn.js.map +0 -1
- package/dist/edges/derivedFrom.js.map +0 -1
- package/dist/edges/propagationTypes.js.map +0 -1
- package/dist/evaluators/lintCheckerEvaluator.d.ts +0 -11
- package/dist/evaluators/lintCheckerEvaluator.js.map +0 -1
- package/dist/evaluators/sentryCheckerEvaluator.js.map +0 -1
- package/dist/evaluators/testRunnerEvaluator.js.map +0 -1
- package/dist/evaluators/tscCheckerEvaluator.d.ts +0 -11
- package/dist/evaluators/tscCheckerEvaluator.js.map +0 -1
- package/dist/{epistemicQuestions-bwHd2FWE.d.ts → epistemicQuestions-Do1fhYm5.d.ts} +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/convex.ts","../src/ontologyRegistry.ts"],"names":[],"mappings":"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","file":"ontologyRegistry.js","sourcesContent":["import {\n actionGeneric,\n anyApi,\n componentsGeneric,\n httpActionGeneric,\n internalActionGeneric,\n internalMutationGeneric,\n internalQueryGeneric,\n mutationGeneric,\n queryGeneric,\n} from \"convex/server\";\nimport type { GenericId } from \"convex/values\";\n\n// TODO(FR.11-structural): `api`/`internal`/`components` are `anyApi as any`\n// because this module source tree is bundled into the kernel host at deploy time\n// and has NO top-level Convex `_generated/` directory to import a typed surface\n// from. Every `api.*` / `internal.*` / string-literal cross-component ref in this\n// module (topicScope.ts, topicProjectOverlay.ts, questionEvidenceLinks.ts,\n// beliefEvidenceLinks*.ts, epistemicQuestions.helpers.ts) inherits `any` from\n// here. The fix is structural — generate a per-module typed surface or a shared\n// typed function-reference manifest (template: the typed `components.controlPlane`\n// in modules/control-plane/src/component/convex.ts and the\n// `KERNEL_API_REF_MANIFEST` pattern in packages/server-core/src/kernelApi.ts) —\n// owned by the FR.11 closing/synthesis pass, not a mechanical swap.\nexport const api = anyApi as any;\nexport const components = componentsGeneric() as any;\nexport const internal = anyApi as any;\n\nexport type TableNames = string;\nexport type Id<TableName extends TableNames = string> = GenericId<TableName>;\nexport type Doc<TableName extends TableNames = string> = any;\nexport type DataModel = any;\ntype IndexRangeBuilder = {\n field(fieldName: string): string;\n eq(fieldName: string, value: unknown): IndexRangeBuilder;\n gt(fieldName: string, value: unknown): IndexRangeBuilder;\n gte(fieldName: string, value: unknown): IndexRangeBuilder;\n lt(fieldName: string, value: unknown): IndexRangeBuilder;\n lte(fieldName: string, value: unknown): IndexRangeBuilder;\n};\ntype FilterBuilder = {\n eq(left: unknown, right: unknown): unknown;\n neq(left: unknown, right: unknown): unknown;\n gt(left: unknown, right: unknown): unknown;\n gte(left: unknown, right: unknown): unknown;\n lt(left: unknown, right: unknown): unknown;\n lte(left: unknown, right: unknown): unknown;\n and(...clauses: unknown[]): unknown;\n or(...clauses: unknown[]): unknown;\n field(fieldName: string): unknown;\n};\ntype QueryInitializer<TableName extends TableNames> = {\n withIndex(\n indexName: string,\n range?: (q: any) => unknown\n ): QueryInitializer<TableName>;\n filter(predicate: (q: any) => unknown): QueryInitializer<TableName>;\n order(direction: \"asc\" | \"desc\"): QueryInitializer<TableName>;\n collect(): Promise<Doc<TableName>[]>;\n take(limit: number): Promise<Doc<TableName>[]>;\n first(): Promise<Doc<TableName> | null>;\n unique(): Promise<Doc<TableName> | null>;\n};\nexport type DatabaseReader = {\n get<TableName extends TableNames>(\n id: Id<TableName>\n ): Promise<Doc<TableName> | null>;\n query<TableName extends TableNames>(\n tableName: TableName\n ): QueryInitializer<TableName>;\n normalizeId?<TableName extends TableNames>(\n tableName: TableName,\n id: string\n ): Id<TableName> | null;\n};\nexport type DatabaseWriter = DatabaseReader & {\n insert<TableName extends TableNames>(\n tableName: TableName,\n value: Record<string, unknown>\n ): Promise<Id<TableName>>;\n patch<TableName extends TableNames>(\n id: Id<TableName>,\n value: Record<string, unknown>\n ): Promise<void>;\n replace<TableName extends TableNames>(\n id: Id<TableName>,\n value: Record<string, unknown>\n ): Promise<void>;\n delete<TableName extends TableNames>(id: Id<TableName>): Promise<void>;\n};\ntype Scheduler = {\n runAfter(delayMs: number, functionReference: unknown, args?: unknown): Promise<void>;\n};\ntype AuthReader = {\n getUserIdentity(): Promise<unknown>;\n};\ntype RuntimeInvoker = {\n runQuery(functionReference: unknown, args?: unknown): Promise<any>;\n runMutation(functionReference: unknown, args?: unknown): Promise<any>;\n runAction(functionReference: unknown, args?: unknown): Promise<any>;\n};\nexport type QueryCtx = RuntimeInvoker & {\n auth: AuthReader;\n db: DatabaseReader;\n scheduler: Scheduler;\n};\nexport type MutationCtx = RuntimeInvoker & {\n auth: AuthReader;\n db: DatabaseWriter;\n scheduler: Scheduler;\n};\nexport type ActionCtx = RuntimeInvoker & {\n auth: AuthReader;\n scheduler: Scheduler;\n};\n\ntype ConvexFunctionBuilder<Ctx> = <\n Definition extends { handler?: (ctx: Ctx, args: any) => any },\n>(\n definition: Definition\n) => any;\n\nexport const action = actionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const httpAction =\n httpActionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const internalAction =\n internalActionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const internalMutation =\n internalMutationGeneric as unknown as ConvexFunctionBuilder<MutationCtx>;\nexport const internalQuery =\n internalQueryGeneric as unknown as ConvexFunctionBuilder<QueryCtx>;\nexport const mutation =\n mutationGeneric as unknown as ConvexFunctionBuilder<MutationCtx>;\nexport const query = queryGeneric as unknown as ConvexFunctionBuilder<QueryCtx>;\n","/**\n * Ontology Registry\n *\n * Seeds schemaEnumConfig with platform-default entity types, subtypes,\n * and entity edge types. Provides tenant extension API.\n *\n * Categories:\n * - entity_type: Company, Person, Investor, Function, ValueChain\n * - entity_subtype: company/private, investor/vc, etc.\n * - entity_edge_type: works_at, invested_in, etc.\n *\n * @module graph-primitives/ontologyRegistry\n */\n\nimport { v } from \"convex/values\";\nimport { getCurrentUserId } from \"@lucern/access-control/auth\";\nimport { permissiveReturn } from \"@lucern/contracts/schema-helpers/validators\";\nimport type { MutationCtx } from \"./convex\";\nimport { internalMutation, mutation } from \"./convex\";\n\n// =============================================================================\n// PLATFORM-DEFAULT ENTITY TYPES\n// =============================================================================\n\ntype FieldSchema = {\n type: \"string\" | \"number\" | \"boolean\";\n required: boolean;\n};\n\ntype EntityTypeDefinition = {\n value: string;\n label: string;\n description: string;\n schema: Record<string, FieldSchema>;\n};\n\nconst PLATFORM_ENTITY_TYPES: EntityTypeDefinition[] = [\n {\n value: \"company\",\n label: \"Company\",\n description: \"A business entity — startup, portfolio company, or corporate\",\n schema: {\n name: { type: \"string\", required: true },\n sector: { type: \"string\", required: false },\n founded_year: { type: \"number\", required: false },\n website: { type: \"string\", required: false },\n domain: { type: \"string\", required: false },\n },\n },\n {\n value: \"person\",\n label: \"Person\",\n description: \"An individual — founder, executive, or contact\",\n schema: {\n name: { type: \"string\", required: true },\n role: { type: \"string\", required: false },\n affiliation: { type: \"string\", required: false },\n linkedin: { type: \"string\", required: false },\n },\n },\n {\n value: \"investor\",\n label: \"Investor\",\n description: \"An investment entity — fund, GP, or angel\",\n schema: {\n name: { type: \"string\", required: true },\n fund_name: { type: \"string\", required: false },\n investment_focus: { type: \"string\", required: false },\n aum: { type: \"number\", required: false },\n },\n },\n {\n value: \"function\",\n label: \"Function\",\n description: \"A business function in a value chain\",\n schema: {\n name: { type: \"string\", required: true },\n description: { type: \"string\", required: false },\n },\n },\n {\n value: \"value_chain\",\n label: \"Value Chain\",\n description: \"A value chain or industry vertical\",\n schema: {\n name: { type: \"string\", required: true },\n description: { type: \"string\", required: false },\n },\n },\n];\n\n// =============================================================================\n// PLATFORM-DEFAULT ENTITY SUBTYPES\n// =============================================================================\n\ntype SubtypeDefinition = {\n value: string;\n label: string;\n parentType: string;\n};\n\nconst PLATFORM_ENTITY_SUBTYPES: SubtypeDefinition[] = [\n // Company subtypes\n { value: \"company/private\", label: \"Private Company\", parentType: \"company\" },\n { value: \"company/corporate\", label: \"Corporate\", parentType: \"company\" },\n {\n value: \"company/portfolio\",\n label: \"Portfolio Company\",\n parentType: \"company\",\n },\n // Investor subtypes\n { value: \"investor/vc\", label: \"Venture Capital\", parentType: \"investor\" },\n { value: \"investor/lp\", label: \"Limited Partner\", parentType: \"investor\" },\n { value: \"investor/cvc\", label: \"Corporate VC\", parentType: \"investor\" },\n { value: \"investor/pe\", label: \"Private Equity\", parentType: \"investor\" },\n {\n value: \"investor/family_office\",\n label: \"Family Office\",\n parentType: \"investor\",\n },\n { value: \"investor/angel\", label: \"Angel Investor\", parentType: \"investor\" },\n];\n\n// =============================================================================\n// PLATFORM-DEFAULT ENTITY EDGE TYPES\n// =============================================================================\n\ntype EntityEdgeTypeDefinition = {\n value: string;\n label: string;\n description: string;\n};\ntype IndexRangeBuilder = {\n eq(fieldName: string, value: unknown): IndexRangeBuilder;\n};\ntype EnumConfigRow = {\n _id: string;\n value: string;\n};\ntype RegisterEntityTypeArgs = {\n tenantId: string;\n value: string;\n label: string;\n description?: string;\n schema: unknown;\n domainNamespace?: string;\n};\n\nconst PLATFORM_ENTITY_EDGE_TYPES: EntityEdgeTypeDefinition[] = [\n {\n value: \"works_at\",\n label: \"Works At\",\n description: \"Person → Company/Investor employment\",\n },\n {\n value: \"performs\",\n label: \"Performs\",\n description: \"Company → Function capability\",\n },\n {\n value: \"invested_in\",\n label: \"Invested In\",\n description: \"Investor → Company investment\",\n },\n {\n value: \"founded_by\",\n label: \"Founded By\",\n description: \"Company → Person founding\",\n },\n {\n value: \"participates_in\",\n label: \"Participates In\",\n description: \"Company → ValueChain participation\",\n },\n {\n value: \"function_in\",\n label: \"Function In\",\n description: \"Function → ValueChain membership\",\n },\n {\n value: \"impacts\",\n label: \"Impacts\",\n description: \"Theme → ValueChain impact\",\n },\n {\n value: \"mentioned_in\",\n label: \"Mentioned In\",\n description: \"Entity → Source reference\",\n },\n {\n value: \"competes_with\",\n label: \"Competes With\",\n description: \"Company → Company competition\",\n },\n {\n value: \"depends_on\",\n label: \"Depends On\",\n description: \"Entity → Entity dependency\",\n },\n {\n value: \"contains\",\n label: \"Contains\",\n description: \"Containment: ValueChain → Function, Belief/Question/Theme → Entity, Entity → Evidence\",\n },\n {\n value: \"raised_from\",\n label: \"Raised From\",\n description: \"Company → Investor fundraising\",\n },\n {\n value: \"derived_from\",\n label: \"Derived From\",\n description: \"Entity → Entity deduplication merge link (replaces same_as)\",\n },\n];\n\n// =============================================================================\n// SEED MUTATION (idempotent)\n// =============================================================================\n\nasync function upsertEnumEntry(\n ctx: MutationCtx,\n entry: {\n category: string;\n value: string;\n label: string;\n description?: string;\n tier: \"platform\" | \"tenant\";\n metadata?: Record<string, unknown>;\n sortOrder?: number;\n }\n): Promise<{ inserted: boolean }> {\n const existing = await ctx.db\n .query(\"schemaEnumConfig\")\n .withIndex(\"by_category_value\", (q: IndexRangeBuilder) =>\n q.eq(\"category\", entry.category).eq(\"value\", entry.value)\n )\n .first();\n\n if (existing) {\n return { inserted: false };\n }\n\n const now = Date.now();\n await ctx.db.insert(\"schemaEnumConfig\", {\n category: entry.category,\n value: entry.value,\n label: entry.label,\n description: entry.description,\n tier: entry.tier,\n metadata: entry.metadata,\n sortOrder: entry.sortOrder,\n status: \"active\" as const,\n createdAt: now,\n updatedAt: now,\n });\n\n return { inserted: true };\n}\n\n/**\n * Seed the ontology registry with platform-default entity types.\n * Idempotent — safe to call multiple times.\n */\nexport const seedOntologyRegistry = internalMutation({\n args: {},\n returns: permissiveReturn,\n handler: async (ctx: MutationCtx) => {\n let inserted = 0;\n let skipped = 0;\n\n // Seed entity types\n for (let i = 0; i < PLATFORM_ENTITY_TYPES.length; i++) {\n const entityType = PLATFORM_ENTITY_TYPES[i];\n const result = await upsertEnumEntry(ctx, {\n category: \"entity_type\",\n value: entityType.value,\n label: entityType.label,\n description: entityType.description,\n tier: \"platform\",\n metadata: { schema: entityType.schema },\n sortOrder: i + 1,\n });\n if (result.inserted) {\n inserted++;\n } else {\n skipped++;\n }\n }\n\n // Seed entity subtypes\n for (let i = 0; i < PLATFORM_ENTITY_SUBTYPES.length; i++) {\n const subtype = PLATFORM_ENTITY_SUBTYPES[i];\n const result = await upsertEnumEntry(ctx, {\n category: \"entity_subtype\",\n value: subtype.value,\n label: subtype.label,\n tier: \"platform\",\n metadata: { parentType: subtype.parentType },\n sortOrder: i + 1,\n });\n if (result.inserted) {\n inserted++;\n } else {\n skipped++;\n }\n }\n\n // Seed entity edge types\n for (let i = 0; i < PLATFORM_ENTITY_EDGE_TYPES.length; i++) {\n const edgeType = PLATFORM_ENTITY_EDGE_TYPES[i];\n const result = await upsertEnumEntry(ctx, {\n category: \"entity_edge_type\",\n value: edgeType.value,\n label: edgeType.label,\n description: edgeType.description,\n tier: \"platform\",\n sortOrder: i + 1,\n });\n if (result.inserted) {\n inserted++;\n } else {\n skipped++;\n }\n }\n\n return { inserted, skipped, total: inserted + skipped };\n },\n});\n\n// =============================================================================\n// TENANT EXTENSION API\n// =============================================================================\n\n/**\n * Register a new entity type for a tenant.\n * Creates a schemaEnumConfig entry with tier='tenant'.\n */\nexport const registerEntityType = mutation({\n args: {\n tenantId: v.string(),\n value: v.string(),\n label: v.string(),\n description: v.optional(v.string()),\n schema: v.any(), // Record<string, { type, required }>\n domainNamespace: v.optional(v.string()),\n },\n returns: permissiveReturn,\n handler: async (ctx: MutationCtx, args: RegisterEntityTypeArgs) => {\n // Auth guard — tenant mutations require authenticated user\n const userId = await getCurrentUserId(ctx);\n if (!userId) {\n throw new Error(\"Authentication required to register entity types.\");\n }\n\n // Check for existing entry with same value\n const existing = (await ctx.db\n .query(\"schemaEnumConfig\")\n .withIndex(\"by_tenant_category\", (q: IndexRangeBuilder) =>\n q.eq(\"tenantId\", args.tenantId).eq(\"category\", \"entity_type\")\n )\n .collect()) as EnumConfigRow[];\n\n const duplicate = existing.find((e: EnumConfigRow) => e.value === args.value);\n if (duplicate) {\n throw new Error(\n `Entity type \"${args.value}\" already registered for tenant ${args.tenantId}`\n );\n }\n\n const now = Date.now();\n const id = await ctx.db.insert(\"schemaEnumConfig\", {\n tenantId: args.tenantId,\n category: \"entity_type\",\n value: args.value,\n label: args.label,\n description: args.description,\n tier: \"tenant\" as const,\n domainNamespace: args.domainNamespace,\n metadata: { schema: args.schema },\n status: \"active\" as const,\n createdAt: now,\n updatedAt: now,\n });\n\n return { id, value: args.value };\n },\n});\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/convex.ts","../src/ontologyRegistry.ts"],"names":[],"mappings":"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","file":"ontologyRegistry.js","sourcesContent":["import type { Doc as AccessControlDoc } from \"@lucern/access-control/convex\";\nimport {\n type UnsafeConvexAnyApi,\n unsafeConvexAnyApi,\n} from \"@lucern/contracts/convex/unsafeAnyApi\";\nimport {\n actionGeneric,\n componentsGeneric,\n httpActionGeneric,\n internalActionGeneric,\n internalMutationGeneric,\n internalQueryGeneric,\n mutationGeneric,\n queryGeneric,\n} from \"convex/server\";\nimport type { GenericId } from \"convex/values\";\n\n// TODO(FR.11-structural): `api`/`internal`/`components` are `anyApi as any`\n// because this module source tree is bundled into the kernel host at deploy time\n// and has NO top-level Convex `_generated/` directory to import a typed surface\n// from. Every `api.*` / `internal.*` / string-literal cross-component ref in this\n// module (topicScope.ts, topicProjectOverlay.ts, questionEvidenceLinks.ts,\n// beliefEvidenceLinks*.ts, epistemicQuestions.helpers.ts) inherits `any` from\n// here. The fix is structural — generate a per-module typed surface or a shared\n// typed function-reference manifest (template: the typed `components.controlPlane`\n// in modules/control-plane/src/component/convex.ts and the\n// `KERNEL_API_REF_MANIFEST` pattern in packages/server-core/src/kernelApi.ts) —\n// owned by the FR.11 closing/synthesis pass, not a mechanical swap.\nconst unsafeApi = unsafeConvexAnyApi(\n \"graph-primitives top-level module bundle lacks a committed Convex _generated/api surface\"\n);\nexport const api = unsafeApi;\nexport const components =\n componentsGeneric() as unknown as UntypedFunctionReferenceSurface;\nexport const internal = unsafeApi;\n\ntype UntypedFunctionReferenceSurface = UnsafeConvexAnyApi;\ntype BoundaryValue = UntypedFunctionReferenceSurface[string];\n\nexport type TableNames = string;\nexport type Id<TableName extends TableNames = string> = GenericId<TableName>;\nexport type Doc<TableName extends TableNames = string> =\n AccessControlDoc<TableName>;\nexport type DataModel = Record<TableNames, unknown>;\ninterface IndexRangeBuilder {\n eq(fieldName: string, value: unknown): IndexRangeBuilder;\n field(fieldName: string): string;\n gt(fieldName: string, value: unknown): IndexRangeBuilder;\n gte(fieldName: string, value: unknown): IndexRangeBuilder;\n lt(fieldName: string, value: unknown): IndexRangeBuilder;\n lte(fieldName: string, value: unknown): IndexRangeBuilder;\n}\ninterface FilterBuilder {\n and(...clauses: unknown[]): FilterBuilder;\n eq(left: unknown, right: unknown): FilterBuilder;\n field(fieldName: string): string;\n gt(left: unknown, right: unknown): FilterBuilder;\n gte(left: unknown, right: unknown): FilterBuilder;\n lt(left: unknown, right: unknown): FilterBuilder;\n lte(left: unknown, right: unknown): FilterBuilder;\n neq(left: unknown, right: unknown): FilterBuilder;\n or(...clauses: unknown[]): FilterBuilder;\n [operator: string]: unknown;\n}\ninterface QueryInitializer<TableName extends TableNames> {\n collect(): Promise<Doc<TableName>[]>;\n filter(predicate: (q: FilterBuilder) => unknown): QueryInitializer<TableName>;\n first(): Promise<Doc<TableName> | null>;\n order(direction: \"asc\" | \"desc\"): QueryInitializer<TableName>;\n take(limit: number): Promise<Doc<TableName>[]>;\n unique(): Promise<Doc<TableName> | null>;\n withIndex(\n indexName: string,\n range?: (q: IndexRangeBuilder) => unknown\n ): QueryInitializer<TableName>;\n withSearchIndex(\n indexName: string,\n search?: (q: IndexRangeBuilder) => unknown\n ): QueryInitializer<TableName>;\n}\nexport interface DatabaseReader {\n get<TableName extends TableNames>(\n id: unknown\n ): Promise<Doc<TableName> | null>;\n normalizeId?<TableName extends TableNames>(\n tableName: TableName,\n id: string\n ): Id<TableName> | null;\n query<TableName extends TableNames>(\n tableName: TableName\n ): QueryInitializer<TableName>;\n}\nexport type DatabaseWriter = DatabaseReader & {\n insert<TableName extends TableNames>(\n tableName: TableName,\n value: Record<string, unknown>\n ): Promise<Id<TableName>>;\n patch<TableName extends TableNames>(\n id: Id<TableName>,\n value: Record<string, unknown>\n ): Promise<void>;\n replace<TableName extends TableNames>(\n id: Id<TableName>,\n value: Record<string, unknown>\n ): Promise<void>;\n delete<TableName extends TableNames>(id: Id<TableName>): Promise<void>;\n};\ninterface Scheduler {\n runAfter(\n delayMs: number,\n functionReference: unknown,\n args?: unknown\n ): Promise<void>;\n}\ninterface AuthReader {\n getUserIdentity(): Promise<{\n readonly subject: string;\n readonly [claimName: string]: unknown;\n } | null>;\n}\ninterface RuntimeInvoker {\n runAction<Result = unknown>(\n functionReference: unknown,\n args?: unknown\n ): Promise<Result>;\n runMutation<Result = unknown>(\n functionReference: unknown,\n args?: unknown\n ): Promise<Result>;\n runQuery<Result = unknown>(\n functionReference: unknown,\n args?: unknown\n ): Promise<Result>;\n}\nexport type QueryCtx = RuntimeInvoker & {\n auth: AuthReader;\n db: DatabaseReader;\n scheduler: Scheduler;\n};\nexport type MutationCtx = RuntimeInvoker & {\n auth: AuthReader;\n db: DatabaseWriter;\n scheduler: Scheduler;\n};\nexport type ActionCtx = RuntimeInvoker & {\n auth: AuthReader;\n scheduler: Scheduler;\n};\n\ntype ConvexFunctionBuilder<Ctx> = <\n Args = BoundaryValue,\n Result = BoundaryValue,\n>(definition: {\n args?: unknown;\n handler: (ctx: Ctx, args: Args) => Result;\n returns?: unknown;\n}) => unknown;\n\ntype OptionalHandlerConvexFunctionBuilder<Ctx> = <\n Args = BoundaryValue,\n Result = BoundaryValue,\n>(definition: {\n args?: unknown;\n handler?: (ctx: Ctx, args: Args) => Result;\n returns?: unknown;\n}) => unknown;\n\nexport const action =\n actionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const httpAction =\n httpActionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const internalAction =\n internalActionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const internalMutation =\n internalMutationGeneric as unknown as OptionalHandlerConvexFunctionBuilder<MutationCtx>;\nexport const internalQuery =\n internalQueryGeneric as unknown as OptionalHandlerConvexFunctionBuilder<QueryCtx>;\nexport const mutation =\n mutationGeneric as unknown as ConvexFunctionBuilder<MutationCtx>;\nexport const query = queryGeneric as unknown as ConvexFunctionBuilder<QueryCtx>;\n","// biome-ignore-all lint/style/useFilenamingConvention: Public graph-primitives wildcard-export path; rename requires an export-map migration.\n/**\n * Ontology Registry\n *\n * Seeds schemaEnumConfig with platform-default entity types, subtypes,\n * and entity edge types. Provides tenant extension API.\n *\n * Categories:\n * - entity_type: Company, Person, Investor, Function, ValueChain\n * - entity_subtype: company/private, investor/vc, etc.\n * - entity_edge_type: works_at, invested_in, etc.\n *\n * @module graph-primitives/ontologyRegistry\n */\n\nimport { getCurrentUserId } from \"@lucern/access-control/auth\";\nimport { permissiveReturn } from \"@lucern/contracts/schema-helpers/validators\";\nimport { v } from \"convex/values\";\nimport type { Id, MutationCtx } from \"./convex\";\nimport { internalMutation, mutation } from \"./convex\";\n\n// =============================================================================\n// PLATFORM-DEFAULT ENTITY TYPES\n// =============================================================================\n\ninterface FieldSchema {\n required: boolean;\n type: \"string\" | \"number\" | \"boolean\";\n}\n\ninterface EntityTypeDefinition {\n description: string;\n label: string;\n schema: Record<string, FieldSchema>;\n value: string;\n}\n\nconst PLATFORM_ENTITY_TYPES: EntityTypeDefinition[] = [\n {\n value: \"company\",\n label: \"Company\",\n description: \"A business entity — startup, portfolio company, or corporate\",\n schema: {\n name: { type: \"string\", required: true },\n sector: { type: \"string\", required: false },\n founded_year: { type: \"number\", required: false },\n website: { type: \"string\", required: false },\n domain: { type: \"string\", required: false },\n },\n },\n {\n value: \"person\",\n label: \"Person\",\n description: \"An individual — founder, executive, or contact\",\n schema: {\n name: { type: \"string\", required: true },\n role: { type: \"string\", required: false },\n affiliation: { type: \"string\", required: false },\n linkedin: { type: \"string\", required: false },\n },\n },\n {\n value: \"investor\",\n label: \"Investor\",\n description: \"An investment entity — fund, GP, or angel\",\n schema: {\n name: { type: \"string\", required: true },\n fund_name: { type: \"string\", required: false },\n investment_focus: { type: \"string\", required: false },\n aum: { type: \"number\", required: false },\n },\n },\n {\n value: \"function\",\n label: \"Function\",\n description: \"A business function in a value chain\",\n schema: {\n name: { type: \"string\", required: true },\n description: { type: \"string\", required: false },\n },\n },\n {\n value: \"value_chain\",\n label: \"Value Chain\",\n description: \"A value chain or industry vertical\",\n schema: {\n name: { type: \"string\", required: true },\n description: { type: \"string\", required: false },\n },\n },\n];\n\n// =============================================================================\n// PLATFORM-DEFAULT ENTITY SUBTYPES\n// =============================================================================\n\ninterface SubtypeDefinition {\n label: string;\n parentType: string;\n value: string;\n}\n\nconst PLATFORM_ENTITY_SUBTYPES: SubtypeDefinition[] = [\n // Company subtypes\n { value: \"company/private\", label: \"Private Company\", parentType: \"company\" },\n { value: \"company/corporate\", label: \"Corporate\", parentType: \"company\" },\n {\n value: \"company/portfolio\",\n label: \"Portfolio Company\",\n parentType: \"company\",\n },\n // Investor subtypes\n { value: \"investor/vc\", label: \"Venture Capital\", parentType: \"investor\" },\n { value: \"investor/lp\", label: \"Limited Partner\", parentType: \"investor\" },\n { value: \"investor/cvc\", label: \"Corporate VC\", parentType: \"investor\" },\n { value: \"investor/pe\", label: \"Private Equity\", parentType: \"investor\" },\n {\n value: \"investor/family_office\",\n label: \"Family Office\",\n parentType: \"investor\",\n },\n { value: \"investor/angel\", label: \"Angel Investor\", parentType: \"investor\" },\n];\n\n// =============================================================================\n// PLATFORM-DEFAULT ENTITY EDGE TYPES\n// =============================================================================\n\ninterface EntityEdgeTypeDefinition {\n description: string;\n label: string;\n value: string;\n}\ninterface IndexRangeBuilder {\n eq(fieldName: string, value: unknown): IndexRangeBuilder;\n}\ninterface EnumConfigRow {\n _id: Id<\"schemaEnumConfig\">;\n value: string;\n}\ninterface RegisterEntityTypeArgs {\n description?: string;\n domainNamespace?: string;\n label: string;\n schema: unknown;\n tenantId: string;\n value: string;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction readEnumConfigRow(value: unknown, context: string): EnumConfigRow {\n if (!isRecord(value)) {\n throw new Error(`${context} must be an object.`);\n }\n if (typeof value._id !== \"string\" || typeof value.value !== \"string\") {\n throw new Error(`${context} has invalid or missing _id/value.`);\n }\n return {\n _id: value._id as Id<\"schemaEnumConfig\">,\n value: value.value,\n };\n}\n\nfunction readEnumConfigRows(values: unknown[]): EnumConfigRow[] {\n return values.map((value, index) =>\n readEnumConfigRow(value, `schemaEnumConfig[${index}]`)\n );\n}\n\nconst PLATFORM_ENTITY_EDGE_TYPES: EntityEdgeTypeDefinition[] = [\n {\n value: \"works_at\",\n label: \"Works At\",\n description: \"Person → Company/Investor employment\",\n },\n {\n value: \"performs\",\n label: \"Performs\",\n description: \"Company → Function capability\",\n },\n {\n value: \"invested_in\",\n label: \"Invested In\",\n description: \"Investor → Company investment\",\n },\n {\n value: \"founded_by\",\n label: \"Founded By\",\n description: \"Company → Person founding\",\n },\n {\n value: \"participates_in\",\n label: \"Participates In\",\n description: \"Company → ValueChain participation\",\n },\n {\n value: \"function_in\",\n label: \"Function In\",\n description: \"Function → ValueChain membership\",\n },\n {\n value: \"impacts\",\n label: \"Impacts\",\n description: \"Theme → ValueChain impact\",\n },\n {\n value: \"mentioned_in\",\n label: \"Mentioned In\",\n description: \"Entity → Source reference\",\n },\n {\n value: \"competes_with\",\n label: \"Competes With\",\n description: \"Company → Company competition\",\n },\n {\n value: \"depends_on\",\n label: \"Depends On\",\n description: \"Entity → Entity dependency\",\n },\n {\n value: \"contains\",\n label: \"Contains\",\n description:\n \"Containment: ValueChain → Function, Belief/Question/Theme → Entity, Entity → Evidence\",\n },\n {\n value: \"raised_from\",\n label: \"Raised From\",\n description: \"Company → Investor fundraising\",\n },\n {\n value: \"derived_from\",\n label: \"Derived From\",\n description: \"Entity → Entity deduplication merge link (replaces same_as)\",\n },\n];\n\n// =============================================================================\n// SEED MUTATION (idempotent)\n// =============================================================================\n\nasync function upsertEnumEntry(\n ctx: MutationCtx,\n entry: {\n category: string;\n value: string;\n label: string;\n description?: string;\n tier: \"platform\" | \"tenant\";\n metadata?: Record<string, unknown>;\n sortOrder?: number;\n }\n): Promise<{ inserted: boolean }> {\n const existing = await ctx.db\n .query(\"schemaEnumConfig\")\n .withIndex(\"by_category_value\", (q: IndexRangeBuilder) =>\n q.eq(\"category\", entry.category).eq(\"value\", entry.value)\n )\n .first();\n\n if (existing) {\n return { inserted: false };\n }\n\n const now = Date.now();\n await ctx.db.insert(\"schemaEnumConfig\", {\n category: entry.category,\n value: entry.value,\n label: entry.label,\n description: entry.description,\n tier: entry.tier,\n metadata: entry.metadata,\n sortOrder: entry.sortOrder,\n status: \"active\" as const,\n createdAt: now,\n updatedAt: now,\n });\n\n return { inserted: true };\n}\n\n/**\n * Seed the ontology registry with platform-default entity types.\n * Idempotent — safe to call multiple times.\n */\nexport const seedOntologyRegistry = internalMutation({\n args: {},\n returns: permissiveReturn,\n handler: async (ctx: MutationCtx) => {\n let inserted = 0;\n let skipped = 0;\n\n // Seed entity types\n for (let i = 0; i < PLATFORM_ENTITY_TYPES.length; i++) {\n const entityType = PLATFORM_ENTITY_TYPES[i];\n const result = await upsertEnumEntry(ctx, {\n category: \"entity_type\",\n value: entityType.value,\n label: entityType.label,\n description: entityType.description,\n tier: \"platform\",\n metadata: { schema: entityType.schema },\n sortOrder: i + 1,\n });\n if (result.inserted) {\n inserted++;\n } else {\n skipped++;\n }\n }\n\n // Seed entity subtypes\n for (let i = 0; i < PLATFORM_ENTITY_SUBTYPES.length; i++) {\n const subtype = PLATFORM_ENTITY_SUBTYPES[i];\n const result = await upsertEnumEntry(ctx, {\n category: \"entity_subtype\",\n value: subtype.value,\n label: subtype.label,\n tier: \"platform\",\n metadata: { parentType: subtype.parentType },\n sortOrder: i + 1,\n });\n if (result.inserted) {\n inserted++;\n } else {\n skipped++;\n }\n }\n\n // Seed entity edge types\n for (let i = 0; i < PLATFORM_ENTITY_EDGE_TYPES.length; i++) {\n const edgeType = PLATFORM_ENTITY_EDGE_TYPES[i];\n const result = await upsertEnumEntry(ctx, {\n category: \"entity_edge_type\",\n value: edgeType.value,\n label: edgeType.label,\n description: edgeType.description,\n tier: \"platform\",\n sortOrder: i + 1,\n });\n if (result.inserted) {\n inserted++;\n } else {\n skipped++;\n }\n }\n\n return { inserted, skipped, total: inserted + skipped };\n },\n});\n\n// =============================================================================\n// TENANT EXTENSION API\n// =============================================================================\n\n/**\n * Register a new entity type for a tenant.\n * Creates a schemaEnumConfig entry with tier='tenant'.\n */\nexport const registerEntityType = mutation({\n args: {\n tenantId: v.string(),\n value: v.string(),\n label: v.string(),\n description: v.optional(v.string()),\n schema: v.any(), // Record<string, { type, required }>\n domainNamespace: v.optional(v.string()),\n },\n returns: permissiveReturn,\n handler: async (ctx: MutationCtx, args: RegisterEntityTypeArgs) => {\n // Auth guard — tenant mutations require authenticated user\n const userId = await getCurrentUserId(ctx);\n if (!userId) {\n throw new Error(\"Authentication required to register entity types.\");\n }\n\n // Check for existing entry with same value\n const existing = readEnumConfigRows(\n await ctx.db\n .query(\"schemaEnumConfig\")\n .withIndex(\"by_tenant_category\", (q: IndexRangeBuilder) =>\n q.eq(\"tenantId\", args.tenantId).eq(\"category\", \"entity_type\")\n )\n .collect()\n );\n\n const duplicate = existing.find(\n (e: EnumConfigRow) => e.value === args.value\n );\n if (duplicate) {\n throw new Error(\n `Entity type \"${args.value}\" already registered for tenant ${args.tenantId}`\n );\n }\n\n const now = Date.now();\n const id = await ctx.db.insert(\"schemaEnumConfig\", {\n tenantId: args.tenantId,\n category: \"entity_type\",\n value: args.value,\n label: args.label,\n description: args.description,\n tier: \"tenant\" as const,\n domainNamespace: args.domainNamespace,\n metadata: { schema: args.schema },\n status: \"active\" as const,\n createdAt: now,\n updatedAt: now,\n });\n\n return { id, value: args.value };\n },\n});\n"]}
|
package/dist/{projectionReconciliation-jww2fBI0.d.ts → projectionReconciliation-DnrSgHSQ.d.ts}
RENAMED
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
* Phase 2 (WT-C) runtime hooks for Convex-authoritative / Neo4j-projected
|
|
5
5
|
* reconciliation health and endpoint-class staleness evaluation.
|
|
6
6
|
*/
|
|
7
|
-
declare const getProjectionReconciliationStatusInternal:
|
|
8
|
-
declare const getProjectionReconciliationStatus:
|
|
9
|
-
declare const assessProjectionStaleness:
|
|
10
|
-
declare const runProjectionRepairCycle:
|
|
7
|
+
declare const getProjectionReconciliationStatusInternal: unknown;
|
|
8
|
+
declare const getProjectionReconciliationStatus: unknown;
|
|
9
|
+
declare const assessProjectionStaleness: unknown;
|
|
10
|
+
declare const runProjectionRepairCycle: unknown;
|
|
11
11
|
|
|
12
12
|
declare const projectionReconciliation_assessProjectionStaleness: typeof assessProjectionStaleness;
|
|
13
13
|
declare const projectionReconciliation_getProjectionReconciliationStatus: typeof getProjectionReconciliationStatus;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { a as assessProjectionStaleness, g as getProjectionReconciliationStatus, b as getProjectionReconciliationStatusInternal, r as runProjectionRepairCycle } from './projectionReconciliation-
|
|
1
|
+
export { a as assessProjectionStaleness, g as getProjectionReconciliationStatus, b as getProjectionReconciliationStatusInternal, r as runProjectionRepairCycle } from './projectionReconciliation-DnrSgHSQ.js';
|
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
import { v } from 'convex/values';
|
|
2
1
|
import { getCurrentUserId } from '@lucern/access-control/auth';
|
|
3
2
|
import { permissiveReturn } from '@lucern/contracts/schema-helpers/validators';
|
|
4
|
-
import {
|
|
3
|
+
import { v } from 'convex/values';
|
|
4
|
+
import { unsafeConvexAnyApi } from '@lucern/contracts/convex/unsafeAnyApi';
|
|
5
|
+
import { componentsGeneric, internalQueryGeneric, queryGeneric, internalActionGeneric } from 'convex/server';
|
|
5
6
|
|
|
6
7
|
// src/projectionReconciliation.ts
|
|
8
|
+
var unsafeApi = unsafeConvexAnyApi(
|
|
9
|
+
"graph-primitives top-level module bundle lacks a committed Convex _generated/api surface"
|
|
10
|
+
);
|
|
7
11
|
componentsGeneric();
|
|
8
|
-
var internal =
|
|
12
|
+
var internal = unsafeApi;
|
|
9
13
|
var internalAction = internalActionGeneric;
|
|
10
14
|
var internalQuery = internalQueryGeneric;
|
|
11
15
|
var query = queryGeneric;
|
|
@@ -45,7 +49,7 @@ function evaluateProjectionStaleness(input) {
|
|
|
45
49
|
const evaluatedAt = input.nowMs ?? Date.now();
|
|
46
50
|
const stalenessMs = Math.max(0, input.queueBacklogAgeMs);
|
|
47
51
|
const isStale = stalenessMs > policy.thresholdMs;
|
|
48
|
-
const lastSuccessfulSyncAgeMs = input.lastSuccessfulSyncAt
|
|
52
|
+
const lastSuccessfulSyncAgeMs = input.lastSuccessfulSyncAt === void 0 ? void 0 : Math.max(0, evaluatedAt - input.lastSuccessfulSyncAt);
|
|
49
53
|
return {
|
|
50
54
|
endpointClass: input.endpointClass,
|
|
51
55
|
stalenessMs,
|
|
@@ -57,11 +61,54 @@ function evaluateProjectionStaleness(input) {
|
|
|
57
61
|
evaluatedAt,
|
|
58
62
|
lastSuccessfulSyncAt: input.lastSuccessfulSyncAt,
|
|
59
63
|
lastSuccessfulSyncAgeMs,
|
|
60
|
-
reasonCode: isStale
|
|
64
|
+
reasonCode: projectionStalenessReasonCode(isStale, input.queueFailedCount)
|
|
61
65
|
};
|
|
62
66
|
}
|
|
67
|
+
function projectionStalenessReasonCode(isStale, queueFailedCount) {
|
|
68
|
+
if (!isStale) {
|
|
69
|
+
return "PROJECTION_HEALTHY";
|
|
70
|
+
}
|
|
71
|
+
return queueFailedCount > 0 ? "PROJECTION_STALE_WITH_FAILED_RETRIES" : "PROJECTION_STALE";
|
|
72
|
+
}
|
|
63
73
|
|
|
64
74
|
// src/projectionReconciliation.ts
|
|
75
|
+
function isRecord(value) {
|
|
76
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
77
|
+
}
|
|
78
|
+
function readQueueStatus(value, context) {
|
|
79
|
+
if (value !== "pending" && value !== "in_progress" && value !== "failed" && value !== "succeeded") {
|
|
80
|
+
throw new Error(`${context} has invalid or missing status.`);
|
|
81
|
+
}
|
|
82
|
+
return value;
|
|
83
|
+
}
|
|
84
|
+
function readFiniteNumber(row, field, context) {
|
|
85
|
+
const value = row[field];
|
|
86
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
87
|
+
throw new Error(`${context} has invalid or missing ${field}.`);
|
|
88
|
+
}
|
|
89
|
+
return value;
|
|
90
|
+
}
|
|
91
|
+
function readQueueRow(value, context) {
|
|
92
|
+
if (!isRecord(value)) {
|
|
93
|
+
throw new Error(`${context} must be an object.`);
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
createdAt: readFiniteNumber(value, "createdAt", context),
|
|
97
|
+
status: readQueueStatus(value.status, context),
|
|
98
|
+
updatedAt: readFiniteNumber(value, "updatedAt", context)
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
function readQueueRows(values, context) {
|
|
102
|
+
return values.map(
|
|
103
|
+
(value, index) => readQueueRow(value, `${context}[${index}]`)
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
async function getQueueRowsByStatus(ctx, status) {
|
|
107
|
+
return readQueueRows(
|
|
108
|
+
await ctx.db.query("neo4jSyncQueue").withIndex("by_status", (q) => q.eq("status", status)).collect(),
|
|
109
|
+
`neo4jSyncQueue.${status}`
|
|
110
|
+
);
|
|
111
|
+
}
|
|
65
112
|
function maxTimestamp(rows, field) {
|
|
66
113
|
let maxValue;
|
|
67
114
|
for (const row of rows) {
|
|
@@ -90,17 +137,17 @@ function minTimestamp(rows, field) {
|
|
|
90
137
|
}
|
|
91
138
|
async function getQueueSnapshot(ctx) {
|
|
92
139
|
const [pendingRows, inProgressRows, failedRows, succeededRows] = await Promise.all([
|
|
93
|
-
ctx
|
|
94
|
-
ctx
|
|
95
|
-
ctx
|
|
96
|
-
ctx
|
|
140
|
+
getQueueRowsByStatus(ctx, "pending"),
|
|
141
|
+
getQueueRowsByStatus(ctx, "in_progress"),
|
|
142
|
+
getQueueRowsByStatus(ctx, "failed"),
|
|
143
|
+
getQueueRowsByStatus(ctx, "succeeded")
|
|
97
144
|
]);
|
|
98
145
|
const now = Date.now();
|
|
99
146
|
const backlogOldestCreatedAt = minTimestamp(
|
|
100
147
|
[...pendingRows, ...inProgressRows],
|
|
101
148
|
"createdAt"
|
|
102
149
|
);
|
|
103
|
-
const queueBacklogAgeMs = backlogOldestCreatedAt
|
|
150
|
+
const queueBacklogAgeMs = backlogOldestCreatedAt === void 0 ? 0 : Math.max(0, now - backlogOldestCreatedAt);
|
|
104
151
|
const lastSuccessfulSyncAt = maxTimestamp(succeededRows, "updatedAt");
|
|
105
152
|
return {
|
|
106
153
|
now,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/convex.ts","../src/projectionStaleness.ts","../src/projectionReconciliation.ts"],"names":[],"mappings":";;;;;;AAyB0B,iBAAA;AACnB,IAAM,QAAA,GAAW,MAAA;AAmGjB,IAAM,cAAA,GACX,qBAAA;AAGK,IAAM,aAAA,GACX,oBAAA;AAGK,IAAM,KAAA,GAAQ,YAAA;;;ACpFd,IAAM,6BAAA,GAGT;AAAA,EACF,SAAA,EAAW;AAAA,IACT,aAAA,EAAe,WAAA;AAAA,IACf,WAAA,EAAa,GAAA;AAAA,IACb,YAAA,EAAc,eAAA;AAAA,IACd,cAAA,EAAgB;AAAA,GAClB;AAAA,EACA,SAAA,EAAW;AAAA,IACT,aAAA,EAAe,WAAA;AAAA,IACf,WAAA,EAAa,GAAA;AAAA,IACb,YAAA,EAAc,iCAAA;AAAA,IACd,cAAA,EAAgB;AAAA,GAClB;AAAA,EACA,WAAA,EAAa;AAAA,IACX,aAAA,EAAe,aAAA;AAAA,IACf,aAAa,CAAA,GAAI,GAAA;AAAA,IACjB,YAAA,EAAc,gCAAA;AAAA,IACd,cAAA,EAAgB;AAAA,GAClB;AAAA,EACA,SAAA,EAAW;AAAA,IACT,aAAA,EAAe,WAAA;AAAA,IACf,aAAa,MAAA,CAAO,iBAAA;AAAA,IACpB,YAAA,EAAc,MAAA;AAAA,IACd,cAAA,EAAgB;AAAA;AAEpB,CAAA;AAEO,SAAS,6BACd,aAAA,EAC2B;AAC3B,EAAA,OAAO,8BAA8B,aAAa,CAAA;AACpD;AAEO,SAAS,4BACd,KAAA,EAC6B;AAC7B,EAAA,MAAM,MAAA,GAAS,4BAAA,CAA6B,KAAA,CAAM,aAAa,CAAA;AAC/D,EAAA,MAAM,WAAA,GAAc,KAAA,CAAM,KAAA,IAAS,IAAA,CAAK,GAAA,EAAI;AAC5C,EAAA,MAAM,WAAA,GAAc,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,MAAM,iBAAiB,CAAA;AACvD,EAAA,MAAM,OAAA,GAAU,cAAc,MAAA,CAAO,WAAA;AACrC,EAAA,MAAM,uBAAA,GACJ,KAAA,CAAM,oBAAA,KAAyB,MAAA,GAC3B,IAAA,CAAK,IAAI,CAAA,EAAG,WAAA,GAAc,KAAA,CAAM,oBAAoB,CAAA,GACpD,MAAA;AAEN,EAAA,OAAO;AAAA,IACL,eAAe,KAAA,CAAM,aAAA;AAAA,IACrB,WAAA;AAAA,IACA,aAAa,MAAA,CAAO,WAAA;AAAA,IACpB,OAAA;AAAA,IACA,cAAc,MAAA,CAAO,YAAA;AAAA,IACrB,mBAAmB,KAAA,CAAM,iBAAA;AAAA,IACzB,kBAAkB,KAAA,CAAM,gBAAA;AAAA,IACxB,WAAA;AAAA,IACA,sBAAsB,KAAA,CAAM,oBAAA;AAAA,IAC5B,uBAAA;AAAA,IACA,YAAY,OAAA,GACR,KAAA,CAAM,gBAAA,GAAmB,CAAA,GACvB,yCACA,kBAAA,GACF;AAAA,GACN;AACF;;;ACtFA,SAAS,YAAA,CACP,MACA,KAAA,EACoB;AACpB,EAAA,IAAI,QAAA;AACJ,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,IAAA,MAAM,KAAA,GAAQ,IAAI,KAAK,CAAA;AACvB,IAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,EAAG;AAC3B,MAAA;AAAA,IACF;AACA,IAAA,IAAI,QAAA,KAAa,MAAA,IAAa,KAAA,GAAQ,QAAA,EAAU;AAC9C,MAAA,QAAA,GAAW,KAAA;AAAA,IACb;AAAA,EACF;AACA,EAAA,OAAO,QAAA;AACT;AAEA,SAAS,YAAA,CACP,MACA,KAAA,EACoB;AACpB,EAAA,IAAI,QAAA;AACJ,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,IAAA,MAAM,KAAA,GAAQ,IAAI,KAAK,CAAA;AACvB,IAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,EAAG;AAC3B,MAAA;AAAA,IACF;AACA,IAAA,IAAI,QAAA,KAAa,MAAA,IAAa,KAAA,GAAQ,QAAA,EAAU;AAC9C,MAAA,QAAA,GAAW,KAAA;AAAA,IACb;AAAA,EACF;AACA,EAAA,OAAO,QAAA;AACT;AAEA,eAAe,iBAAiB,GAAA,EAAe;AAC7C,EAAA,MAAM,CAAC,aAAa,cAAA,EAAgB,UAAA,EAAY,aAAa,CAAA,GAC3D,MAAM,QAAQ,GAAA,CAAI;AAAA,IAChB,GAAA,CAAI,EAAA,CACD,KAAA,CAAM,gBAAgB,EACtB,SAAA,CAAU,WAAA,EAAa,CAAC,CAAA,KAAyB,EAAE,EAAA,CAAG,QAAA,EAAU,SAAS,CAAC,EAC1E,OAAA,EAAQ;AAAA,IACX,GAAA,CAAI,EAAA,CACD,KAAA,CAAM,gBAAgB,EACtB,SAAA,CAAU,WAAA,EAAa,CAAC,CAAA,KAAyB,EAAE,EAAA,CAAG,QAAA,EAAU,aAAa,CAAC,EAC9E,OAAA,EAAQ;AAAA,IACX,GAAA,CAAI,EAAA,CACD,KAAA,CAAM,gBAAgB,EACtB,SAAA,CAAU,WAAA,EAAa,CAAC,CAAA,KAAyB,EAAE,EAAA,CAAG,QAAA,EAAU,QAAQ,CAAC,EACzE,OAAA,EAAQ;AAAA,IACX,GAAA,CAAI,EAAA,CACD,KAAA,CAAM,gBAAgB,EACtB,SAAA,CAAU,WAAA,EAAa,CAAC,CAAA,KAAyB,EAAE,EAAA,CAAG,QAAA,EAAU,WAAW,CAAC,EAC5E,OAAA;AAAQ,GACZ,CAAA;AAEH,EAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,EAAA,MAAM,sBAAA,GAAyB,YAAA;AAAA,IAC7B,CAAC,GAAG,WAAA,EAAa,GAAG,cAAc,CAAA;AAAA,IAClC;AAAA,GACF;AACA,EAAA,MAAM,iBAAA,GACJ,2BAA2B,MAAA,GACvB,IAAA,CAAK,IAAI,CAAA,EAAG,GAAA,GAAM,sBAAsB,CAAA,GACxC,CAAA;AACN,EAAA,MAAM,oBAAA,GAAuB,YAAA,CAAa,aAAA,EAAe,WAAW,CAAA;AAEpE,EAAA,OAAO;AAAA,IACL,GAAA;AAAA,IACA,mBAAmB,WAAA,CAAY,MAAA;AAAA,IAC/B,sBAAsB,cAAA,CAAe,MAAA;AAAA,IACrC,kBAAkB,UAAA,CAAW,MAAA;AAAA,IAC7B,qBAAqB,aAAA,CAAc,MAAA;AAAA,IACnC,iBAAA;AAAA,IACA,sBAAA;AAAA,IACA;AAAA,GACF;AACF;AAEA,SAAS,yBACP,QAAA,EACA;AACA,EAAA,MAAM,YAAY,2BAAA,CAA4B;AAAA,IAC5C,aAAA,EAAe,WAAA;AAAA,IACf,mBAAmB,QAAA,CAAS,iBAAA;AAAA,IAC5B,iBAAA,EACE,QAAA,CAAS,iBAAA,GAAoB,QAAA,CAAS,oBAAA;AAAA,IACxC,kBAAkB,QAAA,CAAS,gBAAA;AAAA,IAC3B,OAAO,QAAA,CAAS,GAAA;AAAA,IAChB,sBAAsB,QAAA,CAAS;AAAA,GAChC,CAAA;AACD,EAAA,MAAM,YAAY,2BAAA,CAA4B;AAAA,IAC5C,aAAA,EAAe,WAAA;AAAA,IACf,mBAAmB,QAAA,CAAS,iBAAA;AAAA,IAC5B,iBAAA,EACE,QAAA,CAAS,iBAAA,GAAoB,QAAA,CAAS,oBAAA;AAAA,IACxC,kBAAkB,QAAA,CAAS,gBAAA;AAAA,IAC3B,OAAO,QAAA,CAAS,GAAA;AAAA,IAChB,sBAAsB,QAAA,CAAS;AAAA,GAChC,CAAA;AACD,EAAA,MAAM,aAAa,2BAAA,CAA4B;AAAA,IAC7C,aAAA,EAAe,aAAA;AAAA,IACf,mBAAmB,QAAA,CAAS,iBAAA;AAAA,IAC5B,iBAAA,EACE,QAAA,CAAS,iBAAA,GAAoB,QAAA,CAAS,oBAAA;AAAA,IACxC,kBAAkB,QAAA,CAAS,gBAAA;AAAA,IAC3B,OAAO,QAAA,CAAS,GAAA;AAAA,IAChB,sBAAsB,QAAA,CAAS;AAAA,GAChC,CAAA;AACD,EAAA,MAAM,WAAW,2BAAA,CAA4B;AAAA,IAC3C,aAAA,EAAe,WAAA;AAAA,IACf,mBAAmB,QAAA,CAAS,iBAAA;AAAA,IAC5B,iBAAA,EACE,QAAA,CAAS,iBAAA,GAAoB,QAAA,CAAS,oBAAA;AAAA,IACxC,kBAAkB,QAAA,CAAS,gBAAA;AAAA,IAC3B,OAAO,QAAA,CAAS,GAAA;AAAA,IAChB,sBAAsB,QAAA,CAAS;AAAA,GAChC,CAAA;AAED,EAAA,OAAO;AAAA,IACL,SAAA;AAAA,IACA,SAAA;AAAA,IACA,UAAA;AAAA,IACA;AAAA,GACF;AACF;AAEA,SAAS,oCACP,QAAA,EACA;AACA,EAAA,OAAO;AAAA,IACL,GAAG,QAAA;AAAA,IACH,mBAAA,EAAqB,yBAAyB,QAAQ,CAAA;AAAA,IACtD,aAAa,QAAA,CAAS;AAAA,GACxB;AACF;AAEA,SAAS,oBAAoB,OAAA,EAAgC;AAC3D,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,MAAM,IAAI,MAAM,yBAAyB,CAAA;AAAA,EAC3C;AACA,EAAA,OAAO,OAAA;AACT;AAEO,IAAM,4CAA4C,aAAA,CAAc;AAAA,EACrE,MAAM,EAAC;AAAA,EACP,OAAA,EAAS,gBAAA;AAAA,EACT,OAAA,EAAS,OAAO,GAAA,KAAkB;AAChC,IAAA,MAAM,QAAA,GAAW,MAAM,gBAAA,CAAiB,GAAG,CAAA;AAC3C,IAAA,OAAO,oCAAoC,QAAQ,CAAA;AAAA,EACrD;AACF,CAAC;AAEM,IAAM,oCAAoC,KAAA,CAAM;AAAA,EACrD,MAAM,EAAC;AAAA,EACP,OAAA,EAAS,gBAAA;AAAA,EACT,OAAA,EAAS,OAAO,GAAA,KAAkB;AAChC,IAAA,mBAAA,CAAoB,MAAM,gBAAA,CAAiB,GAAG,CAAC,CAAA;AAC/C,IAAA,MAAM,QAAA,GAAW,MAAM,gBAAA,CAAiB,GAAG,CAAA;AAC3C,IAAA,OAAO,oCAAoC,QAAQ,CAAA;AAAA,EACrD;AACF,CAAC;AAEM,IAAM,4BAA4B,KAAA,CAAM;AAAA,EAC7C,IAAA,EAAM;AAAA,IACJ,eAAe,CAAA,CAAE,KAAA;AAAA,MACf,CAAA,CAAE,QAAQ,WAAW,CAAA;AAAA,MACrB,CAAA,CAAE,QAAQ,WAAW,CAAA;AAAA,MACrB,CAAA,CAAE,QAAQ,aAAa,CAAA;AAAA,MACvB,CAAA,CAAE,QAAQ,WAAW;AAAA;AACvB,GACF;AAAA,EACA,OAAA,EAAS,gBAAA;AAAA,EACT,OAAA,EAAS,OACP,GAAA,EACA,IAAA,KACG;AACH,IAAA,mBAAA,CAAoB,MAAM,gBAAA,CAAiB,GAAG,CAAC,CAAA;AAC/C,IAAA,MAAM,QAAA,GAAW,MAAM,gBAAA,CAAiB,GAAG,CAAA;AAC3C,IAAA,MAAM,gBAAgB,IAAA,CAAK,aAAA;AAE3B,IAAA,OAAO;AAAA,MACL,aAAA;AAAA,MACA,YAAY,2BAAA,CAA4B;AAAA,QACtC,aAAA;AAAA,QACA,mBAAmB,QAAA,CAAS,iBAAA;AAAA,QAC5B,iBAAA,EACE,QAAA,CAAS,iBAAA,GAAoB,QAAA,CAAS,oBAAA;AAAA,QACxC,kBAAkB,QAAA,CAAS,gBAAA;AAAA,QAC3B,OAAO,QAAA,CAAS,GAAA;AAAA,QAChB,sBAAsB,QAAA,CAAS;AAAA,OAChC,CAAA;AAAA,MACD;AAAA,KACF;AAAA,EACF;AACF,CAAC;AAEM,IAAM,2BAA2B,cAAA,CAAe;AAAA,EACrD,IAAA,EAAM;AAAA,IACJ,KAAA,EAAO,CAAA,CAAE,QAAA,CAAS,CAAA,CAAE,QAAQ;AAAA,GAC9B;AAAA,EACA,OAAA,EAAS,gBAAA;AAAA,EACT,OAAA,EAAS,OAAO,GAAA,EAAgB,IAAA,KAA6B;AAC3D,IAAA,MAAM,SAAA,GAAY,MAAM,GAAA,CAAI,SAAA;AAAA,MAC1B,SAAS,SAAA,CAAU,iBAAA;AAAA,MACnB;AAAA,QACE,KAAA,EAAO,KAAK,KAAA,IAAS;AAAA;AACvB,KACF;AACA,IAAA,MAAM,MAAA,GAAS,MAAM,GAAA,CAAI,QAAA;AAAA,MACvB,SAAS,wBAAA,CACN,yCAAA;AAAA,MACH;AAAC,KACH;AAEA,IAAA,OAAO;AAAA,MACL,SAAA;AAAA,MACA,MAAA;AAAA,MACA,KAAA,EAAO,KAAK,GAAA;AAAI,KAClB;AAAA,EACF;AACF,CAAC","file":"projectionReconciliation.js","sourcesContent":["import {\n actionGeneric,\n anyApi,\n componentsGeneric,\n httpActionGeneric,\n internalActionGeneric,\n internalMutationGeneric,\n internalQueryGeneric,\n mutationGeneric,\n queryGeneric,\n} from \"convex/server\";\nimport type { GenericId } from \"convex/values\";\n\n// TODO(FR.11-structural): `api`/`internal`/`components` are `anyApi as any`\n// because this module source tree is bundled into the kernel host at deploy time\n// and has NO top-level Convex `_generated/` directory to import a typed surface\n// from. Every `api.*` / `internal.*` / string-literal cross-component ref in this\n// module (topicScope.ts, topicProjectOverlay.ts, questionEvidenceLinks.ts,\n// beliefEvidenceLinks*.ts, epistemicQuestions.helpers.ts) inherits `any` from\n// here. The fix is structural — generate a per-module typed surface or a shared\n// typed function-reference manifest (template: the typed `components.controlPlane`\n// in modules/control-plane/src/component/convex.ts and the\n// `KERNEL_API_REF_MANIFEST` pattern in packages/server-core/src/kernelApi.ts) —\n// owned by the FR.11 closing/synthesis pass, not a mechanical swap.\nexport const api = anyApi as any;\nexport const components = componentsGeneric() as any;\nexport const internal = anyApi as any;\n\nexport type TableNames = string;\nexport type Id<TableName extends TableNames = string> = GenericId<TableName>;\nexport type Doc<TableName extends TableNames = string> = any;\nexport type DataModel = any;\ntype IndexRangeBuilder = {\n field(fieldName: string): string;\n eq(fieldName: string, value: unknown): IndexRangeBuilder;\n gt(fieldName: string, value: unknown): IndexRangeBuilder;\n gte(fieldName: string, value: unknown): IndexRangeBuilder;\n lt(fieldName: string, value: unknown): IndexRangeBuilder;\n lte(fieldName: string, value: unknown): IndexRangeBuilder;\n};\ntype FilterBuilder = {\n eq(left: unknown, right: unknown): unknown;\n neq(left: unknown, right: unknown): unknown;\n gt(left: unknown, right: unknown): unknown;\n gte(left: unknown, right: unknown): unknown;\n lt(left: unknown, right: unknown): unknown;\n lte(left: unknown, right: unknown): unknown;\n and(...clauses: unknown[]): unknown;\n or(...clauses: unknown[]): unknown;\n field(fieldName: string): unknown;\n};\ntype QueryInitializer<TableName extends TableNames> = {\n withIndex(\n indexName: string,\n range?: (q: any) => unknown\n ): QueryInitializer<TableName>;\n filter(predicate: (q: any) => unknown): QueryInitializer<TableName>;\n order(direction: \"asc\" | \"desc\"): QueryInitializer<TableName>;\n collect(): Promise<Doc<TableName>[]>;\n take(limit: number): Promise<Doc<TableName>[]>;\n first(): Promise<Doc<TableName> | null>;\n unique(): Promise<Doc<TableName> | null>;\n};\nexport type DatabaseReader = {\n get<TableName extends TableNames>(\n id: Id<TableName>\n ): Promise<Doc<TableName> | null>;\n query<TableName extends TableNames>(\n tableName: TableName\n ): QueryInitializer<TableName>;\n normalizeId?<TableName extends TableNames>(\n tableName: TableName,\n id: string\n ): Id<TableName> | null;\n};\nexport type DatabaseWriter = DatabaseReader & {\n insert<TableName extends TableNames>(\n tableName: TableName,\n value: Record<string, unknown>\n ): Promise<Id<TableName>>;\n patch<TableName extends TableNames>(\n id: Id<TableName>,\n value: Record<string, unknown>\n ): Promise<void>;\n replace<TableName extends TableNames>(\n id: Id<TableName>,\n value: Record<string, unknown>\n ): Promise<void>;\n delete<TableName extends TableNames>(id: Id<TableName>): Promise<void>;\n};\ntype Scheduler = {\n runAfter(delayMs: number, functionReference: unknown, args?: unknown): Promise<void>;\n};\ntype AuthReader = {\n getUserIdentity(): Promise<unknown>;\n};\ntype RuntimeInvoker = {\n runQuery(functionReference: unknown, args?: unknown): Promise<any>;\n runMutation(functionReference: unknown, args?: unknown): Promise<any>;\n runAction(functionReference: unknown, args?: unknown): Promise<any>;\n};\nexport type QueryCtx = RuntimeInvoker & {\n auth: AuthReader;\n db: DatabaseReader;\n scheduler: Scheduler;\n};\nexport type MutationCtx = RuntimeInvoker & {\n auth: AuthReader;\n db: DatabaseWriter;\n scheduler: Scheduler;\n};\nexport type ActionCtx = RuntimeInvoker & {\n auth: AuthReader;\n scheduler: Scheduler;\n};\n\ntype ConvexFunctionBuilder<Ctx> = <\n Definition extends { handler?: (ctx: Ctx, args: any) => any },\n>(\n definition: Definition\n) => any;\n\nexport const action = actionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const httpAction =\n httpActionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const internalAction =\n internalActionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const internalMutation =\n internalMutationGeneric as unknown as ConvexFunctionBuilder<MutationCtx>;\nexport const internalQuery =\n internalQueryGeneric as unknown as ConvexFunctionBuilder<QueryCtx>;\nexport const mutation =\n mutationGeneric as unknown as ConvexFunctionBuilder<MutationCtx>;\nexport const query = queryGeneric as unknown as ConvexFunctionBuilder<QueryCtx>;\n","/**\n * projectionStaleness module implementation.\n */\n\nexport type ProjectionEndpointClass =\n | \"analytics\"\n | \"traversal\"\n | \"entity_read\"\n | \"non_graph\";\n\nexport type ProjectionFallbackMode =\n | \"fail_with_503\"\n | \"degrade_to_convex_depth_limited\"\n | \"fallback_to_convex_entity_read\"\n | \"none\";\n\nexport type ProjectionStalenessPolicy = {\n endpointClass: ProjectionEndpointClass;\n thresholdMs: number;\n fallbackMode: ProjectionFallbackMode;\n nonOverridable: true;\n};\n\nexport type ProjectionStalenessInput = {\n endpointClass: ProjectionEndpointClass;\n queueBacklogAgeMs: number;\n queuePendingCount: number;\n queueFailedCount: number;\n nowMs?: number;\n lastSuccessfulSyncAt?: number;\n};\n\nexport type ProjectionStalenessEnvelope = {\n endpointClass: ProjectionEndpointClass;\n stalenessMs: number;\n thresholdMs: number;\n isStale: boolean;\n fallbackMode: ProjectionFallbackMode;\n queuePendingCount: number;\n queueFailedCount: number;\n evaluatedAt: number;\n lastSuccessfulSyncAt?: number;\n lastSuccessfulSyncAgeMs?: number;\n reasonCode:\n | \"PROJECTION_HEALTHY\"\n | \"PROJECTION_STALE\"\n | \"PROJECTION_STALE_WITH_FAILED_RETRIES\";\n};\n\nexport const PROJECTION_STALENESS_POLICIES: Record<\n ProjectionEndpointClass,\n ProjectionStalenessPolicy\n> = {\n analytics: {\n endpointClass: \"analytics\",\n thresholdMs: 30_000,\n fallbackMode: \"fail_with_503\",\n nonOverridable: true,\n },\n traversal: {\n endpointClass: \"traversal\",\n thresholdMs: 60_000,\n fallbackMode: \"degrade_to_convex_depth_limited\",\n nonOverridable: true,\n },\n entity_read: {\n endpointClass: \"entity_read\",\n thresholdMs: 5 * 60_000,\n fallbackMode: \"fallback_to_convex_entity_read\",\n nonOverridable: true,\n },\n non_graph: {\n endpointClass: \"non_graph\",\n thresholdMs: Number.POSITIVE_INFINITY,\n fallbackMode: \"none\",\n nonOverridable: true,\n },\n};\n\nexport function getProjectionStalenessPolicy(\n endpointClass: ProjectionEndpointClass\n): ProjectionStalenessPolicy {\n return PROJECTION_STALENESS_POLICIES[endpointClass];\n}\n\nexport function evaluateProjectionStaleness(\n input: ProjectionStalenessInput\n): ProjectionStalenessEnvelope {\n const policy = getProjectionStalenessPolicy(input.endpointClass);\n const evaluatedAt = input.nowMs ?? Date.now();\n const stalenessMs = Math.max(0, input.queueBacklogAgeMs);\n const isStale = stalenessMs > policy.thresholdMs;\n const lastSuccessfulSyncAgeMs =\n input.lastSuccessfulSyncAt !== undefined\n ? Math.max(0, evaluatedAt - input.lastSuccessfulSyncAt)\n : undefined;\n\n return {\n endpointClass: input.endpointClass,\n stalenessMs,\n thresholdMs: policy.thresholdMs,\n isStale,\n fallbackMode: policy.fallbackMode,\n queuePendingCount: input.queuePendingCount,\n queueFailedCount: input.queueFailedCount,\n evaluatedAt,\n lastSuccessfulSyncAt: input.lastSuccessfulSyncAt,\n lastSuccessfulSyncAgeMs,\n reasonCode: isStale\n ? input.queueFailedCount > 0\n ? \"PROJECTION_STALE_WITH_FAILED_RETRIES\"\n : \"PROJECTION_STALE\"\n : \"PROJECTION_HEALTHY\",\n };\n}\n\nexport function shouldFailClosedForProjection(\n envelope: ProjectionStalenessEnvelope\n): boolean {\n return envelope.isStale && envelope.fallbackMode === \"fail_with_503\";\n}\n","/**\n * Projection Reconciliation Runtime\n *\n * Phase 2 (WT-C) runtime hooks for Convex-authoritative / Neo4j-projected\n * reconciliation health and endpoint-class staleness evaluation.\n */\n\nimport { v } from \"convex/values\";\nimport { getCurrentUserId } from \"@lucern/access-control/auth\";\nimport { permissiveReturn } from \"@lucern/contracts/schema-helpers/validators\";\nimport { internal, internalAction, internalQuery, query } from \"./convex\";\nimport type { ActionCtx, QueryCtx } from \"./convex\";\nimport {\n evaluateProjectionStaleness,\n type ProjectionEndpointClass,\n} from \"./projectionStaleness\";\ntype QueueStatus = \"pending\" | \"in_progress\" | \"failed\" | \"succeeded\";\n\ntype QueueRow = {\n status: QueueStatus;\n createdAt: number;\n updatedAt: number;\n};\n\ntype IndexQueryBuilder = {\n eq(field: string, value: unknown): IndexQueryBuilder;\n};\n\nfunction maxTimestamp(\n rows: QueueRow[],\n field: \"createdAt\" | \"updatedAt\"\n): number | undefined {\n let maxValue: number | undefined;\n for (const row of rows) {\n const value = row[field];\n if (!Number.isFinite(value)) {\n continue;\n }\n if (maxValue === undefined || value > maxValue) {\n maxValue = value;\n }\n }\n return maxValue;\n}\n\nfunction minTimestamp(\n rows: QueueRow[],\n field: \"createdAt\" | \"updatedAt\"\n): number | undefined {\n let minValue: number | undefined;\n for (const row of rows) {\n const value = row[field];\n if (!Number.isFinite(value)) {\n continue;\n }\n if (minValue === undefined || value < minValue) {\n minValue = value;\n }\n }\n return minValue;\n}\n\nasync function getQueueSnapshot(ctx: QueryCtx) {\n const [pendingRows, inProgressRows, failedRows, succeededRows] =\n await Promise.all([\n ctx.db\n .query(\"neo4jSyncQueue\")\n .withIndex(\"by_status\", (q: IndexQueryBuilder) => q.eq(\"status\", \"pending\"))\n .collect() as Promise<QueueRow[]>,\n ctx.db\n .query(\"neo4jSyncQueue\")\n .withIndex(\"by_status\", (q: IndexQueryBuilder) => q.eq(\"status\", \"in_progress\"))\n .collect() as Promise<QueueRow[]>,\n ctx.db\n .query(\"neo4jSyncQueue\")\n .withIndex(\"by_status\", (q: IndexQueryBuilder) => q.eq(\"status\", \"failed\"))\n .collect() as Promise<QueueRow[]>,\n ctx.db\n .query(\"neo4jSyncQueue\")\n .withIndex(\"by_status\", (q: IndexQueryBuilder) => q.eq(\"status\", \"succeeded\"))\n .collect() as Promise<QueueRow[]>,\n ]);\n\n const now = Date.now();\n const backlogOldestCreatedAt = minTimestamp(\n [...pendingRows, ...inProgressRows],\n \"createdAt\"\n );\n const queueBacklogAgeMs =\n backlogOldestCreatedAt !== undefined\n ? Math.max(0, now - backlogOldestCreatedAt)\n : 0;\n const lastSuccessfulSyncAt = maxTimestamp(succeededRows, \"updatedAt\");\n\n return {\n now,\n queuePendingCount: pendingRows.length,\n queueInProgressCount: inProgressRows.length,\n queueFailedCount: failedRows.length,\n queueSucceededCount: succeededRows.length,\n queueBacklogAgeMs,\n backlogOldestCreatedAt,\n lastSuccessfulSyncAt,\n };\n}\n\nfunction buildEndpointAssessments(\n snapshot: Awaited<ReturnType<typeof getQueueSnapshot>>\n) {\n const analytics = evaluateProjectionStaleness({\n endpointClass: \"analytics\",\n queueBacklogAgeMs: snapshot.queueBacklogAgeMs,\n queuePendingCount:\n snapshot.queuePendingCount + snapshot.queueInProgressCount,\n queueFailedCount: snapshot.queueFailedCount,\n nowMs: snapshot.now,\n lastSuccessfulSyncAt: snapshot.lastSuccessfulSyncAt,\n });\n const traversal = evaluateProjectionStaleness({\n endpointClass: \"traversal\",\n queueBacklogAgeMs: snapshot.queueBacklogAgeMs,\n queuePendingCount:\n snapshot.queuePendingCount + snapshot.queueInProgressCount,\n queueFailedCount: snapshot.queueFailedCount,\n nowMs: snapshot.now,\n lastSuccessfulSyncAt: snapshot.lastSuccessfulSyncAt,\n });\n const entityRead = evaluateProjectionStaleness({\n endpointClass: \"entity_read\",\n queueBacklogAgeMs: snapshot.queueBacklogAgeMs,\n queuePendingCount:\n snapshot.queuePendingCount + snapshot.queueInProgressCount,\n queueFailedCount: snapshot.queueFailedCount,\n nowMs: snapshot.now,\n lastSuccessfulSyncAt: snapshot.lastSuccessfulSyncAt,\n });\n const nonGraph = evaluateProjectionStaleness({\n endpointClass: \"non_graph\",\n queueBacklogAgeMs: snapshot.queueBacklogAgeMs,\n queuePendingCount:\n snapshot.queuePendingCount + snapshot.queueInProgressCount,\n queueFailedCount: snapshot.queueFailedCount,\n nowMs: snapshot.now,\n lastSuccessfulSyncAt: snapshot.lastSuccessfulSyncAt,\n });\n\n return {\n analytics,\n traversal,\n entityRead,\n nonGraph,\n };\n}\n\nfunction buildProjectionReconciliationStatus(\n snapshot: Awaited<ReturnType<typeof getQueueSnapshot>>\n) {\n return {\n ...snapshot,\n endpointAssessments: buildEndpointAssessments(snapshot),\n generatedAt: snapshot.now,\n };\n}\n\nfunction assertAuthenticated(clerkId: string | null): string {\n if (!clerkId) {\n throw new Error(\"Authentication required\");\n }\n return clerkId;\n}\n\nexport const getProjectionReconciliationStatusInternal = internalQuery({\n args: {},\n returns: permissiveReturn,\n handler: async (ctx: QueryCtx) => {\n const snapshot = await getQueueSnapshot(ctx);\n return buildProjectionReconciliationStatus(snapshot);\n },\n});\n\nexport const getProjectionReconciliationStatus = query({\n args: {},\n returns: permissiveReturn,\n handler: async (ctx: QueryCtx) => {\n assertAuthenticated(await getCurrentUserId(ctx));\n const snapshot = await getQueueSnapshot(ctx);\n return buildProjectionReconciliationStatus(snapshot);\n },\n});\n\nexport const assessProjectionStaleness = query({\n args: {\n endpointClass: v.union(\n v.literal(\"analytics\"),\n v.literal(\"traversal\"),\n v.literal(\"entity_read\"),\n v.literal(\"non_graph\")\n ),\n },\n returns: permissiveReturn,\n handler: async (\n ctx: QueryCtx,\n args: { endpointClass: ProjectionEndpointClass }\n ) => {\n assertAuthenticated(await getCurrentUserId(ctx));\n const snapshot = await getQueueSnapshot(ctx);\n const endpointClass = args.endpointClass as ProjectionEndpointClass;\n\n return {\n endpointClass,\n assessment: evaluateProjectionStaleness({\n endpointClass,\n queueBacklogAgeMs: snapshot.queueBacklogAgeMs,\n queuePendingCount:\n snapshot.queuePendingCount + snapshot.queueInProgressCount,\n queueFailedCount: snapshot.queueFailedCount,\n nowMs: snapshot.now,\n lastSuccessfulSyncAt: snapshot.lastSuccessfulSyncAt,\n }),\n snapshot,\n };\n },\n});\n\nexport const runProjectionRepairCycle = internalAction({\n args: {\n limit: v.optional(v.number()),\n },\n returns: permissiveReturn,\n handler: async (ctx: ActionCtx, args: { limit?: number }) => {\n const processed = await ctx.runAction(\n internal.neo4jSync.processRetryQueue,\n {\n limit: args.limit ?? 25,\n }\n );\n const status = await ctx.runQuery(\n internal.projectionReconciliation\n .getProjectionReconciliationStatusInternal,\n {}\n );\n\n return {\n processed,\n status,\n runAt: Date.now(),\n };\n },\n});\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/convex.ts","../src/projectionStaleness.ts","../src/projectionReconciliation.ts"],"names":[],"mappings":"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","file":"projectionReconciliation.js","sourcesContent":["import type { Doc as AccessControlDoc } from \"@lucern/access-control/convex\";\nimport {\n type UnsafeConvexAnyApi,\n unsafeConvexAnyApi,\n} from \"@lucern/contracts/convex/unsafeAnyApi\";\nimport {\n actionGeneric,\n componentsGeneric,\n httpActionGeneric,\n internalActionGeneric,\n internalMutationGeneric,\n internalQueryGeneric,\n mutationGeneric,\n queryGeneric,\n} from \"convex/server\";\nimport type { GenericId } from \"convex/values\";\n\n// TODO(FR.11-structural): `api`/`internal`/`components` are `anyApi as any`\n// because this module source tree is bundled into the kernel host at deploy time\n// and has NO top-level Convex `_generated/` directory to import a typed surface\n// from. Every `api.*` / `internal.*` / string-literal cross-component ref in this\n// module (topicScope.ts, topicProjectOverlay.ts, questionEvidenceLinks.ts,\n// beliefEvidenceLinks*.ts, epistemicQuestions.helpers.ts) inherits `any` from\n// here. The fix is structural — generate a per-module typed surface or a shared\n// typed function-reference manifest (template: the typed `components.controlPlane`\n// in modules/control-plane/src/component/convex.ts and the\n// `KERNEL_API_REF_MANIFEST` pattern in packages/server-core/src/kernelApi.ts) —\n// owned by the FR.11 closing/synthesis pass, not a mechanical swap.\nconst unsafeApi = unsafeConvexAnyApi(\n \"graph-primitives top-level module bundle lacks a committed Convex _generated/api surface\"\n);\nexport const api = unsafeApi;\nexport const components =\n componentsGeneric() as unknown as UntypedFunctionReferenceSurface;\nexport const internal = unsafeApi;\n\ntype UntypedFunctionReferenceSurface = UnsafeConvexAnyApi;\ntype BoundaryValue = UntypedFunctionReferenceSurface[string];\n\nexport type TableNames = string;\nexport type Id<TableName extends TableNames = string> = GenericId<TableName>;\nexport type Doc<TableName extends TableNames = string> =\n AccessControlDoc<TableName>;\nexport type DataModel = Record<TableNames, unknown>;\ninterface IndexRangeBuilder {\n eq(fieldName: string, value: unknown): IndexRangeBuilder;\n field(fieldName: string): string;\n gt(fieldName: string, value: unknown): IndexRangeBuilder;\n gte(fieldName: string, value: unknown): IndexRangeBuilder;\n lt(fieldName: string, value: unknown): IndexRangeBuilder;\n lte(fieldName: string, value: unknown): IndexRangeBuilder;\n}\ninterface FilterBuilder {\n and(...clauses: unknown[]): FilterBuilder;\n eq(left: unknown, right: unknown): FilterBuilder;\n field(fieldName: string): string;\n gt(left: unknown, right: unknown): FilterBuilder;\n gte(left: unknown, right: unknown): FilterBuilder;\n lt(left: unknown, right: unknown): FilterBuilder;\n lte(left: unknown, right: unknown): FilterBuilder;\n neq(left: unknown, right: unknown): FilterBuilder;\n or(...clauses: unknown[]): FilterBuilder;\n [operator: string]: unknown;\n}\ninterface QueryInitializer<TableName extends TableNames> {\n collect(): Promise<Doc<TableName>[]>;\n filter(predicate: (q: FilterBuilder) => unknown): QueryInitializer<TableName>;\n first(): Promise<Doc<TableName> | null>;\n order(direction: \"asc\" | \"desc\"): QueryInitializer<TableName>;\n take(limit: number): Promise<Doc<TableName>[]>;\n unique(): Promise<Doc<TableName> | null>;\n withIndex(\n indexName: string,\n range?: (q: IndexRangeBuilder) => unknown\n ): QueryInitializer<TableName>;\n withSearchIndex(\n indexName: string,\n search?: (q: IndexRangeBuilder) => unknown\n ): QueryInitializer<TableName>;\n}\nexport interface DatabaseReader {\n get<TableName extends TableNames>(\n id: unknown\n ): Promise<Doc<TableName> | null>;\n normalizeId?<TableName extends TableNames>(\n tableName: TableName,\n id: string\n ): Id<TableName> | null;\n query<TableName extends TableNames>(\n tableName: TableName\n ): QueryInitializer<TableName>;\n}\nexport type DatabaseWriter = DatabaseReader & {\n insert<TableName extends TableNames>(\n tableName: TableName,\n value: Record<string, unknown>\n ): Promise<Id<TableName>>;\n patch<TableName extends TableNames>(\n id: Id<TableName>,\n value: Record<string, unknown>\n ): Promise<void>;\n replace<TableName extends TableNames>(\n id: Id<TableName>,\n value: Record<string, unknown>\n ): Promise<void>;\n delete<TableName extends TableNames>(id: Id<TableName>): Promise<void>;\n};\ninterface Scheduler {\n runAfter(\n delayMs: number,\n functionReference: unknown,\n args?: unknown\n ): Promise<void>;\n}\ninterface AuthReader {\n getUserIdentity(): Promise<{\n readonly subject: string;\n readonly [claimName: string]: unknown;\n } | null>;\n}\ninterface RuntimeInvoker {\n runAction<Result = unknown>(\n functionReference: unknown,\n args?: unknown\n ): Promise<Result>;\n runMutation<Result = unknown>(\n functionReference: unknown,\n args?: unknown\n ): Promise<Result>;\n runQuery<Result = unknown>(\n functionReference: unknown,\n args?: unknown\n ): Promise<Result>;\n}\nexport type QueryCtx = RuntimeInvoker & {\n auth: AuthReader;\n db: DatabaseReader;\n scheduler: Scheduler;\n};\nexport type MutationCtx = RuntimeInvoker & {\n auth: AuthReader;\n db: DatabaseWriter;\n scheduler: Scheduler;\n};\nexport type ActionCtx = RuntimeInvoker & {\n auth: AuthReader;\n scheduler: Scheduler;\n};\n\ntype ConvexFunctionBuilder<Ctx> = <\n Args = BoundaryValue,\n Result = BoundaryValue,\n>(definition: {\n args?: unknown;\n handler: (ctx: Ctx, args: Args) => Result;\n returns?: unknown;\n}) => unknown;\n\ntype OptionalHandlerConvexFunctionBuilder<Ctx> = <\n Args = BoundaryValue,\n Result = BoundaryValue,\n>(definition: {\n args?: unknown;\n handler?: (ctx: Ctx, args: Args) => Result;\n returns?: unknown;\n}) => unknown;\n\nexport const action =\n actionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const httpAction =\n httpActionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const internalAction =\n internalActionGeneric as unknown as ConvexFunctionBuilder<ActionCtx>;\nexport const internalMutation =\n internalMutationGeneric as unknown as OptionalHandlerConvexFunctionBuilder<MutationCtx>;\nexport const internalQuery =\n internalQueryGeneric as unknown as OptionalHandlerConvexFunctionBuilder<QueryCtx>;\nexport const mutation =\n mutationGeneric as unknown as ConvexFunctionBuilder<MutationCtx>;\nexport const query = queryGeneric as unknown as ConvexFunctionBuilder<QueryCtx>;\n","// biome-ignore-all lint/style/useFilenamingConvention: Public graph-primitives wildcard-export path; rename requires an export-map migration.\n/**\n * projectionStaleness module implementation.\n */\n\nexport type ProjectionEndpointClass =\n | \"analytics\"\n | \"traversal\"\n | \"entity_read\"\n | \"non_graph\";\n\nexport type ProjectionFallbackMode =\n | \"fail_with_503\"\n | \"degrade_to_convex_depth_limited\"\n | \"fallback_to_convex_entity_read\"\n | \"none\";\n\nexport interface ProjectionStalenessPolicy {\n endpointClass: ProjectionEndpointClass;\n fallbackMode: ProjectionFallbackMode;\n nonOverridable: true;\n thresholdMs: number;\n}\n\nexport interface ProjectionStalenessInput {\n endpointClass: ProjectionEndpointClass;\n lastSuccessfulSyncAt?: number;\n nowMs?: number;\n queueBacklogAgeMs: number;\n queueFailedCount: number;\n queuePendingCount: number;\n}\n\nexport interface ProjectionStalenessEnvelope {\n endpointClass: ProjectionEndpointClass;\n evaluatedAt: number;\n fallbackMode: ProjectionFallbackMode;\n isStale: boolean;\n lastSuccessfulSyncAgeMs?: number;\n lastSuccessfulSyncAt?: number;\n queueFailedCount: number;\n queuePendingCount: number;\n reasonCode:\n | \"PROJECTION_HEALTHY\"\n | \"PROJECTION_STALE\"\n | \"PROJECTION_STALE_WITH_FAILED_RETRIES\";\n stalenessMs: number;\n thresholdMs: number;\n}\n\nexport const PROJECTION_STALENESS_POLICIES: Record<\n ProjectionEndpointClass,\n ProjectionStalenessPolicy\n> = {\n analytics: {\n endpointClass: \"analytics\",\n thresholdMs: 30_000,\n fallbackMode: \"fail_with_503\",\n nonOverridable: true,\n },\n traversal: {\n endpointClass: \"traversal\",\n thresholdMs: 60_000,\n fallbackMode: \"degrade_to_convex_depth_limited\",\n nonOverridable: true,\n },\n entity_read: {\n endpointClass: \"entity_read\",\n thresholdMs: 5 * 60_000,\n fallbackMode: \"fallback_to_convex_entity_read\",\n nonOverridable: true,\n },\n non_graph: {\n endpointClass: \"non_graph\",\n thresholdMs: Number.POSITIVE_INFINITY,\n fallbackMode: \"none\",\n nonOverridable: true,\n },\n};\n\nexport function getProjectionStalenessPolicy(\n endpointClass: ProjectionEndpointClass\n): ProjectionStalenessPolicy {\n return PROJECTION_STALENESS_POLICIES[endpointClass];\n}\n\nexport function evaluateProjectionStaleness(\n input: ProjectionStalenessInput\n): ProjectionStalenessEnvelope {\n const policy = getProjectionStalenessPolicy(input.endpointClass);\n const evaluatedAt = input.nowMs ?? Date.now();\n const stalenessMs = Math.max(0, input.queueBacklogAgeMs);\n const isStale = stalenessMs > policy.thresholdMs;\n const lastSuccessfulSyncAgeMs =\n input.lastSuccessfulSyncAt === undefined\n ? undefined\n : Math.max(0, evaluatedAt - input.lastSuccessfulSyncAt);\n\n return {\n endpointClass: input.endpointClass,\n stalenessMs,\n thresholdMs: policy.thresholdMs,\n isStale,\n fallbackMode: policy.fallbackMode,\n queuePendingCount: input.queuePendingCount,\n queueFailedCount: input.queueFailedCount,\n evaluatedAt,\n lastSuccessfulSyncAt: input.lastSuccessfulSyncAt,\n lastSuccessfulSyncAgeMs,\n reasonCode: projectionStalenessReasonCode(isStale, input.queueFailedCount),\n };\n}\n\nfunction projectionStalenessReasonCode(\n isStale: boolean,\n queueFailedCount: number\n): ProjectionStalenessEnvelope[\"reasonCode\"] {\n if (!isStale) {\n return \"PROJECTION_HEALTHY\";\n }\n return queueFailedCount > 0\n ? \"PROJECTION_STALE_WITH_FAILED_RETRIES\"\n : \"PROJECTION_STALE\";\n}\n\nexport function shouldFailClosedForProjection(\n envelope: ProjectionStalenessEnvelope\n): boolean {\n return envelope.isStale && envelope.fallbackMode === \"fail_with_503\";\n}\n","// biome-ignore-all lint/style/useFilenamingConvention: Public graph-primitives wildcard-export path; rename requires an export-map migration.\n/**\n * Projection Reconciliation Runtime\n *\n * Phase 2 (WT-C) runtime hooks for Convex-authoritative / Neo4j-projected\n * reconciliation health and endpoint-class staleness evaluation.\n */\n\nimport { getCurrentUserId } from \"@lucern/access-control/auth\";\nimport { permissiveReturn } from \"@lucern/contracts/schema-helpers/validators\";\nimport { v } from \"convex/values\";\nimport type { ActionCtx, QueryCtx } from \"./convex\";\nimport { internal, internalAction, internalQuery, query } from \"./convex\";\nimport {\n evaluateProjectionStaleness,\n type ProjectionEndpointClass,\n} from \"./projectionStaleness\";\n\ntype QueueStatus = \"pending\" | \"in_progress\" | \"failed\" | \"succeeded\";\n\ninterface QueueRow {\n createdAt: number;\n status: QueueStatus;\n updatedAt: number;\n}\n\ninterface IndexQueryBuilder {\n eq(field: string, value: unknown): IndexQueryBuilder;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction readQueueStatus(value: unknown, context: string): QueueStatus {\n if (\n value !== \"pending\" &&\n value !== \"in_progress\" &&\n value !== \"failed\" &&\n value !== \"succeeded\"\n ) {\n throw new Error(`${context} has invalid or missing status.`);\n }\n return value;\n}\n\nfunction readFiniteNumber(\n row: Record<string, unknown>,\n field: \"createdAt\" | \"updatedAt\",\n context: string\n): number {\n const value = row[field];\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n throw new Error(`${context} has invalid or missing ${field}.`);\n }\n return value;\n}\n\nfunction readQueueRow(value: unknown, context: string): QueueRow {\n if (!isRecord(value)) {\n throw new Error(`${context} must be an object.`);\n }\n return {\n createdAt: readFiniteNumber(value, \"createdAt\", context),\n status: readQueueStatus(value.status, context),\n updatedAt: readFiniteNumber(value, \"updatedAt\", context),\n };\n}\n\nfunction readQueueRows(values: unknown[], context: string): QueueRow[] {\n return values.map((value, index) =>\n readQueueRow(value, `${context}[${index}]`)\n );\n}\n\nasync function getQueueRowsByStatus(\n ctx: QueryCtx,\n status: QueueStatus\n): Promise<QueueRow[]> {\n return readQueueRows(\n await ctx.db\n .query(\"neo4jSyncQueue\")\n .withIndex(\"by_status\", (q: IndexQueryBuilder) => q.eq(\"status\", status))\n .collect(),\n `neo4jSyncQueue.${status}`\n );\n}\n\nfunction maxTimestamp(\n rows: QueueRow[],\n field: \"createdAt\" | \"updatedAt\"\n): number | undefined {\n let maxValue: number | undefined;\n for (const row of rows) {\n const value = row[field];\n if (!Number.isFinite(value)) {\n continue;\n }\n if (maxValue === undefined || value > maxValue) {\n maxValue = value;\n }\n }\n return maxValue;\n}\n\nfunction minTimestamp(\n rows: QueueRow[],\n field: \"createdAt\" | \"updatedAt\"\n): number | undefined {\n let minValue: number | undefined;\n for (const row of rows) {\n const value = row[field];\n if (!Number.isFinite(value)) {\n continue;\n }\n if (minValue === undefined || value < minValue) {\n minValue = value;\n }\n }\n return minValue;\n}\n\nasync function getQueueSnapshot(ctx: QueryCtx) {\n const [pendingRows, inProgressRows, failedRows, succeededRows] =\n await Promise.all([\n getQueueRowsByStatus(ctx, \"pending\"),\n getQueueRowsByStatus(ctx, \"in_progress\"),\n getQueueRowsByStatus(ctx, \"failed\"),\n getQueueRowsByStatus(ctx, \"succeeded\"),\n ]);\n\n const now = Date.now();\n const backlogOldestCreatedAt = minTimestamp(\n [...pendingRows, ...inProgressRows],\n \"createdAt\"\n );\n const queueBacklogAgeMs =\n backlogOldestCreatedAt === undefined\n ? 0\n : Math.max(0, now - backlogOldestCreatedAt);\n const lastSuccessfulSyncAt = maxTimestamp(succeededRows, \"updatedAt\");\n\n return {\n now,\n queuePendingCount: pendingRows.length,\n queueInProgressCount: inProgressRows.length,\n queueFailedCount: failedRows.length,\n queueSucceededCount: succeededRows.length,\n queueBacklogAgeMs,\n backlogOldestCreatedAt,\n lastSuccessfulSyncAt,\n };\n}\n\nfunction buildEndpointAssessments(\n snapshot: Awaited<ReturnType<typeof getQueueSnapshot>>\n) {\n const analytics = evaluateProjectionStaleness({\n endpointClass: \"analytics\",\n queueBacklogAgeMs: snapshot.queueBacklogAgeMs,\n queuePendingCount:\n snapshot.queuePendingCount + snapshot.queueInProgressCount,\n queueFailedCount: snapshot.queueFailedCount,\n nowMs: snapshot.now,\n lastSuccessfulSyncAt: snapshot.lastSuccessfulSyncAt,\n });\n const traversal = evaluateProjectionStaleness({\n endpointClass: \"traversal\",\n queueBacklogAgeMs: snapshot.queueBacklogAgeMs,\n queuePendingCount:\n snapshot.queuePendingCount + snapshot.queueInProgressCount,\n queueFailedCount: snapshot.queueFailedCount,\n nowMs: snapshot.now,\n lastSuccessfulSyncAt: snapshot.lastSuccessfulSyncAt,\n });\n const entityRead = evaluateProjectionStaleness({\n endpointClass: \"entity_read\",\n queueBacklogAgeMs: snapshot.queueBacklogAgeMs,\n queuePendingCount:\n snapshot.queuePendingCount + snapshot.queueInProgressCount,\n queueFailedCount: snapshot.queueFailedCount,\n nowMs: snapshot.now,\n lastSuccessfulSyncAt: snapshot.lastSuccessfulSyncAt,\n });\n const nonGraph = evaluateProjectionStaleness({\n endpointClass: \"non_graph\",\n queueBacklogAgeMs: snapshot.queueBacklogAgeMs,\n queuePendingCount:\n snapshot.queuePendingCount + snapshot.queueInProgressCount,\n queueFailedCount: snapshot.queueFailedCount,\n nowMs: snapshot.now,\n lastSuccessfulSyncAt: snapshot.lastSuccessfulSyncAt,\n });\n\n return {\n analytics,\n traversal,\n entityRead,\n nonGraph,\n };\n}\n\nfunction buildProjectionReconciliationStatus(\n snapshot: Awaited<ReturnType<typeof getQueueSnapshot>>\n) {\n return {\n ...snapshot,\n endpointAssessments: buildEndpointAssessments(snapshot),\n generatedAt: snapshot.now,\n };\n}\n\nfunction assertAuthenticated(clerkId: string | null): string {\n if (!clerkId) {\n throw new Error(\"Authentication required\");\n }\n return clerkId;\n}\n\nexport const getProjectionReconciliationStatusInternal = internalQuery({\n args: {},\n returns: permissiveReturn,\n handler: async (ctx: QueryCtx) => {\n const snapshot = await getQueueSnapshot(ctx);\n return buildProjectionReconciliationStatus(snapshot);\n },\n});\n\nexport const getProjectionReconciliationStatus = query({\n args: {},\n returns: permissiveReturn,\n handler: async (ctx: QueryCtx) => {\n assertAuthenticated(await getCurrentUserId(ctx));\n const snapshot = await getQueueSnapshot(ctx);\n return buildProjectionReconciliationStatus(snapshot);\n },\n});\n\nexport const assessProjectionStaleness = query({\n args: {\n endpointClass: v.union(\n v.literal(\"analytics\"),\n v.literal(\"traversal\"),\n v.literal(\"entity_read\"),\n v.literal(\"non_graph\")\n ),\n },\n returns: permissiveReturn,\n handler: async (\n ctx: QueryCtx,\n args: { endpointClass: ProjectionEndpointClass }\n ) => {\n assertAuthenticated(await getCurrentUserId(ctx));\n const snapshot = await getQueueSnapshot(ctx);\n const endpointClass = args.endpointClass as ProjectionEndpointClass;\n\n return {\n endpointClass,\n assessment: evaluateProjectionStaleness({\n endpointClass,\n queueBacklogAgeMs: snapshot.queueBacklogAgeMs,\n queuePendingCount:\n snapshot.queuePendingCount + snapshot.queueInProgressCount,\n queueFailedCount: snapshot.queueFailedCount,\n nowMs: snapshot.now,\n lastSuccessfulSyncAt: snapshot.lastSuccessfulSyncAt,\n }),\n snapshot,\n };\n },\n});\n\nexport const runProjectionRepairCycle = internalAction({\n args: {\n limit: v.optional(v.number()),\n },\n returns: permissiveReturn,\n handler: async (ctx: ActionCtx, args: { limit?: number }) => {\n const processed = await ctx.runAction(\n internal.neo4jSync.processRetryQueue,\n {\n limit: args.limit ?? 25,\n }\n );\n const status = await ctx.runQuery(\n internal.projectionReconciliation\n .getProjectionReconciliationStatusInternal,\n {}\n );\n\n return {\n processed,\n status,\n runAt: Date.now(),\n };\n },\n});\n"]}
|
|
@@ -3,33 +3,33 @@
|
|
|
3
3
|
*/
|
|
4
4
|
type ProjectionEndpointClass = "analytics" | "traversal" | "entity_read" | "non_graph";
|
|
5
5
|
type ProjectionFallbackMode = "fail_with_503" | "degrade_to_convex_depth_limited" | "fallback_to_convex_entity_read" | "none";
|
|
6
|
-
|
|
6
|
+
interface ProjectionStalenessPolicy {
|
|
7
7
|
endpointClass: ProjectionEndpointClass;
|
|
8
|
-
thresholdMs: number;
|
|
9
8
|
fallbackMode: ProjectionFallbackMode;
|
|
10
9
|
nonOverridable: true;
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
thresholdMs: number;
|
|
11
|
+
}
|
|
12
|
+
interface ProjectionStalenessInput {
|
|
13
13
|
endpointClass: ProjectionEndpointClass;
|
|
14
|
+
lastSuccessfulSyncAt?: number;
|
|
15
|
+
nowMs?: number;
|
|
14
16
|
queueBacklogAgeMs: number;
|
|
15
|
-
queuePendingCount: number;
|
|
16
17
|
queueFailedCount: number;
|
|
17
|
-
nowMs?: number;
|
|
18
|
-
lastSuccessfulSyncAt?: number;
|
|
19
|
-
};
|
|
20
|
-
type ProjectionStalenessEnvelope = {
|
|
21
|
-
endpointClass: ProjectionEndpointClass;
|
|
22
|
-
stalenessMs: number;
|
|
23
|
-
thresholdMs: number;
|
|
24
|
-
isStale: boolean;
|
|
25
|
-
fallbackMode: ProjectionFallbackMode;
|
|
26
18
|
queuePendingCount: number;
|
|
27
|
-
|
|
19
|
+
}
|
|
20
|
+
interface ProjectionStalenessEnvelope {
|
|
21
|
+
endpointClass: ProjectionEndpointClass;
|
|
28
22
|
evaluatedAt: number;
|
|
29
|
-
|
|
23
|
+
fallbackMode: ProjectionFallbackMode;
|
|
24
|
+
isStale: boolean;
|
|
30
25
|
lastSuccessfulSyncAgeMs?: number;
|
|
26
|
+
lastSuccessfulSyncAt?: number;
|
|
27
|
+
queueFailedCount: number;
|
|
28
|
+
queuePendingCount: number;
|
|
31
29
|
reasonCode: "PROJECTION_HEALTHY" | "PROJECTION_STALE" | "PROJECTION_STALE_WITH_FAILED_RETRIES";
|
|
32
|
-
|
|
30
|
+
stalenessMs: number;
|
|
31
|
+
thresholdMs: number;
|
|
32
|
+
}
|
|
33
33
|
declare const PROJECTION_STALENESS_POLICIES: Record<ProjectionEndpointClass, ProjectionStalenessPolicy>;
|
|
34
34
|
declare function getProjectionStalenessPolicy(endpointClass: ProjectionEndpointClass): ProjectionStalenessPolicy;
|
|
35
35
|
declare function evaluateProjectionStaleness(input: ProjectionStalenessInput): ProjectionStalenessEnvelope;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { P as PROJECTION_STALENESS_POLICIES, a as ProjectionEndpointClass, b as ProjectionFallbackMode, c as ProjectionStalenessEnvelope, d as ProjectionStalenessInput, e as ProjectionStalenessPolicy, f as evaluateProjectionStaleness, g as getProjectionStalenessPolicy, s as shouldFailClosedForProjection } from './projectionStaleness-
|
|
1
|
+
export { P as PROJECTION_STALENESS_POLICIES, a as ProjectionEndpointClass, b as ProjectionFallbackMode, c as ProjectionStalenessEnvelope, d as ProjectionStalenessInput, e as ProjectionStalenessPolicy, f as evaluateProjectionStaleness, g as getProjectionStalenessPolicy, s as shouldFailClosedForProjection } from './projectionStaleness-C8ImQ2zP.js';
|
|
@@ -33,7 +33,7 @@ function evaluateProjectionStaleness(input) {
|
|
|
33
33
|
const evaluatedAt = input.nowMs ?? Date.now();
|
|
34
34
|
const stalenessMs = Math.max(0, input.queueBacklogAgeMs);
|
|
35
35
|
const isStale = stalenessMs > policy.thresholdMs;
|
|
36
|
-
const lastSuccessfulSyncAgeMs = input.lastSuccessfulSyncAt
|
|
36
|
+
const lastSuccessfulSyncAgeMs = input.lastSuccessfulSyncAt === void 0 ? void 0 : Math.max(0, evaluatedAt - input.lastSuccessfulSyncAt);
|
|
37
37
|
return {
|
|
38
38
|
endpointClass: input.endpointClass,
|
|
39
39
|
stalenessMs,
|
|
@@ -45,9 +45,15 @@ function evaluateProjectionStaleness(input) {
|
|
|
45
45
|
evaluatedAt,
|
|
46
46
|
lastSuccessfulSyncAt: input.lastSuccessfulSyncAt,
|
|
47
47
|
lastSuccessfulSyncAgeMs,
|
|
48
|
-
reasonCode: isStale
|
|
48
|
+
reasonCode: projectionStalenessReasonCode(isStale, input.queueFailedCount)
|
|
49
49
|
};
|
|
50
50
|
}
|
|
51
|
+
function projectionStalenessReasonCode(isStale, queueFailedCount) {
|
|
52
|
+
if (!isStale) {
|
|
53
|
+
return "PROJECTION_HEALTHY";
|
|
54
|
+
}
|
|
55
|
+
return queueFailedCount > 0 ? "PROJECTION_STALE_WITH_FAILED_RETRIES" : "PROJECTION_STALE";
|
|
56
|
+
}
|
|
51
57
|
function shouldFailClosedForProjection(envelope) {
|
|
52
58
|
return envelope.isStale && envelope.fallbackMode === "fail_with_503";
|
|
53
59
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/projectionStaleness.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"sources":["../src/projectionStaleness.ts"],"names":[],"mappings":";AAkDO,IAAM,6BAAA,GAGT;AAAA,EACF,SAAA,EAAW;AAAA,IACT,aAAA,EAAe,WAAA;AAAA,IACf,WAAA,EAAa,GAAA;AAAA,IACb,YAAA,EAAc,eAAA;AAAA,IACd,cAAA,EAAgB;AAAA,GAClB;AAAA,EACA,SAAA,EAAW;AAAA,IACT,aAAA,EAAe,WAAA;AAAA,IACf,WAAA,EAAa,GAAA;AAAA,IACb,YAAA,EAAc,iCAAA;AAAA,IACd,cAAA,EAAgB;AAAA,GAClB;AAAA,EACA,WAAA,EAAa;AAAA,IACX,aAAA,EAAe,aAAA;AAAA,IACf,aAAa,CAAA,GAAI,GAAA;AAAA,IACjB,YAAA,EAAc,gCAAA;AAAA,IACd,cAAA,EAAgB;AAAA,GAClB;AAAA,EACA,SAAA,EAAW;AAAA,IACT,aAAA,EAAe,WAAA;AAAA,IACf,aAAa,MAAA,CAAO,iBAAA;AAAA,IACpB,YAAA,EAAc,MAAA;AAAA,IACd,cAAA,EAAgB;AAAA;AAEpB;AAEO,SAAS,6BACd,aAAA,EAC2B;AAC3B,EAAA,OAAO,8BAA8B,aAAa,CAAA;AACpD;AAEO,SAAS,4BACd,KAAA,EAC6B;AAC7B,EAAA,MAAM,MAAA,GAAS,4BAAA,CAA6B,KAAA,CAAM,aAAa,CAAA;AAC/D,EAAA,MAAM,WAAA,GAAc,KAAA,CAAM,KAAA,IAAS,IAAA,CAAK,GAAA,EAAI;AAC5C,EAAA,MAAM,WAAA,GAAc,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,MAAM,iBAAiB,CAAA;AACvD,EAAA,MAAM,OAAA,GAAU,cAAc,MAAA,CAAO,WAAA;AACrC,EAAA,MAAM,uBAAA,GACJ,KAAA,CAAM,oBAAA,KAAyB,MAAA,GAC3B,MAAA,GACA,KAAK,GAAA,CAAI,CAAA,EAAG,WAAA,GAAc,KAAA,CAAM,oBAAoB,CAAA;AAE1D,EAAA,OAAO;AAAA,IACL,eAAe,KAAA,CAAM,aAAA;AAAA,IACrB,WAAA;AAAA,IACA,aAAa,MAAA,CAAO,WAAA;AAAA,IACpB,OAAA;AAAA,IACA,cAAc,MAAA,CAAO,YAAA;AAAA,IACrB,mBAAmB,KAAA,CAAM,iBAAA;AAAA,IACzB,kBAAkB,KAAA,CAAM,gBAAA;AAAA,IACxB,WAAA;AAAA,IACA,sBAAsB,KAAA,CAAM,oBAAA;AAAA,IAC5B,uBAAA;AAAA,IACA,UAAA,EAAY,6BAAA,CAA8B,OAAA,EAAS,KAAA,CAAM,gBAAgB;AAAA,GAC3E;AACF;AAEA,SAAS,6BAAA,CACP,SACA,gBAAA,EAC2C;AAC3C,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,OAAO,oBAAA;AAAA,EACT;AACA,EAAA,OAAO,gBAAA,GAAmB,IACtB,sCAAA,GACA,kBAAA;AACN;AAEO,SAAS,8BACd,QAAA,EACS;AACT,EAAA,OAAO,QAAA,CAAS,OAAA,IAAW,QAAA,CAAS,YAAA,KAAiB,eAAA;AACvD","file":"projectionStaleness.js","sourcesContent":["// biome-ignore-all lint/style/useFilenamingConvention: Public graph-primitives wildcard-export path; rename requires an export-map migration.\n/**\n * projectionStaleness module implementation.\n */\n\nexport type ProjectionEndpointClass =\n | \"analytics\"\n | \"traversal\"\n | \"entity_read\"\n | \"non_graph\";\n\nexport type ProjectionFallbackMode =\n | \"fail_with_503\"\n | \"degrade_to_convex_depth_limited\"\n | \"fallback_to_convex_entity_read\"\n | \"none\";\n\nexport interface ProjectionStalenessPolicy {\n endpointClass: ProjectionEndpointClass;\n fallbackMode: ProjectionFallbackMode;\n nonOverridable: true;\n thresholdMs: number;\n}\n\nexport interface ProjectionStalenessInput {\n endpointClass: ProjectionEndpointClass;\n lastSuccessfulSyncAt?: number;\n nowMs?: number;\n queueBacklogAgeMs: number;\n queueFailedCount: number;\n queuePendingCount: number;\n}\n\nexport interface ProjectionStalenessEnvelope {\n endpointClass: ProjectionEndpointClass;\n evaluatedAt: number;\n fallbackMode: ProjectionFallbackMode;\n isStale: boolean;\n lastSuccessfulSyncAgeMs?: number;\n lastSuccessfulSyncAt?: number;\n queueFailedCount: number;\n queuePendingCount: number;\n reasonCode:\n | \"PROJECTION_HEALTHY\"\n | \"PROJECTION_STALE\"\n | \"PROJECTION_STALE_WITH_FAILED_RETRIES\";\n stalenessMs: number;\n thresholdMs: number;\n}\n\nexport const PROJECTION_STALENESS_POLICIES: Record<\n ProjectionEndpointClass,\n ProjectionStalenessPolicy\n> = {\n analytics: {\n endpointClass: \"analytics\",\n thresholdMs: 30_000,\n fallbackMode: \"fail_with_503\",\n nonOverridable: true,\n },\n traversal: {\n endpointClass: \"traversal\",\n thresholdMs: 60_000,\n fallbackMode: \"degrade_to_convex_depth_limited\",\n nonOverridable: true,\n },\n entity_read: {\n endpointClass: \"entity_read\",\n thresholdMs: 5 * 60_000,\n fallbackMode: \"fallback_to_convex_entity_read\",\n nonOverridable: true,\n },\n non_graph: {\n endpointClass: \"non_graph\",\n thresholdMs: Number.POSITIVE_INFINITY,\n fallbackMode: \"none\",\n nonOverridable: true,\n },\n};\n\nexport function getProjectionStalenessPolicy(\n endpointClass: ProjectionEndpointClass\n): ProjectionStalenessPolicy {\n return PROJECTION_STALENESS_POLICIES[endpointClass];\n}\n\nexport function evaluateProjectionStaleness(\n input: ProjectionStalenessInput\n): ProjectionStalenessEnvelope {\n const policy = getProjectionStalenessPolicy(input.endpointClass);\n const evaluatedAt = input.nowMs ?? Date.now();\n const stalenessMs = Math.max(0, input.queueBacklogAgeMs);\n const isStale = stalenessMs > policy.thresholdMs;\n const lastSuccessfulSyncAgeMs =\n input.lastSuccessfulSyncAt === undefined\n ? undefined\n : Math.max(0, evaluatedAt - input.lastSuccessfulSyncAt);\n\n return {\n endpointClass: input.endpointClass,\n stalenessMs,\n thresholdMs: policy.thresholdMs,\n isStale,\n fallbackMode: policy.fallbackMode,\n queuePendingCount: input.queuePendingCount,\n queueFailedCount: input.queueFailedCount,\n evaluatedAt,\n lastSuccessfulSyncAt: input.lastSuccessfulSyncAt,\n lastSuccessfulSyncAgeMs,\n reasonCode: projectionStalenessReasonCode(isStale, input.queueFailedCount),\n };\n}\n\nfunction projectionStalenessReasonCode(\n isStale: boolean,\n queueFailedCount: number\n): ProjectionStalenessEnvelope[\"reasonCode\"] {\n if (!isStale) {\n return \"PROJECTION_HEALTHY\";\n }\n return queueFailedCount > 0\n ? \"PROJECTION_STALE_WITH_FAILED_RETRIES\"\n : \"PROJECTION_STALE\";\n}\n\nexport function shouldFailClosedForProjection(\n envelope: ProjectionStalenessEnvelope\n): boolean {\n return envelope.isStale && envelope.fallbackMode === \"fail_with_503\";\n}\n"]}
|
|
@@ -6,16 +6,16 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Links evidence (insights) to questions to track what evidence helps answer which questions.
|
|
8
8
|
*/
|
|
9
|
-
declare const create:
|
|
10
|
-
declare const updateImpact:
|
|
11
|
-
declare const reviewSuggestion:
|
|
12
|
-
declare const remove:
|
|
13
|
-
declare const getByQuestion:
|
|
14
|
-
declare const getPendingSuggestions:
|
|
15
|
-
declare const getByInsight:
|
|
16
|
-
declare const getEvidenceWithDetails:
|
|
17
|
-
declare const getByProject:
|
|
18
|
-
declare const getLinkedQuestionsForInsight:
|
|
9
|
+
declare const create: unknown;
|
|
10
|
+
declare const updateImpact: unknown;
|
|
11
|
+
declare const reviewSuggestion: unknown;
|
|
12
|
+
declare const remove: unknown;
|
|
13
|
+
declare const getByQuestion: unknown;
|
|
14
|
+
declare const getPendingSuggestions: unknown;
|
|
15
|
+
declare const getByInsight: unknown;
|
|
16
|
+
declare const getEvidenceWithDetails: unknown;
|
|
17
|
+
declare const getByProject: unknown;
|
|
18
|
+
declare const getLinkedQuestionsForInsight: unknown;
|
|
19
19
|
|
|
20
20
|
declare const questionEvidenceLinks_create: typeof create;
|
|
21
21
|
declare const questionEvidenceLinks_getByInsight: typeof getByInsight;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { c as create, g as getByInsight, a as getByProject, b as getByQuestion, d as getEvidenceWithDetails, e as getLinkedQuestionsForInsight, f as getPendingSuggestions, r as remove, h as reviewSuggestion, u as updateImpact } from './questionEvidenceLinks-
|
|
1
|
+
export { c as create, g as getByInsight, a as getByProject, b as getByQuestion, d as getEvidenceWithDetails, e as getLinkedQuestionsForInsight, f as getPendingSuggestions, r as remove, h as reviewSuggestion, u as updateImpact } from './questionEvidenceLinks-_nPRa-LY.js';
|