bulltrackers-module 1.0.766 → 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.
Files changed (76) hide show
  1. package/functions/computation-system-v2/UserPortfolioMetrics.js +50 -0
  2. package/functions/computation-system-v2/computations/BehavioralAnomaly.js +559 -227
  3. package/functions/computation-system-v2/computations/GlobalAumPerAsset30D.js +103 -0
  4. package/functions/computation-system-v2/computations/NewSectorExposure.js +82 -35
  5. package/functions/computation-system-v2/computations/NewSocialPost.js +52 -24
  6. package/functions/computation-system-v2/computations/PIDailyAssetAUM.js +134 -0
  7. package/functions/computation-system-v2/computations/PiFeatureVectors.js +227 -0
  8. package/functions/computation-system-v2/computations/PiRecommender.js +359 -0
  9. package/functions/computation-system-v2/computations/PopularInvestorProfileMetrics.js +354 -641
  10. package/functions/computation-system-v2/computations/SignedInUserList.js +51 -0
  11. package/functions/computation-system-v2/computations/SignedInUserMirrorHistory.js +138 -0
  12. package/functions/computation-system-v2/computations/SignedInUserPIProfileMetrics.js +106 -0
  13. package/functions/computation-system-v2/computations/SignedInUserProfileMetrics.js +324 -0
  14. package/functions/computation-system-v2/config/bulltrackers.config.js +40 -126
  15. package/functions/computation-system-v2/core-api.js +17 -9
  16. package/functions/computation-system-v2/data_schema_reference.MD +108 -0
  17. package/functions/computation-system-v2/devtools/builder/builder.js +362 -0
  18. package/functions/computation-system-v2/devtools/builder/examples/user-metrics.yaml +26 -0
  19. package/functions/computation-system-v2/devtools/index.js +36 -0
  20. package/functions/computation-system-v2/devtools/shared/MockDataFactory.js +235 -0
  21. package/functions/computation-system-v2/devtools/shared/SchemaTemplates.js +475 -0
  22. package/functions/computation-system-v2/devtools/shared/SystemIntrospector.js +517 -0
  23. package/functions/computation-system-v2/devtools/shared/index.js +16 -0
  24. package/functions/computation-system-v2/devtools/simulation/DAGAnalyzer.js +243 -0
  25. package/functions/computation-system-v2/devtools/simulation/MockDataFetcher.js +306 -0
  26. package/functions/computation-system-v2/devtools/simulation/MockStorageManager.js +336 -0
  27. package/functions/computation-system-v2/devtools/simulation/SimulationEngine.js +525 -0
  28. package/functions/computation-system-v2/devtools/simulation/SimulationServer.js +581 -0
  29. package/functions/computation-system-v2/devtools/simulation/index.js +17 -0
  30. package/functions/computation-system-v2/devtools/simulation/simulate.js +324 -0
  31. package/functions/computation-system-v2/devtools/vscode-computation/package.json +90 -0
  32. package/functions/computation-system-v2/devtools/vscode-computation/snippets/computation.json +128 -0
  33. package/functions/computation-system-v2/devtools/vscode-computation/src/extension.ts +401 -0
  34. package/functions/computation-system-v2/devtools/vscode-computation/src/providers/codeActions.ts +152 -0
  35. package/functions/computation-system-v2/devtools/vscode-computation/src/providers/completions.ts +207 -0
  36. package/functions/computation-system-v2/devtools/vscode-computation/src/providers/diagnostics.ts +205 -0
  37. package/functions/computation-system-v2/devtools/vscode-computation/src/providers/hover.ts +205 -0
  38. package/functions/computation-system-v2/devtools/vscode-computation/tsconfig.json +22 -0
  39. package/functions/computation-system-v2/docs/HowToCreateComputations.MD +602 -0
  40. package/functions/computation-system-v2/framework/core/Manifest.js +9 -16
  41. package/functions/computation-system-v2/framework/core/RunAnalyzer.js +2 -1
  42. package/functions/computation-system-v2/framework/data/DataFetcher.js +330 -126
  43. package/functions/computation-system-v2/framework/data/MaterializedViewManager.js +84 -0
  44. package/functions/computation-system-v2/framework/data/QueryBuilder.js +38 -38
  45. package/functions/computation-system-v2/framework/execution/Orchestrator.js +226 -153
  46. package/functions/computation-system-v2/framework/scheduling/ScheduleValidator.js +17 -19
  47. package/functions/computation-system-v2/framework/storage/StateRepository.js +32 -2
  48. package/functions/computation-system-v2/framework/storage/StorageManager.js +111 -83
  49. package/functions/computation-system-v2/framework/testing/ComputationTester.js +161 -66
  50. package/functions/computation-system-v2/handlers/dispatcher.js +57 -29
  51. package/functions/computation-system-v2/legacy/PiAssetRecommender.js.old +115 -0
  52. package/functions/computation-system-v2/legacy/PiSimilarityMatrix.js +104 -0
  53. package/functions/computation-system-v2/legacy/PiSimilarityVector.js +71 -0
  54. package/functions/computation-system-v2/scripts/debug_aggregation.js +25 -0
  55. package/functions/computation-system-v2/scripts/test-computation-dag.js +109 -0
  56. package/functions/computation-system-v2/scripts/test-invalidation-scenarios.js +234 -0
  57. package/functions/task-engine/helpers/data_storage_helpers.js +6 -6
  58. package/package.json +1 -1
  59. package/functions/computation-system-v2/computations/PopularInvestorRiskAssessment.js +0 -176
  60. package/functions/computation-system-v2/computations/PopularInvestorRiskMetrics.js +0 -294
  61. package/functions/computation-system-v2/computations/UserPortfolioSummary.js +0 -172
  62. package/functions/computation-system-v2/scripts/migrate-sectors.js +0 -73
  63. package/functions/computation-system-v2/test/analyze-results.js +0 -238
  64. package/functions/computation-system-v2/test/other/test-dependency-cascade.js +0 -150
  65. package/functions/computation-system-v2/test/other/test-dispatcher.js +0 -317
  66. package/functions/computation-system-v2/test/other/test-framework.js +0 -500
  67. package/functions/computation-system-v2/test/other/test-real-execution.js +0 -166
  68. package/functions/computation-system-v2/test/other/test-real-integration.js +0 -194
  69. package/functions/computation-system-v2/test/other/test-refactor-e2e.js +0 -131
  70. package/functions/computation-system-v2/test/other/test-results.json +0 -31
  71. package/functions/computation-system-v2/test/other/test-risk-metrics-computation.js +0 -329
  72. package/functions/computation-system-v2/test/other/test-scheduler.js +0 -204
  73. package/functions/computation-system-v2/test/other/test-storage.js +0 -449
  74. package/functions/computation-system-v2/test/run-pipeline-test.js +0 -554
  75. package/functions/computation-system-v2/test/test-full-pipeline.js +0 -227
  76. package/functions/computation-system-v2/test/test-worker-pool.js +0 -266
