# Frontend Rules Use this document during the **Frontend** stage defined in `prompts/general-prompt.md`. ## Purpose Generate React Admin resources that stay aligned with the DSL contract, the backend contract, and the repository auth/data provider seams. ## Mandatory Inputs - `prompts/general-prompt.md` - the active `api API.` block from `domain/toir.api.dsl` - referenced DTOs and enums from `domain/toir.api.dsl` - an intact or repaired official Vite React TypeScript scaffold under `client/` ## Expected Outputs Per entity: - `client/src/resources//List.tsx` - `client/src/resources//Create.tsx` - `client/src/resources//Edit.tsx` - `client/src/resources//Show.tsx` Repository-wide: - `client/src/App.tsx` resource registrations ## Scaffold Baseline - Start frontend initialization and repair from the official Vite React TypeScript scaffold, not from a hand-written shell. - Preserve workspace essentials: - `client/index.html` - `client/tsconfig.json` - `client/vite.config.*` - `client/src/main.tsx` - Repair the scaffold before generating resources if it is degraded. ## Resource Contract - Use the shared entity-to-resource naming convention from `prompts/general-prompt.md`. - Every entity becomes a React Admin resource with `list`, `create`, `edit`, and `show`. - `Resource` registration in `client/src/App.tsx` must include `show={...}`. - Every frontend record must work with React Admin's `id` contract, including natural-key entities. DTO-driven view rules: - List and Show views use fields from `DTO.` - Create view uses fields from `DTO.Create` - Edit view uses fields from `DTO.Update` - Do not derive form fields directly from model attributes when the DTO contract is narrower ## Input And Field Mapping Form inputs: - `integer`, `number`, `decimal` -> `NumberInput` - `date` -> `DateInput` - required `boolean` -> `BooleanInput` - nullable `boolean` -> `NullableBooleanInput` - enum -> `SelectInput` - FK reference -> `ReferenceInput` + `AutocompleteInput` Display fields: - `integer`, `number`, `decimal` -> `NumberField` - `date` -> `DateField` - `boolean` -> `BooleanField` - enum -> `SelectField` - FK reference -> `ReferenceField` Hard failure rule: - using plain `TextInput` for `integer`, `number`, `decimal`, `date`, or `boolean` is a generation failure ## Filter And Reference Contract - Lists must expose filters and include a toolbar with `FilterButton`. - Enum multi-select filters use `SelectArrayInput`. - Reference filters and form selectors use `ReferenceInput` + `AutocompleteInput` with `filterToQuery={(searchText) => ({ q: searchText })}`. - FK list/show rendering must use `ReferenceField link=\"show\"`. - `dataProvider` query serialization must preserve repeated params for array filters. Reference display expression priority: 1. if `inventoryNumber` exists: ``(record) => `${record.inventoryNumber} — ${record.name ?? record.inventoryNumber}`` 2. else if `code` exists: ``(record) => `${record.code} — ${record.name ?? record.code}`` 3. else if `number` exists: ``(record) => `${record.number} — ${record.name ?? record.number}`` 4. else if `name` exists: `(record) => record.name ?? record.id` 5. else: `(record) => record.id` ## Auth And Provider Seams - `client/src/dataProvider.ts` remains the single authenticated request seam. - `client/src/auth/authProvider.ts` remains the single React Admin auth seam. - Resource components must not embed auth logic. - `getIdentity()` resolves from token claims. - `getPermissions()` may expose realm roles for UI awareness, but backend enforcement stays authoritative. ## Natural-Key Compatibility - Frontend requests and routes must continue to work when the real primary key is not named `id`. - Edit/show/delete flows must preserve compatibility with backend natural-key handling. - Sorting and filtering assumptions must not regress to a fake physical `id`. ## Completion Expectations Frontend generation is incomplete if any of the following is true: - required Vite scaffold files are missing - Create/Edit inputs are type-incorrect - filter UI is missing or incomplete - reference fields stop linking to `show` - resource registration omits `show={...}`