77 lines
2.5 KiB
Markdown
77 lines
2.5 KiB
Markdown
---
|
|
name: api-enums-reference
|
|
description: "Use the central API enums file as the source of truth for enum values in this project. Use when: adding enum fields, updating enum options, creating form selects, typing status/discount/rate fields, syncing backend enum changes, or avoiding duplicated hardcoded enum literals."
|
|
---
|
|
|
|
# API Enums Reference
|
|
|
|
Use this skill whenever work touches enum-like fields in API clients, schemas, forms, table filters, or page logic.
|
|
|
|
## Source of Truth
|
|
|
|
All shared enum values and enum union types must come from:
|
|
|
|
- packages/api/src/contracts/enums.ts
|
|
|
|
Do not recreate enum arrays inline when an equivalent enum already exists in this file.
|
|
|
|
## Rules
|
|
|
|
1. Reuse before creating.
|
|
Search and import from `@garage/api` exports (or local contracts path inside packages/api) before adding new literals.
|
|
|
|
2. Keep runtime and type together.
|
|
For every enum, keep this pattern in `enums.ts`:
|
|
|
|
```ts
|
|
export const ExampleStatus = ['a', 'b'] as const;
|
|
export type ExampleStatus = (typeof ExampleStatus)[number];
|
|
```
|
|
|
|
3. Preserve backend values exactly.
|
|
Enum string values are case- and space-sensitive; keep exact spelling from backend migrations/spec.
|
|
|
|
4. Avoid duplicate synonyms.
|
|
If two domains share the same canonical values, prefer reusing an existing enum unless domain separation is intentional.
|
|
|
|
5. Update centrally first.
|
|
When backend enum options change, update `packages/api/src/contracts/enums.ts` first, then update consuming UI/API code.
|
|
|
|
6. Prefer imports in forms and schemas.
|
|
Use central enums for select options and for typed payload/status fields instead of hardcoded string unions.
|
|
|
|
## Workflow
|
|
|
|
1. Identify the enum field and backend values.
|
|
2. Check `packages/api/src/contracts/enums.ts` for an existing enum.
|
|
3. If found, import and use it.
|
|
4. If missing, add a new const+type pair in `enums.ts`.
|
|
5. Update consumers to reference the central enum.
|
|
6. Verify there are no duplicated literal arrays for the same field.
|
|
|
|
## Examples
|
|
|
|
```ts
|
|
import { InvoiceStatus, type InvoiceStatus as InvoiceStatusType } from '@garage/api'
|
|
|
|
const statusOptions = InvoiceStatus
|
|
|
|
type Payload = {
|
|
status: InvoiceStatusType
|
|
}
|
|
```
|
|
|
|
```ts
|
|
import { DiscountType } from '@garage/api'
|
|
|
|
const discountOptions = DiscountType.map((value) => ({
|
|
label: value,
|
|
value,
|
|
}))
|
|
```
|
|
|
|
## Notes
|
|
|
|
- If a module needs a presentation-specific label, map from the central enum value instead of changing raw enum literals.
|
|
- If backend adds/removes values, keep API and dashboard aligned in the same change set.
|