@onlineapps/service-wrapper 2.1.7 → 2.1.10

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onlineapps/service-wrapper",
3
- "version": "2.1.7",
3
+ "version": "2.1.10",
4
4
  "description": "Thin orchestration layer for microservices - delegates all infrastructure concerns to specialized connectors",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -273,6 +273,7 @@ class ServiceWrapper {
273
273
  * @private
274
274
  */
275
275
  _logPhase(phase, phaseName, status, error = null, duration = null) {
276
+ const serviceName = this.config.service?.name || 'unnamed-service';
276
277
  const logMsg = `[FÁZE ${phase}] ${phaseName} - ${status}`;
277
278
  const logData = {
278
279
  phase,
@@ -281,8 +282,19 @@ class ServiceWrapper {
281
282
  timestamp: new Date().toISOString(),
282
283
  duration,
283
284
  error: error ? { message: error.message, stack: error.stack } : null,
284
- serviceName: this.config.service?.name || 'unnamed-service'
285
+ serviceName
285
286
  };
287
+
288
+ // Structured log for service wrapper phases
289
+ console.log(`[${serviceName}:service-wrapper:init:PHASE_${status}] ${JSON.stringify({
290
+ timestamp: new Date().toISOString(),
291
+ service: serviceName,
292
+ phase,
293
+ phase_name: phaseName,
294
+ status,
295
+ duration_ms: duration,
296
+ error: error ? error.message : null
297
+ })}`);
286
298
 
287
299
  if (status === 'PASSED') {
288
300
  this.logger?.info(logMsg, logData);
@@ -1255,10 +1267,13 @@ class ServiceWrapper {
1255
1267
  }
1256
1268
 
1257
1269
  // Normalize message format: Gateway sends workflowId, orchestrator expects workflow_id
1270
+ // V2 format uses step_id, V1 used id - support both for backwards compatibility during migration
1271
+ const firstStep = message.cookbook?.steps?.[0];
1272
+ const firstStepId = firstStep?.step_id || firstStep?.id;
1258
1273
  const normalizedMessage = {
1259
1274
  ...message,
1260
1275
  workflow_id: message.workflow_id || message.workflowId,
1261
- current_step: message.current_step || (message.cookbook?.steps?.[0]?.id)
1276
+ current_step: message.current_step || firstStepId
1262
1277
  };
1263
1278
 
1264
1279
  // Validate normalized message has required fields
package/src/index.js CHANGED
@@ -11,6 +11,7 @@
11
11
  * @since 2.0.0
12
12
  */
13
13
 
14
+ const path = require('path');
14
15
  const ServiceWrapper = require('./ServiceWrapper');
15
16
  const { ConfigLoader } = require('./ConfigLoader');
16
17
 
@@ -21,8 +22,98 @@ const { ConfigLoader } = require('./ConfigLoader');
21
22
  // Note: HTTP logging middleware is now in each service's middlewares/httpLogging.js
22
23
  // It uses lazy logger access via lib/logger.js (set after wrapper.initialize())
23
24
 
25
+ /**
26
+ * Bootstrap a business service with standard configuration
27
+ * Eliminates boilerplate code in service index.js
28
+ *
29
+ * @param {string} serviceRoot - Service root directory (__dirname from index.js)
30
+ * @param {Object} [options] - Optional overrides
31
+ * @param {Object} [options.app] - Express app (default: require('./src/app'))
32
+ * @param {Object} [options.config] - Config (default: require('./src/config'))
33
+ * @param {Function} [options.setLogger] - Logger setter (default: require('./src/lib/logger').setLogger)
34
+ * @returns {Promise<{wrapper: ServiceWrapper, server: Object}>}
35
+ *
36
+ * @example
37
+ * // index.js (minimal)
38
+ * require('@onlineapps/service-wrapper').bootstrap(__dirname);
39
+ */
40
+ async function bootstrap(serviceRoot, options = {}) {
41
+ // Load dotenv first
42
+ require('dotenv').config({ path: path.join(serviceRoot, '.env') });
43
+
44
+ // Load app, config, and logger from service
45
+ const app = options.app || require(path.join(serviceRoot, 'src', 'app'));
46
+ const config = options.config || require(path.join(serviceRoot, 'src', 'config'));
47
+
48
+ // Logger setter is optional - some services may not have it
49
+ let setLogger = options.setLogger;
50
+ if (!setLogger) {
51
+ try {
52
+ const loggerModule = require(path.join(serviceRoot, 'src', 'lib', 'logger'));
53
+ setLogger = loggerModule.setLogger;
54
+ } catch (e) {
55
+ // No logger module - that's OK
56
+ setLogger = () => {};
57
+ }
58
+ }
59
+
60
+ console.log(`Starting ${config.service.name} v${config.service.version}...`);
61
+
62
+ // 1. Start HTTP server
63
+ const PORT = config.service.port;
64
+ const server = app.listen(PORT, () => {
65
+ console.log(`✓ HTTP server listening on port ${PORT}`);
66
+ console.log(`✓ Health check: http://localhost:${PORT}/health`);
67
+ });
68
+
69
+ // 2. Initialize Service Wrapper (MQ, Registry, Monitoring, etc.)
70
+ const wrapper = new ServiceWrapper({
71
+ app,
72
+ server,
73
+ serviceRoot,
74
+ config: {
75
+ service: {
76
+ name: config.service.name,
77
+ version: config.service.version,
78
+ port: config.service.port,
79
+ url: process.env.SERVICE_URL || `http://localhost:${PORT}`
80
+ },
81
+ wrapper: config.wrapper
82
+ },
83
+ operations: config.operations,
84
+ validationProof: config.validationProof
85
+ });
86
+
87
+ await wrapper.initialize();
88
+
89
+ // Initialize centralized logger for use throughout the service
90
+ if (setLogger && wrapper.logger) {
91
+ setLogger(wrapper.logger);
92
+ }
93
+
94
+ console.log(`✓ Service Wrapper initialized (MQ, Registry, Monitoring)`);
95
+ console.log(`✓ Local logs: logs/app.{date}.log`);
96
+ console.log(`✓ ${config.service.name} ready\n`);
97
+
98
+ // 3. Setup graceful shutdown
99
+ const shutdown = async () => {
100
+ console.log('\nShutting down gracefully...');
101
+ await wrapper.shutdown();
102
+ server.close(() => {
103
+ console.log('Server closed');
104
+ process.exit(0);
105
+ });
106
+ };
107
+
108
+ process.on('SIGTERM', shutdown);
109
+ process.on('SIGINT', shutdown);
110
+
111
+ return { wrapper, server };
112
+ }
113
+
24
114
  module.exports = ServiceWrapper;
25
115
  module.exports.ServiceWrapper = ServiceWrapper;
26
116
  module.exports.ConfigLoader = ConfigLoader;
117
+ module.exports.bootstrap = bootstrap;
27
118
  module.exports.default = ServiceWrapper;
28
- module.exports.VERSION = '2.1.6';
119
+ module.exports.VERSION = '2.1.10';