bulltrackers-module 1.0.105 → 1.0.106

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 (33) hide show
  1. package/README.MD +222 -222
  2. package/functions/appscript-api/helpers/errors.js +19 -19
  3. package/functions/appscript-api/index.js +58 -58
  4. package/functions/computation-system/helpers/orchestration_helpers.js +647 -113
  5. package/functions/computation-system/utils/data_loader.js +191 -191
  6. package/functions/computation-system/utils/utils.js +149 -254
  7. package/functions/core/utils/firestore_utils.js +433 -433
  8. package/functions/core/utils/pubsub_utils.js +53 -53
  9. package/functions/dispatcher/helpers/dispatch_helpers.js +47 -47
  10. package/functions/dispatcher/index.js +52 -52
  11. package/functions/etoro-price-fetcher/helpers/handler_helpers.js +124 -124
  12. package/functions/fetch-insights/helpers/handler_helpers.js +91 -91
  13. package/functions/generic-api/helpers/api_helpers.js +379 -379
  14. package/functions/generic-api/index.js +150 -150
  15. package/functions/invalid-speculator-handler/helpers/handler_helpers.js +75 -75
  16. package/functions/orchestrator/helpers/discovery_helpers.js +226 -226
  17. package/functions/orchestrator/helpers/update_helpers.js +92 -92
  18. package/functions/orchestrator/index.js +147 -147
  19. package/functions/price-backfill/helpers/handler_helpers.js +116 -123
  20. package/functions/social-orchestrator/helpers/orchestrator_helpers.js +61 -61
  21. package/functions/social-task-handler/helpers/handler_helpers.js +288 -288
  22. package/functions/task-engine/handler_creator.js +78 -78
  23. package/functions/task-engine/helpers/discover_helpers.js +125 -125
  24. package/functions/task-engine/helpers/update_helpers.js +118 -118
  25. package/functions/task-engine/helpers/verify_helpers.js +162 -162
  26. package/functions/task-engine/utils/firestore_batch_manager.js +258 -258
  27. package/index.js +105 -113
  28. package/package.json +45 -45
  29. package/functions/computation-system/computation_dependencies.json +0 -120
  30. package/functions/computation-system/helpers/worker_helpers.js +0 -340
  31. package/functions/computation-system/utils/computation_state_manager.js +0 -178
  32. package/functions/computation-system/utils/dependency_graph.js +0 -191
  33. package/functions/speculator-cleanup-orchestrator/helpers/cleanup_helpers.js +0 -160
