# ADM-018 Design — Customer List

## Problem
`GET /users` only returns `users_profiles` fields (`userId`, `displayName`, `phone`).
The admin frontend needs `email`, `role`, `createdAt` from `identity_users`, plus search by email, pagination, and total count.

## Design

### Backend changes (users module)

**Domain layer** — extend `Profile` with optional `email` and `role`:
```ts
// profile.ts — add:
export interface CustomerSummary {
  userId: string;
  email: string;
  role: string;
  displayName: string | null;
  phone: string | null;
  createdAt: Date;
}

export interface CustomerListResult {
  items: CustomerSummary[];
  total: number;
}
```

**Port** — add new method to `ProfileRepository`:
```ts
listCustomers(opts: { q?: string; offset: number; limit: number }): Promise<CustomerListResult>;
```

**Infrastructure** — `PgProfileRepository.listCustomers()`:
```sql
SELECT iu.id, iu.email, iu.role, up.display_name, up.phone, iu.created_at
FROM identity_users iu
LEFT JOIN users_profiles up ON up.user_id = iu.id
WHERE ($1::text IS NULL OR iu.email ILIKE '%' || $1 || '%')
ORDER BY iu.created_at DESC
LIMIT $2 OFFSET $3
```
Plus a `COUNT(*)` query for total.

**Application** — new use case `ListCustomers`:
```ts
export class ListCustomers {
  constructor(private readonly profiles: ProfileRepository) {}
  async execute(opts): Promise<CustomerListResult> { ... }
}
```

**API** — enhance `GET /users`:
- Query params: `q` (optional string), `offset` (default 0), `limit` (default 20)
- Response: `{ items: CustomerSummary[], total: number }`
- Serialize `userId` as `id` to match frontend `Customer` type

### Frontend changes

**api-client.ts** — `customersApi.list()` already passes `offset`, `limit`, `q`. Update return type to include `total`.

**customers/page.tsx** — set `total` from API response: `setTotal(data.total)`.

## Boundaries
- No new module — stays in users module
- No migration needed — `identity_users` already has `email`, `role` (migration 003)
- Domain layer stays DB-free (ports pattern)
- Admin-only endpoint (already gated by `requireRole('admin')`)

## Files to change
1. `project/src/modules/users/domain/profile.ts` — add `CustomerSummary`, `CustomerListResult`
2. `project/src/modules/users/domain/ports.ts` — add `listCustomers()` to `ProfileRepository`
3. `project/src/modules/users/application/profile-use-cases.ts` — add `ListCustomers`
4. `project/src/modules/users/infrastructure/pg-profile-repository.ts` — implement `listCustomers()`
5. `project/src/modules/users/api/users.routes.ts` — enhance `GET /users`
6. `project/apps/admin/src/lib/api-client.ts` — update return type
7. `project/apps/admin/src/app/(dashboard)/customers/page.tsx` — wire `total`
