# Entity Template Standards for domain entities / ORM models in every service. ## Entities | Rule | Detail | | --- | --- | | Naming | `PascalCase` class; `snake_case` table | | Primary key | UUID (preferred) or documented exception | | Tenant | Business entities include non-null `tenant_id` ([ADR-003](../architecture/adr/ADR-003.md)) | | Timestamps | `created_at` / `updated_at` (timezone-aware) | | Identity | No business meaning in surrogate keys | | Mapping | SQLAlchemy models in `app/models/`; no business workflows in model methods beyond trivial helpers | ## Relationships 1. Relationships only within the same database. 2. No cross-service foreign keys. 3. Cross-service association: store external ref IDs (`*_ref`, UUID strings) without FK. 4. Prefer explicit relationship directions; avoid implicit cascade deletes across aggregates unless documented. 5. Owning aggregate controls lifecycle of child rows. ## Indexes 1. Index `tenant_id` (alone or composite) for tenant-scoped lists. 2. Composite indexes for common filters: `(tenant_id, status)`, `(tenant_id, created_at)`, unique business numbers per tenant. 3. Unique constraints that are tenant-scoped must include `tenant_id`. 4. Document unusual indexes in the phase/migration notes. ## Constraints 1. DB constraints enforce integrity the domain relies on (unique, check, non-null). 2. Do not rely only on application validation for critical invariants. 3. Monetary / quantity fields use precise types (Numeric) where applicable. 4. Enums: DB + Python enums kept in sync; prefer string enums for readability. ## Soft Delete | Rule | Detail | | --- | --- | | Default for master/business records | Prefer `deleted_at` / `is_deleted` pattern used by sibling modules | | Queries | Default repositories exclude soft-deleted rows | | Uniqueness | Unique constraints must consider soft-delete strategy (partial unique indexes when required) | | Hard delete | Only when phase explicitly allows (e.g. ephemeral logs with retention policy) | ## Audit 1. Every business action must be auditable ([project-principles.md](../development/project-principles.md)). 2. Prefer `created_by` / `updated_by` (actor ids) on mutable entities when the service pattern uses them. 3. Sensitive domains keep append-only audit tables (CRM/Loyalty/Accounting patterns). 4. Audit rows are tenant-scoped and immutable after insert. ## Validation 1. Structural validation: Pydantic schemas at API boundary. 2. Domain validation: service-layer validators (`app/validators/`). 3. DB constraints: last line of defense. 4. Never trust client-provided `tenant_id` over resolved tenant context. 5. Normalize phones/codes via shared helpers where applicable. ## Entity Checklist (per new table) - [ ] Table name + model documented in phase - [ ] `tenant_id` (if business data) - [ ] Indexes / uniques defined - [ ] Soft delete policy stated - [ ] Audit fields or audit table linkage - [ ] Migration included - [ ] Schema reference updated when public/shared docs require it ([database-schema.md](../reference/database-schema.md)) ## Related Documents - [Database Architecture](../architecture/database-architecture.md) - [Repository Template](repository-template.md) - [Coding Standards](../development/coding-standards.md) - [ADR-001](../architecture/adr/ADR-001.md) ยท [ADR-003](../architecture/adr/ADR-003.md)