@@ -0,0 +1,324 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @fileoverview CLI for Computation Simulation
4
+ * * Usage:
5
+ * node simulate.js [command] [options]
6
+ * * Commands:
7
+ * serve Start the simulation server with dashboard
8
+ * run <computation> Run a single computation simulation
9
+ * run-all <computation> Run a computation with all its dependencies
10
+ * validate <computation> Validate a computation's configuration
11
+ * list List all computations
12
+ * info <computation> Get detailed info about a computation
13
+ * dag Print DAG summary
14
+ * * Options:
15
+ * --port <port> Server port (default: 3210)
16
+ * --entities <count> Number of mock entities (default: 10)
17
+ * --date <YYYY-MM-DD> Target date for simulation
18
+ * --verbose Enable verbose logging
19
+ * --json Output in JSON format
20
+ */
21
+
22
+ const path = require('path');
23
+
24
+ // Load config (relative to this script's location)
25
+ const configPath = path.resolve(__dirname, '../../config/bulltrackers.config.js');
26
+ let config;
27
+ try {
28
+ config = require(configPath);
29
+ } catch (e) {
30
+ console.error('Failed to load config:', e.message);
31
+ console.error('Expected at:', configPath);
32
+ process.exit(1);
33
+ }
34
+
35
+ const { SimulationEngine } = require('./SimulationEngine');
36
+ const { SimulationServer } = require('./SimulationServer');
37
+ const { DAGAnalyzer } = require('./DAGAnalyzer');
38
+ const { SystemIntrospector } = require('../shared/SystemIntrospector');
39
+
40
+ // Parse CLI arguments
41
+ const args = process.argv.slice(2);
42
+ const command = args[0] || 'serve';
43
+ const target = args[1];
44
+
45
+ // Parse options
46
+ const options = {
47
+ port: parseInt(getOption('--port', '3210')),
48
+ entities: parseInt(getOption('--entities', '10')),
49
+ date: getOption('--date', new Date().toISOString().split('T')[0]),
50
+ verbose: args.includes('--verbose'),
51
+ json: args.includes('--json')
52
+ };
53
+
54
+ function getOption(name, defaultValue) {
55
+ const idx = args.indexOf(name);
56
+ return idx >= 0 && args[idx + 1] ? args[idx + 1] : defaultValue;
57
+ }
58
+
59
+ async function main() {
60
+ switch (command) {
61
+ case 'serve':
62
+ await startServer();
63
+ break;
64
+
65
+ case 'run':
66
+ if (!target) {
67
+ console.error('Usage: simulate.js run <computation-name>');
68
+ process.exit(1);
69
+ }
70
+ await runSimulation(target, false);
71
+ break;
72
+
73
+ case 'run-all':
74
+ if (!target) {
75
+ console.error('Usage: simulate.js run-all <computation-name>');
76
+ process.exit(1);
77
+ }
78
+ await runSimulation(target, true);
79
+ break;
80
+
81
+ case 'validate':
82
+ if (!target) {
83
+ console.error('Usage: simulate.js validate <computation-name>');
84
+ process.exit(1);
85
+ }
86
+ await validateComputation(target);
87
+ break;
88
+
89
+ case 'list':
90
+ await listComputations();
91
+ break;
92
+
93
+ case 'info':
94
+ if (!target) {
95
+ console.error('Usage: simulate.js info <computation-name>');
96
+ process.exit(1);
97
+ }
98
+ await showInfo(target);
99
+ break;
100
+
101
+ case 'dag':
102
+ await showDAG();
103
+ break;
104
+
105
+ case 'help':
106
+ case '--help':
107
+ case '-h':
108
+ showHelp();
109
+ break;
110
+
111
+ default:
112
+ console.error(`Unknown command: ${command}`);
113
+ showHelp();
114
+ process.exit(1);
115
+ }
116
+ }
117
+
118
+ async function startServer() {
119
+ const server = new SimulationServer(config, {
120
+ port: options.port,
121
+ entityCount: options.entities,
122
+ watch: true
123
+ });
124
+ await server.start();
125
+ }
126
+
127
+ async function runSimulation(computationName, withDependencies) {
128
+ const engine = new SimulationEngine(config, {
129
+ entityCount: options.entities,
130
+ targetDate: options.date,
131
+ verbose: options.verbose
132
+ });
133
+
134
+ console.log(`\n🔄 Running simulation: ${computationName}`);
135
+ console.log(` Date: ${options.date}`);
136
+ console.log(` Entities: ${options.entities}`);
137
+ if (withDependencies) {
138
+ console.log(' Mode: With Dependencies\n');
139
+ } else {
140
+ console.log(' Mode: Single Computation\n');
141
+ }
142
+
143
+ try {
144
+ let result;
145
+ if (withDependencies) {
146
+ result = await engine.runWithDependencies(computationName, {
147
+ targetDate: options.date
148
+ });
149
+ } else {
150
+ result = await engine.runComputation(computationName, {
151
+ targetDate: options.date
152
+ });
153
+ }
154
+
155
+ if (options.json) {
156
+ console.log(JSON.stringify(result, null, 2));
157
+ } else {
158
+ if (result.success) {
159
+ console.log(`✅ Success!`);
160
+ console.log(` Execution Time: ${result.stats.executionTimeMs}ms`);
161
+ console.log(` Entities Processed: ${result.stats.entitiesProcessed}`);
162
+ console.log(` Memory Used: ${Math.round(result.stats.memoryUsedBytes / 1024)}KB`);
163
+ console.log(`\nSample Result:`);
164
+ const keys = Object.keys(result.results);
165
+ if (keys.length === 0) {
166
+ console.log(' (No results returned)');
167
+ } else {
168
+ const firstEntity = keys[0];
169
+ console.log(` Key: ${firstEntity}`);
170
+ console.log(JSON.stringify(result.results[firstEntity], null, 2));
171
+ }
172
+ } else {
173
+ console.log(`❌ Failed: ${result.error}`);
174
+ }
175
+ }
176
+ } catch (e) {
177
+ console.error('Simulation failed:', e.message);
178
+ if (options.verbose) console.error(e.stack);
179
+ process.exit(1);
180
+ }
181
+ }
182
+
183
+ async function validateComputation(computationName) {
184
+ const introspector = new SystemIntrospector(config);
185
+ const configObj = introspector.getComputationConfig(computationName);
186
+
187
+ if (!configObj) {
188
+ console.error(`Computation not found: ${computationName}`);
189
+ process.exit(1);
190
+ }
191
+
192
+ const result = introspector.validateComputationConfig(configObj);
193
+
194
+ if (options.json) {
195
+ console.log(JSON.stringify(result, null, 2));
196
+ } else {
197
+ if (result.valid) {
198
+ console.log(`✅ ${computationName}: Valid`);
199
+ if (result.warnings.length > 0) {
200
+ console.log(`\n⚠️ Warnings:`);
201
+ result.warnings.forEach(w => console.log(` - ${w}`));
202
+ }
203
+ } else {
204
+ console.log(`❌ ${computationName}: Invalid`);
205
+ console.log(`\nErrors:`);
206
+ result.errors.forEach(e => console.log(` - ${e}`));
207
+ }
208
+ }
209
+ }
210
+
211
+ async function listComputations() {
212
+ const introspector = new SystemIntrospector(config);
213
+ const names = introspector.getComputationNames();
214
+ const levels = introspector.getPassLevels();
215
+
216
+ if (options.json) {
217
+ console.log(JSON.stringify(names.map(n => ({
218
+ name: n,
219
+ passLevel: levels.get(n) || 1
220
+ })), null, 2));
221
+ } else {
222
+ console.log(`\n📋 Computations (${names.length} total)\n`);
223
+
224
+ // Group by pass level
225
+ const byLevel = {};
226
+ for (const name of names) {
227
+ const level = levels.get(name) || 1;
228
+ if (!byLevel[level]) byLevel[level] = [];
229
+ byLevel[level].push(name);
230
+ }
231
+
232
+ for (const level of Object.keys(byLevel).sort((a, b) => a - b)) {
233
+ console.log(`Pass ${level}:`);
234
+ byLevel[level].forEach(n => console.log(` - ${n}`));
235
+ console.log();
236
+ }
237
+ }
238
+ }
239
+
240
+ async function showInfo(computationName) {
241
+ const introspector = new SystemIntrospector(config);
242
+ const dagAnalyzer = new DAGAnalyzer(introspector);
243
+
244
+ const info = {
245
+ name: computationName,
246
+ passLevel: introspector.getPassLevel(computationName),
247
+ config: introspector.getComputationConfig(computationName),
248
+ validation: introspector.validateComputationConfig(
249
+ introspector.getComputationConfig(computationName)
250
+ ),
251
+ impact: dagAnalyzer.getImpactAnalysis(computationName)
252
+ };
253
+
254
+ if (options.json) {
255
+ console.log(JSON.stringify(info, null, 2));
256
+ } else {
257
+ console.log(`\n📊 ${computationName}\n`);
258
+ console.log(`Pass Level: ${info.passLevel}`);
259
+ console.log(`Type: ${info.config?.type || 'unknown'}`);
260
+ console.log(`Category: ${info.config?.category || 'unknown'}`);
261
+ console.log(`\nDependencies: ${info.impact.directDependents.length > 0 ? '' : 'None'}`);
262
+ (info.config?.dependencies || []).forEach(d => console.log(` ← ${d}`));
263
+ console.log(`\nDependents: ${info.impact.directDependents.length > 0 ? '' : 'None'}`);
264
+ info.impact.directDependents.forEach(d => console.log(` → ${d}`));
265
+ console.log(`\nValidation: ${info.validation.valid ? '✅ Valid' : '❌ Invalid'}`);
266
+ }
267
+ }
268
+
269
+ async function showDAG() {
270
+ const introspector = new SystemIntrospector(config);
271
+ const dagAnalyzer = new DAGAnalyzer(introspector);
272
+ const summary = dagAnalyzer.getSummary();
273
+
274
+ if (options.json) {
275
+ console.log(JSON.stringify(summary, null, 2));
276
+ } else {
277
+ console.log(`\n📈 DAG Summary\n`);
278
+ console.log(`Total Computations: ${summary.totalNodes}`);
279
+ console.log(`Total Edges: ${summary.totalEdges}`);
280
+ console.log(`Total Passes: ${summary.totalPasses}`);
281
+ console.log(`Entry Points: ${summary.entryPointCount}`);
282
+ console.log(` ${summary.entryPoints.join(', ')}${summary.entryPointCount > 5 ? '...' : ''}`);
283
+ if (summary.cycles.length > 0) {
284
+ console.log(`\n⚠️ Cycles Detected: ${summary.cycles.length}`);
285
+ }
286
+ }
287
+ }
288
+
289
+ function showHelp() {
290
+ console.log(`
291
+ Computation Simulator CLI
292
+
293
+ Usage: node simulate.js [command] [options]
294
+
295
+ Commands:
296
+ serve Start the simulation server with dashboard
297
+ run <computation> Run a single computation simulation
298
+ run-all <computation> Run a computation with all its dependencies
299
+ validate <computation> Validate a computation's configuration
300
+ list List all computations
301
+ info <computation> Get detailed info about a computation
302
+ dag Print DAG summary
303
+
304
+ Options:
305
+ --port <port> Server port (default: 3210)
306
+ --entities <count> Number of mock entities (default: 10)
307
+ --date <YYYY-MM-DD> Target date for simulation
308
+ --verbose Enable verbose logging
309
+ --json Output in JSON format
310
+ -h, --help Show this help message
311
+
312
+ Examples:
313
+ node simulate.js serve
314
+ node simulate.js run SignedInUserMirrorHistory --entities 50
315
+ node simulate.js run-all PopularInvestorProfileMetrics --date 2026-01-15
316
+ node simulate.js validate SignedInUserList
317
+ `);
318
+ }
319
+
320
+ main().catch(e => {
321
+ console.error('Fatal error:', e.message);
322
+ if (options.verbose) console.error(e.stack);
323
+ process.exit(1);
324
+ });
@@ -0,0 +1,90 @@
1
+ {
2
+ "name": "computation-developer",
3
+ "displayName": "BullTrackers Computation Developer",
4
+ "description": "Intelligent autocomplete and validation for BullTrackers computations",
5
+ "version": "0.1.0",
6
+ "publisher": "bulltrackers",
7
+ "engines": {
8
+ "vscode": "^1.75.0"
9
+ },
10
+ "categories": [
11
+ "Programming Languages",
12
+ "Linters",
13
+ "Snippets"
14
+ ],
15
+ "activationEvents": [
16
+ "onLanguage:javascript",
17
+ "workspaceContains:**/computation-system-v2/**"
18
+ ],
19
+ "main": "./out/extension.js",
20
+ "contributes": {
21
+ "configuration": {
22
+ "title": "Computation Developer",
23
+ "properties": {
24
+ "computationDeveloper.enableDiagnostics": {
25
+ "type": "boolean",
26
+ "default": true,
27
+ "description": "Enable real-time validation diagnostics"
28
+ },
29
+ "computationDeveloper.enableHover": {
30
+ "type": "boolean",
31
+ "default": true,
32
+ "description": "Enable hover documentation"
33
+ },
34
+ "computationDeveloper.maxLookbackWarningThreshold": {
35
+ "type": "number",
36
+ "default": 63,
37
+ "description": "Warn when lookback exceeds this percentage of max (90)"
38
+ },
39
+ "computationDeveloper.simulationServerUrl": {
40
+ "type": "string",
41
+ "default": "http://localhost:3210",
42
+ "description": "URL of the simulation server"
43
+ }
44
+ }
45
+ },
46
+ "commands": [
47
+ {
48
+ "command": "computationDeveloper.validate",
49
+ "title": "Validate Computation",
50
+ "category": "Computation"
51
+ },
52
+ {
53
+ "command": "computationDeveloper.simulate",
54
+ "title": "Simulate Computation",
55
+ "category": "Computation"
56
+ },
57
+ {
58
+ "command": "computationDeveloper.showDAG",
59
+ "title": "Show DAG Position",
60
+ "category": "Computation"
61
+ },
62
+ {
63
+ "command": "computationDeveloper.generateBoilerplate",
64
+ "title": "Generate Computation Boilerplate",
65
+ "category": "Computation"
66
+ }
67
+ ],
68
+ "snippets": [
69
+ {
70
+ "language": "javascript",
71
+ "path": "./snippets/computation.json"
72
+ }
73
+ ]
74
+ },
75
+ "scripts": {
76
+ "vscode:prepublish": "npm run compile",
77
+ "compile": "tsc -p ./",
78
+ "watch": "tsc -watch -p ./",
79
+ "lint": "eslint src --ext ts"
80
+ },
81
+ "devDependencies": {
82
+ "@types/vscode": "^1.75.0",
83
+ "@types/node": "^18.x",
84
+ "typescript": "^5.0.0",
85
+ "eslint": "^8.0.0"
86
+ },
87
+ "dependencies": {
88
+ "vscode-languageclient": "^8.0.0"
89
+ }
90
+ }
@@ -0,0 +1,128 @@
1
+ {
2
+ "Computation Class": {
3
+ "prefix": "comp",
4
+ "body": [
5
+ "const { Computation } = require('../framework');",
6
+ "",
7
+ "class ${1:ComputationName} extends Computation {",
8
+ " static getConfig() {",
9
+ " return {",
10
+ " name: '${1:ComputationName}',",
11
+ " description: '${2:Description}',",
12
+ " type: '${3|per-entity,global|}',",
13
+ " category: '${4|signed_in_user,popular_investor,global|}',",
14
+ " isHistorical: ${5|false,true|},",
15
+ " requires: {",
16
+ " '${6:table_name}': {",
17
+ " lookback: ${7:0},",
18
+ " mandatory: true,",
19
+ " fields: [${8:'user_id', 'date'}]",
20
+ " }",
21
+ " },",
22
+ " storage: {",
23
+ " bigquery: true,",
24
+ " firestore: {",
25
+ " enabled: ${9|false,true|},",
26
+ " path: '${10:collection}/{entityId}',",
27
+ " merge: true",
28
+ " }",
29
+ " }",
30
+ " };",
31
+ " }",
32
+ "",
33
+ " async process(data, { entityId, targetDate, rules, getDependency }) {",
34
+ " $0",
35
+ " return {",
36
+ " // result",
37
+ " };",
38
+ " }",
39
+ "}",
40
+ "",
41
+ "module.exports = ${1:ComputationName};"
42
+ ],
43
+ "description": "Create a new computation class"
44
+ },
45
+ "Computation Config": {
46
+ "prefix": "compconfig",
47
+ "body": [
48
+ "static getConfig() {",
49
+ " return {",
50
+ " name: '${1:ComputationName}',",
51
+ " description: '${2:Description}',",
52
+ " type: '${3|per-entity,global|}',",
53
+ " category: '${4|signed_in_user,popular_investor,global|}',",
54
+ " isHistorical: ${5|false,true|},",
55
+ " requires: {",
56
+ " ${0}",
57
+ " }",
58
+ " };",
59
+ "}"
60
+ ],
61
+ "description": "Computation config method"
62
+ },
63
+ "Table Requirement": {
64
+ "prefix": "req",
65
+ "body": [
66
+ "'${1:table_name}': {",
67
+ " lookback: ${2:0},",
68
+ " mandatory: ${3|true,false|},",
69
+ " fields: [${4:'user_id', 'date'}]",
70
+ "}"
71
+ ],
72
+ "description": "Add a table requirement"
73
+ },
74
+ "Dependency Requirement": {
75
+ "prefix": "dep",
76
+ "body": [
77
+ "'${1:DependencyName}': {",
78
+ " type: 'metric',",
79
+ " computation: '${1:DependencyName}',",
80
+ " mandatory: ${2|true,false|}",
81
+ "}"
82
+ ],
83
+ "description": "Add a computation dependency"
84
+ },
85
+ "Storage Config": {
86
+ "prefix": "storage",
87
+ "body": [
88
+ "storage: {",
89
+ " bigquery: true,",
90
+ " firestore: {",
91
+ " enabled: ${1|true,false|},",
92
+ " path: '${2:collection}/{entityId}',",
93
+ " merge: true",
94
+ " }",
95
+ "}"
96
+ ],
97
+ "description": "Storage configuration block"
98
+ },
99
+ "Process Method": {
100
+ "prefix": "process",
101
+ "body": [
102
+ "async process(data, { entityId, targetDate, rules, getDependency }) {",
103
+ " const ${1:tableData} = data.${2:table_name}[entityId] || [];",
104
+ " ",
105
+ " $0",
106
+ " ",
107
+ " return {",
108
+ " // result",
109
+ " };",
110
+ "}"
111
+ ],
112
+ "description": "Process method template"
113
+ },
114
+ "Extract Rule": {
115
+ "prefix": "rulesext",
116
+ "body": [
117
+ "const ${1:result} = rules.${2|portfolio,metrics,rankings|}.${3:functionName}(${4:data});"
118
+ ],
119
+ "description": "Use a rules function"
120
+ },
121
+ "Get Dependency": {
122
+ "prefix": "getdep",
123
+ "body": [
124
+ "const ${1:depResult} = getDependency('${2:DependencyName}', entityId);"
125
+ ],
126
+ "description": "Get dependency result"
127
+ }
128
+ }