# Service Template

How to design a new **independent** service under `backend/services/<name>/`.

Use when the capability is shared across domains or requires sole database ownership (patterns: Loyalty [ADR-011](../architecture/adr/ADR-011.md), Communication [ADR-012](../architecture/adr/ADR-012.md)).

For a slice inside an existing service, use [module-template.md](module-template.md) instead.

## Architecture

1. Deployable FastAPI app with package layout per [service-architecture.md](../architecture/service-architecture.md) and [coding-standards.md](../development/coding-standards.md).
2. Layering: `API → Services → Repositories → Models`.
3. Database-per-service ([ADR-001](../architecture/adr/ADR-001.md)).
4. Outbox-ready events ([ADR-006](../architecture/adr/ADR-006.md)).
5. No imports of other services’ models/repos.
6. Frontend remains a separate client ([ADR-002](../architecture/adr/ADR-002.md)).

```
backend/services/<name>/
  app/
    api/v1/
    core/          # config, database, security, logging
    models/
    schemas/
    services/
    repositories/
    providers/     # adapters if this service owns providers
    events/
    permissions/
    middlewares/
    validators/
    tests/
  alembic/
  Dockerfile.dev
  requirements.txt
  README.md
```

## Ownership

| Owns | Must not own |
| --- | --- |
| Its database schema and migrations | Other services’ tables |
| Its permission tree `{service}.*` | Foreign domain aggregates |
| Its public API + publish events | UI business rules |
| Provider adapters for its channel/domain | Direct calls into other DBs |

Document boundaries in [module-boundaries.md](../architecture/module-boundaries.md) when introducing a platform service.

## Dependencies

| Kind | Rule |
| --- | --- |
| Core | Entitlement / tenant identity as required |
| Other services | HTTP + events only |
| Providers | Behind protocols; register in [provider-registry.md](../provider-registry.md) |
| shared-lib | Envelope, JWT helpers, exceptions only |
| AI | Optional contract; core flows work without AI |

## Public APIs

- Versioned under `/api/v1`
- Documented in service README and eventually [api-reference.md](../reference/api-reference.md) / [services-contracts.md](../reference/services-contracts.md)
- Auth: JWT + tenant header pattern used by sibling services
- Stable error codes via shared exceptions
- See [api-template.md](api-template.md)

## Private APIs

- Internal-only routes (if any) require internal service token or network isolation
- Never expose admin debug endpoints without auth in non-dev profiles
- Do not publish private routes in public contracts

## Events

- Publish domain events for state changes other services may need
- Prefer outbox in the same transaction as writes
- Naming and payload rules: [event-template.md](event-template.md)
- Catalog: [event-catalog.md](../reference/event-catalog.md)

## Database Ownership

| Field | Value |
| --- | --- |
| Database name | `<name>_db` |
| Migrations | Alembic in this service only |
| Cross-DB FK | Forbidden |
| Tenant column | Required on business tables |

Reference: [database-architecture.md](../architecture/database-architecture.md), [database-schema.md](../reference/database-schema.md).

## Configuration

- All settings via env / settings class — no hardcoded secrets or brand
- Document keys in `.env.example` and service README when the phase wires runtime
- Feature flags / entitlement keys documented

## Permissions

- Prefix: `{service}.*`
- Map routes to permission checks
- Document tree in module registry and phase doc

## Tenant Awareness

- Middleware / deps resolve `tenant_id`
- Repositories always filter by tenant for tenant-owned rows
- Isolation tests mandatory
- See [multi-tenant-architecture.md](../architecture/multi-tenant-architecture.md)

## Monitoring

- Structured logging via service logging setup
- Operational stats endpoints when the domain requires them (see Communication monitoring pattern)
- Align with [deployment/monitoring.md](../deployment/monitoring.md)

## Health Checks

| Endpoint | Purpose |
| --- | --- |
| `GET /health` | Liveness (and basic dependency signal as appropriate) |
| Optional `GET /capabilities` | Feature/channel discovery for platform services |

Register health URL in [service-manifest.yaml](service-manifest.yaml).

## Registration Checklist

- [ ] [service-manifest.yaml](service-manifest.yaml)
- [ ] [module-registry.md](../module-registry.md)
- [ ] ADR if platform ownership decision
- [ ] Phase doc + handover
- [ ] Compose/port docs when runtime is in scope
- [ ] Tests per [testing-template.md](testing-template.md)

## Related Documents

- [Module Template](module-template.md)
- [Phase Template](phase-template.md)
- [Module Registry](../module-registry.md)
- [Service Architecture](../architecture/service-architecture.md)
- [ADR-001](../architecture/adr/ADR-001.md)
