git init
This commit is contained in:
123
frontend/architecture.md
Normal file
123
frontend/architecture.md
Normal file
@@ -0,0 +1,123 @@
|
||||
# Frontend Architecture
|
||||
|
||||
Frontend stack:
|
||||
|
||||
- React
|
||||
- TypeScript
|
||||
- Vite
|
||||
- React Admin
|
||||
- shadcn/ui
|
||||
|
||||
The frontend is generated from the DSL and API specification.
|
||||
|
||||
Each entity becomes a React Admin resource.
|
||||
|
||||
---
|
||||
|
||||
# Project Structure
|
||||
|
||||
client/
|
||||
src/
|
||||
|
||||
App.tsx
|
||||
|
||||
resources/
|
||||
|
||||
{entity}/
|
||||
{entity}List.tsx
|
||||
{entity}Create.tsx
|
||||
{entity}Edit.tsx
|
||||
{entity}Show.tsx
|
||||
|
||||
---
|
||||
|
||||
# Resource Registration
|
||||
|
||||
Each resource must be registered in App.tsx.
|
||||
|
||||
Example:
|
||||
|
||||
<Resource
|
||||
name="equipment"
|
||||
list={EquipmentList}
|
||||
create={EquipmentCreate}
|
||||
edit={EquipmentEdit}
|
||||
show={EquipmentShow}
|
||||
/>
|
||||
|
||||
---
|
||||
|
||||
# Data Provider
|
||||
|
||||
React Admin uses the standard REST provider.
|
||||
|
||||
API format must follow:
|
||||
|
||||
GET /resource
|
||||
GET /resource/:id
|
||||
POST /resource
|
||||
PATCH /resource/:id
|
||||
DELETE /resource/:id
|
||||
|
||||
List response format:
|
||||
|
||||
{
|
||||
data: [],
|
||||
total: number
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
# Foreign Keys
|
||||
|
||||
Foreign keys must use ReferenceInput and ReferenceField.
|
||||
|
||||
Example:
|
||||
|
||||
<ReferenceInput source="equipmentTypeCode" reference="equipment-types" />
|
||||
|
||||
---
|
||||
|
||||
# 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).
|
||||
|
||||
1. **Entity → resource name:** PascalCase entity name is converted to kebab-case and pluralized.
|
||||
2. **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} ... />`
|
||||
98
frontend/react-admin-rules.md
Normal file
98
frontend/react-admin-rules.md
Normal file
@@ -0,0 +1,98 @@
|
||||
# DSL → React Admin Mapping
|
||||
|
||||
Entity attributes determine UI fields.
|
||||
|
||||
---
|
||||
|
||||
# Type Mapping
|
||||
|
||||
| DSL Type | React Admin Component |
|
||||
|---------|-----------------------|
|
||||
| string | TextInput / TextField |
|
||||
| integer | NumberInput |
|
||||
| decimal | NumberInput |
|
||||
| date | DateInput |
|
||||
| enum | SelectInput |
|
||||
| foreign key | ReferenceInput |
|
||||
|
||||
---
|
||||
|
||||
# Example
|
||||
|
||||
DSL
|
||||
|
||||
attribute name {
|
||||
type string;
|
||||
}
|
||||
|
||||
React Admin
|
||||
|
||||
<TextInput source="name" />
|
||||
|
||||
---
|
||||
|
||||
# Enum Example
|
||||
|
||||
DSL
|
||||
|
||||
attribute status {
|
||||
type EquipmentStatus;
|
||||
}
|
||||
|
||||
React Admin
|
||||
|
||||
<SelectInput source="status" choices={statusChoices} />
|
||||
|
||||
---
|
||||
|
||||
# Foreign Key Example
|
||||
|
||||
DSL
|
||||
|
||||
attribute equipmentTypeCode {
|
||||
type string;
|
||||
}
|
||||
|
||||
React Admin
|
||||
|
||||
<ReferenceInput source="equipmentTypeCode" reference="equipment-types" />
|
||||
|
||||
---
|
||||
|
||||
# React Admin ID Field Requirement
|
||||
|
||||
React Admin requires every record in list and detail responses to contain a field named **`id`**. It uses this field for resource identity, cache keys, and references.
|
||||
|
||||
**Rules:**
|
||||
|
||||
1. Every record returned by the API must contain an **`id`** field.
|
||||
2. If the DSL primary key is not named `id`, the generator must **map** the primary key value to an `id` field in the API response (backend) or in a frontend adapter.
|
||||
3. The `id` field must contain the **value of the primary key** (e.g. uuid string, or `code` value for EquipmentType).
|
||||
|
||||
**Example:**
|
||||
|
||||
DSL entity with primary key `code`:
|
||||
|
||||
```
|
||||
entity EquipmentType {
|
||||
attribute code {
|
||||
key primary;
|
||||
type string;
|
||||
}
|
||||
attribute name { type string; }
|
||||
}
|
||||
```
|
||||
|
||||
API response must include `id` so React Admin can identify the record:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "pump",
|
||||
"code": "pump",
|
||||
"name": "Pump"
|
||||
}
|
||||
```
|
||||
|
||||
If the response only had `{ "code": "pump", "name": "Pump" }`, React Admin would not work correctly because it expects `id`. The backend or frontend adapter must therefore set `id: record.code` (or equivalent) when the primary key is not `id`.
|
||||
|
||||
This rule ensures compatibility with React Admin resource identity handling.
|
||||
Reference in New Issue
Block a user