bulltrackers-module 1.0.739 → 1.0.741

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.
@@ -0,0 +1,88 @@
1
+ /**
2
+ * @fileoverview Core System API
3
+ * Contains the business logic and orchestrator management.
4
+ * Separated from index.js to prevent circular dependencies with handlers.
5
+ */
6
+
7
+ const { Orchestrator } = require('./framework');
8
+ const config = require('./config/bulltrackers.config');
9
+ const { ManifestBuilder } = require('./framework/core/Manifest');
10
+ const { Computation } = require('./framework/core/Computation');
11
+
12
+ // Add computations to config
13
+ config.computations = [
14
+ require('./computations/UserPortfolioSummary'),
15
+ require('./computations/PopularInvestorProfileMetrics'),
16
+ require('./computations/PopularInvestorRiskAssessment'),
17
+ require('./computations/PopularInvestorRiskMetrics'),
18
+ // Add more computations here as they're migrated
19
+ ];
20
+
21
+ // Singleton orchestrator instance
22
+ let orchestrator = null;
23
+
24
+ async function getOrchestrator(customConfig = null, logger = null) {
25
+ if (!orchestrator || customConfig) {
26
+ const cfg = customConfig || config;
27
+ orchestrator = new Orchestrator(cfg, logger);
28
+ }
29
+ return orchestrator;
30
+ }
31
+
32
+ async function analyze(options) {
33
+ const { date, config: customConfig = null, logger = null } = options;
34
+ const orch = await getOrchestrator(customConfig, logger);
35
+ return orch.analyze({ date });
36
+ }
37
+
38
+ async function execute(options) {
39
+ const { date, pass = null, computation = null, dryRun = false, entities = null, config: customConfig = null, logger = null } = options;
40
+ const orch = await getOrchestrator(customConfig, logger);
41
+ return orch.execute({ date, pass, computation, dryRun, entities });
42
+ }
43
+
44
+ async function runComputation(options) {
45
+ const { date, computation, entityIds = null, dryRun = false, force = false, useWorkerPool, config: customConfig = null, logger = null } = options;
46
+ const orch = await getOrchestrator(customConfig, logger);
47
+
48
+ if (!orch.manifest) await orch.initialize();
49
+
50
+ const normalizedName = computation.toLowerCase().replace(/[^a-z0-9]/g, '');
51
+ const entry = orch.manifest.find(c => c.name === normalizedName);
52
+
53
+ if (!entry) throw new Error(`Computation not found: ${computation}`);
54
+
55
+ return orch.runSingle(entry, date, { entityIds, dryRun, force, useWorkerPool });
56
+ }
57
+
58
+ async function getManifest(options = {}) {
59
+ const { config: customConfig = null, logger = null } = options;
60
+ const orch = await getOrchestrator(customConfig, logger);
61
+ if (!orch.manifest) await orch.initialize();
62
+ return orch.manifest;
63
+ }
64
+
65
+ async function warmCache(options = {}) {
66
+ const { config: customConfig = null, logger = null } = options;
67
+ const orch = await getOrchestrator(customConfig, logger);
68
+ const allTables = Object.keys(orch.config.tables);
69
+ return orch.schemaRegistry.warmCache(allTables);
70
+ }
71
+
72
+ function reset() {
73
+ orchestrator = null;
74
+ }
75
+
76
+ module.exports = {
77
+ analyze,
78
+ execute,
79
+ runComputation,
80
+ getManifest,
81
+ warmCache,
82
+ reset,
83
+ getOrchestrator,
84
+ config,
85
+ ManifestBuilder,
86
+ Computation,
87
+ ...require('./framework')
88
+ };
@@ -1,9 +1,35 @@
1
+ Here is the updated `admin.md` file. I have replaced the hardcoded placeholder URL with a dynamic variable (`$FUNCTION_URL`) and corrected the token generation command to remove the invalid `--audiences` flag.
2
+
3
+ This version is copy-paste ready for your terminal.
4
+
5
+ ### `computation-system-v2/docs/admin.md`
6
+
7
+ ```markdown
1
8
  # Admin Test Endpoint
2
9
 
3
10
  ## Deploy
4
11
 
5
12
  ```bash
