109 lines
3.8 KiB
Markdown
109 lines
3.8 KiB
Markdown
# Frontend Action Slots Design
|
|
|
|
## Goal
|
|
|
|
Generate user-facing frontend pages from the system module blueprint, then attach business workflow actions to explicit page slots such as detail primary buttons and list row actions.
|
|
|
|
## Problem
|
|
|
|
The current blueprint flow already separates static application modules from executable business actions:
|
|
|
|
- `AppBlueprintDesign` stores roles plus `frontendMenus` and `adminMenus`.
|
|
- `BusinessActionDesign` stores executable action details such as `ownerTable`, `requestFields`, `ruleChecks`, and `effects`.
|
|
|
|
Generated frontend templates still attach actions by table only. A table-owned action appears in both the generated list page and detail page because templates iterate `tableBusinessActions`. This cannot express cases such as:
|
|
|
|
- Book catalog is the only frontend menu.
|
|
- Book detail is a child page, not a top-level menu.
|
|
- Borrow and reserve appear on book detail.
|
|
- Return appears in My Borrows row actions.
|
|
- Cancel reservation appears in My Reservations row actions.
|
|
|
|
## Architecture
|
|
|
|
Add a small frontend page composition layer between menus and business actions.
|
|
|
|
System module blueprint gains `frontendPages`. A menu can point to a page with `pageCode`, while child pages such as details can use `parentPageCode`. Business actions gain `uiBindings`, each of which names a target page and a supported slot.
|
|
|
|
The generator keeps existing table-based action rendering as a compatibility fallback. When `uiBindings` are present, frontend templates render by slot instead of blindly rendering every action for the table.
|
|
|
|
## DSL
|
|
|
|
`frontendPages` item:
|
|
|
|
```json
|
|
{
|
|
"code": "book_detail_page",
|
|
"name": "Book Detail",
|
|
"menuCode": "book_catalog",
|
|
"parentPageCode": "book_catalog_page",
|
|
"path": "/books/:id",
|
|
"pageType": "detail",
|
|
"tableName": "book_info"
|
|
}
|
|
```
|
|
|
|
`uiBindings` item:
|
|
|
|
```json
|
|
{
|
|
"target": "frontend",
|
|
"pageCode": "book_detail_page",
|
|
"slot": "detail.primaryActions",
|
|
"component": "button",
|
|
"inputMapping": {
|
|
"book_id": "detail.book_id"
|
|
},
|
|
"refresh": "detail"
|
|
}
|
|
```
|
|
|
|
Supported first-phase slots:
|
|
|
|
- `list.toolbarActions`
|
|
- `list.rowActions`
|
|
- `detail.primaryActions`
|
|
- `detail.secondaryActions`
|
|
- `form.footerActions`
|
|
|
|
First implementation renders `list.rowActions` and `detail.primaryActions`. Other slot names are validated and preserved for later template expansion.
|
|
|
|
## Data Flow
|
|
|
|
1. AI generates system module blueprint with menus and pages.
|
|
2. Frontend sends confirmed app blueprint when generating business blueprint.
|
|
3. Business blueprint prompt includes saved schema and confirmed app blueprint.
|
|
4. AI returns actions with `uiBindings`.
|
|
5. Backend normalizes and validates table, field, page, slot, component, and refresh values.
|
|
6. `GenProjectServiceImpl` builds `slotBusinessActions` and exposes it to Velocity.
|
|
7. Vue3 frontend templates render row and detail buttons from slot-specific action lists.
|
|
|
|
## Compatibility
|
|
|
|
Existing saved projects without `frontendPages` or `uiBindings` still work:
|
|
|
|
- Menus render as they do today.
|
|
- Backend action code still uses `ownerTable`.
|
|
- Frontend action buttons fall back to table-owned actions when no slot bindings exist.
|
|
|
|
## Validation
|
|
|
|
Validation rejects:
|
|
|
|
- Unknown page codes in `uiBindings`.
|
|
- Unknown slot names.
|
|
- Unknown target values other than `frontend` and `admin_frontend`.
|
|
- Unknown component values other than `button`, `link`, and `dropdown-item`.
|
|
- Unsafe input mapping expressions.
|
|
|
|
For first phase, page validation is strict when the app blueprint is present and lenient when legacy actions have no bindings.
|
|
|
|
## Testing
|
|
|
|
Tests cover:
|
|
|
|
- DTO serialization and task worker propagation of app blueprint into business blueprint requests.
|
|
- Validator acceptance of valid frontend page bindings and rejection of unknown page codes.
|
|
- Velocity context grouping of actions into `slotBusinessActions`.
|
|
- Vue3 template seed rendering of `list.rowActions` and `detail.primaryActions`.
|