@@ -1,151 +1,151 @@
1
- /**
2
- * @fileoverview Main entry point for the Generic API module.
3
- * Exports the 'createApiApp' main pipe function.
4
- * REFACTORED: /manifest endpoint now uses a dynamic "test harness"
5
- * to generate the schema without modifying calculation files.
6
- */
7
-
8
- const express = require('express');
9
- const cors = require('cors');
10
- const { FieldPath } = require('@google-cloud/firestore');
11
- const {
12
- buildCalculationMap,
13
- createApiHandler,
14
- getComputationStructure,
15
- getDynamicSchema // <-- IMPORT NEW HELPER
16
- } = require('./helpers/api_helpers.js');
17
-
18
- /**
19
- * Main pipe: pipe.api.createApiApp
20
- * Creates and configures the Express app for the Generic API.
21
- * @param {object} config - The Generic API V2 configuration object.
22
- * @param {object} dependencies - Shared dependencies { db, logger }.
23
- * @param {Object} unifiedCalculations - The calculations manifest from 'aiden-shared-calculations-unified'.
24
- * @returns {express.Application} The configured Express app.
25
- */
26
- function createApiApp(config, dependencies, unifiedCalculations) {
27
- const app = express();
28
- const { logger } = dependencies; // db is in dependencies
29
-
30
- // --- Pre-compute Calculation Map ---
31
- const calcMap = buildCalculationMap(unifiedCalculations);
32
-
33
- // --- Middleware ---
34
- app.use(cors({ origin: true }));
35
- app.use(express.json());
36
-
37
- // --- Main API Endpoint ---
38
- app.get('/', createApiHandler(config, dependencies, calcMap));
39
-
40
- // --- Health Check Endpoint ---
41
- app.get('/health', (req, res) => {
42
- res.status(200).send('OK');
43
- });
44
-
45
- // --- Debug Endpoint to list all computation keys ---
46
- app.get('/list-computations', (req, res) => {
47
- try {
48
- const computationKeys = Object.keys(calcMap);
49
- res.status(200).send({
50
- status: 'success',
51
- count: computationKeys.length,
52
- computations: computationKeys.sort(),
53
- });
54
- } catch (error) {
55
- logger.log('ERROR', 'API /list-computations failed.', { errorMessage: error.message });
56
- res.status(500).send({ status: 'error', message: 'An internal error occurred.' });
57
- }
58
- });
59
-
60
- // --- Debug Endpoint to get *stored* structure from Firestore ---
61
- app.get('/structure/:computationName', async (req, res) => {
62
- const { computationName } = req.params;
63
-
64
- // Call sub-pipe, passing dependencies
65
- const result = await getComputationStructure(computationName, calcMap, config, dependencies);
66
-
67
- if (result.status === 'error') {
68
- const statusCode = result.message.includes('not found') ? 404 : 500;
69
- return res.status(statusCode).send(result);
70
- }
71
-
72
- res.status(200).send(result);
73
- });
74
-
75
- // --- NEW: Fully Refactored Manifest Endpoint (Dynamic Test Run) ---
76
- app.get('/manifest', async (req, res) => {
77
- logger.log('INFO', 'API /manifest dynamic generation starting...');
78
- try {
79
- const manifest = {};
80
- let successCount = 0;
81
- const errors = [];
82
-
83
- // This logic iterates through the calculation module structure
84
- for (const category in unifiedCalculations) {
85
- for (const subKey in unifiedCalculations[category]) {
86
- const item = unifiedCalculations[category][subKey];
87
- let calcName = null;
88
- let CalcClass = null;
89
-
90
- // Handle nested 'historical' directory
91
- if (subKey === 'historical' && typeof item === 'object') {
92
- for (const name in item) {
93
- calcName = name;
94
- CalcClass = item[name];
95
- if (CalcClass && typeof CalcClass === 'function') {
96
- try {
97
- manifest[calcName] = {
98
- category: category,
99
- structure: await getDynamicSchema(CalcClass, calcName) // <-- DYNAMIC CALL
100
- };
101
- successCount++;
102
- } catch (e) { errors.push(`${category}/${calcName}: ${e.message}`); }
103
- }
104
- }
105
- }
106
- // Handle regular calc at root of category
107
- else if (typeof item === 'function') {
108
- calcName = subKey;
109
- CalcClass = item;
110
- if (CalcClass && typeof CalcClass === 'function') {
111
- try {
112
- manifest[calcName] = {
113
- category: category,
114
- structure: await getDynamicSchema(CalcClass, calcName) // <-- DYNAMIC CALL
115
- };
116
- successCount++;
117
- } catch (e) { errors.push(`${category}/${calcName}: ${e.message}`); }
118
- }
119
- }
120
- }
121
- }
122
-
123
- const totalComputations = Object.keys(calcMap).length;
124
- logger.log('INFO', `API /manifest complete. Generated schema for ${successCount}/${totalComputations} computations.`);
125
-
126
- res.status(200).send({
127
- status: 'success',
128
- summary: {
129
- source: 'computation_module_dynamic_test',
130
- totalComputations: totalComputations,
131
- schemasGenerated: successCount,
132
- schemasFailed: errors.length,
133
- },
134
- manifest: manifest,
135
- errors: errors.length > 0 ? errors : undefined,
136
- });
137
-
138
- } catch (error) {
139
- logger.log('ERROR', `API /manifest failed unexpectedly.`, { errorMessage: error.message, stack: error.stack });
140
- res.status(500).send({ status: 'error', message: `An internal error occurred while building the manifest.` });
141
- }
142
- });
143
-
144
- return app;
145
- }
146
-
147
- module.exports = {
148
- createApiApp,
149
- // Exporting helpers so they can be part of the pipe.api.helpers object
150
- helpers: require('./helpers/api_helpers'),
1
+ /**
2
+ * @fileoverview Main entry point for the Generic API module.
3
+ * Exports the 'createApiApp' main pipe function.
4
+ * REFACTORED: /manifest endpoint now uses a dynamic "test harness"
5
+ * to generate the schema without modifying calculation files.
6
+ */
7
+
8
+ const express = require('express');
9
+ const cors = require('cors');
10
+ const { FieldPath } = require('@google-cloud/firestore');
11
+ const {
12
+ buildCalculationMap,
13
+ createApiHandler,
14
+ getComputationStructure,
15
+ getDynamicSchema // <-- IMPORT NEW HELPER
16
+ } = require('./helpers/api_helpers.js');
17
+
18
+ /**
19
+ * Main pipe: pipe.api.createApiApp
20
+ * Creates and configures the Express app for the Generic API.
21
+ * @param {object} config - The Generic API V2 configuration object.
22
+ * @param {object} dependencies - Shared dependencies { db, logger }.
23
+ * @param {Object} unifiedCalculations - The calculations manifest from 'aiden-shared-calculations-unified'.
24
+ * @returns {express.Application} The configured Express app.
25
+ */
26
+ function createApiApp(config, dependencies, unifiedCalculations) {
27
+ const app = express();
28
+ const { logger } = dependencies; // db is in dependencies
29
+
30
+ // --- Pre-compute Calculation Map ---
31
+ const calcMap = buildCalculationMap(unifiedCalculations);
32
+
33
+ // --- Middleware ---
34
+ app.use(cors({ origin: true }));
35
+ app.use(express.json());
36
+
37
+ // --- Main API Endpoint ---
38
+ app.get('/', createApiHandler(config, dependencies, calcMap));
39
+
40
+ // --- Health Check Endpoint ---
41
+ app.get('/health', (req, res) => {
42
+ res.status(200).send('OK');
43
+ });
44
+
45
+ // --- Debug Endpoint to list all computation keys ---
46
+ app.get('/list-computations', (req, res) => {
47
+ try {
48
+ const computationKeys = Object.keys(calcMap);
49
+ res.status(200).send({
50
+ status: 'success',
51
+ count: computationKeys.length,
52
+ computations: computationKeys.sort(),
53
+ });
54
+ } catch (error) {
55
+ logger.log('ERROR', 'API /list-computations failed.', { errorMessage: error.message });
56
+ res.status(500).send({ status: 'error', message: 'An internal error occurred.' });
57
+ }
58
+ });
59
+
60
+ // --- Debug Endpoint to get *stored* structure from Firestore ---
61
+ app.get('/structure/:computationName', async (req, res) => {
62
+ const { computationName } = req.params;
63
+
64
+ // Call sub-pipe, passing dependencies
65
+ const result = await getComputationStructure(computationName, calcMap, config, dependencies);
66
+
67
+ if (result.status === 'error') {
68
+ const statusCode = result.message.includes('not found') ? 404 : 500;
69
+ return res.status(statusCode).send(result);
70
+ }
71
+
72
+ res.status(200).send(result);
73
+ });
74
+
75
+ // --- NEW: Fully Refactored Manifest Endpoint (Dynamic Test Run) ---
76
+ app.get('/manifest', async (req, res) => {
77
+ logger.log('INFO', 'API /manifest dynamic generation starting...');
78
+ try {
79
+ const manifest = {};
80
+ let successCount = 0;
81
+ const errors = [];
82
+
83
+ // This logic iterates through the calculation module structure
84
+ for (const category in unifiedCalculations) {
85
+ for (const subKey in unifiedCalculations[category]) {
86
+ const item = unifiedCalculations[category][subKey];
87
+ let calcName = null;
88
+ let CalcClass = null;
89
+
90
+ // Handle nested 'historical' directory
91
+ if (subKey === 'historical' && typeof item === 'object') {
92
+ for (const name in item) {
93
+ calcName = name;
94
+ CalcClass = item[name];
95
+ if (CalcClass && typeof CalcClass === 'function') {
96
+ try {
97
+ manifest[calcName] = {
98
+ category: category,
99
+ structure: await getDynamicSchema(CalcClass, calcName) // <-- DYNAMIC CALL
100
+ };
101
+ successCount++;
102
+ } catch (e) { errors.push(`${category}/${calcName}: ${e.message}`); }
103
+ }
104
+ }
105
+ }
106
+ // Handle regular calc at root of category
107
+ else if (typeof item === 'function') {
108
+ calcName = subKey;
109
+ CalcClass = item;
110
+ if (CalcClass && typeof CalcClass === 'function') {
111
+ try {
112
+ manifest[calcName] = {
113
+ category: category,
114
+ structure: await getDynamicSchema(CalcClass, calcName) // <-- DYNAMIC CALL
115
+ };
116
+ successCount++;
117
+ } catch (e) { errors.push(`${category}/${calcName}: ${e.message}`); }
118
+ }
119
+ }
120
+ }
121
+ }
122
+
123
+ const totalComputations = Object.keys(calcMap).length;
124
+ logger.log('INFO', `API /manifest complete. Generated schema for ${successCount}/${totalComputations} computations.`);
125
+
126
+ res.status(200).send({
127
+ status: 'success',
128
+ summary: {
129
+ source: 'computation_module_dynamic_test',
130
+ totalComputations: totalComputations,
131
+ schemasGenerated: successCount,
132
+ schemasFailed: errors.length,
133
+ },
134
+ manifest: manifest,
135
+ errors: errors.length > 0 ? errors : undefined,
136
+ });
137
+
138
+ } catch (error) {
139
+ logger.log('ERROR', `API /manifest failed unexpectedly.`, { errorMessage: error.message, stack: error.stack });
140
+ res.status(500).send({ status: 'error', message: `An internal error occurred while building the manifest.` });
141
+ }
142
+ });
143
+
144
+ return app;
145
+ }
146
+
147
+ module.exports = {
148
+ createApiApp,
149
+ // Exporting helpers so they can be part of the pipe.api.helpers object
150
+ helpers: require('./helpers/api_helpers'),
151
151
  };
@@ -1,75 +1,75 @@
1
- /**
2
- * @fileoverview Main pipe: pipe.maintenance.handleInvalidSpeculator
3
- * REFACTORED: Now stateless and receives dependencies.
4
- */
5
- const { FieldValue } = require('@google-cloud/firestore');
6
-
7
- /**
8
- * Main pipe: pipe.maintenance.handleInvalidSpeculator
9
- * @param {object} message The Pub/Sub message.
10
- * @param {object} context The message context.
11
- * @param {object} config The configuration object.
12
- * @param {object} dependencies - Contains db, logger.
13
- */
14
- exports.handleInvalidSpeculator = async (message, context, config, dependencies) => {
15
- const { db, logger } = dependencies;
16
- try {
17
- const { invalidCids } = JSON.parse(Buffer.from(message.data, 'base64').toString());
18
-
19
- if (!invalidCids || invalidCids.length === 0) {
20
- logger.log('WARN', 'Received message with no invalid CIDs. Nothing to do.');
21
- return;
22
- }
23
-
24
- const collectionRef = db.collection(config.invalidSpeculatorsCollectionName); // Use db
25
- const maxPerDoc = config.maxInvalidUsersPerDoc;
26
-
27
- const querySnapshot = await collectionRef
28
- .where('userCount', '<', maxPerDoc)
29
- .limit(10)
30
- .get();
31
-
32
- let targetDocRef;
33
-
34
- if (!querySnapshot.empty) {
35
- const randomIndex = Math.floor(Math.random() * querySnapshot.docs.length);
36
- targetDocRef = querySnapshot.docs[randomIndex].ref;
37
- } else {
38
- targetDocRef = collectionRef.doc();
39
- }
40
-
41
- // Use db from dependencies
42
- await db.runTransaction(async (transaction) => {
43
- const doc = await transaction.get(targetDocRef);
44
-
45
- const updates = {};
46
- let newUsersCount = 0;
47
-
48
- if (!doc.exists) {
49
- updates.userCount = 0;
50
- }
51
-
52
- for (const cid of invalidCids) {
53
- const fieldPath = `users.${cid}`;
54
- if (!doc.exists || !doc.data().users || !doc.data().users[cid]) {
55
- updates[fieldPath] = true;
56
- newUsersCount++;
57
- }
58
- }
59
-
60
- if (newUsersCount > 0) {
61
- updates.userCount = FieldValue.increment(newUsersCount);
62
- transaction.set(targetDocRef, updates, { merge: true });
63
- }
64
- });
65
-
66
- logger.log('SUCCESS', `Successfully stored ${invalidCids.length} invalid speculator IDs in document ${targetDocRef.id}.`);
67
-
68
- } catch (error) {
69
- logger.log('ERROR', 'FATAL Error in Invalid Speculator Handler', {
70
- errorMessage: error.message,
71
- errorStack: error.stack
72
- });
73
- throw error;
74
- }
75
- };
1
+ /**
2
+ * @fileoverview Main pipe: pipe.maintenance.handleInvalidSpeculator
3
+ * REFACTORED: Now stateless and receives dependencies.
4
+ */
5
+ const { FieldValue } = require('@google-cloud/firestore');
6
+
7
+ /**
8
+ * Main pipe: pipe.maintenance.handleInvalidSpeculator
9
+ * @param {object} message The Pub/Sub message.
10
+ * @param {object} context The message context.
11
+ * @param {object} config The configuration object.
12
+ * @param {object} dependencies - Contains db, logger.
13
+ */
14
+ exports.handleInvalidSpeculator = async (message, context, config, dependencies) => {
15
+ const { db, logger } = dependencies;
16
+ try {
17
+ const { invalidCids } = JSON.parse(Buffer.from(message.data, 'base64').toString());
18
+
19
+ if (!invalidCids || invalidCids.length === 0) {
20
+ logger.log('WARN', 'Received message with no invalid CIDs. Nothing to do.');
21
+ return;
22
+ }
23
+
24
+ const collectionRef = db.collection(config.invalidSpeculatorsCollectionName); // Use db
25
+ const maxPerDoc = config.maxInvalidUsersPerDoc;
26
+
27
+ const querySnapshot = await collectionRef
28
+ .where('userCount', '<', maxPerDoc)
29
+ .limit(10)
30
+ .get();
31
+
32
+ let targetDocRef;
33
+
34
+ if (!querySnapshot.empty) {
35
+ const randomIndex = Math.floor(Math.random() * querySnapshot.docs.length);
36
+ targetDocRef = querySnapshot.docs[randomIndex].ref;
37
+ } else {
38
+ targetDocRef = collectionRef.doc();
39
+ }
40
+
41
+ // Use db from dependencies
42
+ await db.runTransaction(async (transaction) => {
43
+ const doc = await transaction.get(targetDocRef);
44
+
45
+ const updates = {};
46
+ let newUsersCount = 0;
47
+
48
+ if (!doc.exists) {
49
+ updates.userCount = 0;
50
+ }
51
+
52
+ for (const cid of invalidCids) {
53
+ const fieldPath = `users.${cid}`;
54
+ if (!doc.exists || !doc.data().users || !doc.data().users[cid]) {
55
+ updates[fieldPath] = true;
56
+ newUsersCount++;
57
+ }
58
+ }
59
+
60
+ if (newUsersCount > 0) {
61
+ updates.userCount = FieldValue.increment(newUsersCount);
62
+ transaction.set(targetDocRef, updates, { merge: true });
63
+ }
64
+ });
65
+
66
+ logger.log('SUCCESS', `Successfully stored ${invalidCids.length} invalid speculator IDs in document ${targetDocRef.id}.`);
67
+
68
+ } catch (error) {
69
+ logger.log('ERROR', 'FATAL Error in Invalid Speculator Handler', {
70
+ errorMessage: error.message,
71
+ errorStack: error.stack
72
+ });
73
+ throw error;
74
+ }
75
+ };