feat(F-154): completed feature

This commit is contained in:
chattie
2026-08-22 08:35:46 +02:00
parent 1415590106
commit 5098723284
19 changed files with 535 additions and 114 deletions

View File

@@ -1,34 +1,28 @@
# F-153 — Acceptance Criteria
# F-154 — Acceptance Criteria
## AC1 — Order detail exposes customer email
`GET /orders/:id` and `GET /orders/:id/admin` responses include a top-level `email` field equal
to the linked `identity_users.email`. When the order has no linked identity_user, `email` is
`null`.
## AC1 — Customers list shows only storefront customers
`GET /users` (admin) devuelve SOLO usuarios con `role = 'customer'`. Un usuario
interno (admin/editor) NO aparece en el listado. El buscador `q` sigue filtrando sobre email
dentro de los clientes.
## AC2 — Admin order list exposes customer email
Every item in `GET /orders` (admin list) includes the `email` field, resolved via the same
read-model association (no N+1 per item beyond the repository's single read).
## AC2 — Users list shows only internal/backoffice users
`GET /admin/users` (admin, default sin `?role=`) devuelve SOLO usuarios con
`role != 'customer'` (admin/editor/pos). Un cliente (`role = 'customer'`) NO aparece.
`?role=admin` y `?role=editor` siguen afinando dentro de internos; `?role=customer`
NO devuelve clientes (devuelve vacío) — la separación está forzada en backend.
## AC3 — Admin force-transition uses the associated email
`POST /orders/:id/transitions/admin` resolves the customer email from the order view
(`order.email`) — it no longer issues a separate inline `SELECT email FROM identity_users`.
When `email` is present, the status notification is sent; when absent, it logs
"El cliente no tiene email asociado" via `request.log.warn` and still completes the transition.
## AC3 — No regression on user profile / addresses
`/users/:id` (GET/PATCH) owner-or-admin sigue devolviendo/editando CUALQUIER usuario
sin filtro por rol (admin ve perfil de cliente; cliente ve el suyo). CRUD de
`/users/:id/addresses` inalterado.
## AC4 — No regression
All existing order flows keep their behavior (create, customer/admin detail, list, edit items,
shipping update, transitions). Only `email` is added to serialization; no new state transitions,
endpoints, or side effects.
## AC4 — No boundary / injection violation
- `identity_users` referenciado solo como tabla SQL (sin import TS).
- Valores `q`/`role` parametrizados; el literal `'customer'`/`'customer'` es constante de código.
- Sin migración.
## AC5 — No migration
`email` is derived from the pre-existing `identity_users.email` column; no schema migration is
required.
## AC6 — Quality gates
- `tsc --noEmit`: 0 errors.
- `prettier --check` + `eslint`: clean on touched files.
- `lint:boundaries`: no new R1/R2 violations (orders→identity_users is a SQL table-name
reference, same as the existing `search` join; no TS cross-import).
- `vitest run`: full suite green (existing order/payments/checkout/notification tests + new
pg-order-repository test).
- `verify.sh`: exit 0 (backlog F-153 in_progress, runtime stage valid).
## AC5 — Quality gates
- `tsc --noEmit` (API) 0 errores; `npx tsc --noEmit` (apps/admin) sin errores nuevos.
- `npm run lint:boundaries` sin violaciones nuevas.
- `vitest run` (sin DB) → suite nueva F-154 + suite existente en verde.
- `verify.sh` exit 0 (backlog F-154 in_progress, runtime stage válido).