Include Loyalty/Communication/Sports Center backends and registry updates alongside production nginx and compose wiring. Co-authored-by: Cursor <cursoragent@cursor.com>
2.0 KiB
2.0 KiB
Service Layer Template
Standards for business logic services.
Responsibility
Services:
- Own domain rules and orchestration
- Validate invariants (via validators)
- Authorize at domain level when required (with permission deps at API)
- Write audit records
- Write outbox/domain events in the same transaction as state changes
- Call other services only via HTTP clients / events — never via foreign repos
Services must not:
- Depend on FastAPI
Request/ response objects - Emit raw SQL bypassing repositories (except rare documented cases)
- Perform provider I/O without going through provider adapters owned by the service
- Mutate another aggregate’s invariants across boundaries without explicit domain rules
Conventions
| Topic | Rule |
|---|---|
| Location | app/services/ |
| Naming | {Capability}Service |
| Dependencies | Repositories, validators, event publisher, provider protocols |
| DTOs | Accept/return schema objects or typed domain results — not ORM leakage to API |
| Errors | Raise shared/domain exceptions with stable codes |
| Idempotency | Document for retried operations (OTP, webhooks, messaging) |
Transaction & Events
- State change + outbox row in one transaction (ADR-006).
- Event types follow event-template.md.
- Failures calling remote systems must not corrupt local invariants; use async patterns where required (Communication pattern).
Audit
- Record actor, action, entity, tenant, timestamp for sensitive mutations.
- Prefer dedicated audit tables where the service already has them.
Testing
Service tests cover business rules with DB or fakes — see testing-template.md.