Files
mercadodevida/work/artifacts/ADM-018/implementer.md
2026-08-17 22:23:10 +02:00

57 lines
2.1 KiB
Markdown

# ADM-018 Implementer Evidence
## Summary
Enhanced `GET /users` backend to support admin customer listing with search, pagination, and total count. Updated frontend to consume the new response shape.
## Changes
### Backend (users module)
**Domain layer** (`profile.ts`):
- Added `CustomerSummary` interface (userId, email, role, displayName, phone, createdAt)
- Added `CustomerListResult` interface (items, total)
- Added `CustomerListOptions` interface (q, offset, limit)
**Ports** (`ports.ts`):
- Added `listCustomers(opts)` and `findCustomerById(userId)` to `ProfileRepository`
**Application** (`profile-use-cases.ts`):
- Added `ListCustomers` use case
- Added `GetCustomer` use case
**Infrastructure** (`pg-profile-repository.ts`):
- Implemented `listCustomers()`: JOIN identity_users + users_profiles, ILIKE search on email, LIMIT/OFFSET pagination, COUNT for total
- Implemented `findCustomerById()`: single customer lookup with JOIN
**API** (`users.routes.ts`):
- `GET /users` now accepts `q`, `offset`, `limit` query params; returns `{ items, total }`
- `GET /users/:id` now returns CustomerSummary (includes email, role) instead of bare Profile
- Added `serializeCustomer()` function mapping `userId``id` for frontend compatibility
### Frontend (admin app)
**api-client.ts**: Updated `customersApi.list()` return type to `{ items, total }`
**customers/page.tsx**: Wired `setTotal(data.total)` from API response
## Verification
| Check | Result |
|-------|--------|
| Backend typecheck | ✅ clean |
| Backend build | ✅ clean |
| Backend tests | ✅ 123 passed |
| Admin typecheck | ✅ clean |
| Domain purity | ✅ no DB/HTTP imports in domain |
| Parameterized queries | ✅ all SQL uses `$1`, `$2`, etc. |
## Acceptance traceability
| Criterion | Evidence |
|-----------|----------|
| Customer list with search | `GET /users?q=foo` → ILIKE on email |
| Pagination | `offset`/`limit` params, default 20 per page |
| Total count | `COUNT(*)` query, returned as `total` |
| Email and role in response | JOIN identity_users + users_profiles |
| Admin-only | Existing `requireRole(user, 'admin')` gate |