5.4 KiB
Frontend Architecture
Frontend stack:
- React
- TypeScript
- Vite
- React Admin
- shadcn/ui
- Keycloak JS
The frontend is generated from domain/*.dsl.
Each entity becomes a React Admin resource.
The generated frontend must also include Keycloak authentication by default.
Single Source of Truth
domain/*.dslis the only required input for frontend generation.- React Admin resources, fields, references, and routes must be derived from the domain model, primary keys, foreign keys, and enums defined in the domain DSL.
- Frontend documentation, generation rules, and optional overrides must not duplicate entity, attribute, or relation structures outside the domain DSL.
- Deprecated multi-DSL inputs are compatibility-only artifacts and must never be treated as authoritative frontend inputs or used to redefine entities, attributes, primary keys, foreign keys, relations, or enums.
Project Structure
client/ src/
App.tsx
main.tsx
dataProvider.ts
auth/
keycloak.ts
authProvider.ts
config/
env.ts
resources/
{entity}/
{entity}List.tsx
{entity}Create.tsx
{entity}Edit.tsx
{entity}Show.tsx
Resource Registration
Each resource must be registered in App.tsx.
The generated App.tsx must register:
dataProviderauthProvider
The generated Admin root must enforce authenticated operation. The generated frontend must not operate anonymously once auth is enabled.
The generated authProvider.getIdentity() must resolve identity from token claims already present in the parsed token and must not trigger a baseline Keycloak /account request.
Example:
Data Provider
React Admin uses a generated shared REST-compatible data provider.
API format must follow:
GET /resource GET /resource/:id POST /resource PATCH /resource/:id DELETE /resource/:id
List response format:
{ data: [], total: number }
The generated dataProvider.ts must remain the single shared request seam for backend API calls.
Rules:
- Use an env-driven API base URL.
- Attach
Authorization: Bearer <access_token>in this shared seam. - Cover all React Admin operations, including references and bulk fetches.
- Do not scatter auth headers across resource components.
Application Bootstrap
The generated main.tsx must initialize Keycloak before rendering the SPA.
Rules:
- Use redirect-based Keycloak login only.
- Use Authorization Code + PKCE (
S256). - Do not generate a custom in-app username/password login form.
- Do not render the authenticated admin app before Keycloak initialization completes.
- Do not introduce
keycloak.loadUserProfile()or/accountprofile-fetch requests as part of baseline app startup or identity resolution.
Config
The generated frontend must include a dedicated config module in src/config/.
Required env variables:
VITE_API_URLVITE_KEYCLOAK_URLVITE_KEYCLOAK_REALMVITE_KEYCLOAK_CLIENT_ID
The generated frontend config must fail fast if required auth variables are missing. The generated frontend must not silently fall back to production auth settings in code.
Foreign Keys
Foreign keys must use ReferenceInput and ReferenceField.
Example:
Naming Conventions
React component naming
Components are named after the entity in PascalCase. One entity = one resource with four main views.
- List:
{Entity}List.tsx(e.g.EquipmentList.tsx,RepairOrderList.tsx) - Create:
{Entity}Create.tsx(e.g.EquipmentCreate.tsx) - Edit:
{Entity}Edit.tsx(e.g.EquipmentEdit.tsx) - Show:
{Entity}Show.tsx(e.g.EquipmentShow.tsx)
Examples:
- Equipment →
EquipmentList.tsx,EquipmentCreate.tsx,EquipmentEdit.tsx,EquipmentShow.tsx - EquipmentType →
EquipmentTypeList.tsx,EquipmentTypeCreate.tsx,EquipmentTypeEdit.tsx,EquipmentTypeShow.tsx - RepairOrder →
RepairOrderList.tsx,RepairOrderCreate.tsx,RepairOrderEdit.tsx,RepairOrderShow.tsx
Resource folder naming
Folder under resources/ uses kebab-case, matching the React Admin resource name:
resources/equipment/resources/equipment-type/resources/repair-order/
Resource Naming Rules
React Admin resource name (used in <Resource name="..." /> and in reference for ReferenceInput) must match the API resource path (no leading slash, same segment string).
- Entity → resource name: PascalCase entity name is converted to kebab-case and pluralized.
- Consistency with API: The resource name must be the same as the backend path segment so that the data provider calls the correct URL.
| Entity (DSL) | Resource name (React Admin) | API path |
|---|---|---|
| Equipment | equipment | /equipment |
| EquipmentType | equipment-types | /equipment-types |
| RepairOrder | repair-orders | /repair-orders |
Examples in App.tsx:
<Resource name="equipment" list={EquipmentList} create={EquipmentCreate} edit={EquipmentEdit} show={EquipmentShow} /><Resource name="equipment-types" list={EquipmentTypeList} ... /><Resource name="repair-orders" list={RepairOrderList} ... />