135 lines
6.2 KiB
Markdown
135 lines
6.2 KiB
Markdown
# Module Generator Backend
|
|
|
|
The backend generator exposes authenticated schema-inspection and generation endpoints. It renders backend files from Handlebars templates and writes frontend files using a copied template plus source strings supplied by the admin app.
|
|
|
|
## Endpoints
|
|
|
|
Routes are registered in `apps/backend/start/routes.ts`.
|
|
|
|
| Method | Path | Controller method | Purpose |
|
|
| ------ | ---------------------------- | ----------------- | -------------------------------------------------- |
|
|
| `GET` | `/makeModule/tables` | `tables` | List eligible public PostgreSQL tables |
|
|
| `GET` | `/makeModule/columns/:table` | `columns` | Return columns used to configure form/table fields |
|
|
| `POST` | `/makeModule/generate` | `generate` | Generate selected frontend and backend assets |
|
|
|
|
All three endpoints use `middleware.auth()`.
|
|
|
|
## Database Inspection
|
|
|
|
`apps/backend/app/services/database_inspector.ts` reads PostgreSQL `information_schema`.
|
|
|
|
- Table discovery is limited to the `public` schema.
|
|
- framework, authentication, access-control, migration, and PostgreSQL system tables are excluded.
|
|
- columns provide `column_name`, `data_type`, and `is_nullable`.
|
|
- columns ending in `_id` are treated as belongs-to relationship candidates.
|
|
- tables containing a `<table>_id` column are treated as has-many relationship candidates.
|
|
- searchable string and numeric columns are derived for generated resource controllers.
|
|
|
|
Relationship inference is heuristic. Review generated model imports, related class names, property names, and module availability.
|
|
|
|
## Type Mapping
|
|
|
|
The controller maps database types separately for Lucid models, Vine validators, and frontend entities.
|
|
|
|
| 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 database columns receive `| null` in generated model/entity types and optional validation where applicable. `created_at`, `updated_at`, and `deleted_at` receive special handling.
|
|
|
|
## Backend Output
|
|
|
|
For module name `<name>`, table `<table>`, and derived module class `<ModuleName>`, selected assets are written under:
|
|
|
|
```txt
|
|
apps/backend/modules/<ModuleName>/
|
|
├── api/
|
|
│ ├── controllers/<entity>_api_controller.ts
|
|
│ ├── validators/<entity>_create_api_validator.ts
|
|
│ ├── validators/<entity>_update_api_validator.ts
|
|
│ └── routes.ts
|
|
├── config/permissions.ts
|
|
├── controller/<entity>_controller.ts
|
|
├── model/<entity>.ts
|
|
├── policy/<entity>_policy.ts
|
|
├── validators/<entity>_create_validator.ts
|
|
├── validators/<entity>_update_validator.ts
|
|
└── routes.ts
|
|
```
|
|
|
|
Tests are written under:
|
|
|
|
```txt
|
|
apps/backend/tests/modules/<ModuleName>/
|
|
├── <entity>.spec.ts
|
|
└── <entity>.api.spec.ts
|
|
```
|
|
|
|
`<entity>` is derived by removing the final character from the selected table name. This assumes a plural table name and must be reviewed for irregular plurals.
|
|
|
|
## Asset Behavior
|
|
|
|
### Model
|
|
|
|
Renders `apps/backend/app/templates/backend/model.hbs` with columns, inferred relationships, searchable fields, and optional password hashing.
|
|
|
|
### Controller and routes
|
|
|
|
Renders an authenticated resource controller with list/search/sort/pagination and CRUD actions. `routes.hbs` registers an `apiOnly` resource route and applies authentication.
|
|
|
|
### Validators
|
|
|
|
Creates separate create and update Vine validators. Primary keys and timestamp/deletion fields are excluded according to controller rules. Email, password, nullable, and string trimming behavior is inferred from column names and database metadata.
|
|
|
|
### Policy and permissions
|
|
|
|
Creates a Bouncer policy with view/create/update/delete checks, creates `config/permissions.ts`, and adds a lazy policy import to `apps/backend/app/policies/main.ts` when missing.
|
|
|
|
Permission slugs are derived from the module name, for example:
|
|
|
|
```txt
|
|
<name>s.view
|
|
<name>s.create
|
|
<name>s.update
|
|
<name>s.delete
|
|
```
|
|
|
|
Review names that are already plural because policy and frontend metadata derivation are not a general-purpose pluralization system.
|
|
|
|
### API subtree
|
|
|
|
Creates a second CRUD controller and route group under `/api/<entity>`, plus API-specific validators and a test. The controller imports the generated model and passes it to `modelToSchema` for Swagger response metadata.
|
|
|
|
API routes currently do not add authentication middleware in the generated API template. Add the required authentication and authorization explicitly before exposing the route.
|
|
|
|
## Frontend Writes Performed by the Backend
|
|
|
|
The backend copies `apps/admin/src/modules/_template` to `apps/admin/src/modules/<name>` and then writes:
|
|
|
|
- configured form component and form definition;
|
|
- configured datatable and list page;
|
|
- configured manage trigger, menu, and module manifest;
|
|
- generated `config/meta.ts`;
|
|
- database-derived `entities/Entity.ts`.
|
|
|
|
See [frontend.md](./frontend.md) for the complete frontend structure and payload ownership.
|
|
|
|
## Template Helpers
|
|
|
|
The controller registers Handlebars helpers for `eq`, `not`, `or`, and `and`. New templates should use the existing render function and receive an explicit context object from the controller.
|
|
|
|
## Extending the Backend Generator
|
|
|
|
1. Add or update a Handlebars template under `apps/backend/app/templates/`.
|
|
2. Add an explicit destination path in the controller `paths` object.
|
|
3. Create its parent directory through the existing path initialization.
|
|
4. Render only when the corresponding asset is selected.
|
|
5. Pass normalized metadata rather than querying the database inside templates.
|
|
6. Add generation tests for nullable values, dates, numeric types, passwords, and irregular names.
|
|
7. Verify both backend and frontend builds after generation.
|
|
|
|
Avoid adding hidden writes. Every generated or modified destination, including shared registries such as `app/policies/main.ts`, should remain visible in the controller flow and documented here.
|