@memberjunction/core-entities-server 6.2.0-edge.6 → 6.2.0-edge.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +155 -100
- package/dist/custom/AnchoredConversationReadSecurityHook.d.ts +22 -0
- package/dist/custom/AnchoredConversationReadSecurityHook.d.ts.map +1 -0
- package/dist/custom/AnchoredConversationReadSecurityHook.js +293 -0
- package/dist/custom/AnchoredConversationReadSecurityHook.js.map +1 -0
- package/dist/custom/MJAIAgentExampleEntityServer.server.d.ts +2 -0
- package/dist/custom/MJAIAgentExampleEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJAIAgentExampleEntityServer.server.js +8 -5
- package/dist/custom/MJAIAgentExampleEntityServer.server.js.map +1 -1
- package/dist/custom/MJAIAgentNoteEntityServer.server.d.ts +2 -0
- package/dist/custom/MJAIAgentNoteEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJAIAgentNoteEntityServer.server.js +8 -5
- package/dist/custom/MJAIAgentNoteEntityServer.server.js.map +1 -1
- package/dist/custom/MJAIAgentRelationshipEntityServer.server.d.ts +17 -0
- package/dist/custom/MJAIAgentRelationshipEntityServer.server.d.ts.map +1 -0
- package/dist/custom/MJAIAgentRelationshipEntityServer.server.js +71 -0
- package/dist/custom/MJAIAgentRelationshipEntityServer.server.js.map +1 -0
- package/dist/custom/MJAIAgentSessionEntityServer.server.d.ts +8 -22
- package/dist/custom/MJAIAgentSessionEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJAIAgentSessionEntityServer.server.js +24 -1
- package/dist/custom/MJAIAgentSessionEntityServer.server.js.map +1 -1
- package/dist/custom/MJAIAgentUserPolicyEntityServer.server.d.ts +23 -0
- package/dist/custom/MJAIAgentUserPolicyEntityServer.server.d.ts.map +1 -0
- package/dist/custom/MJAIAgentUserPolicyEntityServer.server.js +53 -0
- package/dist/custom/MJAIAgentUserPolicyEntityServer.server.js.map +1 -0
- package/dist/custom/MJAIPromptEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJAIPromptEntityServer.server.js +2 -1
- package/dist/custom/MJAIPromptEntityServer.server.js.map +1 -1
- package/dist/custom/MJBrandKitEntityServer.server.d.ts +14 -0
- package/dist/custom/MJBrandKitEntityServer.server.d.ts.map +1 -0
- package/dist/custom/MJBrandKitEntityServer.server.js +75 -0
- package/dist/custom/MJBrandKitEntityServer.server.js.map +1 -0
- package/dist/custom/MJCompanyIntegrationEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJCompanyIntegrationEntityServer.server.js +1 -0
- package/dist/custom/MJCompanyIntegrationEntityServer.server.js.map +1 -1
- package/dist/custom/MJComponentEntityServer.server.d.ts +2 -0
- package/dist/custom/MJComponentEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJComponentEntityServer.server.js +5 -1
- package/dist/custom/MJComponentEntityServer.server.js.map +1 -1
- package/dist/custom/MJConversationDetailEntityServer.server.d.ts +20 -30
- package/dist/custom/MJConversationDetailEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJConversationDetailEntityServer.server.js +89 -35
- package/dist/custom/MJConversationDetailEntityServer.server.js.map +1 -1
- package/dist/custom/MJConversationEntityServer.server.d.ts +19 -4
- package/dist/custom/MJConversationEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJConversationEntityServer.server.js +169 -11
- package/dist/custom/MJConversationEntityServer.server.js.map +1 -1
- package/dist/custom/MJEntityDocumentEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJEntityDocumentEntityServer.server.js +1 -0
- package/dist/custom/MJEntityDocumentEntityServer.server.js.map +1 -1
- package/dist/custom/MJListDetailEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJListDetailEntityServer.server.js +1 -0
- package/dist/custom/MJListDetailEntityServer.server.js.map +1 -1
- package/dist/custom/MJProjectEntityServer.server.d.ts +21 -0
- package/dist/custom/MJProjectEntityServer.server.d.ts.map +1 -0
- package/dist/custom/MJProjectEntityServer.server.js +106 -0
- package/dist/custom/MJProjectEntityServer.server.js.map +1 -0
- package/dist/custom/MJQueryEntityServer.server.d.ts +177 -47
- package/dist/custom/MJQueryEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJQueryEntityServer.server.js +479 -164
- package/dist/custom/MJQueryEntityServer.server.js.map +1 -1
- package/dist/custom/MJQuerySQLEntityServer.server.d.ts +15 -18
- package/dist/custom/MJQuerySQLEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJQuerySQLEntityServer.server.js +34 -42
- package/dist/custom/MJQuerySQLEntityServer.server.js.map +1 -1
- package/dist/custom/MJTagEntityServer.server.d.ts +2 -0
- package/dist/custom/MJTagEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJTagEntityServer.server.js +13 -7
- package/dist/custom/MJTagEntityServer.server.js.map +1 -1
- package/dist/custom/MJUserRoutineEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJUserRoutineEntityServer.server.js +8 -1
- package/dist/custom/MJUserRoutineEntityServer.server.js.map +1 -1
- package/dist/custom/RestrictedFieldCommentClassifier.d.ts +73 -0
- package/dist/custom/RestrictedFieldCommentClassifier.d.ts.map +1 -0
- package/dist/custom/RestrictedFieldCommentClassifier.js +240 -0
- package/dist/custom/RestrictedFieldCommentClassifier.js.map +1 -0
- package/dist/custom/query-extraction/childRowWriter.d.ts +77 -0
- package/dist/custom/query-extraction/childRowWriter.d.ts.map +1 -0
- package/dist/custom/query-extraction/childRowWriter.js +277 -0
- package/dist/custom/query-extraction/childRowWriter.js.map +1 -0
- package/dist/custom/query-extraction/compositionTargets.d.ts +40 -0
- package/dist/custom/query-extraction/compositionTargets.d.ts.map +1 -0
- package/dist/custom/query-extraction/compositionTargets.js +99 -0
- package/dist/custom/query-extraction/compositionTargets.js.map +1 -0
- package/dist/custom/query-extraction/declared.d.ts +79 -0
- package/dist/custom/query-extraction/declared.d.ts.map +1 -0
- package/dist/custom/query-extraction/declared.js +91 -0
- package/dist/custom/query-extraction/declared.js.map +1 -0
- package/dist/custom/query-extraction/describeFacts.d.ts +40 -0
- package/dist/custom/query-extraction/describeFacts.d.ts.map +1 -0
- package/dist/custom/query-extraction/describeFacts.js +225 -0
- package/dist/custom/query-extraction/describeFacts.js.map +1 -0
- package/dist/custom/query-extraction/descriptionPass.d.ts +23 -0
- package/dist/custom/query-extraction/descriptionPass.d.ts.map +1 -0
- package/dist/custom/query-extraction/descriptionPass.js +95 -0
- package/dist/custom/query-extraction/descriptionPass.js.map +1 -0
- package/dist/custom/query-extraction/extractQuery.d.ts +25 -0
- package/dist/custom/query-extraction/extractQuery.d.ts.map +1 -0
- package/dist/custom/query-extraction/extractQuery.js +146 -0
- package/dist/custom/query-extraction/extractQuery.js.map +1 -0
- package/dist/custom/query-extraction/extractionTypes.d.ts +133 -0
- package/dist/custom/query-extraction/extractionTypes.d.ts.map +1 -0
- package/dist/custom/query-extraction/extractionTypes.js +2 -0
- package/dist/custom/query-extraction/extractionTypes.js.map +1 -0
- package/dist/custom/query-extraction/index.d.ts +16 -0
- package/dist/custom/query-extraction/index.d.ts.map +1 -1
- package/dist/custom/query-extraction/index.js +11 -1
- package/dist/custom/query-extraction/index.js.map +1 -1
- package/dist/custom/query-extraction/pipeline.d.ts +6 -2
- package/dist/custom/query-extraction/pipeline.d.ts.map +1 -1
- package/dist/custom/query-extraction/pipeline.js +21 -14
- package/dist/custom/query-extraction/pipeline.js.map +1 -1
- package/dist/custom/query-extraction/resolve.d.ts +7 -2
- package/dist/custom/query-extraction/resolve.d.ts.map +1 -1
- package/dist/custom/query-extraction/resolve.js +17 -14
- package/dist/custom/query-extraction/resolve.js.map +1 -1
- package/dist/custom/query-extraction/sourceBinding.d.ts +57 -0
- package/dist/custom/query-extraction/sourceBinding.d.ts.map +1 -0
- package/dist/custom/query-extraction/sourceBinding.js +104 -0
- package/dist/custom/query-extraction/sourceBinding.js.map +1 -0
- package/dist/custom/query-extraction/sync.d.ts +27 -3
- package/dist/custom/query-extraction/sync.d.ts.map +1 -1
- package/dist/custom/query-extraction/sync.js +69 -44
- package/dist/custom/query-extraction/sync.js.map +1 -1
- package/dist/custom/query-extraction/templateFacts.d.ts +62 -0
- package/dist/custom/query-extraction/templateFacts.d.ts.map +1 -0
- package/dist/custom/query-extraction/templateFacts.js +229 -0
- package/dist/custom/query-extraction/templateFacts.js.map +1 -0
- package/dist/custom/query-extraction/types.d.ts +4 -0
- package/dist/custom/query-extraction/types.d.ts.map +1 -1
- package/dist/custom/query-refresh/QueryExtractionService.d.ts +54 -0
- package/dist/custom/query-refresh/QueryExtractionService.d.ts.map +1 -0
- package/dist/custom/query-refresh/QueryExtractionService.js +207 -0
- package/dist/custom/query-refresh/QueryExtractionService.js.map +1 -0
- package/dist/custom/query-refresh/QueryRefreshExtractionServerOperation.d.ts +28 -0
- package/dist/custom/query-refresh/QueryRefreshExtractionServerOperation.d.ts.map +1 -0
- package/dist/custom/query-refresh/QueryRefreshExtractionServerOperation.js +106 -0
- package/dist/custom/query-refresh/QueryRefreshExtractionServerOperation.js.map +1 -0
- package/dist/custom/query-refresh/index.d.ts +14 -0
- package/dist/custom/query-refresh/index.d.ts.map +1 -0
- package/dist/custom/query-refresh/index.js +10 -0
- package/dist/custom/query-refresh/index.js.map +1 -0
- package/dist/custom/query-refresh/queryRebind.d.ts +33 -0
- package/dist/custom/query-refresh/queryRebind.d.ts.map +1 -0
- package/dist/custom/query-refresh/queryRebind.js +85 -0
- package/dist/custom/query-refresh/queryRebind.js.map +1 -0
- package/dist/custom/query-refresh/refreshAuthorization.d.ts +29 -0
- package/dist/custom/query-refresh/refreshAuthorization.d.ts.map +1 -0
- package/dist/custom/query-refresh/refreshAuthorization.js +66 -0
- package/dist/custom/query-refresh/refreshAuthorization.js.map +1 -0
- package/dist/custom/query-refresh/refreshFormat.d.ts +16 -0
- package/dist/custom/query-refresh/refreshFormat.d.ts.map +1 -0
- package/dist/custom/query-refresh/refreshFormat.js +67 -0
- package/dist/custom/query-refresh/refreshFormat.js.map +1 -0
- package/dist/custom/query-refresh/refreshOrder.d.ts +25 -0
- package/dist/custom/query-refresh/refreshOrder.d.ts.map +1 -0
- package/dist/custom/query-refresh/refreshOrder.js +95 -0
- package/dist/custom/query-refresh/refreshOrder.js.map +1 -0
- package/dist/custom/query-refresh/refreshSelection.d.ts +15 -0
- package/dist/custom/query-refresh/refreshSelection.d.ts.map +1 -0
- package/dist/custom/query-refresh/refreshSelection.js +99 -0
- package/dist/custom/query-refresh/refreshSelection.js.map +1 -0
- package/dist/custom/query-refresh/refreshTypes.d.ts +81 -0
- package/dist/custom/query-refresh/refreshTypes.d.ts.map +1 -0
- package/dist/custom/query-refresh/refreshTypes.js +5 -0
- package/dist/custom/query-refresh/refreshTypes.js.map +1 -0
- package/dist/custom/util.d.ts +8 -0
- package/dist/custom/util.d.ts.map +1 -1
- package/dist/custom/util.js +18 -1
- package/dist/custom/util.js.map +1 -1
- package/dist/engines/QueryEngineServer.d.ts +8 -5
- package/dist/engines/QueryEngineServer.d.ts.map +1 -1
- package/dist/engines/QueryEngineServer.js +16 -23
- package/dist/engines/QueryEngineServer.js.map +1 -1
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/package.json +30 -30
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import { LogError, LogStatus, RunView, WellKnownUserSource } from '@memberjunction/core';
|
|
2
|
+
import { AIPromptParams } from '@memberjunction/ai-core-plus';
|
|
3
|
+
import { AIPromptRunner } from '@memberjunction/ai-prompts';
|
|
4
|
+
import { AIEngine } from '@memberjunction/aiengine';
|
|
5
|
+
import { BuildLinkedRecordPrimaryKeyFilter, DetectReferencedRestrictedFieldsDeterministic, MergeRestrictedFieldsIntoAnchorMetadata, ParseConversationAnchorMetadata } from '@memberjunction/core-entities';
|
|
6
|
+
let customRestrictedFieldClassifier = null;
|
|
7
|
+
/**
|
|
8
|
+
* Registers (or clears with `null`) a custom semantic classifier callback for detecting
|
|
9
|
+
* references to FLS-restricted fields in record comments. Used by tests and custom
|
|
10
|
+
* enterprise classification policies; when `null`, the default `AIEngine` classifier runs.
|
|
11
|
+
*/
|
|
12
|
+
export function RegisterRestrictedFieldLLMClassifier(callback) {
|
|
13
|
+
customRestrictedFieldClassifier = callback;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Returns the currently registered custom classifier callback, if any.
|
|
17
|
+
*/
|
|
18
|
+
export function GetRegisteredRestrictedFieldLLMClassifier() {
|
|
19
|
+
return customRestrictedFieldClassifier;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Inspects a comment (`messageText`) posted on an anchored conversation to detect whether it
|
|
23
|
+
* references any FLS-governed fields on `entityInfo`, and stamps any newly detected field names
|
|
24
|
+
* into `conversation.AnchorMetadataObject.restrictedFields`.
|
|
25
|
+
*
|
|
26
|
+
* Two-stage detection:
|
|
27
|
+
* 1. **Stage 1 (Deterministic, 0ms)**: Checks direct field anchors (`AnchorType === 'Field'`),
|
|
28
|
+
* restricted field names/labels (`Name`, camelCase words, `DisplayName`), and actual restricted
|
|
29
|
+
* field values loaded from the linked record.
|
|
30
|
+
* 2. **Stage 2 (Semantic LLM Classifier)**: If `entityInfo` has remaining unmatched FLS fields and
|
|
31
|
+
* `messageText` is non-empty, invokes either the registered `RestrictedFieldLLMClassifierCallback`
|
|
32
|
+
* or a lightweight `AIEngine` language model to detect semantic/paraphrased references
|
|
33
|
+
* (for example `"making six figures"` → `Salary`).
|
|
34
|
+
*/
|
|
35
|
+
export async function InspectAndStampRestrictedFieldsForComment(params) {
|
|
36
|
+
const { Provider, ContextUser, Conversation, EntityInfo: entityInfo, MessageText } = params;
|
|
37
|
+
// fls-guard: inspect and stamp restrictedFields on anchored conversation comments
|
|
38
|
+
if (!entityInfo.FieldLevelSecurityApplies) {
|
|
39
|
+
return {
|
|
40
|
+
Allowed: true,
|
|
41
|
+
Reason: null,
|
|
42
|
+
DetectedFields: [],
|
|
43
|
+
AuthorDeniedFields: []
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
const restrictedFields = entityInfo.Fields.filter((f) => f.HasFieldPermissions);
|
|
47
|
+
if (restrictedFields.length === 0) {
|
|
48
|
+
return {
|
|
49
|
+
Allowed: true,
|
|
50
|
+
Reason: null,
|
|
51
|
+
DetectedFields: [],
|
|
52
|
+
AuthorDeniedFields: []
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
// Security invariant: never value-match against fields the authoring user is denied Read access to.
|
|
56
|
+
// An author who cannot read a field cannot be disclosing its value from the record, and matching their
|
|
57
|
+
// comment text against hidden system-loaded values would create a yes/no guessing oracle.
|
|
58
|
+
// Only fields the author CAN read are eligible for record-value matching (to stamp restrictedFields
|
|
59
|
+
// so downstream readers who lack access to that field do not see the thread).
|
|
60
|
+
const deniedLower = entityInfo.GetDeniedReadFields(ContextUser);
|
|
61
|
+
const authorReadableRestrictedFields = restrictedFields.filter((f) => !deniedLower.has(f.Name.trim().toLowerCase()));
|
|
62
|
+
let readableRecordValues = null;
|
|
63
|
+
if (authorReadableRestrictedFields.length > 0 && (MessageText ?? '').trim().length > 0) {
|
|
64
|
+
const rawRecordValues = params.RecordValues ??
|
|
65
|
+
(Conversation.LinkedRecordID
|
|
66
|
+
? await loadLinkedRecordRestrictedFieldValues(Provider, ContextUser, entityInfo, Conversation.LinkedRecordID, authorReadableRestrictedFields)
|
|
67
|
+
: null);
|
|
68
|
+
if (rawRecordValues) {
|
|
69
|
+
readableRecordValues = {};
|
|
70
|
+
for (const f of authorReadableRestrictedFields) {
|
|
71
|
+
if (Object.prototype.hasOwnProperty.call(rawRecordValues, f.Name)) {
|
|
72
|
+
readableRecordValues[f.Name] = rawRecordValues[f.Name];
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// Stage 1: Deterministic detection (field anchor + field names/labels + author-readable record values)
|
|
78
|
+
const deterministicMatches = DetectReferencedRestrictedFieldsDeterministic(entityInfo, MessageText, Conversation.AnchorType, Conversation.AnchorKey, readableRecordValues);
|
|
79
|
+
const detectedSet = new Set(deterministicMatches);
|
|
80
|
+
// Stage 2: Semantic LLM classification for any remaining FLS-governed fields
|
|
81
|
+
const text = (MessageText ?? '').trim();
|
|
82
|
+
const unmatchedFields = restrictedFields.filter((f) => !detectedSet.has(f.Name));
|
|
83
|
+
if (!params.SkipLLMStage && text.length > 0 && unmatchedFields.length > 0) {
|
|
84
|
+
const llmMatches = await runSemanticRestrictedFieldClassifier(entityInfo, unmatchedFields, text, Conversation.AnchorType, Conversation.AnchorKey, ContextUser);
|
|
85
|
+
for (const fieldName of llmMatches) {
|
|
86
|
+
detectedSet.add(fieldName);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const detectedFields = [...detectedSet];
|
|
90
|
+
// Also include any previously stamped restrictedFields on the conversation when checking author access
|
|
91
|
+
const existingMeta = ParseConversationAnchorMetadata(Conversation.AnchorMetadataObject ?? Conversation.AnchorMetadata);
|
|
92
|
+
const allThreadRestrictedFields = new Set(detectedFields);
|
|
93
|
+
if (Array.isArray(existingMeta?.restrictedFields)) {
|
|
94
|
+
for (const f of existingMeta.restrictedFields) {
|
|
95
|
+
if (typeof f === 'string' && f.trim()) {
|
|
96
|
+
allThreadRestrictedFields.add(f.trim());
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
// Check whether the authoring user is denied Read access on any referenced restricted field.
|
|
101
|
+
// Return a generic message without naming which field matched.
|
|
102
|
+
const authorDeniedFields = [...allThreadRestrictedFields].filter((f) => deniedLower.has(f.trim().toLowerCase()));
|
|
103
|
+
if (authorDeniedFields.length > 0) {
|
|
104
|
+
return {
|
|
105
|
+
Allowed: false,
|
|
106
|
+
Reason: 'You do not have permission to comment on restricted fields.',
|
|
107
|
+
DetectedFields: detectedFields,
|
|
108
|
+
AuthorDeniedFields: authorDeniedFields
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
// Stamp newly detected restricted fields onto the parent conversation's AnchorMetadataObject
|
|
112
|
+
if (detectedFields.length > 0) {
|
|
113
|
+
const { Metadata, Changed } = MergeRestrictedFieldsIntoAnchorMetadata(existingMeta, detectedFields);
|
|
114
|
+
if (Changed) {
|
|
115
|
+
Conversation.AnchorMetadataObject = Metadata;
|
|
116
|
+
if (Conversation.IsSaved) {
|
|
117
|
+
const saved = await Conversation.Save();
|
|
118
|
+
if (!saved) {
|
|
119
|
+
LogError(`InspectAndStampRestrictedFieldsForComment: failed to update AnchorMetadata on conversation ${Conversation.ID}: ${Conversation.LatestResult?.CompleteMessage ?? 'unknown error'}`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
Allowed: true,
|
|
126
|
+
Reason: null,
|
|
127
|
+
DetectedFields: detectedFields,
|
|
128
|
+
AuthorDeniedFields: []
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
async function loadLinkedRecordRestrictedFieldValues(provider, contextUser, entityInfo, linkedRecordId, restrictedFields) {
|
|
132
|
+
if (provider?.ProviderType !== 'Database' || restrictedFields.length === 0) {
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
const pkFilter = BuildLinkedRecordPrimaryKeyFilter(entityInfo, linkedRecordId, provider);
|
|
136
|
+
if (!pkFilter) {
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
try {
|
|
140
|
+
const systemUser = (await WellKnownUserSource.Instance.GetSystemUser(provider)) ?? contextUser;
|
|
141
|
+
const rv = RunView.FromMetadataProvider(provider);
|
|
142
|
+
const fieldNames = [
|
|
143
|
+
...entityInfo.PrimaryKeys.map((pk) => pk.Name),
|
|
144
|
+
...restrictedFields.map((f) => f.Name)
|
|
145
|
+
];
|
|
146
|
+
const result = await rv.RunView({
|
|
147
|
+
EntityName: entityInfo.Name,
|
|
148
|
+
ExtraFilter: pkFilter,
|
|
149
|
+
Fields: fieldNames,
|
|
150
|
+
MaxRows: 1,
|
|
151
|
+
ResultType: 'simple'
|
|
152
|
+
}, systemUser);
|
|
153
|
+
if (result.Success && result.Results && result.Results.length > 0) {
|
|
154
|
+
return result.Results[0];
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
LogError(`loadLinkedRecordRestrictedFieldValues failed on ${entityInfo.Name} (${linkedRecordId}): ${error instanceof Error ? error.message : String(error)}`);
|
|
159
|
+
}
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
async function runSemanticRestrictedFieldClassifier(entityInfo, candidateFields, messageText, anchorType, anchorKey, contextUser) {
|
|
163
|
+
const prompt = {
|
|
164
|
+
EntityName: entityInfo.Name,
|
|
165
|
+
EntityDisplayName: entityInfo.DisplayNameOrName,
|
|
166
|
+
MessageText: messageText,
|
|
167
|
+
AnchorType: anchorType,
|
|
168
|
+
AnchorKey: anchorKey,
|
|
169
|
+
CandidateFields: candidateFields.map((f) => ({
|
|
170
|
+
Name: f.Name,
|
|
171
|
+
DisplayName: f.DisplayNameOrName,
|
|
172
|
+
Description: f.Description ?? null
|
|
173
|
+
}))
|
|
174
|
+
};
|
|
175
|
+
const validByLower = new Map();
|
|
176
|
+
for (const f of candidateFields) {
|
|
177
|
+
validByLower.set(f.Name.toLowerCase(), f.Name);
|
|
178
|
+
}
|
|
179
|
+
if (customRestrictedFieldClassifier) {
|
|
180
|
+
try {
|
|
181
|
+
const rawMatches = await customRestrictedFieldClassifier(prompt, contextUser);
|
|
182
|
+
return normalizeMatchedFieldNames(rawMatches, validByLower);
|
|
183
|
+
}
|
|
184
|
+
catch (error) {
|
|
185
|
+
LogError(`Custom RestrictedFieldLLMClassifier threw: ${error instanceof Error ? error.message : String(error)}`);
|
|
186
|
+
return [];
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return runDefaultAIEngineRestrictedFieldClassifier(prompt, contextUser, validByLower);
|
|
190
|
+
}
|
|
191
|
+
function normalizeMatchedFieldNames(rawNames, validByLower) {
|
|
192
|
+
if (!Array.isArray(rawNames)) {
|
|
193
|
+
return [];
|
|
194
|
+
}
|
|
195
|
+
const canonical = new Set();
|
|
196
|
+
for (const name of rawNames) {
|
|
197
|
+
if (typeof name === 'string') {
|
|
198
|
+
const found = validByLower.get(name.trim().toLowerCase());
|
|
199
|
+
if (found) {
|
|
200
|
+
canonical.add(found);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return [...canonical];
|
|
205
|
+
}
|
|
206
|
+
const RESTRICTED_FIELD_CLASSIFIER_PROMPT_NAME = 'Anchored Comment Restricted Field Classifier';
|
|
207
|
+
async function runDefaultAIEngineRestrictedFieldClassifier(prompt, contextUser, validByLower) {
|
|
208
|
+
try {
|
|
209
|
+
await AIEngine.Instance.Config(false, contextUser);
|
|
210
|
+
}
|
|
211
|
+
catch (error) {
|
|
212
|
+
LogStatus(`[RestrictedFieldCommentClassifier] AIEngine.Config unavailable; skipping Stage 2 semantic classification: ${error instanceof Error ? error.message : String(error)}`);
|
|
213
|
+
return [];
|
|
214
|
+
}
|
|
215
|
+
const aiPrompt = AIEngine.Instance.Prompts?.find((p) => p.Name === RESTRICTED_FIELD_CLASSIFIER_PROMPT_NAME && p.Status === 'Active');
|
|
216
|
+
if (!aiPrompt) {
|
|
217
|
+
return [];
|
|
218
|
+
}
|
|
219
|
+
try {
|
|
220
|
+
const runner = new AIPromptRunner();
|
|
221
|
+
const params = new AIPromptParams();
|
|
222
|
+
params.prompt = aiPrompt;
|
|
223
|
+
params.data = prompt;
|
|
224
|
+
params.contextUser = contextUser;
|
|
225
|
+
const execution = await runner.ExecutePrompt(params);
|
|
226
|
+
if (!execution.success || !execution.result) {
|
|
227
|
+
LogStatus(`[RestrictedFieldCommentClassifier] Governed prompt "${RESTRICTED_FIELD_CLASSIFIER_PROMPT_NAME}" returned unsuccessful result: ${execution.errorMessage ?? 'unknown'}`);
|
|
228
|
+
return [];
|
|
229
|
+
}
|
|
230
|
+
const list = execution.result.restrictedFields;
|
|
231
|
+
if (Array.isArray(list)) {
|
|
232
|
+
return normalizeMatchedFieldNames(list.filter((item) => typeof item === 'string'), validByLower);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
catch (error) {
|
|
236
|
+
LogStatus(`[RestrictedFieldCommentClassifier] Governed prompt "${RESTRICTED_FIELD_CLASSIFIER_PROMPT_NAME}" threw: ${error instanceof Error ? error.message : String(error)}`);
|
|
237
|
+
}
|
|
238
|
+
return [];
|
|
239
|
+
}
|
|
240
|
+
//# sourceMappingURL=RestrictedFieldCommentClassifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RestrictedFieldCommentClassifier.js","sourceRoot":"","sources":["../../src/custom/RestrictedFieldCommentClassifier.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { IEntityDataProvider, IMetadataProvider, IRunViewProvider, UserInfo } from "@memberjunction/core";
|
|
2
|
+
import type { MJQueryFieldEntity } from "@memberjunction/core-entities";
|
|
3
|
+
import type { QueryExtractionResult, QueryFieldFact } from "./extractionTypes.js";
|
|
4
|
+
/** Where the child rows are written, and as whom. */
|
|
5
|
+
export interface ChildRowWriteContext {
|
|
6
|
+
readonly QueryID: string;
|
|
7
|
+
/**
|
|
8
|
+
* The caller's provider. The writes run in an entity transaction on it, joining the caller's
|
|
9
|
+
* transaction when one is open; a provider without entity transactions writes without one.
|
|
10
|
+
*/
|
|
11
|
+
readonly Provider: IMetadataProvider & IRunViewProvider & Partial<Pick<IEntityDataProvider, 'SupportsEntityTransactions' | 'BeginEntityTransaction'>>;
|
|
12
|
+
/** The user the rows are read and written as: the system user for save-triggered extraction. */
|
|
13
|
+
readonly User: UserInfo;
|
|
14
|
+
/** Work out and report the changes without writing anything. */
|
|
15
|
+
readonly DryRun?: boolean;
|
|
16
|
+
/** The name a Query Entities change is reported under, for an entity ID; the ID when omitted. */
|
|
17
|
+
readonly EntityName?: (entityID: string) => string;
|
|
18
|
+
}
|
|
19
|
+
/** The child collection of a query a row belongs to. */
|
|
20
|
+
export type QueryChildCollection = 'Fields' | 'Parameters' | 'Entities' | 'Dependencies';
|
|
21
|
+
/** One child row the writes add, update or remove. */
|
|
22
|
+
export interface ChildRowChange {
|
|
23
|
+
readonly Collection: QueryChildCollection;
|
|
24
|
+
readonly Action: 'Added' | 'Updated' | 'Removed';
|
|
25
|
+
/** The field or parameter name, the entity name, or the dependency's reference path. */
|
|
26
|
+
readonly Name: string;
|
|
27
|
+
/** For an update, the columns that change. */
|
|
28
|
+
readonly ChangedColumns: readonly string[];
|
|
29
|
+
/** For a field row, the entity field its output column comes from, when it maps to one. */
|
|
30
|
+
readonly SourceEntityFieldID: string | null;
|
|
31
|
+
}
|
|
32
|
+
/** What the writes changed, and which rows still have no description. */
|
|
33
|
+
export interface ChildRowWriteSummary {
|
|
34
|
+
Added: number;
|
|
35
|
+
Updated: number;
|
|
36
|
+
Removed: number;
|
|
37
|
+
/** Every row added, updated or removed, in write order. */
|
|
38
|
+
readonly Changes: ChildRowChange[];
|
|
39
|
+
/** Authored parameters the SQL no longer uses: kept, and flagged on the query. */
|
|
40
|
+
readonly FlaggedParameters: string[];
|
|
41
|
+
/** Field rows with an empty description, for the description pass. */
|
|
42
|
+
readonly FieldsWithoutDescription: string[];
|
|
43
|
+
/** Parameter rows with an empty description, for the description pass. */
|
|
44
|
+
readonly ParametersWithoutDescription: string[];
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Brings a query's child rows in line with its extracted facts, keeping what people authored.
|
|
48
|
+
*
|
|
49
|
+
* **Facts** are corrected on every row, including declared and `Manual` ones: a field's name
|
|
50
|
+
* casing, sequence, types, nullability, source and computed flag; whether a parameter exists
|
|
51
|
+
* (and its name casing); which entities and dependencies the query has.
|
|
52
|
+
*
|
|
53
|
+
* **Annotations** are never overwritten when authored (`DetectionMethod` `Manual`, or a
|
|
54
|
+
* non-empty value): descriptions, `ComputationDescription`, `IsSummary` / `SummaryDescription`,
|
|
55
|
+
* and a `Manual` parameter's type, required flag, default, sample, validation filters and
|
|
56
|
+
* server-set flag. A doc-comment description is authored too: it fills an empty description and
|
|
57
|
+
* replaces one extraction or an LLM wrote.
|
|
58
|
+
*
|
|
59
|
+
* An authored parameter the SQL no longer uses is kept (extraction flags it on the query); an
|
|
60
|
+
* auto-detected one is deleted. Rows keep their IDs. A `null` fact collection leaves its rows as
|
|
61
|
+
* they are. Existing rows are read from the database on the caller's provider, never a cache, so
|
|
62
|
+
* rows written earlier in the same transaction are seen.
|
|
63
|
+
*
|
|
64
|
+
* The writes are one unit of work: they run in an entity transaction on the caller's provider,
|
|
65
|
+
* which joins the caller's transaction when one is open (a nested scope), so a failed write rolls
|
|
66
|
+
* every write of this call back and throws. A provider without entity transactions (a client)
|
|
67
|
+
* writes without one.
|
|
68
|
+
*
|
|
69
|
+
* With `DryRun` the same changes are worked out and reported, and nothing is written.
|
|
70
|
+
*/
|
|
71
|
+
export declare function WriteExtractedChildRows(context: ChildRowWriteContext, result: QueryExtractionResult): Promise<ChildRowWriteSummary>;
|
|
72
|
+
/**
|
|
73
|
+
* Sets a field row's facts (name casing, sequence, types, nullability, computed flag, source) from
|
|
74
|
+
* the extracted fact, leaving its annotations alone.
|
|
75
|
+
*/
|
|
76
|
+
export declare function ApplyFieldFacts(row: MJQueryFieldEntity, fact: QueryFieldFact): void;
|
|
77
|
+
//# sourceMappingURL=childRowWriter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"childRowWriter.d.ts","sourceRoot":"","sources":["../../../src/custom/query-extraction/childRowWriter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAc,mBAAmB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAC3H,OAAO,KAAK,EAGR,kBAAkB,EAErB,MAAM,+BAA+B,CAAC;AAEvC,OAAO,KAAK,EAGR,qBAAqB,EACrB,cAAc,EAEjB,MAAM,mBAAmB,CAAC;AAE3B,qDAAqD;AACrD,MAAM,WAAW,oBAAoB;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,GAAG,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,mBAAmB,EAAE,4BAA4B,GAAG,wBAAwB,CAAC,CAAC,CAAC;IACtJ,gGAAgG;IAChG,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,gEAAgE;IAChE,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,iGAAiG;IACjG,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;CACtD;AAED,wDAAwD;AACxD,MAAM,MAAM,oBAAoB,GAAG,QAAQ,GAAG,YAAY,GAAG,UAAU,GAAG,cAAc,CAAC;AAEzF,sDAAsD;AACtD,MAAM,WAAW,cAAc;IAC3B,QAAQ,CAAC,UAAU,EAAE,oBAAoB,CAAC;IAC1C,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,CAAC;IACjD,wFAAwF;IACxF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,8CAA8C;IAC9C,QAAQ,CAAC,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C,2FAA2F;IAC3F,QAAQ,CAAC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/C;AAED,yEAAyE;AACzE,MAAM,WAAW,oBAAoB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,QAAQ,CAAC,OAAO,EAAE,cAAc,EAAE,CAAC;IACnC,kFAAkF;IAClF,QAAQ,CAAC,iBAAiB,EAAE,MAAM,EAAE,CAAC;IACrC,sEAAsE;IACtE,QAAQ,CAAC,wBAAwB,EAAE,MAAM,EAAE,CAAC;IAC5C,0EAA0E;IAC1E,QAAQ,CAAC,4BAA4B,EAAE,MAAM,EAAE,CAAC;CACnD;AAYD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,oBAAoB,EAAE,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAWzI;AAsGD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,kBAAkB,EAAE,IAAI,EAAE,cAAc,GAAG,IAAI,CAWnF"}
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import { RunInEntityTransaction, RunMaybeSerial } from "@memberjunction/core";
|
|
2
|
+
import { EscapeSQLString, NormalizeUUID, UUIDsEqual } from "@memberjunction/global";
|
|
3
|
+
/**
|
|
4
|
+
* Brings a query's child rows in line with its extracted facts, keeping what people authored.
|
|
5
|
+
*
|
|
6
|
+
* **Facts** are corrected on every row, including declared and `Manual` ones: a field's name
|
|
7
|
+
* casing, sequence, types, nullability, source and computed flag; whether a parameter exists
|
|
8
|
+
* (and its name casing); which entities and dependencies the query has.
|
|
9
|
+
*
|
|
10
|
+
* **Annotations** are never overwritten when authored (`DetectionMethod` `Manual`, or a
|
|
11
|
+
* non-empty value): descriptions, `ComputationDescription`, `IsSummary` / `SummaryDescription`,
|
|
12
|
+
* and a `Manual` parameter's type, required flag, default, sample, validation filters and
|
|
13
|
+
* server-set flag. A doc-comment description is authored too: it fills an empty description and
|
|
14
|
+
* replaces one extraction or an LLM wrote.
|
|
15
|
+
*
|
|
16
|
+
* An authored parameter the SQL no longer uses is kept (extraction flags it on the query); an
|
|
17
|
+
* auto-detected one is deleted. Rows keep their IDs. A `null` fact collection leaves its rows as
|
|
18
|
+
* they are. Existing rows are read from the database on the caller's provider, never a cache, so
|
|
19
|
+
* rows written earlier in the same transaction are seen.
|
|
20
|
+
*
|
|
21
|
+
* The writes are one unit of work: they run in an entity transaction on the caller's provider,
|
|
22
|
+
* which joins the caller's transaction when one is open (a nested scope), so a failed write rolls
|
|
23
|
+
* every write of this call back and throws. A provider without entity transactions (a client)
|
|
24
|
+
* writes without one.
|
|
25
|
+
*
|
|
26
|
+
* With `DryRun` the same changes are worked out and reported, and nothing is written.
|
|
27
|
+
*/
|
|
28
|
+
export async function WriteExtractedChildRows(context, result) {
|
|
29
|
+
const stored = await loadStoredChildRows(context);
|
|
30
|
+
const summary = { Added: 0, Updated: 0, Removed: 0, Changes: [], FlaggedParameters: [], FieldsWithoutDescription: [], ParametersWithoutDescription: [] };
|
|
31
|
+
const writes = [];
|
|
32
|
+
if (result.Fields)
|
|
33
|
+
writes.push(...await fieldWrites(context, stored.Fields, result.Fields, summary));
|
|
34
|
+
writes.push(...await parameterWrites(context, stored.Parameters, result.Parameters, summary));
|
|
35
|
+
if (result.Entities)
|
|
36
|
+
writes.push(...await entityWrites(context, stored.Entities, result.Entities, summary));
|
|
37
|
+
if (result.Dependencies)
|
|
38
|
+
writes.push(...await dependencyWrites(context, stored.Dependencies, result.Dependencies, summary));
|
|
39
|
+
if (context.DryRun || writes.length === 0)
|
|
40
|
+
return summary;
|
|
41
|
+
await RunInEntityTransaction(context.Provider, () => runWrites(context, writes));
|
|
42
|
+
return summary;
|
|
43
|
+
}
|
|
44
|
+
/** Runs the writes; throws when any of them failed, so the enclosing transaction rolls them all back. */
|
|
45
|
+
async function runWrites(context, writes) {
|
|
46
|
+
const outcomes = await RunMaybeSerial(context.Provider, [...writes]);
|
|
47
|
+
const failed = outcomes.filter(ok => !ok).length;
|
|
48
|
+
if (failed > 0)
|
|
49
|
+
throw new Error(`Query ${context.QueryID}: ${failed} of ${writes.length} child-row writes failed; none of them were kept.`);
|
|
50
|
+
}
|
|
51
|
+
async function loadStoredChildRows(context) {
|
|
52
|
+
const filter = `QueryID='${EscapeSQLString(context.QueryID)}'`;
|
|
53
|
+
const load = async (entityName) => {
|
|
54
|
+
const result = await context.Provider.RunView({ EntityName: entityName, ExtraFilter: filter, ResultType: 'entity_object', BypassCache: true, IgnoreMaxRows: true }, context.User);
|
|
55
|
+
if (!result.Success)
|
|
56
|
+
throw new Error(`Could not read the stored ${entityName} of query ${context.QueryID}: ${result.ErrorMessage}`);
|
|
57
|
+
return result.Results ?? [];
|
|
58
|
+
};
|
|
59
|
+
const [fields, parameters, entities, dependencies] = await Promise.all([
|
|
60
|
+
load('MJ: Query Fields'),
|
|
61
|
+
load('MJ: Query Parameters'),
|
|
62
|
+
load('MJ: Query Entities'),
|
|
63
|
+
load('MJ: Query Dependencies'),
|
|
64
|
+
]);
|
|
65
|
+
return { Fields: fields, Parameters: parameters, Entities: entities, Dependencies: dependencies };
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* A write for `row` when it has unsaved changes; counts and records it as added or updated.
|
|
69
|
+
*
|
|
70
|
+
* `alsoChanged` names columns that changed although the entity's dirty check does not see it: a
|
|
71
|
+
* nullable bit column going between `null` and `false` reads as unchanged there. Such a row is
|
|
72
|
+
* still written (ignoring the dirty state) and the column is reported.
|
|
73
|
+
*/
|
|
74
|
+
function saveIfDirty(row, summary, label, alsoChanged = []) {
|
|
75
|
+
if (row.IsSaved && !row.Dirty && alsoChanged.length === 0)
|
|
76
|
+
return [];
|
|
77
|
+
const action = row.IsSaved ? 'Updated' : 'Added';
|
|
78
|
+
if (row.IsSaved)
|
|
79
|
+
summary.Updated++;
|
|
80
|
+
else
|
|
81
|
+
summary.Added++;
|
|
82
|
+
const dirtyColumns = row.IsSaved ? row.Fields.filter(f => f.Dirty).map(f => f.Name) : [];
|
|
83
|
+
const changedColumns = row.IsSaved ? [...dirtyColumns, ...alsoChanged.filter(c => !dirtyColumns.includes(c))] : [];
|
|
84
|
+
summary.Changes.push({ ...changeOf(label, action), ChangedColumns: changedColumns });
|
|
85
|
+
const ignoreDirtyState = row.IsSaved && !row.Dirty;
|
|
86
|
+
return [() => row.Save(ignoreDirtyState ? { IgnoreDirtyState: true } : undefined)];
|
|
87
|
+
}
|
|
88
|
+
function deleteRows(rows, summary, labelOf) {
|
|
89
|
+
summary.Removed += rows.length;
|
|
90
|
+
for (const row of rows)
|
|
91
|
+
summary.Changes.push(changeOf(labelOf(row), 'Removed'));
|
|
92
|
+
return rows.map(row => () => row.Delete());
|
|
93
|
+
}
|
|
94
|
+
function changeOf(label, action) {
|
|
95
|
+
return { Collection: label.Collection, Action: action, Name: label.Name, ChangedColumns: [], SourceEntityFieldID: label.SourceEntityFieldID ?? null };
|
|
96
|
+
}
|
|
97
|
+
function fieldLabel(row) {
|
|
98
|
+
return { Collection: 'Fields', Name: row.Name, SourceEntityFieldID: row.SourceEntityFieldID };
|
|
99
|
+
}
|
|
100
|
+
function parameterLabel(row) {
|
|
101
|
+
return { Collection: 'Parameters', Name: row.Name };
|
|
102
|
+
}
|
|
103
|
+
function byLowerName(rows) {
|
|
104
|
+
return new Map(rows.map(r => [r.Name.toLowerCase(), r]));
|
|
105
|
+
}
|
|
106
|
+
function isEmpty(value) {
|
|
107
|
+
return !value || value.trim().length === 0;
|
|
108
|
+
}
|
|
109
|
+
// ─── Fields ─────────────────────────────────────────────────────────────────
|
|
110
|
+
async function fieldWrites(context, stored, facts, summary) {
|
|
111
|
+
const existing = byLowerName(stored);
|
|
112
|
+
const writes = [];
|
|
113
|
+
for (const fact of facts) {
|
|
114
|
+
let row = existing.get(fact.Name.toLowerCase());
|
|
115
|
+
existing.delete(fact.Name.toLowerCase());
|
|
116
|
+
if (!row)
|
|
117
|
+
row = await newRow(context, 'MJ: Query Fields', r => newField(r, context.QueryID, fact));
|
|
118
|
+
else
|
|
119
|
+
applyFieldAnnotations(row, fact);
|
|
120
|
+
const nullabilityChanged = row.IsSaved && (row.IsNullable ?? null) !== (fact.IsNullable ?? null);
|
|
121
|
+
ApplyFieldFacts(row, fact);
|
|
122
|
+
writes.push(...saveIfDirty(row, summary, fieldLabel(row), nullabilityChanged ? ['IsNullable'] : []));
|
|
123
|
+
if (isEmpty(row.Description))
|
|
124
|
+
summary.FieldsWithoutDescription.push(row.Name);
|
|
125
|
+
}
|
|
126
|
+
return [...writes, ...deleteRows([...existing.values()], summary, fieldLabel)];
|
|
127
|
+
}
|
|
128
|
+
function newField(row, queryID, fact) {
|
|
129
|
+
row.QueryID = queryID;
|
|
130
|
+
row.Description = fact.DocDescription ?? fact.SourceDescription;
|
|
131
|
+
row.IsSummary = false;
|
|
132
|
+
row.DetectionMethod = 'Database';
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Sets a field row's facts (name casing, sequence, types, nullability, computed flag, source) from
|
|
136
|
+
* the extracted fact, leaving its annotations alone.
|
|
137
|
+
*/
|
|
138
|
+
export function ApplyFieldFacts(row, fact) {
|
|
139
|
+
row.Name = fact.Name;
|
|
140
|
+
row.Sequence = fact.Sequence;
|
|
141
|
+
row.SQLBaseType = fact.SQLBaseType;
|
|
142
|
+
row.SQLFullType = fact.SQLFullType;
|
|
143
|
+
row.IsNullable = fact.IsNullable;
|
|
144
|
+
row.IsComputed = fact.IsComputed;
|
|
145
|
+
row.SourceEntityID = fact.SourceEntityID;
|
|
146
|
+
row.SourceEntityFieldID = fact.SourceEntityFieldID;
|
|
147
|
+
row.SourceFieldName = fact.SourceFieldName;
|
|
148
|
+
row.SourceObjectName = fact.SourceObjectName;
|
|
149
|
+
}
|
|
150
|
+
/** A stored field's description and detection method: authored ones kept, a doc comment applied. */
|
|
151
|
+
function applyFieldAnnotations(row, fact) {
|
|
152
|
+
const authored = row.DetectionMethod === 'Manual';
|
|
153
|
+
if (fact.DocDescription !== null && (!authored || isEmpty(row.Description)))
|
|
154
|
+
row.Description = fact.DocDescription;
|
|
155
|
+
if (!authored && row.DetectionMethod !== 'AI')
|
|
156
|
+
row.DetectionMethod = 'Database';
|
|
157
|
+
if (row.DetectionMethod === 'AI' && fact.DocDescription !== null)
|
|
158
|
+
row.DetectionMethod = 'Database';
|
|
159
|
+
}
|
|
160
|
+
// ─── Parameters ─────────────────────────────────────────────────────────────
|
|
161
|
+
async function parameterWrites(context, stored, facts, summary) {
|
|
162
|
+
const existing = byLowerName(stored);
|
|
163
|
+
const writes = [];
|
|
164
|
+
for (const fact of facts) {
|
|
165
|
+
let row = existing.get(fact.Name.toLowerCase());
|
|
166
|
+
existing.delete(fact.Name.toLowerCase());
|
|
167
|
+
if (!row)
|
|
168
|
+
row = await newRow(context, 'MJ: Query Parameters', r => newParameter(r, context.QueryID, fact));
|
|
169
|
+
else
|
|
170
|
+
applyParameterAnnotations(row, fact);
|
|
171
|
+
row.Name = fact.Name;
|
|
172
|
+
writes.push(...saveIfDirty(row, summary, parameterLabel(row)));
|
|
173
|
+
if (isEmpty(row.Description))
|
|
174
|
+
summary.ParametersWithoutDescription.push(row.Name);
|
|
175
|
+
}
|
|
176
|
+
const leftover = [...existing.values()];
|
|
177
|
+
summary.FlaggedParameters.push(...leftover.filter(row => row.DetectionMethod === 'Manual').map(row => row.Name));
|
|
178
|
+
const unused = leftover.filter(row => row.DetectionMethod !== 'Manual');
|
|
179
|
+
return [...writes, ...deleteRows(unused, summary, parameterLabel)];
|
|
180
|
+
}
|
|
181
|
+
function newParameter(row, queryID, fact) {
|
|
182
|
+
row.QueryID = queryID;
|
|
183
|
+
row.Type = fact.Type ?? 'string';
|
|
184
|
+
row.IsRequired = fact.IsRequired;
|
|
185
|
+
row.DefaultValue = fact.DefaultValue;
|
|
186
|
+
row.SampleValue = fact.SampleValue;
|
|
187
|
+
row.Description = fact.DocDescription ?? fact.InheritedDescription;
|
|
188
|
+
row.IsServerSet = false;
|
|
189
|
+
row.DetectionMethod = 'Parser';
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* A stored parameter: a `Manual` row keeps every annotation (only an empty description is filled);
|
|
193
|
+
* an auto-detected row takes the template's type, required flag and default, keeps a non-empty
|
|
194
|
+
* sample and description, and takes a doc comment's description.
|
|
195
|
+
*/
|
|
196
|
+
function applyParameterAnnotations(row, fact) {
|
|
197
|
+
if (row.DetectionMethod === 'Manual') {
|
|
198
|
+
if (isEmpty(row.Description))
|
|
199
|
+
row.Description = fact.DocDescription ?? fact.InheritedDescription ?? row.Description;
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
if (fact.Type !== null)
|
|
203
|
+
row.Type = fact.Type;
|
|
204
|
+
row.IsRequired = fact.IsRequired;
|
|
205
|
+
row.DefaultValue = fact.DefaultValue;
|
|
206
|
+
if (isEmpty(row.SampleValue))
|
|
207
|
+
row.SampleValue = fact.SampleValue;
|
|
208
|
+
if (fact.DocDescription !== null)
|
|
209
|
+
row.Description = fact.DocDescription;
|
|
210
|
+
else if (isEmpty(row.Description))
|
|
211
|
+
row.Description = fact.InheritedDescription;
|
|
212
|
+
row.DetectionMethod = 'Parser';
|
|
213
|
+
}
|
|
214
|
+
// ─── Entities ───────────────────────────────────────────────────────────────
|
|
215
|
+
async function entityWrites(context, stored, facts, summary) {
|
|
216
|
+
const remaining = [...stored];
|
|
217
|
+
const writes = [];
|
|
218
|
+
const unmatched = facts.filter(fact => !takeRow(remaining, r => sameEntityLink(r, fact)));
|
|
219
|
+
for (const fact of unmatched) {
|
|
220
|
+
const row = takeRow(remaining, r => UUIDsEqual(r.EntityID, fact.EntityID))
|
|
221
|
+
?? await newRow(context, 'MJ: Query Entities', r => newEntityLink(r, context.QueryID, fact));
|
|
222
|
+
row.AlternateBaseViewID = fact.AlternateBaseViewID;
|
|
223
|
+
writes.push(...saveIfDirty(row, summary, entityLabel(context, row)));
|
|
224
|
+
}
|
|
225
|
+
return [...writes, ...deleteRows(remaining, summary, row => entityLabel(context, row))];
|
|
226
|
+
}
|
|
227
|
+
function entityLabel(context, row) {
|
|
228
|
+
return { Collection: 'Entities', Name: context.EntityName ? context.EntityName(row.EntityID) : (row.Entity || row.EntityID) };
|
|
229
|
+
}
|
|
230
|
+
function sameEntityLink(row, fact) {
|
|
231
|
+
const abv = (id) => (id ? NormalizeUUID(id) : '');
|
|
232
|
+
return UUIDsEqual(row.EntityID, fact.EntityID) && abv(row.AlternateBaseViewID) === abv(fact.AlternateBaseViewID);
|
|
233
|
+
}
|
|
234
|
+
function newEntityLink(row, queryID, fact) {
|
|
235
|
+
row.QueryID = queryID;
|
|
236
|
+
row.EntityID = fact.EntityID;
|
|
237
|
+
row.DetectionMethod = 'Parser';
|
|
238
|
+
row.AutoDetectConfidenceScore = 1;
|
|
239
|
+
}
|
|
240
|
+
/** Removes and returns the first row matching `test`. */
|
|
241
|
+
function takeRow(rows, test) {
|
|
242
|
+
const index = rows.findIndex(test);
|
|
243
|
+
return index < 0 ? undefined : rows.splice(index, 1)[0];
|
|
244
|
+
}
|
|
245
|
+
// ─── Dependencies ───────────────────────────────────────────────────────────
|
|
246
|
+
async function dependencyWrites(context, stored, facts, summary) {
|
|
247
|
+
const remaining = [...stored];
|
|
248
|
+
const writes = [];
|
|
249
|
+
const seen = new Set();
|
|
250
|
+
for (const fact of facts) {
|
|
251
|
+
const key = `${NormalizeUUID(fact.DependsOnQueryID)}|${fact.ReferencePath.toLowerCase()}`;
|
|
252
|
+
if (seen.has(key))
|
|
253
|
+
continue;
|
|
254
|
+
seen.add(key);
|
|
255
|
+
const row = takeRow(remaining, r => UUIDsEqual(r.DependsOnQueryID, fact.DependsOnQueryID) && r.ReferencePath.toLowerCase() === fact.ReferencePath.toLowerCase())
|
|
256
|
+
?? await newRow(context, 'MJ: Query Dependencies', r => newDependency(r, context.QueryID, fact));
|
|
257
|
+
row.ReferencePath = fact.ReferencePath;
|
|
258
|
+
row.Alias = fact.Alias;
|
|
259
|
+
row.ParameterMapping = fact.ParameterMapping;
|
|
260
|
+
writes.push(...saveIfDirty(row, summary, dependencyLabel(row)));
|
|
261
|
+
}
|
|
262
|
+
return [...writes, ...deleteRows(remaining, summary, dependencyLabel)];
|
|
263
|
+
}
|
|
264
|
+
function dependencyLabel(row) {
|
|
265
|
+
return { Collection: 'Dependencies', Name: row.ReferencePath };
|
|
266
|
+
}
|
|
267
|
+
function newDependency(row, queryID, fact) {
|
|
268
|
+
row.QueryID = queryID;
|
|
269
|
+
row.DependsOnQueryID = fact.DependsOnQueryID;
|
|
270
|
+
row.DetectionMethod = 'Auto';
|
|
271
|
+
}
|
|
272
|
+
async function newRow(context, entityName, init) {
|
|
273
|
+
const row = await context.Provider.GetEntityObject(entityName, context.User);
|
|
274
|
+
init(row);
|
|
275
|
+
return row;
|
|
276
|
+
}
|
|
277
|
+
//# sourceMappingURL=childRowWriter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"childRowWriter.js","sourceRoot":"","sources":["../../../src/custom/query-extraction/childRowWriter.ts"],"names":[],"mappings":"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"}
|