Definition of Done
Every PR must satisfy every applicable box before merge. The PR template enforces this checklist. Boxes are grouped by surface; tick only the groups that the PR actually touches.
Universal (every PR)
- Code reviewed and approved by at least one other engineer.
- Conventional commit messages (
feat,fix,refactor,docs,test,chore,perf,ci,build). - Lint + format + typecheck pass locally and in CI (TypeScript
strict: true, zero errors). - Unit tests pass. Coverage thresholds met: 95% on aggregates, 100% on value objects, 90% on domain services.
- Mutation testing on changed files ≥ 75% (aggregates), ≥ 85% (VOs).
- No new
TODO/FIXMEwithout a linked issue. - No
.only,.skip,debugger, orconsole.logleft behind. - Secrets are not committed.
.env.exampleupdated if new env vars added. - Changelog entry under the affected service (or under
docs/CHANGELOG.mdfor cross-cutting changes).
Features that touch data / domain
-
tenant_id uuid NOT NULLon every new multi-tenant table. - RLS policy named
<table>_tenant_isolationadded in the same migration. - Migration is backward-compatible within the current major version (additive only; destructive changes ship behind a flag and a follow-up cleanup migration).
- Repository methods accept
tenantIdas an explicit parameter (no implicit context). - Domain aggregate guards against cross-tenant references in its constructor (throws
MELMASTOON.GENERAL.CROSS_TENANT_REFERENCE). - Branded ID types used (
TenantId,ReservationId,KeyCredentialId, …) — no rawstringIDs in domain or application layers. - Money stored as
bigintmicro-units; columns suffixed_micro. No floats. - Integration tests with Testcontainers (Postgres) cover happy path + failure path.
-
services/<name>/DATA_MODEL.mdupdated. -
test/integration/tenant-isolation.spec.tsstill passes.
Features that touch API
- OpenAPI generated, committed (
openapi.json), and the OpenAPI diff gate is green (no breaking changes without a major version bump). -
services/<name>/API_CONTRACTS.mdupdated. - Pact consumer contract test added/updated; Pact broker green.
- Error responses use canonical codes from ERROR_CODES.md (
MELMASTOON.<DOMAIN>.<CODE>). -
Idempotency-Keyhandling verified on every write endpoint (POST/PUT/PATCH/DELETE). - Cursor-based pagination (no offset/limit on lists > 100 items).
- No response leaks domain entities — DTOs only.
- Deprecation headers (
Sunset,Deprecation) set if deprecating a route.
Features that touch events
- New event types added to the schema registry under
event-schemas/melmastoon/<service>/<aggregate>/<event>/v<N>.json. -
services/<name>/EVENT_SCHEMAS.mdupdated. - Outbox pattern used in the producer (transactional with the aggregate write).
- Inbox pattern used in every consumer (dedupe by message ID + idempotent apply).
- Schema conformance contract test added.
- No PII in event payloads. References by ID only.
- Retention class declared (
operational/regulated/audit). -
test/integration/outbox.spec.tsandtest/integration/inbox.spec.tsstill pass.
Features that touch security (auth, payment, lock, key, secrets)
-
services/<name>/SECURITY_MODEL.mdupdated. - RBAC/ABAC matrix updated in tests.
- Mandatory
security-revieweragent run for any change toiam-service,payment-gateway-service,billing-service,lock-integration-service, or any code that handles secrets, key credentials, or payment instruments. Zero critical/high findings required to merge. - Secrets managed via GCP Secret Manager + KMS envelope encryption. Never in env files committed to git.
- argon2id (no bcrypt, no PBKDF2) for any new password handling.
- JWT TTLs respected: ≤ 15 min access, ≤ 30 d refresh; refresh tokens rotated on use.
- No PII in logs (guest names, card PANs, key credential codes, lock pairing secrets, JWTs).
- Lock vendor secrets stored only in Secret Manager; rotated per the schedule in
lock-integration-service/SECURITY_MODEL.md.
Features that touch AI
- All provider calls go through
ai-orchestrator-service. - No direct import of
openai,anthropic,@google-cloud/vertexai, or any LLM SDK outsideai-orchestrator-service. -
AIProvenanceVO ({ model, version, promptId, traceId, reviewedBy?, reviewedAt?, local }) attached to every persisted AI artifact. - HITL flow: any AI-generated guest-facing or irreversible action requires
decisionIdbefore commit (e.g., AI-suggested rate change, AI-drafted guest message, AI auto-cancel). - Pre-call + post-call moderation applied where the call surfaces text to a user.
- Prompt regression suite green (≥ parity vs baseline).
- AI telemetry fields present (
ai.purpose,ai.model,ai.cost_micro_usd,ai.safety.action,ai.local). - Feature flag default-off, per-tenant opt-in.
Features that touch frontend (web, mobile, desktop)
- i18n strings extracted — every user-facing string flows through ICU MessageFormat / the i18n bundle. No hardcoded English / Pashto / Dari / Arabic.
- RTL screenshot added to the PR for any UI change. Both LTR and RTL Storybook stories present.
- Logical CSS properties only (
padding-inline,margin-block,inset-inline-start, …). Neverpadding-left/rightormargin-left/right. - Accessibility check passes — axe-playwright scan shows zero new serious/critical findings. WCAG 2.2 AA target.
- Animations gated on
prefers-reduced-motion. - Lighthouse / web-vitals budgets met (LCP, INP, CLS, JS gzip per page) on consumer + tenant booking surfaces.
- Forms use React Hook Form + shared Zod schemas from
@ghasi/api-contracts. - Desktop changes: feature works offline (or degrades with a clear UI sync indicator), and the affected sync aggregate has a declared conflict policy in
SYNC_CONTRACT.md.
Features that touch observability
-
@ghasi/telemetryused (no vendor SDKs imported directly). - Logs include
trace_id,tenant_id,request_idon every line. - Metrics carry the
tenant_idlabel (and aservicelabel). - Traces propagate W3C
traceparentacross HTTP, Pub/Sub, and the desktop sync boundary. - Required span attributes present on DB / Redis / HTTP / Pub/Sub / Cloud Storage / AI / lock-vendor calls.
- SLIs/SLOs updated in
services/<name>/OBSERVABILITY.md. - Any new alert has a runbook + named owner.
Bug fixes (in addition to above)
- A regression test is included in the same commit.
- Root cause documented in the PR body (not just the symptom).
New service (in addition to above)
- All 17 docs from SERVICE_TEMPLATE.md exist (stubs acceptable initially).
- Directory skeleton in place (four-layer NestJS).
-
tenant-isolation.spec.ts,outbox.spec.ts,inbox.spec.tspassing. - Pact broker + schema registry updated.
- OpenTelemetry verified in staging (traces + logs + metrics visible with
tenant_id). - Helm chart + Terraform module added.
-
SERVICE_READINESS.mdsigned off by tech lead + SRE before prod.
Architectural changes
- ADR added under
docs/architecture/for any cross-cutting decision: a new dependency, a new vendor, a sync conflict policy change, a security boundary change, an event topology change, or a new bounded context. The ADR captures context, decision, alternatives considered, and consequences.
Before production deploy
- Canary 5% for 30 min passed in staging.
- Rollback plan verified.
- On-call alerted of deploy window.
- Feature flags set as intended.
Spec vs code
- If this PR changes behavior that contradicts a spec doc, update the spec (with user approval) in the same PR.
- If this PR adds a new rule worth remembering, add it to
AGENTS.md(in the future code monorepo), the matching.cursor/rules/*.mdc, ordocs/standards/*.mdin the same PR.