6
13
  node deploy.mjs ComputeAdminTest
14
+
15
+ ```
16
+
17
+ ## Setup (Run Before Testing)
18
+
19
+ First, retrieve your function's actual URL and generate an authentication token.
20
+
21
+ ```bash
22
+ # 1. Get the Function URL dynamically
23
+ # (Adjust region if not in europe-west1)
24
+ FUNCTION_URL=$(gcloud functions describe compute-admin-test \
25
+ --region=europe-west1 \
26
+ --format="value(serviceConfig.uri)")
27
+
28
+ # 2. Generate an Identity Token (Standard User account)
29
+ TOKEN=$(gcloud auth print-identity-token)
30
+
31
+ echo "Targeting: $FUNCTION_URL"
32
+
7
33
  ```
8
34
 
9
35
  ## Usage Examples
@@ -11,81 +37,81 @@ node deploy.mjs ComputeAdminTest
11
37
  ### 1. Check System Status
12
38
 
13
39
  ```bash
14
- TOKEN=$(gcloud auth print-identity-token --audiences="https://europe-west1-stocks-12345.cloudfunctions.net/compute-admin-test")
15
-
16
- curl -X POST \
17
- "https://europe-west1-stocks-12345.cloudfunctions.net/compute-admin-test" \
40
+ curl -X POST "$FUNCTION_URL" \
18
41
  -H "Authorization: Bearer $TOKEN" \
19
42
  -H "Content-Type: application/json" \
20
43
  -d '{"action": "status"}'
44
+
21
45
  ```
22
46
 
23
47
  ### 2. Analyze What Would Run
24
48
 
25
49
  ```bash
26
- curl -X POST \
27
- "https://europe-west1-stocks-12345.cloudfunctions.net/compute-admin-test" \
50
+ curl -X POST "$FUNCTION_URL" \
28
51
  -H "Authorization: Bearer $TOKEN" \
29
52
  -H "Content-Type: application/json" \
30
53
  -d '{"action": "analyze", "date": "2026-01-25"}'
54
+
31
55
  ```
32
56
 
33
57
  ### 3. Run Full Computation
34
58
 
35
59
  ```bash
36
- curl -X POST \
37
- "https://europe-west1-stocks-12345.cloudfunctions.net/compute-admin-test" \
60
+ curl -X POST "$FUNCTION_URL" \
38
61
  -H "Authorization: Bearer $TOKEN" \
39
62
  -H "Content-Type: application/json" \
40
63
  -d '{"action": "run", "computation": "UserPortfolioSummary", "date": "2026-01-25", "force": true}'
64
+
41
65
  ```
42
66
 
43
67
  ### 4. Run Limited Test
44
68
 
45
69
  ```bash
46
- curl -X POST \
47
- "https://europe-west1-stocks-12345.cloudfunctions.net/compute-admin-test" \
70
+ curl -X POST "$FUNCTION_URL" \
48
71
  -H "Authorization: Bearer $TOKEN" \
49
72
  -H "Content-Type: application/json" \
50
73
  -d '{"action": "run_limited", "computation": "UserPortfolioSummary", "date": "2026-01-25", "limit": 5}'
74
+
51
75
  ```
52
76
 
53
77
  ### 5. Test Specific Entities
54
78
 
55
79
  ```bash
56
- curl -X POST \
57
- "https://europe-west1-stocks-12345.cloudfunctions.net/compute-admin-test" \
80
+ curl -X POST "$FUNCTION_URL" \
58
81
  -H "Authorization: Bearer $TOKEN" \
59
82
  -H "Content-Type: application/json" \
60
83
  -d '{"action": "run", "computation": "UserPortfolioSummary", "date": "2026-01-25", "entityIds": ["user-123", "user-456"], "force": true}'
84
+
61
85
  ```
62
86
 
63
87
  ### 6. Test Worker Directly
64
88
 
65
89
  ```bash
66
- curl -X POST \
67
- "https://europe-west1-stocks-12345.cloudfunctions.net/compute-admin-test" \
90
+ curl -X POST "$FUNCTION_URL" \
68
91
  -H "Authorization: Bearer $TOKEN" \
69
92
  -H "Content-Type: application/json" \
