Product Attribute Module — Vendor surface
Vendor-facing read endpoints for platform-defined product attributes and attribute groups that the vendor product form binds to. Attributes themselves (definitions, codes, types,…
Vendor-facing read endpoints for platform-defined product attributes and attribute groups that the vendor product form binds to. Attributes themselves (definitions, codes, types, values) are platform-managed via the admin surface — vendors only browse the existing catalogue to attach values to their products.
Source:
api-modules/product-attribute/src/controllers/vendor-product-attribute.controller.ts,api-modules/product-attribute/src/controllers/vendor-product-attribute-group.controller.ts.
Conventions
Authentication
Both controllers require a Better-Auth bearer session with an active vendor.
Authorization: Bearer <session-token>The active vendor is resolved via resolveActiveVendorId(session) and the guard fails closed when no active vendor is bound, but the rows returned are the platform-wide attribute / group catalogue (they are not partitioned by vendor — every vendor sees the same set).
Tenant scoping
Attribute and attribute-group rows are shared across vendors. There is no per-vendor variant — the active-vendor check is purely a gate on who can list the catalogue, not which rows are visible. Soft-deleted rows (deletedAt != null) return 404 on the detail endpoint.
Response envelope
{
"data": <payload>,
"message": "Success",
"statusCode": 200,
"metadata": { /* optional, e.g. pagination */ }
}Error envelope
statusCode | errorCode examples |
|---|---|
| 400 | BAD_REQUEST, VALIDATION_ERROR |
| 401 | UNAUTHORIZED |
| 403 | FORBIDDEN |
| 404 | NOT_FOUND |
| 500 | INTERNAL_SERVER_ERROR |
Domain types
ProductAttributeType
type ProductAttributeType =
| "multi_select"
| "select"
| "text"
| "boolean"
| "number";ProductAttributeValueResponse
type ProductAttributeValueResponse = {
id: string;
attributeId: string;
value: string;
sortOrder: number;
createdAt: string; // ISO
updatedAt: string;
deletedAt: string | null;
};ProductAttributeResponse
type ProductAttributeResponse = {
id: string;
title: string;
code: string; // /^[a-z0-9]+(?:-[a-z0-9]+)*$/
type: ProductAttributeType;
isRequired: boolean;
isUnique: boolean;
createdAt: string;
updatedAt: string;
deletedAt: string | null;
values: ProductAttributeValueResponse[]; // empty for non-(multi_)select types
};ProductAttributeGroupResponse
type ProductAttributeGroupResponse = {
id: string;
title: string;
code: string;
createdAt: string;
updatedAt: string;
deletedAt: string | null;
attributes: Array<ProductAttributeResponse & { sortOrder: number }>;
};Product attributes
Base path: /vendor/product-attributes.
GET /vendor/product-attributes — Search product attributes
Standard QueryDto (page / limit / search / filters[] / sort). Substring match on title and code.
Response 200 — paginated envelope of ProductAttributeResponse.
GET /vendor/product-attributes/:id — Get product attribute
Returns the attribute with its values[].
Errors
| Status | Code | When |
|---|---|---|
| 404 | NOT_FOUND | Unknown id or soft-deleted attribute |
Product attribute groups
Base path: /vendor/product-attribute-groups. A group is a named bundle of attributes the product form renders together (e.g. "Fashion basics" = brand + material + season).
GET /vendor/product-attribute-groups — Search groups
Standard QueryDto. Returns the active groups + their member attributes.
Response 200 — paginated envelope of ProductAttributeGroupResponse.
GET /vendor/product-attribute-groups/:id — Get a group with its fields
Returns the group plus every attribute in it (each carrying its own values[] and the group-specific sortOrder).
Errors
| Status | Code | When |
|---|---|---|
| 404 | NOT_FOUND | Unknown id or soft-deleted group |
Related modules
catalog— products bind attribute values via the product-attribute-value table; this module owns the definitions.admin-rbac— admin endpoints for creating/updating attributes + groups (seeproduct-attribute.mdfor the admin surface) requireproduct-attribute: create / update / deletepermissions.
Order Module — Vendor surface
Vendor-facing HTTP surface for sub-order fulfillment (assign shipping provider, mark fulfilled, mark delivered, cancel), returns processing (approve / reject / pickup / receive /…
Reviews Module — Vendor surface
Vendor-facing HTTP surface for moderating reviews on the vendor's own products — listing, editing content, approving/rejecting, marking/unmarking spam, and soft-deleting. List is…