TorbatYar/docs/ai-framework/service-template.md
2026-07-28 20:39:10 +03:30

5.5 KiB
Raw Blame History

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, Communication ADR-012).

For a slice inside an existing service, use module-template.md instead.

Architecture

  1. Deployable FastAPI app with package layout per service-architecture.md and coding-standards.md.
  2. Layering: API → Services → Repositories → Models.
  3. Database-per-service (ADR-001).
  4. Outbox-ready events (ADR-006).
  5. No imports of other services models/repos.
  6. Frontend remains a separate client (ADR-002).
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. Boundaries: 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 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
shared-lib Envelope, JWT helpers, exceptions only
AI Optional contract; core flows work without AI

Public APIs

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
  • Catalog: 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, 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

Monitoring

  • Structured logging via service logging setup
  • Operational stats endpoints when the domain requires them (see Communication monitoring pattern)
  • Align with 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. Keep OpenAPI accurate for /api/v1 routes.

Registration Checklist