@zintrust/workers 0.1.27
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/README.md +861 -0
- package/dist/AnomalyDetection.d.ts +102 -0
- package/dist/AnomalyDetection.js +321 -0
- package/dist/AutoScaler.d.ts +127 -0
- package/dist/AutoScaler.js +425 -0
- package/dist/BroadcastWorker.d.ts +21 -0
- package/dist/BroadcastWorker.js +24 -0
- package/dist/CanaryController.d.ts +103 -0
- package/dist/CanaryController.js +380 -0
- package/dist/ChaosEngineering.d.ts +79 -0
- package/dist/ChaosEngineering.js +216 -0
- package/dist/CircuitBreaker.d.ts +106 -0
- package/dist/CircuitBreaker.js +374 -0
- package/dist/ClusterLock.d.ts +90 -0
- package/dist/ClusterLock.js +385 -0
- package/dist/ComplianceManager.d.ts +177 -0
- package/dist/ComplianceManager.js +556 -0
- package/dist/DatacenterOrchestrator.d.ts +133 -0
- package/dist/DatacenterOrchestrator.js +404 -0
- package/dist/DeadLetterQueue.d.ts +122 -0
- package/dist/DeadLetterQueue.js +539 -0
- package/dist/HealthMonitor.d.ts +42 -0
- package/dist/HealthMonitor.js +301 -0
- package/dist/MultiQueueWorker.d.ts +89 -0
- package/dist/MultiQueueWorker.js +277 -0
- package/dist/NotificationWorker.d.ts +21 -0
- package/dist/NotificationWorker.js +23 -0
- package/dist/Observability.d.ts +153 -0
- package/dist/Observability.js +530 -0
- package/dist/PluginManager.d.ts +123 -0
- package/dist/PluginManager.js +392 -0
- package/dist/PriorityQueue.d.ts +117 -0
- package/dist/PriorityQueue.js +244 -0
- package/dist/ResourceMonitor.d.ts +164 -0
- package/dist/ResourceMonitor.js +605 -0
- package/dist/SLAMonitor.d.ts +110 -0
- package/dist/SLAMonitor.js +274 -0
- package/dist/WorkerFactory.d.ts +193 -0
- package/dist/WorkerFactory.js +1507 -0
- package/dist/WorkerInit.d.ts +85 -0
- package/dist/WorkerInit.js +223 -0
- package/dist/WorkerMetrics.d.ts +114 -0
- package/dist/WorkerMetrics.js +509 -0
- package/dist/WorkerRegistry.d.ts +145 -0
- package/dist/WorkerRegistry.js +319 -0
- package/dist/WorkerShutdown.d.ts +61 -0
- package/dist/WorkerShutdown.js +159 -0
- package/dist/WorkerVersioning.d.ts +107 -0
- package/dist/WorkerVersioning.js +300 -0
- package/dist/build-manifest.json +462 -0
- package/dist/config/workerConfig.d.ts +3 -0
- package/dist/config/workerConfig.js +19 -0
- package/dist/createQueueWorker.d.ts +23 -0
- package/dist/createQueueWorker.js +113 -0
- package/dist/dashboard/index.d.ts +1 -0
- package/dist/dashboard/index.js +1 -0
- package/dist/dashboard/types.d.ts +117 -0
- package/dist/dashboard/types.js +1 -0
- package/dist/dashboard/workers-api.d.ts +4 -0
- package/dist/dashboard/workers-api.js +638 -0
- package/dist/dashboard/workers-dashboard-ui.d.ts +3 -0
- package/dist/dashboard/workers-dashboard-ui.js +1026 -0
- package/dist/dashboard/workers-dashboard.d.ts +4 -0
- package/dist/dashboard/workers-dashboard.js +904 -0
- package/dist/helper/index.d.ts +5 -0
- package/dist/helper/index.js +10 -0
- package/dist/http/WorkerApiController.d.ts +38 -0
- package/dist/http/WorkerApiController.js +312 -0
- package/dist/http/WorkerController.d.ts +374 -0
- package/dist/http/WorkerController.js +1351 -0
- package/dist/http/middleware/CustomValidation.d.ts +92 -0
- package/dist/http/middleware/CustomValidation.js +270 -0
- package/dist/http/middleware/DatacenterValidator.d.ts +3 -0
- package/dist/http/middleware/DatacenterValidator.js +94 -0
- package/dist/http/middleware/EditWorkerValidation.d.ts +7 -0
- package/dist/http/middleware/EditWorkerValidation.js +55 -0
- package/dist/http/middleware/FeaturesValidator.d.ts +3 -0
- package/dist/http/middleware/FeaturesValidator.js +60 -0
- package/dist/http/middleware/InfrastructureValidator.d.ts +31 -0
- package/dist/http/middleware/InfrastructureValidator.js +226 -0
- package/dist/http/middleware/OptionsValidator.d.ts +3 -0
- package/dist/http/middleware/OptionsValidator.js +112 -0
- package/dist/http/middleware/PayloadSanitizer.d.ts +7 -0
- package/dist/http/middleware/PayloadSanitizer.js +42 -0
- package/dist/http/middleware/ProcessorPathSanitizer.d.ts +3 -0
- package/dist/http/middleware/ProcessorPathSanitizer.js +74 -0
- package/dist/http/middleware/QueueNameSanitizer.d.ts +3 -0
- package/dist/http/middleware/QueueNameSanitizer.js +45 -0
- package/dist/http/middleware/ValidateDriver.d.ts +7 -0
- package/dist/http/middleware/ValidateDriver.js +20 -0
- package/dist/http/middleware/VersionSanitizer.d.ts +3 -0
- package/dist/http/middleware/VersionSanitizer.js +25 -0
- package/dist/http/middleware/WorkerNameSanitizer.d.ts +3 -0
- package/dist/http/middleware/WorkerNameSanitizer.js +46 -0
- package/dist/http/middleware/WorkerValidationChain.d.ts +27 -0
- package/dist/http/middleware/WorkerValidationChain.js +185 -0
- package/dist/index.d.ts +46 -0
- package/dist/index.js +48 -0
- package/dist/routes/workers.d.ts +12 -0
- package/dist/routes/workers.js +81 -0
- package/dist/storage/WorkerStore.d.ts +45 -0
- package/dist/storage/WorkerStore.js +195 -0
- package/dist/type.d.ts +76 -0
- package/dist/type.js +1 -0
- package/dist/ui/router/ui.d.ts +3 -0
- package/dist/ui/router/ui.js +83 -0
- package/dist/ui/types/worker-ui.d.ts +229 -0
- package/dist/ui/types/worker-ui.js +5 -0
- package/package.json +53 -0
- package/src/AnomalyDetection.ts +434 -0
- package/src/AutoScaler.ts +654 -0
- package/src/BroadcastWorker.ts +34 -0
- package/src/CanaryController.ts +531 -0
- package/src/ChaosEngineering.ts +301 -0
- package/src/CircuitBreaker.ts +495 -0
- package/src/ClusterLock.ts +499 -0
- package/src/ComplianceManager.ts +815 -0
- package/src/DatacenterOrchestrator.ts +561 -0
- package/src/DeadLetterQueue.ts +733 -0
- package/src/HealthMonitor.ts +390 -0
- package/src/MultiQueueWorker.ts +431 -0
- package/src/NotificationWorker.ts +33 -0
- package/src/Observability.ts +696 -0
- package/src/PluginManager.ts +551 -0
- package/src/PriorityQueue.ts +351 -0
- package/src/ResourceMonitor.ts +769 -0
- package/src/SLAMonitor.ts +408 -0
- package/src/WorkerFactory.ts +2108 -0
- package/src/WorkerInit.ts +313 -0
- package/src/WorkerMetrics.ts +709 -0
- package/src/WorkerRegistry.ts +443 -0
- package/src/WorkerShutdown.ts +210 -0
- package/src/WorkerVersioning.ts +422 -0
- package/src/config/workerConfig.ts +25 -0
- package/src/createQueueWorker.ts +174 -0
- package/src/dashboard/index.ts +6 -0
- package/src/dashboard/types.ts +141 -0
- package/src/dashboard/workers-api.ts +785 -0
- package/src/dashboard/zintrust.svg +30 -0
- package/src/helper/index.ts +11 -0
- package/src/http/WorkerApiController.ts +369 -0
- package/src/http/WorkerController.ts +1512 -0
- package/src/http/middleware/CustomValidation.ts +360 -0
- package/src/http/middleware/DatacenterValidator.ts +124 -0
- package/src/http/middleware/EditWorkerValidation.ts +74 -0
- package/src/http/middleware/FeaturesValidator.ts +82 -0
- package/src/http/middleware/InfrastructureValidator.ts +295 -0
- package/src/http/middleware/OptionsValidator.ts +144 -0
- package/src/http/middleware/PayloadSanitizer.ts +52 -0
- package/src/http/middleware/ProcessorPathSanitizer.ts +86 -0
- package/src/http/middleware/QueueNameSanitizer.ts +55 -0
- package/src/http/middleware/ValidateDriver.ts +29 -0
- package/src/http/middleware/VersionSanitizer.ts +30 -0
- package/src/http/middleware/WorkerNameSanitizer.ts +56 -0
- package/src/http/middleware/WorkerValidationChain.ts +230 -0
- package/src/index.ts +98 -0
- package/src/routes/workers.ts +154 -0
- package/src/storage/WorkerStore.ts +240 -0
- package/src/type.ts +89 -0
- package/src/types/queue-monitor.d.ts +38 -0
- package/src/types/queue-redis.d.ts +38 -0
- package/src/ui/README.md +13 -0
- package/src/ui/components/JsonEditor.js +670 -0
- package/src/ui/components/JsonViewer.js +387 -0
- package/src/ui/components/WorkerCard.js +178 -0
- package/src/ui/components/WorkerExpandPanel.js +257 -0
- package/src/ui/components/fetcher.js +42 -0
- package/src/ui/components/sla-scorecard.js +32 -0
- package/src/ui/components/styles.css +30 -0
- package/src/ui/components/table-expander.js +34 -0
- package/src/ui/integration/worker-ui-integration.js +565 -0
- package/src/ui/router/ui.ts +99 -0
- package/src/ui/services/workerApi.js +240 -0
- package/src/ui/types/worker-ui.ts +283 -0
- package/src/ui/utils/jsonValidator.js +444 -0
- package/src/ui/workers/index.html +202 -0
- package/src/ui/workers/main.js +1781 -0
- package/src/ui/workers/styles.css +1350 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<svg width="120" height="120" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="zt-g2d" x1="10" y1="50" x2="90" y2="50" gradientUnits="userSpaceOnUse">
|
|
4
|
+
<stop stop-color="#22c55e" />
|
|
5
|
+
<stop offset="1" stop-color="#38bdf8" />
|
|
6
|
+
</linearGradient>
|
|
7
|
+
</defs>
|
|
8
|
+
<circle cx="50" cy="50" r="34" stroke="rgba(255,255,255,0.16)" stroke-width="4" />
|
|
9
|
+
<ellipse cx="50" cy="50" rx="40" ry="18" stroke="url(#zt-g2d)" stroke-width="4" />
|
|
10
|
+
<ellipse cx="50" cy="50" rx="18" ry="40" stroke="url(#zt-g2d)" stroke-width="4" opacity="0.75" />
|
|
11
|
+
<circle cx="50" cy="50" r="6" fill="url(#zt-g2d)" />
|
|
12
|
+
<path
|
|
13
|
+
d="M40 52C35 52 32 49 32 44C32 39 35 36 40 36H48"
|
|
14
|
+
stroke="white"
|
|
15
|
+
stroke-width="6"
|
|
16
|
+
stroke-linecap="round"
|
|
17
|
+
/>
|
|
18
|
+
<path
|
|
19
|
+
d="M60 48C65 48 68 51 68 56C68 61 65 64 60 64H52"
|
|
20
|
+
stroke="white"
|
|
21
|
+
stroke-width="6"
|
|
22
|
+
stroke-linecap="round"
|
|
23
|
+
/>
|
|
24
|
+
<path
|
|
25
|
+
d="M44 50H56"
|
|
26
|
+
stroke="rgba(255,255,255,0.22)"
|
|
27
|
+
stroke-width="6"
|
|
28
|
+
stroke-linecap="round"
|
|
29
|
+
/>
|
|
30
|
+
</svg>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { IRequest } from '@zintrust/core';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Helper to get path parameter
|
|
5
|
+
*/
|
|
6
|
+
export const getParam = (req: IRequest, key: string): string => {
|
|
7
|
+
const direct = req.getParam?.(key);
|
|
8
|
+
if (typeof direct === 'string' && direct.length > 0) return direct;
|
|
9
|
+
const params = (req.params as Record<string, string> | undefined) ?? {};
|
|
10
|
+
return params[key] ?? '';
|
|
11
|
+
};
|
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Worker API Controller
|
|
3
|
+
* HTTP handlers for worker management API
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { IRequest, IResponse } from '@zintrust/core';
|
|
7
|
+
import { Logger } from '@zintrust/core';
|
|
8
|
+
import type {
|
|
9
|
+
GetWorkersQuery,
|
|
10
|
+
WorkerDriver,
|
|
11
|
+
WorkerSortBy,
|
|
12
|
+
WorkerSortOrder,
|
|
13
|
+
WorkerStatus,
|
|
14
|
+
} from '../dashboard/types';
|
|
15
|
+
import { getWorkerDetails, getWorkers } from '../dashboard/workers-api';
|
|
16
|
+
import { getParam } from '../helper';
|
|
17
|
+
import { WorkerFactory } from '../WorkerFactory';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Helper to safely get a single string value from query params
|
|
21
|
+
*/
|
|
22
|
+
const getQueryParam = (
|
|
23
|
+
query: Record<string, string | string[]>,
|
|
24
|
+
key: string,
|
|
25
|
+
defaultValue: string = ''
|
|
26
|
+
): string => {
|
|
27
|
+
const value = query[key];
|
|
28
|
+
return Array.isArray(value) ? value[0] : value || defaultValue;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Helper to safely get a number from query params
|
|
33
|
+
*/
|
|
34
|
+
const getNumberParam = (
|
|
35
|
+
query: Record<string, string | string[]>,
|
|
36
|
+
key: string,
|
|
37
|
+
defaultValue: number
|
|
38
|
+
): number => {
|
|
39
|
+
const value = getQueryParam(query, key, String(defaultValue));
|
|
40
|
+
const parsed = Number.parseInt(value, 10);
|
|
41
|
+
return Number.isNaN(parsed) ? defaultValue : parsed;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Helper to safely get a boolean from query params
|
|
46
|
+
*/
|
|
47
|
+
const getBooleanParam = (
|
|
48
|
+
query: Record<string, string | string[]>,
|
|
49
|
+
key: string,
|
|
50
|
+
defaultValue: boolean
|
|
51
|
+
): boolean => {
|
|
52
|
+
const value = getQueryParam(query, key, '').toLowerCase();
|
|
53
|
+
if (value === 'true') return true;
|
|
54
|
+
if (value === 'false') return false;
|
|
55
|
+
return defaultValue;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Helper function to get typed enum value with type safety
|
|
60
|
+
*/
|
|
61
|
+
const getEnumParam = <T extends string>(
|
|
62
|
+
query: Record<string, string | string[]>,
|
|
63
|
+
key: string,
|
|
64
|
+
validValues: readonly T[],
|
|
65
|
+
defaultValue: T
|
|
66
|
+
): T => {
|
|
67
|
+
const value = getQueryParam(query, key, defaultValue);
|
|
68
|
+
return validValues.includes(value as T) ? (value as T) : defaultValue;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Helper to safely get optional enum value
|
|
73
|
+
*/
|
|
74
|
+
const getOptionalEnumParam = <T extends string>(
|
|
75
|
+
query: Record<string, string | string[]>,
|
|
76
|
+
key: string,
|
|
77
|
+
validValues: readonly T[]
|
|
78
|
+
): T | undefined => {
|
|
79
|
+
const value = getQueryParam(query, key, '').trim();
|
|
80
|
+
if (!value) return undefined;
|
|
81
|
+
return validValues.includes(value as T) ? (value as T) : undefined;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* GET /api/workers - List workers with pagination, filtering, and sorting
|
|
86
|
+
*/
|
|
87
|
+
export const listWorkers = async (req: IRequest, res: IResponse): Promise<void> => {
|
|
88
|
+
try {
|
|
89
|
+
const query = req.getQuery() as Record<string, string | string[]>;
|
|
90
|
+
const sortByRaw = getQueryParam(query, 'sortBy', getQueryParam(query, 'sort', 'name'));
|
|
91
|
+
|
|
92
|
+
const queryParams: GetWorkersQuery = {
|
|
93
|
+
page: getNumberParam(query, 'page', 1),
|
|
94
|
+
limit: getNumberParam(query, 'limit', 100),
|
|
95
|
+
sortBy: getEnumParam<WorkerSortBy>(
|
|
96
|
+
{ ...query, sortBy: sortByRaw },
|
|
97
|
+
'sortBy',
|
|
98
|
+
['name', 'status', 'driver', 'health', 'version', 'processed'] as const,
|
|
99
|
+
'name'
|
|
100
|
+
),
|
|
101
|
+
sortOrder: getEnumParam<WorkerSortOrder>(query, 'sortOrder', ['asc', 'desc'] as const, 'asc'),
|
|
102
|
+
status: getOptionalEnumParam<WorkerStatus>(query, 'status', [
|
|
103
|
+
'running',
|
|
104
|
+
'stopped',
|
|
105
|
+
'error',
|
|
106
|
+
'paused',
|
|
107
|
+
] as const),
|
|
108
|
+
driver: getOptionalEnumParam<WorkerDriver>(query, 'driver', [
|
|
109
|
+
'database',
|
|
110
|
+
'redis',
|
|
111
|
+
'memory',
|
|
112
|
+
] as const),
|
|
113
|
+
search: getQueryParam(query, 'search'),
|
|
114
|
+
includeDetails: getBooleanParam(query, 'includeDetails', false),
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
const result = await getWorkers(queryParams);
|
|
118
|
+
res.json(result);
|
|
119
|
+
} catch (error) {
|
|
120
|
+
Logger.error('Error fetching workers:', error);
|
|
121
|
+
res.status(500).json({
|
|
122
|
+
error: 'Failed to fetch workers',
|
|
123
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* GET /api/workers/:name/details - Get detailed worker information
|
|
130
|
+
*/
|
|
131
|
+
export const getWorkerDetailsHandler = async (req: IRequest, res: IResponse): Promise<void> => {
|
|
132
|
+
try {
|
|
133
|
+
const name = getParam(req, 'name');
|
|
134
|
+
if (!name) {
|
|
135
|
+
res.setStatus(400).json({ error: 'Worker name is required' });
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
const driver = getQueryParam(req.getQuery?.() || {}, 'driver');
|
|
139
|
+
const details = await getWorkerDetails(name, driver);
|
|
140
|
+
res.json(details);
|
|
141
|
+
} catch (error) {
|
|
142
|
+
if (error instanceof Error && error.message.includes('not found')) {
|
|
143
|
+
res.status(404).json({
|
|
144
|
+
error: 'Worker not found',
|
|
145
|
+
message: error.message,
|
|
146
|
+
});
|
|
147
|
+
} else {
|
|
148
|
+
Logger.error('Error fetching worker details:', error);
|
|
149
|
+
res.status(500).json({
|
|
150
|
+
error: 'Failed to fetch worker details',
|
|
151
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* GET /api/workers/drivers - Get available worker drivers
|
|
159
|
+
*/
|
|
160
|
+
export const getDriversHandler = async (_req: IRequest, res: IResponse): Promise<void> => {
|
|
161
|
+
try {
|
|
162
|
+
const result = await getWorkers({});
|
|
163
|
+
res.json({
|
|
164
|
+
drivers: result.drivers,
|
|
165
|
+
count: result.drivers.length,
|
|
166
|
+
});
|
|
167
|
+
} catch (error) {
|
|
168
|
+
Logger.error('Error fetching drivers:', error);
|
|
169
|
+
res.status(500).json({
|
|
170
|
+
error: 'Failed to fetch drivers',
|
|
171
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* GET /api/workers/queue-data - Get queue statistics
|
|
178
|
+
*/
|
|
179
|
+
export const getQueueDataHandler = async (_req: IRequest, res: IResponse): Promise<void> => {
|
|
180
|
+
try {
|
|
181
|
+
const result = await getWorkers({});
|
|
182
|
+
res.json(result.queueData);
|
|
183
|
+
} catch (error) {
|
|
184
|
+
Logger.error('Error fetching queue data:', error);
|
|
185
|
+
res.status(500).json({
|
|
186
|
+
error: 'Failed to fetch queue data',
|
|
187
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* GET /api/workers/health - Get overall workers health summary
|
|
194
|
+
*/
|
|
195
|
+
export const getHealthSummaryHandler = async (_req: IRequest, res: IResponse): Promise<void> => {
|
|
196
|
+
try {
|
|
197
|
+
const result = await getWorkers({});
|
|
198
|
+
|
|
199
|
+
const healthSummary = {
|
|
200
|
+
total: result.workers.length,
|
|
201
|
+
running: result.workers.filter((w) => w.status === 'running').length,
|
|
202
|
+
stopped: result.workers.filter((w) => w.status === 'stopped').length,
|
|
203
|
+
error: result.workers.filter((w) => w.status === 'error').length,
|
|
204
|
+
paused: result.workers.filter((w) => w.status === 'paused').length,
|
|
205
|
+
healthy: result.workers.filter((w) => w.health.status === 'healthy').length,
|
|
206
|
+
unhealthy: result.workers.filter((w) => w.health.status === 'unhealthy').length,
|
|
207
|
+
warning: result.workers.filter((w) => w.health.status === 'warning').length,
|
|
208
|
+
drivers: result.drivers,
|
|
209
|
+
queueData: result.queueData,
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
res.json(healthSummary);
|
|
213
|
+
} catch (error) {
|
|
214
|
+
Logger.error('Error fetching health summary:', error);
|
|
215
|
+
res.status(500).json({
|
|
216
|
+
error: 'Failed to fetch health summary',
|
|
217
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
const getWorkerJsonHandler = async (req: IRequest, res: IResponse): Promise<void> => {
|
|
223
|
+
try {
|
|
224
|
+
const { id } = req.params;
|
|
225
|
+
|
|
226
|
+
if (!id) {
|
|
227
|
+
return res.setStatus(400).json({
|
|
228
|
+
error: 'Worker ID is required',
|
|
229
|
+
code: 'MISSING_WORKER_ID',
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
const worker = await getWorkerDetails(id);
|
|
234
|
+
if (!worker) {
|
|
235
|
+
return res.setStatus(404).json({
|
|
236
|
+
error: 'Worker not found',
|
|
237
|
+
code: 'WORKER_NOT_FOUND',
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return res.json({
|
|
242
|
+
success: true,
|
|
243
|
+
data: worker,
|
|
244
|
+
});
|
|
245
|
+
} catch (error) {
|
|
246
|
+
Logger.error('Failed to get worker JSON', error);
|
|
247
|
+
return res.setStatus(500).json({
|
|
248
|
+
error: 'Internal server error',
|
|
249
|
+
code: 'INTERNAL_ERROR',
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* GET /api/workers/:name/driver-data - Get direct driver data for editing
|
|
256
|
+
* This retrieves the raw persisted data without enrichment for editing purposes
|
|
257
|
+
*/
|
|
258
|
+
const getWorkerDriverDataHandler = async (req: IRequest, res: IResponse): Promise<void> => {
|
|
259
|
+
try {
|
|
260
|
+
const name = getParam(req, 'name');
|
|
261
|
+
if (!name) {
|
|
262
|
+
return res.setStatus(400).json({
|
|
263
|
+
error: 'Worker name is required',
|
|
264
|
+
code: 'MISSING_WORKER_NAME',
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
const driver = getQueryParam(req.getQuery?.() || {}, 'driver') as WorkerDriver;
|
|
269
|
+
const persistenceOverride = driver ? { driver } : undefined;
|
|
270
|
+
|
|
271
|
+
// Get direct driver data without enrichment
|
|
272
|
+
const persistedData = await WorkerFactory.getPersisted(name, persistenceOverride);
|
|
273
|
+
|
|
274
|
+
if (!persistedData) {
|
|
275
|
+
return res.setStatus(404).json({
|
|
276
|
+
error: 'Worker not found in driver',
|
|
277
|
+
code: 'WORKER_NOT_FOUND',
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
return res.json({
|
|
282
|
+
success: true,
|
|
283
|
+
data: persistedData,
|
|
284
|
+
});
|
|
285
|
+
} catch (error) {
|
|
286
|
+
Logger.error('Failed to get worker driver data', error);
|
|
287
|
+
return res.setStatus(500).json({
|
|
288
|
+
error: 'Internal server error',
|
|
289
|
+
code: 'INTERNAL_ERROR',
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
const updateWorkerJsonHandler = async (req: IRequest, res: IResponse): Promise<void> => {
|
|
295
|
+
try {
|
|
296
|
+
const workerData = req.data();
|
|
297
|
+
const workerId = workerData['id'] as string;
|
|
298
|
+
|
|
299
|
+
if (!workerId) {
|
|
300
|
+
return res.setStatus(400).json({
|
|
301
|
+
error: 'Worker ID is required',
|
|
302
|
+
code: 'MISSING_WORKER_ID',
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
if (!workerData) {
|
|
307
|
+
return res.setStatus(400).json({
|
|
308
|
+
error: 'Worker data is required',
|
|
309
|
+
code: 'MISSING_WORKER_DATA',
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// Basic validation for now - can be enhanced with full schema validation
|
|
314
|
+
if (
|
|
315
|
+
!workerData['name'] ||
|
|
316
|
+
!workerData['queueName'] ||
|
|
317
|
+
!workerData['processor'] ||
|
|
318
|
+
!workerData['version']
|
|
319
|
+
) {
|
|
320
|
+
return res.setStatus(400).json({
|
|
321
|
+
error: 'Missing required fields: name, queueName, processor, version',
|
|
322
|
+
code: 'MISSING_REQUIRED_FIELDS',
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// Get existing worker
|
|
327
|
+
const existingWorker = await getWorkerDetails(workerId);
|
|
328
|
+
if (!existingWorker) {
|
|
329
|
+
return res.setStatus(404).json({
|
|
330
|
+
error: 'Worker not found',
|
|
331
|
+
code: 'WORKER_NOT_FOUND',
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// For now, return the updated data as if it was updated
|
|
336
|
+
// In a real implementation, this would update the worker in the database
|
|
337
|
+
const updatedWorker = { ...existingWorker, ...workerData };
|
|
338
|
+
|
|
339
|
+
return res.json({
|
|
340
|
+
success: true,
|
|
341
|
+
data: updatedWorker,
|
|
342
|
+
message: 'Worker updated successfully',
|
|
343
|
+
});
|
|
344
|
+
} catch (error) {
|
|
345
|
+
Logger.error('Failed to update worker JSON', error);
|
|
346
|
+
return res.setStatus(500).json({
|
|
347
|
+
error: 'Internal server error',
|
|
348
|
+
code: 'INTERNAL_ERROR',
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
};
|
|
352
|
+
|
|
353
|
+
export const WorkerApiController = Object.freeze({
|
|
354
|
+
create() {
|
|
355
|
+
// Compose grouped handlers to keep this function short
|
|
356
|
+
return {
|
|
357
|
+
getDriversHandler,
|
|
358
|
+
getQueueDataHandler,
|
|
359
|
+
getHealthSummaryHandler,
|
|
360
|
+
listWorkers,
|
|
361
|
+
getWorkerDetailsHandler,
|
|
362
|
+
getWorkerJsonHandler,
|
|
363
|
+
getWorkerDriverDataHandler,
|
|
364
|
+
updateWorkerJsonHandler,
|
|
365
|
+
};
|
|
366
|
+
},
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
export default WorkerApiController;
|