# 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`.