70
93
  -d '{"action": "test_worker", "computation": "UserPortfolioSummary", "date": "2026-01-25", "entityIds": ["user-123"]}'
94
+
71
95
  ```
72
96
 
73
97
  ### 7. Test with Worker Pool Override
74
98
 
75
99
  ```bash
76
- curl -X POST \
77
- "https://europe-west1-stocks-12345.cloudfunctions.net/compute-admin-test" \
100
+ curl -X POST "$FUNCTION_URL" \
78
101
  -H "Authorization: Bearer $TOKEN" \
79
102
  -H "Content-Type: application/json" \
80
103
  -d '{"action": "run", "computation": "UserPortfolioSummary", "date": "2026-01-25", "useWorkerPool": true, "force": true}'
104
+
81
105
  ```
82
106
 
83
107
  ## Available Actions
84
108
 
85
109
  | Action | Description |
86
- |--------|-------------|
110
+ | --- | --- |
87
111
  | `status` | List all computations and system status |
88
112
  | `analyze` | Check what would run for a given date |
89
113
  | `run` | Execute a full computation |
90
114
  | `run_limited` | Execute on N random entities (safer for testing) |
91
- | `test_worker` | Direct test of worker function logic |
115
+ | `test_worker` | Direct test of worker function logic |
116
+
117
+ ```
@@ -1,23 +1,20 @@
1
1
  /**
2
2
  * @fileoverview Admin Test Endpoint for Computation System
3
- *
4
- * SECURITY: This endpoint is protected by GCP IAM (requireAuth: true).
3
+ * * SECURITY: This endpoint is protected by GCP IAM (requireAuth: true).
5
4
  * Only service accounts and users with cloudfunctions.invoker can access it.
6
- *
7
- * PURPOSE:
5
+ * * PURPOSE:
8
6
  * - Test computations in production without waiting for schedule
9
7
  * - Force re-runs of computations (bypass hash checks)
10
8
  * - Test worker pool functionality
11
9
  * - Run on specific entities for debugging
12
- *
13
- * USAGE:
14
- * curl -X POST https://REGION-PROJECT.cloudfunctions.net/compute-admin-test \
15
- * -H "Authorization: Bearer $(gcloud auth print-identity-token)" \
16
- * -H "Content-Type: application/json" \
17
- * -d '{"action": "run", "computation": "UserPortfolioSummary", "date": "2026-01-25"}'
10
+ * * USAGE:
11
+ * curl -X POST https://REGION-PROJECT.cloudfunctions.net/compute-admin-test \
12
+ * -H "Authorization: Bearer $(gcloud auth print-identity-token)" \
13
+ * -H "Content-Type: application/json" \
14
+ * -d '{"action": "run", "computation": "UserPortfolioSummary", "date": "2026-01-25"}'
18
15
  */
19
16
 
20
- const system = require('../index');
17
+ const system = require('../core-api');
21
18
 
