@onlineapps/service-wrapper 2.1.113 → 2.1.115

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.113",
3
+ "version": "2.1.115",
4
4
  "description": "Thin orchestration layer for microservices - delegates all infrastructure concerns to specialized connectors",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -1078,7 +1078,7 @@ class ServiceWrapper {
1078
1078
  _setupHealthChecks() {
1079
1079
  const healthEndpoint = this.config.wrapper?.health?.endpoint || '/health';
1080
1080
 
1081
- this.app.get(healthEndpoint, async (req, res) => {
1081
+ const healthHandler = async (req, res) => {
1082
1082
  const health = {
1083
1083
  status: 'healthy',
1084
1084
  service: this.config.service?.name || 'unnamed-service',
@@ -1113,7 +1113,16 @@ class ServiceWrapper {
1113
1113
  }
1114
1114
 
1115
1115
  res.json(health);
1116
- });
1116
+ };
1117
+
1118
+ // Health route must be registered BEFORE catch-all 404/error handlers.
1119
+ // Services register routes (including 404) in app.js before ServiceWrapper initializes.
1120
+ // We use _healthHandler reference that bootstrap() registered early in the stack.
1121
+ if (this._healthRouteRegistered) {
1122
+ this._healthImpl = healthHandler;
1123
+ } else {
1124
+ this.app.get(healthEndpoint, healthHandler);
1125
+ }
1117
1126
 
1118
1127
  this.logger?.info(`Health check endpoint registered at ${healthEndpoint}`);
1119
1128
 
package/src/index.js CHANGED
@@ -95,6 +95,31 @@ async function bootstrap(serviceRoot, options = {}) {
95
95
  stack.pop();
96
96
  stack.unshift(lastLayer);
97
97
 
98
+ // Register /health route BEFORE service's 404 handler.
99
+ // ServiceWrapper._setupHealthChecks() will later set _healthImpl with actual MQ checks.
100
+ // Until then, this returns a basic healthy response (service is starting up).
101
+ let wrapperRef = null;
102
+ const healthEndpoint = config.wrapper?.health?.endpoint || '/health';
103
+ app.get(healthEndpoint, async (req, res) => {
104
+ if (wrapperRef && wrapperRef._healthImpl) {
105
+ return wrapperRef._healthImpl(req, res);
106
+ }
107
+ res.json({ status: 'starting', service: config.service.name, timestamp: new Date().toISOString() });
108
+ });
109
+
110
+ // Move health route before 404/error handlers (same stack technique as tenant context)
111
+ const healthLayer = stack.pop();
112
+ if (healthLayer) {
113
+ const catchAllIdx = stack.findIndex((layer, i) =>
114
+ i > 0 && !layer.route && !['query', 'expressInit', 'jsonParser', 'urlencodedParser'].includes(layer.name)
115
+ );
116
+ if (catchAllIdx > 0) {
117
+ stack.splice(catchAllIdx, 0, healthLayer);
118
+ } else {
119
+ stack.push(healthLayer);
120
+ }
121
+ }
122
+
98
123
  // 1. Start HTTP server
99
124
  const PORT = config.service.port;
100
125
  const server = app.listen(PORT, () => {
@@ -123,7 +148,9 @@ async function bootstrap(serviceRoot, options = {}) {
123
148
  validationProof: config.validationProof
124
149
  });
125
150
 
151
+ wrapper._healthRouteRegistered = true;
126
152
  await wrapper.initialize();
153
+ wrapperRef = wrapper;
127
154
 
128
155
  // Initialize centralized logger for use throughout the service
129
156
  if (setLogger && wrapper.logger) {