4.5 KiB
Module Generator Backend
Authenticated schema-inspection and generation endpoints; backend files rendered from Handlebars templates, frontend files written from a copied template plus source strings supplied by the admin app.
Endpoints
Registered in apps/backend/start/routes.ts, all behind middleware.auth():
| Method | Path | Purpose |
|---|---|---|
GET |
/makeModule/tables |
List eligible public PostgreSQL tables |
GET |
/makeModule/columns/:table |
Return columns used to configure form/table fields |
POST |
/makeModule/generate |
Generate selected frontend and backend assets |
Database Inspection
database_inspector.ts reads information_schema: only the public schema, excluding framework/auth/access-control/migration/system tables. Columns ending in _id become belongs-to candidates; tables containing a <table>_id column become has-many candidates; searchable string/numeric columns are derived for resource controllers. Relationship inference is heuristic — review generated model imports, class and property names.
Type Mapping
| Database category | Lucid TypeScript type | Vine type | Frontend type |
|---|---|---|---|
| integer/numeric types | number |
number |
number |
| boolean | boolean |
boolean |
boolean |
| date/timestamp | DateTime |
date |
IsoDateString |
| other values | string |
string |
string |
Nullable columns get | null and optional validation; created_at, updated_at, deleted_at receive special handling.
Backend Output
apps/backend/modules/<ModuleName>/
├── api/ # controller, create/update validators, routes.ts
├── config/permissions.ts
├── controller/<entity>_controller.ts
├── model/<entity>.ts
├── policy/<entity>_policy.ts
├── validators/ # <entity>_create/_update_validator.ts
└── routes.ts
apps/backend/tests/modules/<ModuleName>/ # <entity>.spec.ts, <entity>.api.spec.ts
<entity> is the table name minus its final character — assumes a plural table name; review irregular plurals.
Asset Behavior
- Model —
model.hbswith columns, inferred relationships, searchable fields, optional password hashing. - Controller and routes — authenticated resource controller with list/search/sort/pagination and CRUD;
routes.hbsregisters anapiOnlyresource route with authentication. - Validators — separate create/update Vine validators; primary keys and timestamp/deletion fields excluded; email, password, nullable, and trimming behavior inferred from names and metadata.
- Policy and permissions — Bouncer policy with view/create/update/delete,
config/permissions.ts, and a lazy policy import added toapp/policies/main.tswhen missing. Slugs derive from the module name (<name>s.view,.create,.update,.delete) — review already-plural names, this is not a general pluralization system. - API subtree — a second CRUD controller and routes under
/api/<entity>with validators and a test; imports the model formodelToSchemaSwagger metadata. The generated API template adds no authentication middleware — add auth and authorization before exposing the route.
Frontend Writes
The backend copies apps/admin/src/modules/_template to apps/admin/src/modules/<name>, then writes the configured form (component + definition), datatable and list page, manage trigger, menu, module manifest, generated config/meta.ts, and database-derived entities/Entity.ts. See frontend.md.
Extending
Handlebars helpers available: eq, not, or, and. To add a generated artifact: add the template under apps/backend/app/templates/, an explicit destination in the controller paths object (parent dir via existing path initialization), render only when its asset is selected, and pass normalized metadata — never query the database inside templates. Add generation tests for nullable values, dates, numerics, passwords, and irregular names; verify both builds. No hidden writes — every destination, including shared registries like app/policies/main.ts, stays visible in the controller flow and documented here.