bulltrackers-module 1.0.768 → 1.0.770
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/RiskScoreIncrease.js +13 -13
- 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/handlers/scheduler.js +172 -203
- 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,336 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Mock Storage Manager
|
|
3
|
+
*
|
|
4
|
+
* Drop-in replacement for StorageManager that captures results in memory.
|
|
5
|
+
* Designed to be injected into the real Orchestrator for 1:1 simulation.
|
|
6
|
+
*
|
|
7
|
+
* Key Features:
|
|
8
|
+
* - Implements same interface as StorageManager
|
|
9
|
+
* - Stores results in memory instead of BigQuery/Firestore
|
|
10
|
+
* - Provides access to captured results for inspection
|
|
11
|
+
* - Simulates computation_results table for pass dependencies
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
class MockStorageManager {
|
|
15
|
+
/**
|
|
16
|
+
* @param {Object} options
|
|
17
|
+
* @param {Object} [options.config] - Storage config (for compatibility)
|
|
18
|
+
*/
|
|
19
|
+
constructor(options = {}) {
|
|
20
|
+
this.config = options.config || {};
|
|
21
|
+
|
|
22
|
+
// In-memory result storage
|
|
23
|
+
// Structure: { computationName: { entityId: result } }
|
|
24
|
+
this.results = {};
|
|
25
|
+
|
|
26
|
+
// Full row storage (for computation_results table simulation)
|
|
27
|
+
// Structure: { computationName: Row[] }
|
|
28
|
+
this.resultRows = {};
|
|
29
|
+
|
|
30
|
+
// Checkpoint storage
|
|
31
|
+
this.checkpoints = {};
|
|
32
|
+
|
|
33
|
+
// Stats
|
|
34
|
+
this.stats = {
|
|
35
|
+
commitsCount: 0,
|
|
36
|
+
finalizationsCount: 0,
|
|
37
|
+
totalRowsStored: 0,
|
|
38
|
+
checkpointsSaved: 0
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
// Operation log for inspection
|
|
42
|
+
this.operationLog = [];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Stage results - matches StorageManager.commitResults signature.
|
|
47
|
+
*
|
|
48
|
+
* @param {string} dateStr - Date string (YYYY-MM-DD)
|
|
49
|
+
* @param {Object} entry - Manifest entry { name, category, ... }
|
|
50
|
+
* @param {Object} results - { entityId: result }
|
|
51
|
+
* @param {Object} depResultHashes - Dependency result hashes
|
|
52
|
+
* @returns {Object} Write results
|
|
53
|
+
*/
|
|
54
|
+
async commitResults(dateStr, entry, results, depResultHashes = {}) {
|
|
55
|
+
const computationName = entry.name.toLowerCase();
|
|
56
|
+
const startTime = Date.now();
|
|
57
|
+
|
|
58
|
+
this.operationLog.push({
|
|
59
|
+
operation: 'commitResults',
|
|
60
|
+
computation: computationName,
|
|
61
|
+
date: dateStr,
|
|
62
|
+
entityCount: Object.keys(results).length,
|
|
63
|
+
timestamp: new Date().toISOString()
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// Store results
|
|
67
|
+
if (!this.results[computationName]) {
|
|
68
|
+
this.results[computationName] = {};
|
|
69
|
+
}
|
|
70
|
+
Object.assign(this.results[computationName], results);
|
|
71
|
+
|
|
72
|
+
// Build rows in computation_results format
|
|
73
|
+
const rows = this._buildBigQueryRows(dateStr, entry, results, depResultHashes);
|
|
74
|
+
if (!this.resultRows[computationName]) {
|
|
75
|
+
this.resultRows[computationName] = [];
|
|
76
|
+
}
|
|
77
|
+
this.resultRows[computationName].push(...rows);
|
|
78
|
+
|
|
79
|
+
this.stats.commitsCount++;
|
|
80
|
+
this.stats.totalRowsStored += Object.keys(results).length;
|
|
81
|
+
|
|
82
|
+
const duration = Date.now() - startTime;
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
bigquery: { staged: true, rowCount: Object.keys(results).length },
|
|
86
|
+
firestore: { written: false },
|
|
87
|
+
duration
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Finalize results - matches StorageManager.finalizeResults signature.
|
|
93
|
+
* For mock, this is a no-op since data is already stored in memory.
|
|
94
|
+
*
|
|
95
|
+
* @param {string} dateStr
|
|
96
|
+
* @param {Object} entry
|
|
97
|
+
*/
|
|
98
|
+
async finalizeResults(dateStr, entry) {
|
|
99
|
+
const computationName = entry.name;
|
|
100
|
+
|
|
101
|
+
this.operationLog.push({
|
|
102
|
+
operation: 'finalizeResults',
|
|
103
|
+
computation: computationName,
|
|
104
|
+
date: dateStr,
|
|
105
|
+
timestamp: new Date().toISOString()
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
this.stats.finalizationsCount++;
|
|
109
|
+
|
|
110
|
+
// No-op for mock - data already in memory
|
|
111
|
+
return { finalized: true };
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// =========================================================================
|
|
115
|
+
// CHECKPOINT METHODS (Simplified for simulation)
|
|
116
|
+
// =========================================================================
|
|
117
|
+
|
|
118
|
+
async saveCheckpoint(state) {
|
|
119
|
+
const id = state.checkpointId || `mock_${Date.now()}`;
|
|
120
|
+
this.checkpoints[id] = {
|
|
121
|
+
...state,
|
|
122
|
+
lastUpdated: new Date().toISOString()
|
|
123
|
+
};
|
|
124
|
+
this.stats.checkpointsSaved++;
|
|
125
|
+
return { saved: true, id };
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
async initCheckpoint(dateStr, computationName, checkpointId, totalEntities, workerId, codeHash) {
|
|
129
|
+
const checkpoint = {
|
|
130
|
+
dateStr,
|
|
131
|
+
computationName,
|
|
132
|
+
checkpointId,
|
|
133
|
+
totalEntities,
|
|
134
|
+
workerId,
|
|
135
|
+
codeHash,
|
|
136
|
+
status: 'RUNNING',
|
|
137
|
+
processedEntities: 0,
|
|
138
|
+
lastUpdated: new Date().toISOString()
|
|
139
|
+
};
|
|
140
|
+
this.checkpoints[checkpointId] = checkpoint;
|
|
141
|
+
return checkpoint;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
async updateCheckpoint(dateStr, computationName, checkpointId, state) {
|
|
145
|
+
if (this.checkpoints[checkpointId]) {
|
|
146
|
+
Object.assign(this.checkpoints[checkpointId], state, {
|
|
147
|
+
lastUpdated: new Date().toISOString()
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
return { updated: true };
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
async updateHeartbeat(checkpointId, workerId) {
|
|
154
|
+
if (this.checkpoints[checkpointId]) {
|
|
155
|
+
this.checkpoints[checkpointId].lastHeartbeat = new Date().toISOString();
|
|
156
|
+
}
|
|
157
|
+
return { updated: true };
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
async completeCheckpoint(dateStr, computationName, checkpointId) {
|
|
161
|
+
if (this.checkpoints[checkpointId]) {
|
|
162
|
+
this.checkpoints[checkpointId].status = 'COMPLETED';
|
|
163
|
+
this.checkpoints[checkpointId].completedAt = new Date().toISOString();
|
|
164
|
+
}
|
|
165
|
+
return { completed: true };
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
async failCheckpoint(checkpointId, reason) {
|
|
169
|
+
if (this.checkpoints[checkpointId]) {
|
|
170
|
+
this.checkpoints[checkpointId].status = 'FAILED';
|
|
171
|
+
this.checkpoints[checkpointId].failureReason = reason;
|
|
172
|
+
}
|
|
173
|
+
return { failed: true };
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
async getLatestCheckpoint(dateStr, computationName) {
|
|
177
|
+
// Find matching checkpoint
|
|
178
|
+
for (const [id, cp] of Object.entries(this.checkpoints)) {
|
|
179
|
+
if (cp.dateStr === dateStr && cp.computationName === computationName) {
|
|
180
|
+
return cp;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
async getLatestCheckpointById(checkpointId) {
|
|
187
|
+
return this.checkpoints[checkpointId] || null;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
async findZombies(minutesThreshold = 15) {
|
|
191
|
+
return []; // No zombies in simulation
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
async claimZombie(checkpointId) {
|
|
195
|
+
return { claimed: false };
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
async claimCheckpoint(checkpointId, newWorkerId, minutesThreshold = 15) {
|
|
199
|
+
return { claimed: false };
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// =========================================================================
|
|
203
|
+
// PERFORMANCE REPORTS
|
|
204
|
+
// =========================================================================
|
|
205
|
+
|
|
206
|
+
async savePerformanceReport(report) {
|
|
207
|
+
this.operationLog.push({
|
|
208
|
+
operation: 'savePerformanceReport',
|
|
209
|
+
report,
|
|
210
|
+
timestamp: new Date().toISOString()
|
|
211
|
+
});
|
|
212
|
+
return { saved: true };
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// =========================================================================
|
|
216
|
+
// RESULT ACCESS METHODS (For simulation inspection)
|
|
217
|
+
// =========================================================================
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Get results for a computation.
|
|
221
|
+
* @param {string} computationName
|
|
222
|
+
* @returns {Object} { entityId: result }
|
|
223
|
+
*/
|
|
224
|
+
getResults(computationName) {
|
|
225
|
+
return this.results[computationName.toLowerCase()] || {};
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Get all results across all computations.
|
|
230
|
+
* @returns {Object} { computationName: { entityId: result } }
|
|
231
|
+
*/
|
|
232
|
+
getAllResults() {
|
|
233
|
+
return { ...this.results };
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Get results as computation_results rows (for dependency simulation).
|
|
238
|
+
* @param {string} computationName
|
|
239
|
+
* @returns {Object[]} Rows in computation_results format
|
|
240
|
+
*/
|
|
241
|
+
getResultRows(computationName) {
|
|
242
|
+
return this.resultRows[computationName.toLowerCase()] || [];
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Get results keyed by entity ID (for feeding to dependent computations).
|
|
247
|
+
* This is what dependent computations receive when querying for metrics.
|
|
248
|
+
* @param {string} computationName
|
|
249
|
+
* @returns {Object} { entityId: result }
|
|
250
|
+
*/
|
|
251
|
+
getResultsForDependency(computationName) {
|
|
252
|
+
const rows = this.resultRows[computationName.toLowerCase()] || [];
|
|
253
|
+
const byEntity = {};
|
|
254
|
+
|
|
255
|
+
for (const row of rows) {
|
|
256
|
+
byEntity[row.entity_id] = row.result;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
return byEntity;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Clear all stored data.
|
|
264
|
+
*/
|
|
265
|
+
clear() {
|
|
266
|
+
this.results = {};
|
|
267
|
+
this.resultRows = {};
|
|
268
|
+
this.checkpoints = {};
|
|
269
|
+
this.operationLog = [];
|
|
270
|
+
this.stats = {
|
|
271
|
+
commitsCount: 0,
|
|
272
|
+
finalizationsCount: 0,
|
|
273
|
+
totalRowsStored: 0,
|
|
274
|
+
checkpointsSaved: 0
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Get storage statistics.
|
|
280
|
+
*/
|
|
281
|
+
getStats() {
|
|
282
|
+
return { ...this.stats };
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Get operation log.
|
|
287
|
+
*/
|
|
288
|
+
getOperationLog() {
|
|
289
|
+
return [...this.operationLog];
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// =========================================================================
|
|
293
|
+
// PRIVATE METHODS
|
|
294
|
+
// =========================================================================
|
|
295
|
+
|
|
296
|
+
_buildBigQueryRows(dateStr, entry, results, depResultHashes) {
|
|
297
|
+
const rows = [];
|
|
298
|
+
const timestamp = new Date().toISOString();
|
|
299
|
+
|
|
300
|
+
for (const [entityId, result] of Object.entries(results)) {
|
|
301
|
+
rows.push({
|
|
302
|
+
date: dateStr,
|
|
303
|
+
computation_name: entry.name,
|
|
304
|
+
category: entry.category || 'unknown',
|
|
305
|
+
entity_id: entityId,
|
|
306
|
+
result: result,
|
|
307
|
+
dependency_hashes: JSON.stringify(depResultHashes),
|
|
308
|
+
hash: this._hashResult(result),
|
|
309
|
+
created_at: timestamp
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
return rows;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
_hashResult(data) {
|
|
317
|
+
// Simple hash for mock purposes
|
|
318
|
+
const str = JSON.stringify(data) || '';
|
|
319
|
+
let hash = 0;
|
|
320
|
+
for (let i = 0; i < str.length; i++) {
|
|
321
|
+
const chr = str.charCodeAt(i);
|
|
322
|
+
hash = ((hash << 5) - hash) + chr;
|
|
323
|
+
hash |= 0;
|
|
324
|
+
}
|
|
325
|
+
return Math.abs(hash).toString(16);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Firestore accessor (returns dummy for compatibility).
|
|
330
|
+
*/
|
|
331
|
+
get firestore() {
|
|
332
|
+
return null;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
module.exports = { MockStorageManager };
|