22
19
  /**
23
20
  * Admin test handler.
@@ -104,15 +101,31 @@ async function adminTestHandler(req, res) {
104
101
  console.log(`[AdminTest] Running ${computation} for ${date}...`);
105
102
  console.log(`[AdminTest] Options: force=${force}, dryRun=${dryRun}, entityIds=${entityIds?.join(',') || 'all'}`);
106
103
 
107
- const result = await system.runComputation({
104
+ // Prepare run options
105
+ const runOptions = {
108
106
  date,
109
107
  computation,
110
108
  entityIds: entityIds || null,
111
109
  dryRun,
112
110
  force,
113
- // Pass worker pool override explicitly (avoids env var caching issues)
114
111
  useWorkerPool
115
- });
112
+ };
113
+
114
+ // [FIX] If forcing worker pool, inject config to enable it dynamically
115
+ // This prevents Orchestrator from ignoring the request if default config has enabled: false
116
+ if (useWorkerPool) {
117
+ const baseConfig = system.config;
118
+ runOptions.config = {
119
+ ...baseConfig,
120
+ workerPool: {
121
+ ...(baseConfig.workerPool || {}),
122
+ enabled: true
123
+ }
124
+ };
125
+ console.log('[AdminTest] Injecting config to FORCE enable RemoteTaskRunner');
126
+ }
127
+
128
+ const result = await system.runComputation(runOptions);
116
129
 
117
130
  const duration = Date.now() - startTime;
118
131
 
@@ -156,14 +169,28 @@ async function adminTestHandler(req, res) {
156
169
 
157
170
  console.log(`[AdminTest] Running LIMITED test: ${sampleEntities.length} entities`);
158
171
 
159
- const result = await system.runComputation({
172
+ const runOptions = {
160
173
  date,
161
174
  computation,
162
175
  entityIds: sampleEntities,
163
176
  dryRun,
164
177
  force,
165
- useWorkerPool // Pass worker pool override
166
- });
178
+ useWorkerPool
179
+ };
180
+
181
+ // Apply the same fix for run_limited if needed
182
+ if (useWorkerPool) {
183
+ const baseConfig = system.config;
184
+ runOptions.config = {
185
+ ...baseConfig,
186
+ workerPool: {
187
+ ...(baseConfig.workerPool || {}),
188
+ enabled: true
189
+ }
190
+ };
191
+ }
192
+
193
+ const result = await system.runComputation(runOptions);
167
194
 
168
195
  const duration = Date.now() - startTime;
169
196
 
@@ -324,4 +351,4 @@ async function getSampleEntities(computation, date, limit) {
324
351
  }
325
352
  }
326
353
 
327
- module.exports = { adminTestHandler };
354
+ module.exports = { adminTestHandler };
@@ -1,184 +1,12 @@
1
1
  /**
2
2
  * @fileoverview Computation System v2 Entry Point
3
- * * Usage:
4
- * const { execute, analyze, runComputation } = require('./computation-system-v2');
5
- * * // Analyze what can run
6
- * const report = await analyze({ date: '2026-01-24' });
7
- * * // Execute computations (Monolith/Scheduler mode)
8
- * const result = await execute({ date: '2026-01-24' });
9
- * * // Run single computation (Worker mode)
10
- * const task = await runComputation({
11
- * date: '2026-01-24',
12
- * computation: 'UserPortfolioSummary'
13
- * });
3
+ * Exports both the Core API and the Cloud Function Handlers.
14
4
  */
15
5
 
