@onlineapps/service-wrapper 2.0.6 → 2.0.8
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 +11 -0
- package/docs/API_STRUCTURE_STANDARD.md +132 -0
- package/docs/CONFIGURATION_GUIDE.md +261 -0
- package/docs/OPERATIONS_SCHEMA.md +363 -0
- package/docs/SERVICE_TESTING_STANDARD.md +389 -0
- package/package.json +9 -7
- package/src/ServiceWrapper.js +39 -6
- package/test/e2e/full-flow.test.js +293 -0
- package/test/monitoring-integration.test.js +150 -0
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
# Service Testing Standard and OpenAPI Generation
|
|
2
|
+
|
|
3
|
+
## 1. OpenAPI Schema Generation
|
|
4
|
+
|
|
5
|
+
### Step 1: Analyze Your Service Endpoints
|
|
6
|
+
|
|
7
|
+
List all your service endpoints and their:
|
|
8
|
+
- HTTP methods (GET, POST, PUT, DELETE)
|
|
9
|
+
- Request parameters (query, path, body)
|
|
10
|
+
- Response structures
|
|
11
|
+
- Error responses
|
|
12
|
+
|
|
13
|
+
### Step 2: Create openapi.yaml
|
|
14
|
+
|
|
15
|
+
Create `openapi.yaml` in your service root directory with this structure:
|
|
16
|
+
|
|
17
|
+
```yaml
|
|
18
|
+
openapi: 3.0.0
|
|
19
|
+
info:
|
|
20
|
+
title: # Your service name from package.json
|
|
21
|
+
version: # Your service version from package.json
|
|
22
|
+
description: # Brief description of what your service does
|
|
23
|
+
|
|
24
|
+
servers:
|
|
25
|
+
- url: http://localhost:{your-port}
|
|
26
|
+
description: Local development
|
|
27
|
+
- url: http://{container-name}:3000
|
|
28
|
+
description: Docker container
|
|
29
|
+
|
|
30
|
+
paths:
|
|
31
|
+
# Document each endpoint
|
|
32
|
+
/your-endpoint:
|
|
33
|
+
get/post/put/delete:
|
|
34
|
+
summary: # One line description
|
|
35
|
+
operationId: # Unique identifier (e.g., getUsers, createOrder)
|
|
36
|
+
parameters: # If applicable
|
|
37
|
+
requestBody: # If applicable
|
|
38
|
+
responses:
|
|
39
|
+
'200':
|
|
40
|
+
description: # Success response
|
|
41
|
+
content:
|
|
42
|
+
application/json:
|
|
43
|
+
schema:
|
|
44
|
+
# Define or reference schema
|
|
45
|
+
'400':
|
|
46
|
+
# Bad request
|
|
47
|
+
'500':
|
|
48
|
+
# Server error
|
|
49
|
+
|
|
50
|
+
components:
|
|
51
|
+
schemas:
|
|
52
|
+
# Define reusable schemas here
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Step 3: Generate Schema from Code (Alternative)
|
|
56
|
+
|
|
57
|
+
If you have many endpoints, generate initial schema:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
# Install openapi generator
|
|
61
|
+
npm install --save-dev @apidevtools/swagger-cli
|
|
62
|
+
|
|
63
|
+
# For Express apps, use express-openapi-generator
|
|
64
|
+
npm install --save-dev express-openapi-generator
|
|
65
|
+
|
|
66
|
+
# Add generation script to package.json
|
|
67
|
+
"scripts": {
|
|
68
|
+
"generate:openapi": "node scripts/generate-openapi.js"
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Create `scripts/generate-openapi.js`:
|
|
73
|
+
```javascript
|
|
74
|
+
const app = require('../src/app');
|
|
75
|
+
const generator = require('express-openapi-generator');
|
|
76
|
+
|
|
77
|
+
generator(app, {
|
|
78
|
+
outputFile: './openapi.yaml',
|
|
79
|
+
info: {
|
|
80
|
+
title: process.env.SERVICE_NAME,
|
|
81
|
+
version: require('../package.json').version
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Step 4: Validate Your Schema
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
# Install validator
|
|
90
|
+
npm install --save-dev @apidevtools/swagger-parser
|
|
91
|
+
|
|
92
|
+
# Add validation script
|
|
93
|
+
"scripts": {
|
|
94
|
+
"validate:openapi": "swagger-cli validate openapi.yaml"
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## 2. Test Structure
|
|
99
|
+
|
|
100
|
+
### Directory Structure
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
/your-service
|
|
104
|
+
/test
|
|
105
|
+
/unit # Unit tests for individual functions
|
|
106
|
+
/integration # Integration tests with mocked dependencies
|
|
107
|
+
/api # API endpoint tests
|
|
108
|
+
/compliance # OpenAPI compliance tests
|
|
109
|
+
test.config.js # Shared test configuration
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Test Configuration
|
|
113
|
+
|
|
114
|
+
Create `test/test.config.js`:
|
|
115
|
+
```javascript
|
|
116
|
+
module.exports = {
|
|
117
|
+
// Service configuration for tests
|
|
118
|
+
service: {
|
|
119
|
+
name: process.env.SERVICE_NAME || 'your-service',
|
|
120
|
+
port: process.env.PORT || 3000,
|
|
121
|
+
baseUrl: `http://localhost:${process.env.PORT || 3000}`
|
|
122
|
+
},
|
|
123
|
+
|
|
124
|
+
// Timeouts
|
|
125
|
+
timeouts: {
|
|
126
|
+
unit: 5000,
|
|
127
|
+
integration: 10000,
|
|
128
|
+
api: 15000
|
|
129
|
+
},
|
|
130
|
+
|
|
131
|
+
// Mock data
|
|
132
|
+
mocks: {
|
|
133
|
+
validRequest: { /* valid request data */ },
|
|
134
|
+
invalidRequest: { /* invalid request data */ }
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## 3. Test Implementation
|
|
140
|
+
|
|
141
|
+
### Unit Tests (`test/unit/`)
|
|
142
|
+
|
|
143
|
+
Test individual functions without external dependencies:
|
|
144
|
+
|
|
145
|
+
```javascript
|
|
146
|
+
describe('Business Logic', () => {
|
|
147
|
+
test('should process valid input', () => {
|
|
148
|
+
const result = processFunction(validInput);
|
|
149
|
+
expect(result).toBeDefined();
|
|
150
|
+
expect(result.status).toBe('success');
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
test('should handle invalid input', () => {
|
|
154
|
+
expect(() => processFunction(invalidInput)).toThrow();
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### API Tests (`test/api/`)
|
|
160
|
+
|
|
161
|
+
Test actual HTTP endpoints:
|
|
162
|
+
|
|
163
|
+
```javascript
|
|
164
|
+
const request = require('supertest');
|
|
165
|
+
const app = require('../../src/app');
|
|
166
|
+
|
|
167
|
+
describe('API Endpoints', () => {
|
|
168
|
+
describe('GET /your-endpoint', () => {
|
|
169
|
+
test('should return 200 with valid response', async () => {
|
|
170
|
+
const response = await request(app)
|
|
171
|
+
.get('/your-endpoint')
|
|
172
|
+
.expect(200);
|
|
173
|
+
|
|
174
|
+
expect(response.body).toHaveProperty('expectedField');
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
test('should return 400 for invalid request', async () => {
|
|
178
|
+
const response = await request(app)
|
|
179
|
+
.get('/your-endpoint?invalid=true')
|
|
180
|
+
.expect(400);
|
|
181
|
+
|
|
182
|
+
expect(response.body).toHaveProperty('error');
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Compliance Tests (`test/compliance/`)
|
|
189
|
+
|
|
190
|
+
Test OpenAPI compliance:
|
|
191
|
+
|
|
192
|
+
```javascript
|
|
193
|
+
const SwaggerParser = require('@apidevtools/swagger-parser');
|
|
194
|
+
const request = require('supertest');
|
|
195
|
+
const app = require('../../src/app');
|
|
196
|
+
const openApiSchema = require('../../openapi.yaml');
|
|
197
|
+
|
|
198
|
+
describe('OpenAPI Compliance', () => {
|
|
199
|
+
let api;
|
|
200
|
+
|
|
201
|
+
beforeAll(async () => {
|
|
202
|
+
// Validate and parse schema
|
|
203
|
+
api = await SwaggerParser.validate(openApiSchema);
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
test('schema should be valid OpenAPI 3.0', () => {
|
|
207
|
+
expect(api.openapi).toBe('3.0.0');
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
test('all endpoints should match schema', async () => {
|
|
211
|
+
for (const [path, methods] of Object.entries(api.paths)) {
|
|
212
|
+
for (const [method, spec] of Object.entries(methods)) {
|
|
213
|
+
if (['get', 'post', 'put', 'delete'].includes(method)) {
|
|
214
|
+
const response = await request(app)[method](path);
|
|
215
|
+
// Validate response matches schema
|
|
216
|
+
expect(response.status).toBeDefined();
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## 4. NPM Scripts
|
|
225
|
+
|
|
226
|
+
Add to `package.json`:
|
|
227
|
+
|
|
228
|
+
```json
|
|
229
|
+
{
|
|
230
|
+
"scripts": {
|
|
231
|
+
"test": "npm run test:unit && npm run test:api && npm run test:compliance",
|
|
232
|
+
"test:unit": "jest test/unit",
|
|
233
|
+
"test:integration": "jest test/integration",
|
|
234
|
+
"test:api": "jest test/api",
|
|
235
|
+
"test:compliance": "jest test/compliance",
|
|
236
|
+
"test:coverage": "jest --coverage",
|
|
237
|
+
"validate:openapi": "swagger-cli validate openapi.yaml",
|
|
238
|
+
"generate:openapi": "node scripts/generate-openapi.js",
|
|
239
|
+
"serve:docs": "swagger-ui-express openapi.yaml"
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### Coverage Requirements
|
|
245
|
+
|
|
246
|
+
**Minimum recommended coverage: 80%**
|
|
247
|
+
|
|
248
|
+
Configure Jest coverage thresholds in `package.json`:
|
|
249
|
+
|
|
250
|
+
```json
|
|
251
|
+
{
|
|
252
|
+
"jest": {
|
|
253
|
+
"coverageThreshold": {
|
|
254
|
+
"global": {
|
|
255
|
+
"branches": 80,
|
|
256
|
+
"functions": 80,
|
|
257
|
+
"lines": 80,
|
|
258
|
+
"statements": 80
|
|
259
|
+
}
|
|
260
|
+
},
|
|
261
|
+
"collectCoverageFrom": [
|
|
262
|
+
"src/**/*.js",
|
|
263
|
+
"!src/**/*.test.js",
|
|
264
|
+
"!src/**/*.spec.js"
|
|
265
|
+
]
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
## 5. Service Wrapper Integration
|
|
271
|
+
|
|
272
|
+
### Endpoint for OpenAPI Schema
|
|
273
|
+
|
|
274
|
+
Your service must expose its schema:
|
|
275
|
+
|
|
276
|
+
```javascript
|
|
277
|
+
// In your app.js or routes
|
|
278
|
+
const fs = require('fs');
|
|
279
|
+
const yaml = require('js-yaml');
|
|
280
|
+
|
|
281
|
+
app.get('/openapi', (req, res) => {
|
|
282
|
+
try {
|
|
283
|
+
const doc = yaml.load(fs.readFileSync('./openapi.yaml', 'utf8'));
|
|
284
|
+
res.json(doc);
|
|
285
|
+
} catch (e) {
|
|
286
|
+
res.status(500).json({ error: 'Schema not available' });
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### Validation Middleware
|
|
292
|
+
|
|
293
|
+
Use Service Wrapper's validation:
|
|
294
|
+
|
|
295
|
+
```javascript
|
|
296
|
+
const { validateRequest } = require('@onlineapps/service-wrapper/middleware');
|
|
297
|
+
const openApiSchema = require('./openapi.yaml');
|
|
298
|
+
|
|
299
|
+
// Apply validation to routes
|
|
300
|
+
app.post('/your-endpoint',
|
|
301
|
+
validateRequest(openApiSchema, '/your-endpoint', 'post'),
|
|
302
|
+
(req, res) => {
|
|
303
|
+
// Request is already validated
|
|
304
|
+
}
|
|
305
|
+
);
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
## 6. Continuous Validation
|
|
309
|
+
|
|
310
|
+
### Pre-commit Hook
|
|
311
|
+
|
|
312
|
+
`.husky/pre-commit`:
|
|
313
|
+
```bash
|
|
314
|
+
#!/bin/sh
|
|
315
|
+
npm run validate:openapi
|
|
316
|
+
npm run test:compliance
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### CI/CD Pipeline
|
|
320
|
+
|
|
321
|
+
```yaml
|
|
322
|
+
# .github/workflows/test.yml or gitlab-ci.yml
|
|
323
|
+
test:
|
|
324
|
+
script:
|
|
325
|
+
- npm install
|
|
326
|
+
- npm run validate:openapi
|
|
327
|
+
- npm run test
|
|
328
|
+
- npm run test:coverage
|
|
329
|
+
coverage: '/Lines\s*:\s*(\d+\.\d+)%/'
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
## 7. Validation Checklist
|
|
333
|
+
|
|
334
|
+
Before deployment, ensure:
|
|
335
|
+
|
|
336
|
+
- [ ] OpenAPI schema exists at `/openapi.yaml`
|
|
337
|
+
- [ ] Schema validates with `swagger-cli validate`
|
|
338
|
+
- [ ] All endpoints documented in schema
|
|
339
|
+
- [ ] Request/response schemas defined
|
|
340
|
+
- [ ] Error responses documented
|
|
341
|
+
- [ ] Schema version matches package.json
|
|
342
|
+
- [ ] `/openapi` endpoint returns schema
|
|
343
|
+
- [ ] Unit tests pass (>80% coverage)
|
|
344
|
+
- [ ] API tests pass
|
|
345
|
+
- [ ] Compliance tests pass
|
|
346
|
+
- [ ] Service Wrapper can load schema
|
|
347
|
+
- [ ] Validation middleware works
|
|
348
|
+
|
|
349
|
+
## 8. Common Issues and Solutions
|
|
350
|
+
|
|
351
|
+
### Issue: Schema doesn't match implementation
|
|
352
|
+
**Solution**: Generate schema from code first, then refine manually
|
|
353
|
+
|
|
354
|
+
### Issue: Validation too strict
|
|
355
|
+
**Solution**: Use `additionalProperties: true` in schemas during development
|
|
356
|
+
|
|
357
|
+
### Issue: Complex nested objects
|
|
358
|
+
**Solution**: Break into components and use `$ref`
|
|
359
|
+
|
|
360
|
+
### Issue: Different environments need different configs
|
|
361
|
+
**Solution**: Use environment variables in schema:
|
|
362
|
+
```yaml
|
|
363
|
+
servers:
|
|
364
|
+
- url: ${API_BASE_URL}
|
|
365
|
+
description: Configured base URL
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
## 9. Testing with conn-e2e-testing
|
|
369
|
+
|
|
370
|
+
The connector testing framework will:
|
|
371
|
+
1. Load your OpenAPI schema
|
|
372
|
+
2. Start your service
|
|
373
|
+
3. Test each endpoint against schema
|
|
374
|
+
4. Validate requests and responses
|
|
375
|
+
5. Generate compliance report
|
|
376
|
+
|
|
377
|
+
Ensure your service is ready by:
|
|
378
|
+
1. Exposing `/openapi` endpoint
|
|
379
|
+
2. Having all endpoints documented
|
|
380
|
+
3. Returning proper HTTP status codes
|
|
381
|
+
4. Using consistent error format
|
|
382
|
+
|
|
383
|
+
## 10. Resources
|
|
384
|
+
|
|
385
|
+
- [OpenAPI 3.0 Specification](https://swagger.io/specification/)
|
|
386
|
+
- [JSON Schema Validation](https://json-schema.org/draft/2019-09/json-schema-validation.html)
|
|
387
|
+
- [swagger-cli Documentation](https://apitools.dev/swagger-cli/)
|
|
388
|
+
- Service Wrapper documentation: `/shared/connector/service-wrapper/README.md`
|
|
389
|
+
- Testing examples: `/shared/connector/conn-e2e-testing/examples/`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onlineapps/service-wrapper",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.8",
|
|
4
4
|
"description": "Thin orchestration layer for microservices - delegates all infrastructure concerns to specialized connectors",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -24,17 +24,19 @@
|
|
|
24
24
|
"author": "OA Drive Team",
|
|
25
25
|
"license": "MIT",
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@onlineapps/conn-base-
|
|
27
|
+
"@onlineapps/conn-base-cache": "^1.0.0",
|
|
28
|
+
"@onlineapps/conn-base-monitoring": "file:../conn-base-monitoring/onlineapps-conn-base-monitoring-1.0.0.tgz",
|
|
29
|
+
"@onlineapps/conn-infra-error-handler": "^1.0.0",
|
|
28
30
|
"@onlineapps/conn-infra-mq": "^1.1.0",
|
|
29
|
-
"@onlineapps/conn-orch-
|
|
31
|
+
"@onlineapps/conn-orch-api-mapper": "^1.0.0",
|
|
30
32
|
"@onlineapps/conn-orch-cookbook": "^2.0.0",
|
|
31
33
|
"@onlineapps/conn-orch-orchestrator": "^1.0.1",
|
|
32
|
-
"@onlineapps/conn-orch-
|
|
33
|
-
"@onlineapps/
|
|
34
|
-
"@onlineapps/conn-infra-error-handler": "^1.0.0"
|
|
34
|
+
"@onlineapps/conn-orch-registry": "^1.1.4",
|
|
35
|
+
"@onlineapps/monitoring-core": "file:../../../api/shared/monitoring-core/onlineapps-monitoring-core-1.0.0.tgz"
|
|
35
36
|
},
|
|
36
37
|
"devDependencies": {
|
|
37
|
-
"
|
|
38
|
+
"express": "^5.1.0",
|
|
39
|
+
"jest": "^29.7.0",
|
|
38
40
|
"jsdoc": "^4.0.2",
|
|
39
41
|
"jsdoc-to-markdown": "^8.0.0"
|
|
40
42
|
},
|
package/src/ServiceWrapper.js
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
// Import connectors
|
|
14
14
|
const MQConnector = require('@onlineapps/conn-infra-mq');
|
|
15
15
|
const RegistryConnector = require('@onlineapps/conn-orch-registry');
|
|
16
|
-
const
|
|
16
|
+
const MonitoringConnector = require('@onlineapps/conn-base-monitoring');
|
|
17
17
|
const OrchestratorConnector = require('@onlineapps/conn-orch-orchestrator');
|
|
18
18
|
const ApiMapperConnector = require('@onlineapps/conn-orch-api-mapper');
|
|
19
19
|
const CookbookConnector = require('@onlineapps/conn-orch-cookbook');
|
|
@@ -69,7 +69,8 @@ class ServiceWrapper {
|
|
|
69
69
|
this.config = options.config || {};
|
|
70
70
|
|
|
71
71
|
// Initialize connectors
|
|
72
|
-
this.logger =
|
|
72
|
+
this.logger = MonitoringConnector; // Singleton, will be initialized later
|
|
73
|
+
this.monitoring = MonitoringConnector; // Also expose as monitoring for clarity
|
|
73
74
|
this.mqClient = null;
|
|
74
75
|
this.registryClient = null;
|
|
75
76
|
this.orchestrator = null;
|
|
@@ -109,11 +110,14 @@ class ServiceWrapper {
|
|
|
109
110
|
*/
|
|
110
111
|
async start() {
|
|
111
112
|
if (this.isRunning) {
|
|
112
|
-
|
|
113
|
+
console.warn('Service wrapper already running');
|
|
113
114
|
return;
|
|
114
115
|
}
|
|
115
116
|
|
|
116
117
|
try {
|
|
118
|
+
// Initialize monitoring first
|
|
119
|
+
await this.monitoring.init({ serviceName: this.serviceName });
|
|
120
|
+
|
|
117
121
|
this.logger.info(`Starting service wrapper for ${this.serviceName}`);
|
|
118
122
|
|
|
119
123
|
// 1. Initialize infrastructure connectors
|
|
@@ -298,8 +302,37 @@ class ServiceWrapper {
|
|
|
298
302
|
// Subscribe to workflow messages
|
|
299
303
|
await this.mqClient.consume(
|
|
300
304
|
queueName,
|
|
301
|
-
async (
|
|
305
|
+
async (rawMessage) => {
|
|
302
306
|
try {
|
|
307
|
+
// Parse message content if it's a buffer (AMQP message)
|
|
308
|
+
let message;
|
|
309
|
+
if (rawMessage && rawMessage.content) {
|
|
310
|
+
// This is an AMQP message with content buffer
|
|
311
|
+
const messageContent = rawMessage.content.toString();
|
|
312
|
+
try {
|
|
313
|
+
message = JSON.parse(messageContent);
|
|
314
|
+
} catch (parseError) {
|
|
315
|
+
this.logger.error('Failed to parse message content', {
|
|
316
|
+
error: parseError.message,
|
|
317
|
+
content: messageContent
|
|
318
|
+
});
|
|
319
|
+
throw parseError;
|
|
320
|
+
}
|
|
321
|
+
} else {
|
|
322
|
+
// Already parsed or direct message
|
|
323
|
+
message = rawMessage;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// DEBUG: Log the actual message structure
|
|
327
|
+
this.logger.info('DEBUG: Received message structure', {
|
|
328
|
+
workflow_id: message.workflow_id,
|
|
329
|
+
has_cookbook: !!message.cookbook,
|
|
330
|
+
cookbook_name: message.cookbook?.name,
|
|
331
|
+
cookbook_steps: message.cookbook?.steps?.length,
|
|
332
|
+
first_step: message.cookbook?.steps?.[0],
|
|
333
|
+
current_step: message.current_step
|
|
334
|
+
});
|
|
335
|
+
|
|
303
336
|
// Delegate ALL processing to orchestrator
|
|
304
337
|
const result = await this.orchestrator.processWorkflowMessage(
|
|
305
338
|
message,
|
|
@@ -314,8 +347,8 @@ class ServiceWrapper {
|
|
|
314
347
|
|
|
315
348
|
} catch (error) {
|
|
316
349
|
this.logger.error('Message processing failed', {
|
|
317
|
-
workflow_id: message
|
|
318
|
-
step: message
|
|
350
|
+
workflow_id: message?.workflow_id || 'unknown',
|
|
351
|
+
step: message?.current_step || 'unknown',
|
|
319
352
|
error: error.message
|
|
320
353
|
});
|
|
321
354
|
}
|