152 lines
5.5 KiB
Markdown
152 lines
5.5 KiB
Markdown
# 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/
|
||
commands/ # state-changing use cases (or equivalent)
|
||
queries/ # read use cases (or equivalent)
|
||
policies/ # authz / domain policies
|
||
specifications/
|
||
repositories/
|
||
providers/ # adapters if this service owns providers
|
||
events/
|
||
permissions/
|
||
middlewares/
|
||
validators/
|
||
tests/
|
||
alembic/
|
||
Dockerfile.dev
|
||
requirements.txt
|
||
README.md
|
||
```
|
||
|
||
Mandatory artifact defaults: [mandatory-phase-artifacts.md](mandatory-phase-artifacts.md). Boundaries: [boundary-rules.md](boundary-rules.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) |
|
||
| `GET /capabilities` | Feature/channel discovery for platform services |
|
||
| `GET /metrics` | Operational metrics (or justified N/A) |
|
||
|
||
Register health URL in [service-manifest.yaml](service-manifest.yaml). Keep OpenAPI accurate for `/api/v1` routes.
|
||
|
||
## Registration Checklist
|
||
|
||
- [ ] [service-manifest.yaml](service-manifest.yaml)
|
||
- [ ] [module-registry.md](../module-registry.md)
|
||
- [ ] ADR if platform ownership decision
|
||
- [ ] Phase doc + handover (DoD + Enterprise Completeness)
|
||
- [ ] Compose/port docs when runtime is in scope
|
||
- [ ] Tests per [testing-template.md](testing-template.md)
|
||
- [ ] Mandatory artifacts for foundation phase delivered
|
||
|
||
## Related Documents
|
||
|
||
- [Module Template](module-template.md)
|
||
- [Phase Template](phase-template.md)
|
||
- [Definition of Done](definition-of-done.md)
|
||
- [Boundary Rules](boundary-rules.md)
|
||
- [Module Registry](../module-registry.md)
|
||
- [Service Architecture](../architecture/service-architecture.md)
|
||
- [ADR-001](../architecture/adr/ADR-001.md)
|