Files
mercadodevida/work/artifacts/F-153/implementer.md
2026-08-22 07:41:08 +02:00

3.3 KiB

F-153 — Implementer Evidence

Build

Feature: F-153 — Orders: associate the linked customer's email to the order read model and display it (customer email was missing despite the user having an email).

Changes (production)

  • src/modules/orders/domain/order.ts — added email?: string | null to OrderView (read model). Order core aggregate is untouched (email is a denormalized read attr).
  • src/modules/orders/infrastructure/pg-order-repository.ts:
    • added email: string | null to OrderRow;
    • added toOrderView(row, items) helper;
    • findById, findByIdAndUserId, findAll, search now SELECT o.*, u.email with LEFT JOIN identity_users u ON u.id = o.user_id (reuses the existing search join pattern);
    • every OrderView is built via toOrderView, so email is always populated (string | null; null when the order has no linked identity_user).
  • src/modules/orders/api/orders.routes.ts:
    • serializeOrder now emits email: order.email ?? null (detail + list);
    • admin force-transition (POST /orders/:id/transitions/admin) consumes order.email (the associated email) and no longer issues a separate inline SELECT email FROM identity_users lookup → no N+1, single source of truth.

Changes (tests)

  • new src/modules/orders/infrastructure/pg-order-repository.test.ts:
    • findById resolves email via the identity_users join (asserts the query contains identity_users + u.email and returns the row's email);
    • returns null when the order has no linked identity_user;
    • returns undefined when the order does not exist.
  • existing OrderView literals (order-service, payments-service, checkout-service) needed no change (email is optional on the view; fixtures omit it → serialized as null).

Boundary / compatibility notes

  • identity_users is referenced only as a SQL table name (pre-existing pattern in search); no TypeScript import crosses the identity↔orders boundary → lint:boundaries unchanged.
  • No migration (identity_users.email already citext NOT NULL UNIQUE).
  • Additive API field; no state-machine / endpoint / contract change.

Evidence (commands + results)

  • npx tsc --noEmit0 errors (TSC_EXIT:0).
  • npx vitest run200 passed | 56 skipped (50 files); new F-153 suite orders/infrastructure/pg-order-repository.test.ts3 passed.
  • npx eslint (touched files) → 0 errors / 0 warnings (ESLINT_EXIT:0).
  • npx prettier --check on touched files → only pre-existing baseline warnings (identical to HEAD for both pg-order-repository.ts and orders.routes.ts; my added lines are short / long string literals accepted by Prettier; no new reformatting).
  • npm run lint:boundaries1 violation, pre-existing (security/routes R1); 0 new violations from F-153.
  • git diff --checkclean (no whitespace errors).
  • ./scripts/verify.shexit 0 (backlog 270 features valid; runtime-status advance to build/running with F-153 in_progress — see below).

Decisions

  • Resolved via the read model (Option A in ADR) rather than route-layer lookups (Option B) because orders already joins identity_users in SQL for search; generalizing that join to all order reads gives the email as a first-class read attribute and removes the per-request lookup from the admin transition.