Customer Module — Admin
HTTP surface for the admin-only customer picker. The customer's storefront address book lives in the same module but is out of scope here (see store/customer.md). The picker is…
HTTP surface for the admin-only customer picker. The customer's storefront address book lives in the same module but is out of scope here (see store/customer.md). The picker is consumed by admin features that need to pin a customer onto another entity (e.g. admin-create review, manual order draft, manual payout).
Source:
api-modules/customer/src/controllers/admin-customer.controller.ts.The customer identity itself lives in Better-Auth's
usertable; this module owns the shopping-related customer data on top of that. The admin picker reads fromuserbut is the customer module's contract because the address book, order ownership, and payout addressee all key off the same id.
Conventions
Authentication
Every endpoint requires a Better-Auth admin session and a role granting user: list.
| Endpoint | Permission |
|---|---|
GET /admin/customers | user: list |
Response envelope
Successful responses are wrapped by ResponseInterceptor:
{
"data": <payload>,
"message": "Success",
"statusCode": 200,
"metadata": { /* optional, e.g. pagination */ }
}This endpoint uses the picker envelope (items[] + pinned[]) — see Picker responses in catalog.md.
Error envelope
statusCode | errorCode examples |
|---|---|
| 400 | BAD_REQUEST, VALIDATION_ERROR |
| 401 | UNAUTHORIZED |
| 403 | FORBIDDEN |
| 500 | INTERNAL_SERVER_ERROR, DATABASE_ERROR |
Domain types
CustomerListItem
type CustomerListItem = {
id: string; // Better-Auth user id
email: string;
name: string;
image: string | null;
createdAt: string; // ISO
};Endpoints
GET /admin/customers — Customer picker
Required permission: user: list. Substring ILIKE search across email and name. Pass selectedIds=<csv> to receive a pinned block of already-applied customers so the picker can render existing selections without searching.
Query — standard QueryDto (page / limit / search / filters[] / selectedIds).
Response 200
{
"data": {
"items": [
{
"id": "01J9...",
"email": "ada@example.com",
"name": "Ada Lovelace",
"image": "https://cdn.example/u/ada.png",
"createdAt": "2026-01-12T08:30:00.000Z"
}
],
"pinned": []
},
"metadata": { "total": 1234, "items": 1, "perPage": 20, "currentPage": 1, "lastPage": 62 }
}When selectedIds is absent, pinned is [].
Picker responses
See Picker responses in catalog.md for the shared envelope semantics.
Related modules
admin-rbac— gates the endpoint viauser: list. Seeadmin-rbac.md.auth— owns the underlyingusertable the picker reads from.order,reviews— admin flows that consume this picker to attach a customer onto an admin-side action.
Catalog Module — Admin
HTTP surface for platform-admin reads of products + variants and full CRUD over the platform-wide taxonomy (brands, categories, tags, ingredients), with a vendor-request approval…
Discount Module — Admin
HTTP surface for managing platform-wide discount coupons: percentage or fixed-amount discounts, with rich targeting (variants / categories / brands / tags / ingredients / vendors…