# 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 `_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 ```txt apps/backend/modules// ├── api/ # controller, create/update validators, routes.ts ├── config/permissions.ts ├── controller/_controller.ts ├── model/.ts ├── policy/_policy.ts ├── validators/ # _create/_update_validator.ts └── routes.ts apps/backend/tests/modules// # .spec.ts, .api.spec.ts ``` `` is the table name minus its final character — assumes a plural table name; review irregular plurals. ## Asset Behavior - **Model** — `model.hbs` with columns, inferred relationships, searchable fields, optional password hashing. - **Controller and routes** — authenticated resource controller with list/search/sort/pagination and CRUD; `routes.hbs` registers an `apiOnly` resource 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 to `app/policies/main.ts` when missing. Slugs derive from the module 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/` with validators and a test; imports the model for `modelToSchema` Swagger 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/`, 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](./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.