7.1 KiB
Module Generator Frontend
The frontend generator UI collects module metadata, selected assets, form layout, and datatable configuration. It converts the configuration into TypeScript/TSX source strings and sends them to the backend generator.
Main Flow
| Responsibility | Source |
|---|---|
| Page submission, notifications, and mutation callbacks | apps/admin/src/devtools/pages/ModuleGeneratorPage/index.tsx |
| Payload assembly | apps/admin/src/devtools/pages/ModuleGeneratorPage/lib/buildGenerateModulePayload.ts |
| Form state and initial values | apps/admin/src/devtools/view/forms/ModuleGeneratorForm/form.ts |
| Metadata, form, and datatable sections | apps/admin/src/devtools/view/forms/ModuleGeneratorForm/sections/ |
| Payload DTOs | apps/admin/src/devtools/data/api/dto.ts |
| HTTP client | apps/admin/src/devtools/data/api/index.ts |
| React Query hooks | apps/admin/src/devtools/data/queries/ |
| Source-code builders | apps/admin/src/devtools/data/builders/ |
The page submits through useGenerateModule. On success it resets the form and shows a success alert; backend or network errors are normalized through the shared React Query error helpers.
Metadata and Assets
The required metadata is:
name: frontend folder name, backend module identity, route segment, and permission-slug base.table: existing PostgreSQL source table.generate: selected backend and frontend assets.
Supported asset values are defined by ModuleAsset:
| Asset | Workspace | Output |
|---|---|---|
model |
Backend | Lucid model |
controller |
Backend | Authenticated resource controller and test |
routes |
Backend | Resource route registration |
validator |
Backend | Create and update Vine validators |
policy |
Backend | Bouncer policy and permission configuration |
api |
Backend | API controller, validators, routes, and test |
form |
Frontend | Form definition, component, and modal/sheet trigger |
datatable |
Frontend | List page table and menu entry |
The default selection includes all backend assets. Form and datatable generation are opt-in.
Schema Queries
The frontend uses two authenticated read endpoints before generation:
GET /makeModule/tablespopulates the table selector.GET /makeModule/columns/:tablepopulates form and datatable field choices.
Table and column requests are cached through React Query. Column queries remain disabled until a table is selected.
Payload Builders
buildGenerateModulePayload delegates source generation to focused builders:
| Builder | Payload field | Generated destination |
|---|---|---|
FormSourceBuilder.buildComponent |
form |
view/forms/MainForm/Component.tsx |
FormSourceBuilder.buildDefinition |
formDefinition |
view/forms/MainForm/form.ts |
ManageTriggerSourceBuilder |
formDialog |
view/widgets/ManageTrigger.tsx |
DataTableSourceBuilder |
dataTable |
view/widgets/DataTable.tsx |
ListPageSourceBuilder |
list |
pages/ListPage/index.tsx |
MenuSourceBuilder |
menu |
config/menu.ts |
ModuleConfigSourceBuilder |
module |
config/module.ts |
If form generation is disabled, form, formDefinition, and formDialog are null. If datatable generation is disabled, dataTable and menu are null, while the list-page builder emits a page without a table.
Generated Frontend Architecture
apps/admin/src/modules/<name>/
├── api/
│ ├── create.ts
│ ├── delete.ts
│ ├── detailed.ts
│ ├── keys.ts
│ ├── list.ts
│ └── update.ts
├── config/
│ ├── translation/
│ ├── menu.ts
│ ├── messages.ts
│ ├── meta.ts
│ ├── module.ts
│ └── routing.tsx
├── entities/
│ └── Entity.ts
├── pages/
│ └── ListPage/
│ └── index.tsx
└── view/
├── forms/
│ └── MainForm/
│ ├── Component.tsx
│ ├── constants.ts
│ ├── form.ts
│ ├── index.ts
│ └── submit.ts
├── layouts/
│ └── Layout.tsx
└── widgets/
├── DataTable.tsx
├── DeleteTrigger.tsx
└── ManageTrigger.tsx
The api directory intentionally has no barrel file. Consumers import each operation directly, for example:
import { useCreate } from "../../../api/create";
import { invalidateDetailed } from "../../../api/detailed";
import { invalidateList } from "../../../api/list";
import { useUpdate } from "../../../api/update";
Each CRUD operation remains isolated in its own file. keys.ts owns React Query key builders, while list.ts and detailed.ts own their cache invalidation helpers.
Layer Responsibilities
entities/Entity.tsis generated from database columns and is shared by API hooks, forms, and widgets.api/owns Axios calls, React Query hooks, cache keys, and mutation notifications.pages/owns route-level composition and permission page gates.view/forms/owns schema, form values, UI integration, and submission orchestration.view/widgets/owns stateful table, delete, and manage interactions.config/integrates routes, menu, translations, metadata, and permissions with the app module registry.
Extending the Frontend Generator
When adding a new generated frontend artifact:
- Add its configuration type under
apps/admin/src/devtools/entities/. - Add UI controls to
ModuleGeneratorForm. - Add a focused builder under
data/builders/if the artifact contains dynamic source. - Add the payload field to
GenerateModulePayloadandbuildGenerateModulePayload. - Accept and write the field in
backend/app/controllers/module_controller.ts. - Add the static structure to
apps/admin/src/modules/_template/when every module needs it. - Verify generation with and without the new asset selected.