# 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 1. State change + outbox row in one transaction ([ADR-006](../architecture/adr/ADR-006.md)). 2. Event types follow [event-template.md](event-template.md). 3. 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](testing-template.md). ## Related Documents - [Repository Template](repository-template.md) - [API Template](api-template.md) - [Project Principles](../development/project-principles.md) - [Service Architecture](../architecture/service-architecture.md) - [Event-Driven Architecture](../architecture/event-driven-architecture.md)