# Index: Shared contract & UI The single API contract. Every frontend change starts here when an endpoint is added or a payload shape changes. ## packages/shared | File | Holds | |---|---| | `src/types.ts` | every DTO shared across API and frontends (money as `number` minor units, `{en, zh}` as `LocalizedText`) | | `src/api.ts` | `ApiClient` interface + `createApi()` live client; input-body types (`ProductUpsertBody`, `SkuUpsertBody`, …) | | `src/locales/en.ts`, `zh.ts` | shared copy; app-specific keys go to the app's `locales-extra.ts`, never here from app work | | `src/theme.css` | Tailwind v4 `@theme` tokens + `html[data-accent]` presets | | `src/money.ts` | `formatMoney(minor, code, exponent, locale)` | ## packages/ui `src/components/`: `VBtn`, `VBadge`, `VCard`, `VField`, `VInput`, `VPage`, `VPanel`, `VTable`, `VAccentSwatch`; `useAccent()`. Auto-registered as a Nuxt module in all three apps. ## Rules of engagement - Adding an API method: declare in the interface, implement in `createApi`, implement the mock in `apps/mall/mock/api.ts` (mall-facing) or `unsupported()` (console-only), and add exact picks to `apps/mall/plugins/api.ts` `LIVE_PICKS` when mall-facing. - Build all three apps after any change here.