bulltrackers-module 1.0.766 → 1.0.768

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 (32) hide show
  1. package/functions/computation-system-v2/computations/BehavioralAnomaly.js +298 -186
  2. package/functions/computation-system-v2/computations/NewSectorExposure.js +82 -35
  3. package/functions/computation-system-v2/computations/NewSocialPost.js +52 -24
  4. package/functions/computation-system-v2/computations/PopularInvestorProfileMetrics.js +354 -641
  5. package/functions/computation-system-v2/config/bulltrackers.config.js +26 -14
  6. package/functions/computation-system-v2/framework/core/Manifest.js +9 -16
  7. package/functions/computation-system-v2/framework/core/RunAnalyzer.js +2 -1
  8. package/functions/computation-system-v2/framework/data/DataFetcher.js +142 -4
  9. package/functions/computation-system-v2/framework/execution/Orchestrator.js +18 -31
  10. package/functions/computation-system-v2/framework/storage/StorageManager.js +7 -17
  11. package/functions/computation-system-v2/framework/testing/ComputationTester.js +155 -66
  12. package/functions/computation-system-v2/scripts/test-computation-dag.js +109 -0
  13. package/functions/task-engine/helpers/data_storage_helpers.js +6 -6
  14. package/package.json +1 -1
  15. package/functions/computation-system-v2/computations/PopularInvestorRiskAssessment.js +0 -176
  16. package/functions/computation-system-v2/computations/PopularInvestorRiskMetrics.js +0 -294
  17. package/functions/computation-system-v2/computations/UserPortfolioSummary.js +0 -172
  18. package/functions/computation-system-v2/scripts/migrate-sectors.js +0 -73
  19. package/functions/computation-system-v2/test/analyze-results.js +0 -238
  20. package/functions/computation-system-v2/test/other/test-dependency-cascade.js +0 -150
  21. package/functions/computation-system-v2/test/other/test-dispatcher.js +0 -317
  22. package/functions/computation-system-v2/test/other/test-framework.js +0 -500
  23. package/functions/computation-system-v2/test/other/test-real-execution.js +0 -166
  24. package/functions/computation-system-v2/test/other/test-real-integration.js +0 -194
  25. package/functions/computation-system-v2/test/other/test-refactor-e2e.js +0 -131
  26. package/functions/computation-system-v2/test/other/test-results.json +0 -31
  27. package/functions/computation-system-v2/test/other/test-risk-metrics-computation.js +0 -329
  28. package/functions/computation-system-v2/test/other/test-scheduler.js +0 -204
  29. package/functions/computation-system-v2/test/other/test-storage.js +0 -449
  30. package/functions/computation-system-v2/test/run-pipeline-test.js +0 -554
  31. package/functions/computation-system-v2/test/test-full-pipeline.js +0 -227
  32. package/functions/computation-system-v2/test/test-worker-pool.js +0 -266
