bulltrackers-module 1.0.768 โ 1.0.769
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/functions/computation-system-v2/UserPortfolioMetrics.js +50 -0
- package/functions/computation-system-v2/computations/BehavioralAnomaly.js +557 -337
- package/functions/computation-system-v2/computations/GlobalAumPerAsset30D.js +103 -0
- package/functions/computation-system-v2/computations/PIDailyAssetAUM.js +134 -0
- package/functions/computation-system-v2/computations/PiFeatureVectors.js +227 -0
- package/functions/computation-system-v2/computations/PiRecommender.js +359 -0
- package/functions/computation-system-v2/computations/SignedInUserList.js +51 -0
- package/functions/computation-system-v2/computations/SignedInUserMirrorHistory.js +138 -0
- package/functions/computation-system-v2/computations/SignedInUserPIProfileMetrics.js +106 -0
- package/functions/computation-system-v2/computations/SignedInUserProfileMetrics.js +324 -0
- package/functions/computation-system-v2/config/bulltrackers.config.js +30 -128
- package/functions/computation-system-v2/core-api.js +17 -9
- package/functions/computation-system-v2/data_schema_reference.MD +108 -0
- package/functions/computation-system-v2/devtools/builder/builder.js +362 -0
- package/functions/computation-system-v2/devtools/builder/examples/user-metrics.yaml +26 -0
- package/functions/computation-system-v2/devtools/index.js +36 -0
- package/functions/computation-system-v2/devtools/shared/MockDataFactory.js +235 -0
- package/functions/computation-system-v2/devtools/shared/SchemaTemplates.js +475 -0
- package/functions/computation-system-v2/devtools/shared/SystemIntrospector.js +517 -0
- package/functions/computation-system-v2/devtools/shared/index.js +16 -0
- package/functions/computation-system-v2/devtools/simulation/DAGAnalyzer.js +243 -0
- package/functions/computation-system-v2/devtools/simulation/MockDataFetcher.js +306 -0
- package/functions/computation-system-v2/devtools/simulation/MockStorageManager.js +336 -0
- package/functions/computation-system-v2/devtools/simulation/SimulationEngine.js +525 -0
- package/functions/computation-system-v2/devtools/simulation/SimulationServer.js +581 -0
- package/functions/computation-system-v2/devtools/simulation/index.js +17 -0
- package/functions/computation-system-v2/devtools/simulation/simulate.js +324 -0
- package/functions/computation-system-v2/devtools/vscode-computation/package.json +90 -0
- package/functions/computation-system-v2/devtools/vscode-computation/snippets/computation.json +128 -0
- package/functions/computation-system-v2/devtools/vscode-computation/src/extension.ts +401 -0
- package/functions/computation-system-v2/devtools/vscode-computation/src/providers/codeActions.ts +152 -0
- package/functions/computation-system-v2/devtools/vscode-computation/src/providers/completions.ts +207 -0
- package/functions/computation-system-v2/devtools/vscode-computation/src/providers/diagnostics.ts +205 -0
- package/functions/computation-system-v2/devtools/vscode-computation/src/providers/hover.ts +205 -0
- package/functions/computation-system-v2/devtools/vscode-computation/tsconfig.json +22 -0
- package/functions/computation-system-v2/docs/HowToCreateComputations.MD +602 -0
- package/functions/computation-system-v2/framework/data/DataFetcher.js +250 -184
- package/functions/computation-system-v2/framework/data/MaterializedViewManager.js +84 -0
- package/functions/computation-system-v2/framework/data/QueryBuilder.js +38 -38
- package/functions/computation-system-v2/framework/execution/Orchestrator.js +215 -129
- package/functions/computation-system-v2/framework/scheduling/ScheduleValidator.js +17 -19
- package/functions/computation-system-v2/framework/storage/StateRepository.js +32 -2
- package/functions/computation-system-v2/framework/storage/StorageManager.js +105 -67
- package/functions/computation-system-v2/framework/testing/ComputationTester.js +12 -6
- package/functions/computation-system-v2/handlers/dispatcher.js +57 -29
- package/functions/computation-system-v2/legacy/PiAssetRecommender.js.old +115 -0
- package/functions/computation-system-v2/legacy/PiSimilarityMatrix.js +104 -0
- package/functions/computation-system-v2/legacy/PiSimilarityVector.js +71 -0
- package/functions/computation-system-v2/scripts/debug_aggregation.js +25 -0
- package/functions/computation-system-v2/scripts/test-invalidation-scenarios.js +234 -0
- package/package.json +1 -1
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Real-World Invalidation Simulator
|
|
3
|
+
* Dynamically loads ALL computation AND rule code to verify:
|
|
4
|
+
* 1. Code Hash Generation (using real files).
|
|
5
|
+
* 2. Invalidation logic (Simulated DB vs Real Disk Hash).
|
|
6
|
+
* 3. Dependency chains (Dynamic discovery of chains).
|
|
7
|
+
* * Usage: node scripts/test-real-scenarios.js
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const fs = require('fs');
|
|
11
|
+
const path = require('path');
|
|
12
|
+
const assert = require('assert');
|
|
13
|
+
|
|
14
|
+
// Framework Components
|
|
15
|
+
const { RunAnalyzer } = require('../framework/core/RunAnalyzer');
|
|
16
|
+
const { Orchestrator } = require('../framework/execution/Orchestrator');
|
|
17
|
+
const { ManifestBuilder } = require('../framework/core/Manifest');
|
|
18
|
+
|
|
19
|
+
// -----------------------------------------------------------------------------
|
|
20
|
+
// 1. MOCKS (Virtual Environment)
|
|
21
|
+
// -----------------------------------------------------------------------------
|
|
22
|
+
|
|
23
|
+
class MockDataFetcher {
|
|
24
|
+
async checkAvailability() { return { canRun: true, missing: [] }; }
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
class MockStateRepository {
|
|
28
|
+
constructor() {
|
|
29
|
+
this.statusMap = new Map();
|
|
30
|
+
this.results = new Map();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
setDailyStatus(date, compName, status) {
|
|
34
|
+
if (!this.statusMap.has(date)) this.statusMap.set(date, new Map());
|
|
35
|
+
this.statusMap.get(date).set(compName.toLowerCase(), status);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async getDailyStatus(date) {
|
|
39
|
+
return this.statusMap.get(date) || new Map();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Simulate finding history for backfills
|
|
43
|
+
async getRunDates(compName) { return ['2024-01-01', '2024-01-02']; }
|
|
44
|
+
|
|
45
|
+
// Mock Result fetching
|
|
46
|
+
async getResult(date, compName) { return this.results.get(`${date}:${compName}`); }
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
class TestOrchestrator extends Orchestrator {
|
|
50
|
+
constructor(config, stateRepo) {
|
|
51
|
+
super(config);
|
|
52
|
+
this.stateRepository = stateRepo;
|
|
53
|
+
this.scheduledTasks = [];
|
|
54
|
+
}
|
|
55
|
+
async _scheduleCloudTask(name, date, source, delay) {
|
|
56
|
+
this.scheduledTasks.push({ name, date, source });
|
|
57
|
+
}
|
|
58
|
+
_log(level, msg) { /* console.log(`[${level}] ${msg}`); */ }
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// -----------------------------------------------------------------------------
|
|
62
|
+
// 2. HELPER: Dynamic Loader
|
|
63
|
+
// -----------------------------------------------------------------------------
|
|
64
|
+
function loadModulesFromDir(directory, label) {
|
|
65
|
+
let modules = [];
|
|
66
|
+
try {
|
|
67
|
+
if (fs.existsSync(directory)) {
|
|
68
|
+
const files = fs.readdirSync(directory).filter(f => f.endsWith('.js') && f !== 'index.js');
|
|
69
|
+
console.log(`INFO: Found ${files.length} ${label} files in ${directory}`);
|
|
70
|
+
|
|
71
|
+
modules = files.map(file => {
|
|
72
|
+
try {
|
|
73
|
+
return require(path.join(directory, file));
|
|
74
|
+
} catch (e) {
|
|
75
|
+
console.warn(`WARN: Failed to load ${file}: ${e.message}`);
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
}).filter(c => c !== null);
|
|
79
|
+
} else {
|
|
80
|
+
console.warn(`WARN: ${label} directory not found at ${directory}`);
|
|
81
|
+
}
|
|
82
|
+
} catch (e) {
|
|
83
|
+
console.error(`ERROR: Could not load ${label}: ${e.message}`);
|
|
84
|
+
}
|
|
85
|
+
return modules;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// -----------------------------------------------------------------------------
|
|
89
|
+
// 3. TEST SUITE
|
|
90
|
+
// -----------------------------------------------------------------------------
|
|
91
|
+
|
|
92
|
+
async function runRealWorldTests() {
|
|
93
|
+
console.log('โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ');
|
|
94
|
+
console.log('โ REAL CODE SIMULATION SUITE โ');
|
|
95
|
+
console.log('โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ');
|
|
96
|
+
|
|
97
|
+
// 1. LOAD ARTIFACTS
|
|
98
|
+
const computationsDir = path.join(__dirname, '../computations');
|
|
99
|
+
const rulesDir = path.join(__dirname, '../rules');
|
|
100
|
+
|
|
101
|
+
const computationClasses = loadModulesFromDir(computationsDir, 'computation');
|
|
102
|
+
const ruleModules = loadModulesFromDir(rulesDir, 'rule'); // <--- NEW: Load Rules
|
|
103
|
+
|
|
104
|
+
if (computationClasses.length === 0) {
|
|
105
|
+
console.error("โ ABORT: No valid computations found to test.");
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// 2. BUILD REAL MANIFEST
|
|
110
|
+
const config = {
|
|
111
|
+
computations: computationClasses,
|
|
112
|
+
rules: ruleModules // <--- NEW: Pass Rules to Config
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
// Initialize ManifestBuilder (this internally initializes RulesRegistry too)
|
|
116
|
+
const builder = new ManifestBuilder(config, console);
|
|
117
|
+
const realManifest = builder.build(config.computations);
|
|
118
|
+
|
|
119
|
+
console.log(`INFO: Successfully built manifest with ${realManifest.length} entries.`);
|
|
120
|
+
|
|
121
|
+
// 3. RUN TESTS
|
|
122
|
+
await test_RealCodeInvalidation(realManifest);
|
|
123
|
+
await test_DynamicDependencyCascading(realManifest, config);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* SCENARIO 1: Simulate a Deployment (Code Change)
|
|
128
|
+
*/
|
|
129
|
+
async function test_RealCodeInvalidation(manifest) {
|
|
130
|
+
// Pick 'RiskScoreIncrease' if available, otherwise the first one
|
|
131
|
+
let target = manifest.find(c => c.name === 'riskscoreincrease');
|
|
132
|
+
if (!target) target = manifest[0];
|
|
133
|
+
|
|
134
|
+
console.log(`\n๐งช Test 1: Real Code Hash Mismatch (${target.originalName})`);
|
|
135
|
+
|
|
136
|
+
const analyzer = new RunAnalyzer(manifest, new MockDataFetcher());
|
|
137
|
+
const date = '2024-06-01';
|
|
138
|
+
|
|
139
|
+
// CONDITION: The DB has an old/different hash
|
|
140
|
+
const dailyStatus = new Map();
|
|
141
|
+
dailyStatus.set(target.name, {
|
|
142
|
+
hash: 'OLD_DEPLOYMENT_HASH_123',
|
|
143
|
+
resultHash: 'res_v1',
|
|
144
|
+
updatedAt: new Date().toISOString()
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
// ANALYZE
|
|
148
|
+
const result = await analyzer._evaluateEntry(target, date, true, dailyStatus, new Map());
|
|
149
|
+
|
|
150
|
+
// ASSERT
|
|
151
|
+
try {
|
|
152
|
+
assert.strictEqual(result.type, 'reRuns', 'Should trigger re-run');
|
|
153
|
+
assert.strictEqual(result.payload.reason, 'Code changed', 'Reason must be code change');
|
|
154
|
+
|
|
155
|
+
console.log(` [Current Disk Hash]: ${target.hash.substring(0, 16)}...`);
|
|
156
|
+
console.log(` [Simulated DB Hash]: OLD_DEPLOYMENT_HASH_123`);
|
|
157
|
+
console.log('โ
PASS: System correctly detected the code mismatch.');
|
|
158
|
+
} catch (e) {
|
|
159
|
+
console.error('โ FAIL:', e.message);
|
|
160
|
+
console.log(' Decision:', result);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* SCENARIO 2: Dynamic Dependency Propagation
|
|
166
|
+
*/
|
|
167
|
+
async function test_DynamicDependencyCascading(manifest, config) {
|
|
168
|
+
console.log('\n๐งช Test 2: Dependency Propagation (Dynamic Chain Detection)');
|
|
169
|
+
|
|
170
|
+
// 1. Find a valid dependency chain (Parent -> Child)
|
|
171
|
+
let upstream = null;
|
|
172
|
+
let downstream = null;
|
|
173
|
+
|
|
174
|
+
for (const child of manifest) {
|
|
175
|
+
if (child.dependencies && child.dependencies.length > 0) {
|
|
176
|
+
// Find the parent object
|
|
177
|
+
const parentName = child.dependencies[0]; // normalized name usually
|
|
178
|
+
const parent = manifest.find(c => c.name === parentName); // match normalized names
|
|
179
|
+
|
|
180
|
+
if (parent) {
|
|
181
|
+
upstream = parent;
|
|
182
|
+
downstream = child;
|
|
183
|
+
break; // Found a pair!
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// 2. Handle Case: No Chains Found
|
|
189
|
+
if (!upstream || !downstream) {
|
|
190
|
+
console.log('โ ๏ธ SKIPPED: No valid dependency chains found in the loaded computations.');
|
|
191
|
+
console.log(' (This is NOT a failure. It simply means all loaded computations are independent)');
|
|
192
|
+
console.log('โ
PASS: Skipped due to lack of testable chains.');
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
console.log(` Found chain: ${upstream.originalName} -> ${downstream.originalName}`);
|
|
197
|
+
|
|
198
|
+
// 3. Setup Orchestrator
|
|
199
|
+
const mockState = new MockStateRepository();
|
|
200
|
+
const orch = new TestOrchestrator({ ...config, bigquery: {}, tables: {} }, mockState);
|
|
201
|
+
orch.manifest = manifest;
|
|
202
|
+
orch._buildDependentsIndex();
|
|
203
|
+
|
|
204
|
+
const date = '2024-06-01';
|
|
205
|
+
|
|
206
|
+
// 4. Simulate Upstream Finishing
|
|
207
|
+
mockState.setDailyStatus(date, upstream.name, {
|
|
208
|
+
hash: upstream.hash,
|
|
209
|
+
resultHash: 'NEW_RESULT_HASH_XYZ',
|
|
210
|
+
updatedAt: new Date().toISOString()
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
// 5. Trigger Cascading Logic
|
|
214
|
+
await orch._scheduleDependents(upstream, date);
|
|
215
|
+
|
|
216
|
+
// 6. Assert
|
|
217
|
+
try {
|
|
218
|
+
const task = orch.scheduledTasks.find(t => t.name === downstream.originalName);
|
|
219
|
+
if (task) {
|
|
220
|
+
console.log(` [Triggered]: ${task.name} due to update in ${upstream.name}`);
|
|
221
|
+
console.log('โ
PASS: Dependency chain resolved and task scheduled.');
|
|
222
|
+
} else {
|
|
223
|
+
console.error(`โ FAIL: Downstream task (${downstream.name}) was NOT scheduled.`);
|
|
224
|
+
console.log(' Dependents Map keys:', Array.from(orch.dependentsByName.keys()));
|
|
225
|
+
}
|
|
226
|
+
} catch (e) {
|
|
227
|
+
console.error('โ FAIL:', e.message);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// EXECUTE
|
|
232
|
+
runRealWorldTests().catch(e => {
|
|
233
|
+
console.error('FATAL:', e);
|
|
234
|
+
});
|