# data-service

`data-service` is the only user-safe data access boundary for Vinova Backbone
applications and microservices.

It exists to protect business data. Every request that reads or writes
user-scoped application data must pass through this service so the authenticated
user can be derived from the authentication token and every operation can be
restricted to the data that user is allowed to access.

## Data Access Boundary

Backbone separates raw persistence access from secure application data access:

- `datahub` exposes internal API access to all database tables. It is the
  persistence/data access layer and does not represent the user-facing security
  boundary.
- `data-service` exposes authenticated, user-scoped APIs. It reads the
  authentication token, derives the logged-in user server-side, applies
  ownership/sharing rules, and only then calls `datahub`.
- `AdminInterface` is the only frontend allowed to access `datahub` directly,
  and only for administrative/operational data management flows.
- User-facing frontends and product microservices must access business data
  through `data-service`, not through `datahub`.

This rule is mandatory because `datahub` can reach every table, while
`data-service` enforces the security layer that prevents callers from selecting
or modifying records owned by other users.

Browser clients and non-admin microservices must never send a trusted `userId`
in the request body or query string. `data-service` must derive the effective
user from the authentication token and build the authorization context itself.

The expected request flow is:

```text
UserInterface / product service
  -> data-service
     -> validate authentication context
     -> derive user and ownership scope
     -> apply authorization filters
     -> call datahub
     -> return only allowed data
```

Direct `datahub` access is reserved for internal platform operations and
AdminInterface tooling. It must not become a shortcut for application features.

## Quick Start

```bash
# Development
npm run dev

# Production
npm start
```

## Architecture

This service uses the centralized microservice framework:

- **BaseService** (modules/main.js): Business logic extends BaseService
- **serverFactory** (server.js): Express server with standard routes
- **No status.js**: Eliminated! Status routes provided by statusRouterFactory

`data-service` owns the authorization layer above `datahub`. Route handlers must
keep business authorization close to the API surface and must call `datahub`
only after the request has been associated with the authenticated user.

## Analytics Boundary

UserInterface must call `data-service` for analytics data.

`data-service` must not implement analytics rules directly. It must:

- authenticate frontend analytics requests
- derive the logged-in user from the token
- enforce ownership and sharing filters
- build an `authorizationContext` from trusted server-side data
- call `analytic-service` internal APIs with an internal JWT
- return only analytics data the logged-in user is allowed to access

When calling `analytic-service`, `data-service` must not forward browser-provided
`userId` values. If a user identifier is required, it must be placed under
`authorizationContext.subject.userId` after being derived from the token.

Internal analytics calls target:

- `POST /internal/analytics/overview`
- `POST /internal/analytics/properties/:propertyId/summary`
- `POST /internal/analytics/contracts/:contractId/summary`
- `POST /internal/analytics/contracts/:contractId/health`
- `POST /internal/analytics/bank-accounts/:bankAccountId/summary`
- `POST /internal/analytics/report`

Frontend-facing analytics endpoints:

- `GET /analytics/overview`
- `GET /analytics/properties/:id/summary`
- `GET /analytics/contracts/:id/summary`
- `GET /analytics/contracts/:id/health`
- `GET /analytics/bank-accounts/:id/summary`
- `GET /analytics/report`

Through Traefik these are exposed under `/data-service/analytics/*`.

Each endpoint derives the user from `req.userCtx`, applies ownership/sharing
checks through the shared access helpers, builds an internal
`authorizationContext`, calls `analytic-service`, and returns the canonical
payload received from the analytics boundary.

Internal token requirements:

- audience: `analytic-service`
- scope: `analytics:read`
- caller: `data-service`

Configuration:

- `ANALYTIC_SERVICE_URL`, fallback `http://analytic-service:3013`

## Code Reduction

Traditional approach: ~650 lines (main.js + server.js + status.js)
**This service: ~165 lines (75% reduction)**

## Standard Endpoints

- `GET /status/health` - Health check
- `GET /status/info` - Service information
- `GET /release` - Release information
- `GET /settings` - Current settings
- `POST /settings/reload` - Reload settings from DB

## Custom Endpoints

Administrative settings (authenticated platform administrators only):

- `GET /admin/settings` - Read settings metadata through `data-service`.
- `PUT /admin/settings/:key` - Persist a setting value in the database.

Add your custom routes in `server.js`:

```javascript
routes: [
  { path: '/api', router: apiRouter, protected: true }
]
```

## Development

Port: 5003

Access locally: http://localhost:5003

## Documentation

- Shared infrastructure: `../../packages/backbone-shared`