@@ -1,500 +0,0 @@
1
- /**
2
- * @fileoverview Framework Test Script
3
- *
4
- * Run with: node test/test-framework.js
5
- *
6
- * This tests the v2 framework independently before integrating with the workflow.
7
- */
8
-
9
- const path = require('path');
10
-
11
- // Set up environment (would normally come from Cloud Functions)
12
- process.env.GCP_PROJECT_ID = process.env.GCP_PROJECT_ID || 'stocks-12345';
13
- process.env.BIGQUERY_DATASET_ID = process.env.BIGQUERY_DATASET_ID || 'bulltrackers_data';
14
-
15
- // Simple logger
16
- const logger = {
17
- log: (level, message) => {
18
- const timestamp = new Date().toISOString().slice(11, 19);
19
- const levelPad = level.padEnd(5);
20
- console.log(`[${timestamp}] ${levelPad} ${message}`);
21
- }
22
- };
23
-
24
- // ============================================================================
25
- // TEST 1: Manifest Building with Dependencies
26
- // ============================================================================
27
- async function testManifestBuilding() {
28
- console.log('\n=== TEST: Manifest Building with Dependencies ===\n');
29
-
30
- const { ManifestBuilder } = require('../../framework/core/Manifest');
31
- const UserPortfolioSummary = require('../../computations/UserPortfolioSummary');
32
- const PopularInvestorProfileMetrics = require('../../computations/PopularInvestorProfileMetrics');
33
- const PopularInvestorRiskAssessment = require('../../computations/PopularInvestorRiskAssessment');
34
-
35
- const config = { epoch: 'test-v1' };
36
- const builder = new ManifestBuilder(config, logger);
37
-
38
- // Test with all 3 computations, including the dependent one
39
- const manifest = builder.build([
40
- UserPortfolioSummary,
41
- PopularInvestorProfileMetrics,
42
- PopularInvestorRiskAssessment // This depends on PopularInvestorProfileMetrics
43
- ]);
44
-
45
- console.log('Manifest entries:', manifest.length);
46
-
47
- // Group by pass and verify
48
- const passes = builder.groupByPass(manifest);
49
- const passNumbers = Object.keys(passes).map(Number).sort((a, b) => a - b);
50
-
51
- console.log(`\nPasses found: ${passNumbers.join(', ')}`);
52
-
53
- for (const passNum of passNumbers) {
54
- console.log(`\n Pass ${passNum}:`);
55
- for (const entry of passes[passNum]) {
56
- console.log(` šŸ“Š ${entry.originalName || entry.name}`);
57
- console.log(` Dependencies: ${entry.dependencies.length > 0 ? entry.dependencies.join(', ') : 'none'}`);
58
- }
59
- }
60
-
61
- // Verify Pass Assignment
62
- const piMetrics = manifest.find(e => e.name === 'popularinvestorprofilemetrics');
63
- const riskAssessment = manifest.find(e => e.name === 'popularinvestorriskassessment');
64
-
65
- console.log('\n--- Pass Assignment Verification ---');
66
- console.log(`PopularInvestorProfileMetrics: Pass ${piMetrics?.pass}`);
67
- console.log(`PopularInvestorRiskAssessment: Pass ${riskAssessment?.pass}`);
68
-
69
- if (riskAssessment?.pass > piMetrics?.pass) {
70
- console.log('\nāœ… Dependency pass assignment CORRECT!');
71
- console.log(` Dependent computation (${riskAssessment?.pass}) is in a later pass than its dependency (${piMetrics?.pass})`);
72
- } else {
73
- console.log('\nāŒ Dependency pass assignment INCORRECT!');
74
- console.log(' The dependent should be in a LATER pass than its dependency');
75
- }
76
-
77
- console.log('\nāœ… Manifest building works!\n');
78
-
79
- return manifest;
80
- }
81
-
82
- // ============================================================================
83
- // TEST 2: Schema Registry
84
- // ============================================================================
85
- async function testSchemaRegistry() {
86
- console.log('\n=== TEST: Schema Registry ===\n');
87
-
88
- const { SchemaRegistry } = require('../../framework/data/SchemaRegistry');
89
-
90
- const config = {
91
- projectId: process.env.GCP_PROJECT_ID,
92
- dataset: process.env.BIGQUERY_DATASET_ID,
93
- location: 'europe-west1'
94
- };
95
-
96
- const registry = new SchemaRegistry(config, logger);
97
-
98
- try {
99
- // List tables
100
- console.log('Listing tables...');
101
- const tables = await registry.listTables();
102
- console.log(`Found ${tables.length} tables:`, tables.slice(0, 5).join(', '), '...');
103
-
104
- // Get schema for a table
105
- if (tables.length > 0) {
106
- const testTable = tables.find(t => t.includes('portfolio')) || tables[0];
107
- console.log(`\nFetching schema for '${testTable}'...`);
108
- const schema = await registry.getSchema(testTable);
109
- console.log(`Columns (${schema.columns.length}):`);
110
- for (const col of schema.columns.slice(0, 5)) {
111
- console.log(` - ${col.name}: ${col.type}${col.nullable ? '' : ' (required)'}`);
112
- }
113
- if (schema.columns.length > 5) {
114
- console.log(` ... and ${schema.columns.length - 5} more`);
115
- }
116
-
117
- // Test validation
118
- console.log('\nValidating columns...');
119
- try {
120
- await registry.validateColumns(testTable, ['date', 'nonexistent_column_xyz']);
121
- console.log('āŒ Validation should have failed!');
122
- } catch (e) {
123
- console.log('āœ… Validation correctly caught invalid column');
124
- }
125
- }
126
-
127
- console.log('\nCache stats:', registry.getStats());
128
- console.log('\nāœ… Schema registry works!\n');
129
-
130
- } catch (e) {
131
- console.log(`\nāš ļø Schema registry test failed (expected if not connected to BigQuery): ${e.message}`);
132
- console.log('This is OK - the framework structure is correct.\n');
133
- }
134
- }
135
-
136
- // ============================================================================
137
- // TEST 3: Query Builder
138
- // ============================================================================
139
- async function testQueryBuilder() {
140
- console.log('\n=== TEST: Query Builder ===\n');
141
-
142
- const { SchemaRegistry } = require('../../framework/data/SchemaRegistry');
143
- const { QueryBuilder } = require('../../framework/data/QueryBuilder');
144
-
145
- const config = {
146
- projectId: process.env.GCP_PROJECT_ID,
147
- dataset: process.env.BIGQUERY_DATASET_ID,
148
- location: 'europe-west1'
149
- };
150
-
151
- const registry = new SchemaRegistry(config, logger);
152
- const builder = new QueryBuilder(config, registry, logger);
153
-
154
- try {
155
- // Build a query (requires BigQuery connection for validation)
156
- const query = await builder.build({
157
- table: 'portfolio_snapshots',
158
- select: ['date', 'user_id', 'portfolio_data'],
159
- where: { user_type: 'POPULAR_INVESTOR' },
160
- dateField: 'date',
161
- targetDate: '2026-01-24',
162
- lookback: 0
163
- });
164
-
165
- console.log('Built query:');
166
- console.log(query.sql);
167
- console.log('\nParams:', query.params);
168
- console.log('\nāœ… Query builder works!\n');
169
-
170
- } catch (e) {
171
- console.log(`\nāš ļø Query builder test requires BigQuery connection: ${e.message}`);
172
- console.log('The framework structure is correct.\n');
173
- }
174
- }
175
-
176
- // ============================================================================
177
- // TEST 4: Computation Validation
178
- // ============================================================================
179
- async function testComputationValidation() {
180
- console.log('\n=== TEST: Computation Validation ===\n');
181
-
182
- const { Computation } = require('../../framework/core/Computation');
183
- const UserPortfolioSummary = require('../../computations/UserPortfolioSummary');
184
- const PopularInvestorProfileMetrics = require('../../computations/PopularInvestorProfileMetrics');
185
- const PopularInvestorRiskAssessment = require('../../computations/PopularInvestorRiskAssessment');
186
-
187
- // Test UserPortfolioSummary
188
- console.log('Testing UserPortfolioSummary...');
189
- const validation1 = UserPortfolioSummary.validateConfig();
190
- console.log(' Validation:', validation1.valid ? 'āœ… Valid' : `āŒ Invalid: ${validation1.errors.join(', ')}`);
191
-
192
- // Test PopularInvestorProfileMetrics
193
- console.log('\nTesting PopularInvestorProfileMetrics...');
194
- const validation2 = PopularInvestorProfileMetrics.validateConfig();
195
- console.log(' Validation:', validation2.valid ? 'āœ… Valid' : `āŒ Invalid: ${validation2.errors.join(', ')}`);
196
-
197
- // Test PopularInvestorRiskAssessment (with dependency)
198
- console.log('\nTesting PopularInvestorRiskAssessment...');
199
- const validation3 = PopularInvestorRiskAssessment.validateConfig();
200
- console.log(' Validation:', validation3.valid ? 'āœ… Valid' : `āŒ Invalid: ${validation3.errors.join(', ')}`);
201
-
202
- // Show dependency details
203
- if (validation3.valid) {
204
- const config = PopularInvestorRiskAssessment.getConfig();
205
- console.log('\n Config details:');
206
- console.log(` Name: ${config.name}`);
207
- console.log(` Dependencies: ${config.dependencies.join(', ')}`);
208
- console.log(` Tables required (${Object.keys(config.requires).length}):`);
209
- for (const [table, spec] of Object.entries(config.requires)) {
210
- const mandatory = spec.mandatory ? '(mandatory)' : '(optional)';
211
- console.log(` - ${table}: ${mandatory}`);
212
- }
213
- }
214
-
215
- // Test instantiation
216
- console.log('\nTesting instantiation...');
217
- const instance1 = new UserPortfolioSummary();
218
- const instance2 = new PopularInvestorProfileMetrics();
219
- const instance3 = new PopularInvestorRiskAssessment();
220
- console.log('UserPortfolioSummary instance:', typeof instance1.process === 'function' ? 'āœ…' : 'āŒ');
221
- console.log('PopularInvestorProfileMetrics instance:', typeof instance2.process === 'function' ? 'āœ…' : 'āŒ');
222
- console.log('PopularInvestorRiskAssessment instance:', typeof instance3.process === 'function' ? 'āœ…' : 'āŒ');
223
-
224
- console.log('\nāœ… Computation validation works!\n');
225
- }
226
-
227
- // ============================================================================
228
- // TEST 5: Dry Run Analysis
229
- // ============================================================================
230
- async function testDryRun() {
231
- console.log('\n=== TEST: Dry Run Analysis ===\n');
232
-
233
- try {
234
- const v2 = require('../../index');
235
-
236
- const report = await v2.analyze({
237
- date: '2026-01-24',
238
- logger
239
- });
240
-
241
- console.log('Analysis report:');
242
- console.log(` Runnable: ${report.runnable.length}`);
243
- console.log(` Skipped: ${report.skipped.length}`);
244
- console.log(` Blocked: ${report.blocked.length}`);
245
- console.log(` Impossible: ${report.impossible.length}`);
246
-
247
- if (report.runnable.length > 0) {
248
- console.log('\nRunnable computations:');
249
- for (const c of report.runnable) {
250
- console.log(` - ${c.name} (Pass ${c.pass}) - ${c.reason}`);
251
- }
252
- }
253
-
254
- if (report.blocked.length > 0) {
255
- console.log('\nBlocked computations (waiting for dependencies):');
256
- for (const c of report.blocked) {
257
- console.log(` - ${c.name}: ${c.reason}`);
258
- }
259
- }
260
-
261
- if (report.impossible.length > 0) {
262
- console.log('\nImpossible computations:');
263
- for (const c of report.impossible) {
264
- console.log(` - ${c.name}: ${c.reason}`);
265
- }
266
- }
267
-
268
- console.log('\nāœ… Dry run analysis works!\n');
269
-
270
- } catch (e) {
271
- console.log(`\nāš ļø Dry run requires BigQuery connection: ${e.message}\n`);
272
- }
273
- }
274
-
275
- // ============================================================================
276
- // TEST 6: REAL DATA EXECUTION
277
- // ============================================================================
278
- async function testRealExecution() {
279
- console.log('\n=== TEST: REAL DATA EXECUTION ===\n');
280
- console.log('āš ļø This test will execute computations and write to BigQuery!\n');
281
-
282
- try {
283
- const v2 = require('../../index');
284
-
285
- // Find a date with data
286
- console.log('Looking for a date with available data...');
287
-
288
- // Try recent dates
289
- const today = new Date();
290
- let targetDate = null;
291
-
292
- for (let i = 0; i < 7; i++) {
293
- const checkDate = new Date(today);
294
- checkDate.setDate(today.getDate() - i);
295
- const dateStr = checkDate.toISOString().slice(0, 10);
296
-
297
- const report = await v2.analyze({ date: dateStr, logger });
298
-
299
- // Look for a date where we can run something
300
- if (report.runnable.length > 0) {
301
- targetDate = dateStr;
302
- console.log(`Found runnable date: ${dateStr}`);
303
- console.log(` Runnable: ${report.runnable.map(c => c.name).join(', ')}`);
304
- break;
305
- }
306
- }
307
-
308
- if (!targetDate) {
309
- console.log('āš ļø No runnable computations found in the last 7 days.');
310
- console.log(' Make sure root data exists in BigQuery.\n');
311
- return;
312
- }
313
-
314
- // Execute with dryRun first to see what would happen
315
- console.log(`\n--- Dry Run for ${targetDate} ---`);
316
- const dryResult = await v2.execute({
317
- date: targetDate,
318
- dryRun: true,
319
- logger
320
- });
321
-
322
- console.log('\nDry run results:');
323
- console.log(` Completed: ${dryResult.summary.completed}`);
324
- console.log(` Skipped: ${dryResult.summary.skipped}`);
325
- console.log(` Blocked: ${dryResult.summary.blocked}`);
326
- console.log(` Impossible: ${dryResult.summary.impossible}`);
327
- console.log(` Errors: ${dryResult.summary.errors}`);
328
-
329
- if (dryResult.completed.length > 0) {
330
- console.log('\nCompleted computations:');
331
- for (const c of dryResult.completed) {
332
- console.log(` - ${c.name}: ${c.resultCount} results in ${c.duration}ms`);
333
- }
334
- }
335
-
336
- // Now execute for real (comment out to skip writing)
337
- console.log(`\n--- REAL Execution for ${targetDate} ---`);
338
- console.log('Writing results to BigQuery...\n');
339
-
340
- const realResult = await v2.execute({
341
- date: targetDate,
342
- dryRun: false,
343
- logger
344
- });
345
-
346
- console.log('\nReal execution results:');
347
- console.log(` Completed: ${realResult.summary.completed}`);
348
- console.log(` Skipped: ${realResult.summary.skipped}`);
349
- console.log(` Blocked: ${realResult.summary.blocked}`);
350
- console.log(` Errors: ${realResult.summary.errors}`);
351
-
352
- if (realResult.completed.length > 0) {
353
- console.log('\nCompleted computations:');
354
- for (const c of realResult.completed) {
355
- console.log(` āœ… ${c.name}: ${c.resultCount} results in ${c.duration}ms`);
356
- }
357
- }
358
-
359
- if (realResult.errors.length > 0) {
360
- console.log('\nErrors:');
361
- for (const e of realResult.errors) {
362
- console.log(` āŒ ${e.name}: ${e.error}`);
363
- }
364
- }
365
-
366
- console.log('\nāœ… Real execution test complete!\n');
367
-
368
- return { targetDate, result: realResult };
369
-
370
- } catch (e) {
371
- console.log(`\nāŒ Real execution test failed: ${e.message}`);
372
- console.log(e.stack);
373
- }
374
- }
375
-
376
- // ============================================================================
377
- // TEST 7: DEPENDENT COMPUTATION EXECUTION
378
- // ============================================================================
379
- async function testDependentExecution(previousResult) {
380
- console.log('\n=== TEST: DEPENDENT COMPUTATION EXECUTION ===\n');
381
-
382
- if (!previousResult?.targetDate) {
383
- console.log('āš ļø No previous execution result. Skipping dependent test.\n');
384
- return;
385
- }
386
-
387
- const { targetDate, result: prevResult } = previousResult;
388
-
389
- // Check if the dependency (PopularInvestorProfileMetrics) was completed
390
- const depCompleted = prevResult.completed.find(c =>
391
- c.name.includes('profilemetrics')
392
- );
393
-
394
- if (!depCompleted) {
395
- console.log('āš ļø Dependency (PopularInvestorProfileMetrics) was not completed.');
396
- console.log(' Cannot test dependent computation.\n');
397
- return;
398
- }
399
-
400
- console.log(`Dependency completed: ${depCompleted.name}`);
401
- console.log(` Results: ${depCompleted.resultCount}`);
402
- console.log(` Duration: ${depCompleted.duration}ms`);
403
-
404
- try {
405
- const v2 = require('../../index');
406
-
407
- // Now try to run the dependent computation
408
- console.log(`\n--- Running Dependent Computation (Pass 2) ---`);
409
-
410
- // Re-analyze to see the updated state
411
- const report = await v2.analyze({ date: targetDate, logger });
412
-
413
- console.log('\nPost-Pass-1 analysis:');
414
- console.log(` Runnable: ${report.runnable.map(c => c.name).join(', ') || 'none'}`);
415
- console.log(` Blocked: ${report.blocked.map(c => c.name).join(', ') || 'none'}`);
416
- console.log(` Skipped: ${report.skipped.map(c => c.name).join(', ') || 'none'}`);
417
-
418
- // Check if RiskAssessment is now runnable
419
- const riskRunnable = report.runnable.find(c =>
420
- c.name.includes('riskassessment')
421
- );
422
-
423
- if (riskRunnable) {
424
- console.log(`\nāœ… PopularInvestorRiskAssessment is now RUNNABLE!`);
425
- console.log(` Reason: ${riskRunnable.reason}`);
426
-
427
- // Execute Pass 2
428
- console.log('\nExecuting Pass 2...');
429
- const pass2Result = await v2.execute({
430
- date: targetDate,
431
- pass: 2,
432
- dryRun: false,
433
- logger
434
- });
435
-
436
- console.log('\nPass 2 results:');
437
- console.log(` Completed: ${pass2Result.summary.completed}`);
438
- console.log(` Errors: ${pass2Result.summary.errors}`);
439
-
440
- if (pass2Result.completed.length > 0) {
441
- for (const c of pass2Result.completed) {
442
- console.log(` āœ… ${c.name}: ${c.resultCount} results in ${c.duration}ms`);
443
- }
444
- }
445
-
446
- if (pass2Result.errors.length > 0) {
447
- for (const e of pass2Result.errors) {
448
- console.log(` āŒ ${e.name}: ${e.error}`);
449
- }
450
- }
451
- } else {
452
- const riskBlocked = report.blocked.find(c => c.name.includes('riskassessment'));
453
- const riskSkipped = report.skipped.find(c => c.name.includes('riskassessment'));
454
-
455
- if (riskBlocked) {
456
- console.log(`\nāš ļø PopularInvestorRiskAssessment is still BLOCKED`);
457
- console.log(` Reason: ${riskBlocked.reason}`);
458
- } else if (riskSkipped) {
459
- console.log(`\nāœ… PopularInvestorRiskAssessment already completed (skipped)`);
460
- } else {
461
- console.log(`\nāš ļø Could not find PopularInvestorRiskAssessment in report`);
462
- }
463
- }
464
-
465
- console.log('\nāœ… Dependent computation test complete!\n');
466
-
467
- } catch (e) {
468
- console.log(`\nāŒ Dependent execution test failed: ${e.message}`);
469
- console.log(e.stack);
470
- }
471
- }
472
-
473
- // ============================================================================
474
- // RUN ALL TESTS
475
- // ============================================================================
476
- async function main() {
477
- console.log('╔════════════════════════════════════════════════════════════╗');
478
- console.log('ā•‘ Computation System v2 - Framework Tests ā•‘');
479
- console.log('ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•');
480
-
481
- // Core framework tests
482
- await testManifestBuilding();
483
- await testComputationValidation();
484
- await testSchemaRegistry();
485
- await testQueryBuilder();
486
- await testDryRun();
487
-
488
- // Real data tests (writes to BigQuery!)
489
- const execResult = await testRealExecution();
490
- await testDependentExecution(execResult);
491
-
492
- console.log('╔════════════════════════════════════════════════════════════╗');
493
- console.log('ā•‘ Tests Complete ā•‘');
494
- console.log('ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•');
495
- }
496
-
497
- main().catch(e => {
498
- console.error('Test failed:', e);
499
- process.exit(1);
500
- });
@@ -1,166 +0,0 @@
1
- /**
2
- * @fileoverview Quick Real Execution Test
3
- *
4
- * Run with: node test/test-real-execution.js
5
- *
6
- * This tests real execution and dependency handling.
7
- */
8
-
9
- // Set up environment
10
- process.env.GCP_PROJECT_ID = process.env.GCP_PROJECT_ID || 'stocks-12345';
11
- process.env.BIGQUERY_DATASET_ID = process.env.BIGQUERY_DATASET_ID || 'bulltrackers_data';
12
-
13
- const logger = {
14
- log: (level, message) => {
15
- const timestamp = new Date().toISOString().slice(11, 19);
16
- console.log(`[${timestamp}] ${level.padEnd(5)} ${message}`);
17
- }
18
- };
19
-
20
- async function main() {
21
- console.log('╔════════════════════════════════════════════════════════════╗');
22
- console.log('ā•‘ Computation System v2 - Real Execution Test ā•‘');
23
- console.log('ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•\n');
24
-
25
- const v2 = require('../../index');
26
-
27
- // Step 1: Verify pass assignment
28
- console.log('=== STEP 1: Verify Pass Assignment ===\n');
29
- const manifest = await v2.getManifest();
30
-
31
- const profileMetrics = manifest.find(m => m.name === 'popularinvestorprofilemetrics');
32
- const riskAssessment = manifest.find(m => m.name === 'popularinvestorriskassessment');
33
-
34
- console.log(`PopularInvestorProfileMetrics: Pass ${profileMetrics?.pass}`);
35
- console.log(`PopularInvestorRiskAssessment: Pass ${riskAssessment?.pass}`);
36
- console.log(`Dependencies: ${riskAssessment?.dependencies?.join(', ')}`);
37
-
38
- if (riskAssessment?.pass > profileMetrics?.pass) {
39
- console.log('\nāœ… Pass assignment correct - dependent is in later pass');
40
- } else {
41
- console.log('\nāŒ Pass assignment incorrect!');
42
- return;
43
- }
44
-
45
- // Step 2: Find runnable date
46
- console.log('\n=== STEP 2: Find Date with Data ===\n');
47
-
48
- const today = new Date();
49
- let targetDate = null;
50
-
51
- for (let i = 0; i < 7; i++) {
52
- const checkDate = new Date(today);
53
- checkDate.setDate(today.getDate() - i);
54
- const dateStr = checkDate.toISOString().slice(0, 10);
55
-
56
- console.log(`Checking ${dateStr}...`);
57
- const report = await v2.analyze({ date: dateStr });
58
-
59
- if (report.runnable.some(c => c.name === 'popularinvestorprofilemetrics')) {
60
- targetDate = dateStr;
61
- console.log(`\nāœ… Found runnable date: ${dateStr}`);
62
- break;
63
- }
64
- }
65
-
66
- if (!targetDate) {
67
- console.log('\nāš ļø No runnable date found in last 7 days');
68
- return;
69
- }
70
-
71
- // Step 3: Run Pass 1 (ProfileMetrics)
72
- console.log('\n=== STEP 3: Execute Pass 1 ===\n');
73
-
74
- const pass1Result = await v2.execute({
75
- date: targetDate,
76
- pass: 1,
77
- computation: 'PopularInvestorProfileMetrics',
78
- dryRun: false,
79
- logger
80
- });
81
-
82
- console.log('\nPass 1 results:');
83
- console.log(` Completed: ${pass1Result.summary.completed}`);
84
- console.log(` Errors: ${pass1Result.summary.errors}`);
85
-
86
- if (pass1Result.completed.length > 0) {
87
- const c = pass1Result.completed[0];
88
- console.log(`\nāœ… ${c.name}: ${c.resultCount} results in ${c.duration}ms`);
89
- }
90
-
91
- if (pass1Result.errors.length > 0) {
92
- console.log('\nāŒ Errors:');
93
- for (const e of pass1Result.errors) {
94
- console.log(` - ${e.name}: ${e.error.substring(0, 100)}...`);
95
- }
96
- return;
97
- }
98
-
99
- // Step 4: Verify RiskAssessment is now unblocked
100
- console.log('\n=== STEP 4: Check Dependency State ===\n');
101
-
102
- // Reset executor to reload status
103
- await v2.reset();
104
-
105
- const report2 = await v2.analyze({ date: targetDate });
106
-
107
- const riskRunnable = report2.runnable.find(c => c.name === 'popularinvestorriskassessment');
108
- const riskBlocked = report2.blocked.find(c => c.name === 'popularinvestorriskassessment');
109
- const riskSkipped = report2.skipped.find(c => c.name === 'popularinvestorriskassessment');
110
-
111
- if (riskRunnable) {
112
- console.log('āœ… PopularInvestorRiskAssessment is now RUNNABLE!');
113
- console.log(` Reason: ${riskRunnable.reason}`);
114
- } else if (riskBlocked) {
115
- console.log('āš ļø PopularInvestorRiskAssessment is still BLOCKED');
116
- console.log(` Reason: ${riskBlocked.reason}`);
117
-
118
- // Debug: check status
119
- console.log('\nDebug: Checking if ProfileMetrics result was saved...');
120
- // The dependency might not be found because status cache was cleared
121
- } else if (riskSkipped) {
122
- console.log('ā„¹ļø PopularInvestorRiskAssessment already up to date (skipped)');
123
- } else {
124
- console.log('āš ļø Could not find PopularInvestorRiskAssessment in analysis');
125
- }
126
-
127
- // Step 5: Run Pass 2 (RiskAssessment)
128
- if (riskRunnable || !riskBlocked) {
129
- console.log('\n=== STEP 5: Execute Pass 2 ===\n');
130
-
131
- const pass2Result = await v2.execute({
132
- date: targetDate,
133
- pass: 2,
134
- dryRun: false,
135
- logger
136
- });
137
-
138
- console.log('\nPass 2 results:');
139
- console.log(` Completed: ${pass2Result.summary.completed}`);
140
- console.log(` Skipped: ${pass2Result.summary.skipped}`);
141
- console.log(` Errors: ${pass2Result.summary.errors}`);
142
-
143
- if (pass2Result.completed.length > 0) {
144
- for (const c of pass2Result.completed) {
145
- console.log(`\nāœ… ${c.name}: ${c.resultCount} results in ${c.duration}ms`);
146
- }
147
- }
148
-
149
- if (pass2Result.errors.length > 0) {
150
- console.log('\nāŒ Errors:');
151
- for (const e of pass2Result.errors) {
152
- console.log(` - ${e.name}: ${e.error.substring(0, 200)}...`);
153
- }
154
- }
155
- }
156
-
157
- console.log('\n╔════════════════════════════════════════════════════════════╗');
158
- console.log('ā•‘ Test Complete ā•‘');
159
- console.log('ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•');
160
- }
161
-
162
- main().catch(e => {
163
- console.error('\nāŒ Test failed:', e.message);
164
- console.error(e.stack);
165
- process.exit(1);
166
- });