# Schemas & Errors — Central Reference Files

<!-- contamination-scan: skip — illustrative SAMPLE-domain reference (see disclaimer below); every docs/references/ literal is a worked example or a documented default of the already-tokenized ${paths.api_schemas}/${paths.api_errors}, not portable contamination. -->

> **Illustrative sample domain.** Error codes, routes, and entity names in the
> examples below are a SAMPLE domain — substitute your own. Only the protocol
> (central schema/error files, anchor cross-referencing) is normative.

Protocol for using and extending `${paths.api_schemas}` and `${paths.api_errors}` (typically `docs/references/api/schemas.md` and `docs/references/errors.md`).

> **Note**: the schema names and domain sections below come from a real project (a multi-merchant fidelity/loyalty platform) and are kept as a concrete example. Replace them with your own domain entities when applying this skill to a new project — the project-specific domain vocabulary lives in `.baldart/overlays/doc-writing-for-rag.md`.

## schemas.md — Struttura attuale

File centrale con **80+ JSON schemas riusabili** organizzati per dominio:

| Domain section | Esempi schemi |
|----------------|---------------|
| Booking | BookingRoom, BookingTable, BookingCombo, ReservationDocument, ReservationStatus |
| Admin | Merchant, MerchantPublic, Store, MerchantEmailSettings, AdminCustomerProfile |
| Customer | CustomerDashboard, CustomerProfile, Coupon, CustomerNotification, GamificationProfile |
| Merchant | MerchantWithStores, BrandSettings, DashboardAnalytics, MerchantSession |
| Stores | StoreLandingSettings, StoreWheelSettings, WheelStats, ActiveWheelToken |
| Promos | Promo, PromoDetail, PromoToken, PromoAnalyticsDetail, DailyOffersSettings |
| Membership | MembershipTier, MembershipBenefit, MembershipCard, BenefitToken |
| Menu | MenuCategory, MenuItem, MenuVariant, NutritionalInfo, CustomerMenuPreference |
| DIO | DioMeta, DioSignal, DioRankedItem, DioMerchantConfig, BeverageQuizAnswers |
| Notifications | NotificationEventType, NotificationSubscription, NotificationDevice |
| Survey | SurveyAnswer, SurveyLinkConfigResponse, SurveyCategoryProductsResponse |
| Wallet | WalletPass, FavoriteStoreLocationSnapshot, MerchantPassSummary |

### Path relativi per riferimenti

| File scrittura | Link schemas.md |
|----------------|-----------------|
| `docs/references/api/*.md` (top level) | `./schemas.md#anchor` |
| `docs/references/api/booking/*.md` | `../schemas.md#anchor` |
| `docs/references/api/survey/*.md` | `../schemas.md#anchor` |
| `docs/references/ui/*.md` | `../api/schemas.md#anchor` |
| `docs/references/ui/merchant/*.md` | `../../api/schemas.md#anchor` |

### Estendere schemas.md

1. **Verifica prima**: `grep -i "SchemaName" docs/references/api/schemas.md` per evitare duplicati
2. **APPEND alla domain section** esistente (o crea nuova sezione `## X Domain Schemas` alla fine)
3. **Format tabella**:
   ```markdown
   ## SchemaName
   | Field | Type | Notes |
   |-------|------|-------|
   | id | string | UUID |
   | name | string | 1-120 chars |
   | createdAt | string | ISO 8601 |
   ```
4. **Union types**: usa `\|` per separare (`"ACTIVE" \| "EXPIRED"`)
5. **Nullable**: `string \| null`
6. **Nested**: crea schema separato (es. `BookingPolicy`) e referenzialo nel field Notes

### Quando NON estendere schemas.md

- Schema usato UNA SOLA VOLTA in un endpoint molto specifico → inline nel file
- Schema differisce significativamente da uno esistente (evita "BookingResponseV2" se è un alias di "BookingResponse")

## errors.md — Struttura attuale

File centrale con **300+ error codes** grouped per dominio:

### Domain sections esistenti

- Auth / Access Control
- Generic Validation
- Booking — Rooms / Tables / Combos / Policies / Availability / Customer Lookup / Hold / Reservations
- No-Show / Blacklist
- Tags / Email Templates / Floor Plan / Swap / Arrival Queue
- Admin (Merchant Management, Stores, Staff, Points Rules, Customers, Membership, DORE)
- Customer (Profile, Phone Change, Notifications, Reward, Referrals, Gamification, Wallet)
- Merchant (Brand Settings, Points, Analytics, Ledger, Session)
- Stores (Landing, Wheel, QR Codes, Pixels)
- Promos (CRUD, Tokens, Time Slots)
- Membership (Tiers, Benefits, Points, Analytics)
- Menu (Categories, Items, Variants, Images, Inferred Orders)
- DIO Menu (Ranking, Quiz, Behavior, Cron)
- Notifications, Survey, Wallet Passes, Closure Days

### Format entry

```markdown
| Code | HTTP | IT Message | Context |
|------|------|------------|---------|
| BOOKING_NOT_FOUND | 404 | Prenotazione non trovata | GET/PATCH /api/v1/merchant/booking/:id |
```

### Error code naming conventions

- **UPPER_SNAKE_CASE**
- Prefix con dominio quando ambiguo: `BOOKING_NOT_FOUND`, `STORE_NOT_FOUND`
- Senza prefix per codes generici: `MISSING_FIELDS`, `INVALID_HEX_COLOR`, `MERCHANT_MISMATCH` (riusati in più domini)
- Descrittivi: `NAME_REQUIRED` meglio di `ERR_001`

### Riutilizzo error codes

**RIUSA** i generic codes esistenti in più domini:
- `MISSING_FIELDS`, `INVALID_FORMAT`, `MERCHANT_MISMATCH`, `STORE_NOT_FOUND`, `FORBIDDEN`

**NON creare duplicati** con prefix non necessari: se `INVALID_HEX_COLOR` esiste in Admin, riusalo in Merchant Brand Settings.

### Link dagli endpoint

Dal file API:
```markdown
**Errors**: BOOKING_NOT_FOUND, BOOKING_CONFLICT ([errors.md](../errors.md#booking---reservations))
```

Il link anchor punta alla **domain section**, non al singolo code.

### Anchor naming per domain sections

Markdownlint genera anchor da heading: tutto lowercase, spazi → `-`, caratteri speciali → rimossi.

Esempi:
- `## Booking — Reservations` → `#booking--reservations`
- `## Admin Domain` → `#admin-domain`
- `## Merchant — Staff Management (FEAT-0119/0485/0486)` → `#merchant--staff-management-feat-01190485-0486`

**Verifica sempre** l'anchor generato con `grep "^## " docs/references/errors.md` prima di committare.

## Workflow estensione in sequenza

Quando scrivi un nuovo endpoint che richiede nuovo schema + nuovo error code:

1. **Grep** in schemas.md e errors.md (evita duplicati)
2. **APPEND** schema in schemas.md (sezione dominio)
3. **APPEND** error codes in errors.md (sezione dominio esistente o nuova)
4. **Scrivi endpoint** con link ai nuovi anchor
5. **Verify** link validity: grep gli anchor per confermare che esistono
