npm package: @onlineapps/service-wrapper
Description: Thin orchestration layer for microservices - delegates all infrastructure concerns to specialized connectors
Author: OA Drive Team
Latest version: 2.3.0

# @onlineapps/service-wrapper

**Collection of connectors providing all infrastructure components for business services**

Service Wrapper is a set of reusable connector components that handle message queue operations, service registration, monitoring, and health checks for microservices in a single-process architecture.

> **For complete architecture documentation, see [docs/FINAL_ARCHITECTURE.md](./docs/FINAL_ARCHITECTURE.md)**

## Naming Convention

This package uses `@onlineapps/service-wrapper` WITHOUT any connector prefix because:
- It's the main orchestration layer, not a specific connector
- All services depend on it directly
- It aggregates all other connectors (base, infra, orch)

Directory: `/shared/connector/conn-app-service-wrapper/` (historical, kept for backward compatibility)

## Purpose

This package provides the infrastructure layer that sits between:
- **Message Queues** (RabbitMQ) and **Services** (business logic)
- **Workflow Engine** and **Service APIs**
- **Service Registry** and **Service Implementation**

## Key Features

- **Automatic workflow processing** - Handles cookbook execution
- **Message queue integration** - Subscribes to queues, routes messages
- **Service registration** - Auto-registers with service registry
- **API-to-Cookbook mapping** - Converts workflow steps to API calls
- **Error handling** - Retry logic, DLQ routing
- **Health checks** - Automatic health endpoint (`GET /health`)
- **Info endpoint** - Runtime version, validation, and standard level info (`GET /info`)

## Architecture

```
[RabbitMQ Message] → [Service Wrapper] → [Service API Call] → [Business Logic]
                           ↑                    ↑                    ↑
                    This package         operations.json     Your service
                    Handles all          Defines API         Pure business
                    infrastructure       mapping             logic only
```

## Usage

### 1. Install Service Wrapper

```bash
npm install @onlineapps/service-wrapper
```

### 2. Create Service Entry Point

```javascript
// index.js
const express = require('express');
const { ServiceWrapper } = require('@onlineapps/service-wrapper');

// Load your Express app (business logic only)
const app = require('./src/app');

// Load configuration
const config = require('./conn-config/config.json');
const operations = require('./conn-config/operations.json');

async function start() {
  // 1. Start Express server
  const server = app.listen(process.env.PORT || 3000);

  // 2. Initialize wrapper components
  const wrapper = new ServiceWrapper({
    app,
    server,
    config,
    operations
  });

  await wrapper.initialize();
  console.log('Service ready with all infrastructure components');
}

start().catch(console.error);
```

### 2. Service Receives

The wrapper automatically:
- Subscribes to `{serviceName}.workflow` queue
- Processes workflow messages
- Calls your API endpoints based on cookbook steps
- Routes results to next service

### 3. Your Service Focuses on Business Logic

Your service only needs to:
- Expose API endpoints
- Implement business logic
- Return results

NO infrastructure code needed in your service!

## Configuration

### Environment Variable Parsing

**ServiceWrapper handles environment variable parsing directly** rather than delegating to a separate connector. This design decision is based on:

1. **Core Responsibility** - Configuration loading is fundamental to the wrapper's initialization, not a specialized concern
2. **Simplicity** - Avoids creating a separate connector for ~20 lines of parsing logic
3. **Performance** - Eliminates unnecessary abstraction layers for a trivial operation
4. **Universal Need** - All connectors (MQ, Registry, Cache) require parsed configuration

The wrapper parses `${VAR:default}` syntax in configuration files:
- `${RABBITMQ_URL}` - Uses environment variable, fails if not set
- `${PORT:3000}` - Uses environment variable, defaults to 3000 if not set
- `${ENABLED:true}` - Uses environment variable, defaults to true

This follows Docker/Kubernetes best practices for configuration management while keeping the wrapper architecture clean and focused.

### operations.json
```json
{
  "operations": {
    "operation-name": {
      "description": "Operation description",
      "endpoint": "/api/operation",
      "method": "POST",
      "input": { "name": { "type": "string", "required": true } },
      "output": { "result": { "type": "string" } }
    }
  }
}
```

### config.json
```json
{
  "service": {
    "name": "my-service",
    "port": "${PORT:3000}"
  },
  "wrapper": {
    "mq": {
      "url": "${RABBITMQ_URL:amqp://localhost:5672}",
      "enabled": "${MQ_ENABLED:true}"
    },
    "registry": {
      "url": "${REGISTRY_URL}",
      "enabled": "${REGISTRY_ENABLED:false}"
    },
    "monitoring": {
      "enabled": "${MONITORING_ENABLED:true}"
    },
    "health": {
      "endpoint": "/health"
    }
  }
}
```

## What This Handles

### Workflow Processing
- Receives workflow messages from queue
- Validates cookbook structure
- Executes steps for this service
- Routes to next service or completion

### API Mapping
- Maps cookbook steps to API calls
- Handles input/output transformation
- Manages context passing between steps

### Infrastructure Concerns
- Service registration and health checks
- Message queue subscription and publishing
- Error handling and retry logic
- Dead letter queue routing

## Service Requirements

Your service needs:
1. **Operations specification** - Describes your API operations ([Operations Standard](/docs/OPERATIONS_STANDARD.md))
2. **Express app** - With business logic endpoints
3. **Configuration files** - Service config and environment variables

Your service should NOT have:
- Workflow processing code
- Message queue operations
- Service registration logic
- Connector imports

## Example Service Structure

```
my-service/
├── src/
│   ├── app.js            # Express app (business logic only)
│   ├── routes/           # API endpoints
│   └── services/         # Business logic
├── conn-config/
│   ├── config.json       # Service & wrapper configuration
│   └── operations.json   # Operations specification
├── index.js              # Main entry point (initializes wrapper)
└── package.json          # Dependencies including @onlineapps/service-wrapper
```

## Testing

The wrapper provides test utilities:

```javascript
const { TestWrapper } = require('@onlineapps/service-wrapper');

describe('My Service', () => {
  let wrapper;

  beforeAll(() => {
    wrapper = new TestWrapper({
      service: myApp,
      mockQueues: true,
      mockRegistry: true
    });
  });

  test('processes workflow step', async () => {
    const result = await wrapper.processStep({
      type: 'task',
      service: 'my-service',
      operation: 'doSomething'
    });
    expect(result).toBeDefined();
  });
});
```

## Info Endpoint

ServiceWrapper automatically registers `GET /info` on every business service. No implementation needed.

Returns runtime information:
- **Service & wrapper versions** + all `@onlineapps/*` dependency versions
- **Validation status** — contract fingerprint, proof age, test results
- **Infrastructure fingerprint** — library manifest hash from Redis
- **Implementation standard level** — highest cumulative level satisfied (v1.0, v1.1, v1.2, ...)
- **Revalidation state** — current backoff cycle status

Standard levels are determined by `ServiceStructureValidator` from `@onlineapps/conn-orch-validator`. See [Implementation Standard Levels](/docs/standards/SERVICE_ENDPOINTS.md#implementation-standard-levels) and [Validator README](/shared/connector/conn-orch-validator/README.md#implementation-standard-levels).

---

## Migration from Embedded Infrastructure

If your service currently has workflow code:

1. Install service-wrapper: `npm install @onlineapps/service-wrapper`
2. Remove all direct connector imports from service code (use wrapper instead)
3. Delete workflow processing files
4. Wrap your Express app with ServiceWrapper
5. Test that everything still works

## License

PROPRIETARY - All rights reserved