16
- const { Orchestrator } = require('./framework');
17
- const config = require('./config/bulltrackers.config');
18
- const { ManifestBuilder } = require('./framework/core/Manifest');
19
- const { Computation } = require('./framework/core/Computation');
20
-
21
- // Add computations to config
22
- // These are loaded from computation-system-v2/computations folder
23
- config.computations = [
24
- require('./computations/UserPortfolioSummary'),
25
- require('./computations/PopularInvestorProfileMetrics'),
26
- require('./computations/PopularInvestorRiskAssessment'),
27
- require('./computations/PopularInvestorRiskMetrics'),
28
- // Add more computations here as they're migrated
29
- ];
30
-
31
- // Singleton orchestrator instance
32
- let orchestrator = null;
33
-
34
- /**
35
- * Get or create the orchestrator instance.
36
- * @param {Object} [customConfig] - Override default config
37
- * @param {Object} [logger] - Custom logger
38
- * @returns {Promise<Orchestrator>}
39
- */
40
- async function getOrchestrator(customConfig = null, logger = null) {
41
- if (!orchestrator || customConfig) {
42
- const cfg = customConfig || config;
43
- orchestrator = new Orchestrator(cfg, logger);
44
- // Note: Orchestrator initializes lazily on first execute/analyze call,
45
- // but we can force it here if needed.
46
- }
47
- return orchestrator;
48
- }
49
-
50
- /**
51
- * Analyze what can run for a given date.
52
- * @param {Object} options
53
- * @param {string} options.date - Target date (YYYY-MM-DD)
54
- * @param {Object} [options.config] - Override config
55
- * @param {Object} [options.logger] - Custom logger
56
- * @returns {Promise<Object>} Analysis report
57
- */
58
- async function analyze(options) {
59
- const { date, config: customConfig = null, logger = null } = options;
60
- const orch = await getOrchestrator(customConfig, logger);
61
- return orch.analyze({ date });
62
- }
63
-
64
- /**
65
- * Execute computations for a given date.
66
- * (Used by Scheduler or Monolithic runs)
67
- */
68
- async function execute(options) {
69
- const {
70
- date,
71
- pass = null,
72
- computation = null,
73
- dryRun = false,
74
- entities = null,
75
- config: customConfig = null,
76
- logger = null
77
- } = options;
78
-
79
- const orch = await getOrchestrator(customConfig, logger);
80
- return orch.execute({ date, pass, computation, dryRun, entities });
81
- }
82
-
83
- /**
84
- * WORKER ENTRY POINT: Run a single computation.
85
- * (Used by Cloud Functions / Dispatcher)
86
- *
87
- * @param {Object} options
88
- * @param {string} options.date - Target date (YYYY-MM-DD)
89
- * @param {string} options.computation - Computation name
90
- * @param {string[]} [options.entityIds] - Specific entities to run (null = all)
91
- * @param {boolean} [options.dryRun] - If true, don't persist results
92
- * @param {boolean} [options.force] - If true, bypass up-to-date checks
93
- * @param {boolean} [options.useWorkerPool] - Override worker pool setting (undefined = use config)
94
- * @param {Object} [options.config] - Override config
95
- * @param {Object} [options.logger] - Custom logger
96
- */
97
- async function runComputation(options) {
98
- const {
99
- date,
100
- computation,
101
- entityIds = null,
102
- dryRun = false,
103
- force = false,
104
- useWorkerPool, // Runtime override for worker pool
105
- config: customConfig = null,
106
- logger = null
107
- } = options;
108
-
109
- const orch = await getOrchestrator(customConfig, logger);
110
-
111
- // 1. Ensure manifest is built
112
- if (!orch.manifest) await orch.initialize();
113
-
114
- // 2. Find the specific entry
115
- // We normalize to handle case-insensitivity
116
- const normalizedName = computation.toLowerCase().replace(/[^a-z0-9]/g, '');
117
- const entry = orch.manifest.find(c => c.name === normalizedName);
118
-
119
- if (!entry) {
120
- throw new Error(`Computation not found: ${computation}`);
121
- }
122
-
123
- // 3. Delegate to Orchestrator's runSingle
124
- // This handles dependencies, data fetching, middleware, etc.
125
- return orch.runSingle(entry, date, {
126
- entityIds,
127
- dryRun,
128
- force,
129
- useWorkerPool // Pass override to Orchestrator
130
- });
131
- }
132
-
133
- /**
134
- * Get the manifest (list of all computations with metadata).
135
- */
136
- async function getManifest(options = {}) {
137
- const { config: customConfig = null, logger = null } = options;
138
- const orch = await getOrchestrator(customConfig, logger);
139
- if (!orch.manifest) await orch.initialize();
140
- return orch.manifest;
141
- }
142
-
143
- /**
144
- * Warm the schema cache for all tables.
145
- */
146
- async function warmCache(options = {}) {
147
- const { config: customConfig = null, logger = null } = options;
148
- const orch = await getOrchestrator(customConfig, logger);
149
- const allTables = Object.keys(orch.config.tables);
150
- return orch.schemaRegistry.warmCache(allTables);
151
- }
152
-
153
- /**
154
- * Reset the singleton (useful for testing).
155
- */
156
- function reset() {
157
- orchestrator = null;
158
- }
159
-
160
- // Import handlers for Cloud Functions
6
+ const coreApi = require('./core-api');
161
7
  const handlers = require('./handlers');
162
8
 
163
9
  module.exports = {
164
- // Main API
165
- analyze,
166
- execute,
167
- ManifestBuilder,
168
- Computation,
169
-
170
- runComputation, // <--- New Method
171
- getManifest,
172
- warmCache,
173
- reset,
174
-
175
- // For advanced usage
176
- getOrchestrator,
177
- config,
178
-
179
- // Cloud Function handlers
180
- ...handlers,
181
-
182
- // Re-export framework components
183
- ...require('./framework')
10
+ ...coreApi,
11
+ ...handlers
184
12
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bulltrackers-module",
3
- "version": "1.0.739",
3
+ "version": "1.0.741",
4
4
  "description": "Helper Functions for Bulltrackers.",
5
5
  "main": "index.js",
6
6
  "files": [