mvc-generator · v4.1.0 · 2026-06-28 · sha256 04fa26c3fa55632d
mvc-generator v4.1.0A
Immutable. This exact content never changes and is served at /api/v1/blob/04fa26c3fa55632d.
---
name: mvc-generator
description: "Generate Protheus MVC (Model-View-Controller) screen structures including ModelDef, ViewDef, MenuDef, and BrowseDef functions. Supports single-entity (Modelo 1) and master-detail (Modelo 3) patterns with FWFormModel, FWFormView, FWFormBrowse, validations, triggers, and entry point hooks. Use when user says 'create MVC screen', 'ModelDef ViewDef', 'FWFormModel', 'master-detail screen'."
license: MIT
metadata:
domain: Protheus
maintainer: Customizações ADVPL/TLPP
author: Thalion Starforge
version: '4.1.0'
category: Code Generation
---
# Protheus MVC Generator
## Overview
Generate complete Protheus MVC screen implementations following the TOTVS framework patterns. Protheus MVC separates business rules (Model), visual presentation (View), and navigation/actions (Controller/Browse) using the `FWFormModel`, `FWFormView`, and `FWFormBrowse` framework classes. This skill generates the three mandatory functions (`ModelDef`, `ViewDef`, `MenuDef`) plus the Browse function that composes them.
## When to Use
Use this skill when:
- Creating a new CRUD screen for a Protheus table
- Building a master-detail form (e.g., invoice header + items)
- Generating MVC boilerplate from a table alias
- Adding validations, triggers, and entry point hooks to MVC screens
- Migrating legacy AxCadastro/Mbrowse screens to MVC
---
## MVC Architecture in Protheus
### Core Components
```
┌─────────────────────────────────────────┐
│ Main Function (e.g., MYMOD01) │
│ ├── MenuDef() → Menu actions │
│ └── FWFormBrowse → Browse grid │
│ ├── ModelDef() → Business rules │
│ │ ├── FWFormStruct → Schema │
│ │ ├── FWFormFieldsModel (Form) │
│ │ ├── FWFormGridModel (Grid) │
│ │ └── Validations / Triggers │
│ └── ViewDef() → Visual layout │
│ ├── FWFormStruct → Schema │
│ ├── Form panels │
│ └── Grid panels │
└─────────────────────────────────────────┘
```
### User Function Responsibilities
| Function | Purpose | Returns |
| ------------- | -------------------------------------------------------------------- | -------------------- |
| `ModelDef()` | Defines the data model: fields, validations, relationships, triggers | `FWFormModel` object |
| `ViewDef()` | Defines the visual layout: panels, grids, field arrangement | `FWFormView` object |
| `MenuDef()` | Defines available actions: Include, Edit, Delete, View, Copy | Array of menu items |
| Main Function | Creates `FWFormBrowse` and activates the screen | — |
---
## Bundled Reference Files
This skill uses progressive disclosure. The SKILL.md body covers the architecture, generation workflow, the checklist, and troubleshooting. Detailed code templates and API references are in the `references/` directory — read them on demand based on the scenario:
| Reference File | When to Read | Content |
| --- | --- | --- |
| [references/mvc-code-templates.md](references/mvc-code-templates.md) | Generating **MVC code** — Single Entity (Modelo 1) or Master-Detail (Modelo 3) templates, event handlers, validation/commit patterns | Full code templates for both MVC patterns, ModelDef/ViewDef/MenuDef boilerplate, validation handlers, commit handlers |
| [references/mvc-api-reference.md](references/mvc-api-reference.md) | Customizing **FWFormStruct**, adjusting **View layout** (boxes, tabs), configuring **MenuDef** actions, or adding custom menu buttons | FWFormStruct parameters, structure customization (RemoveField, SetProperty, FWBuildFeature), HBox/VBox/Folder layout, action codes table, custom actions |
> Also refer to [references/sonarqube-rules-reference.md](../references/sonarqube-rules-reference.md) for the complete SonarQube rules reference shared across skills.
---
## Generation Workflow
### Step 1: Gather Requirements
Determine the generation pattern from the user's request:
| Scenario | MVC Pattern | Key Characteristic |
| --- | --- | --- |
| Simple CRUD (single table) | Single Entity (Modelo 1) | `AddFields` only, no grid |
| Master-detail (header + items) | Master-Detail (Modelo 3) | `AddFields` + `AddGrid` + `SetRelation` |
| Legacy migration (AxCadastro/Mbrowse) | Depends on current structure | Analyze existing code to choose pattern |
Read the appropriate reference files based on the pattern identified:
- **Code generation** → read [references/mvc-code-templates.md](references/mvc-code-templates.md)
- **Structure customization or layout** → read [references/mvc-api-reference.md](references/mvc-api-reference.md)
### Step 2: Generate Code
Using the selected template from the reference files, adapt it to the user's specific requirements:
- Replace table aliases (`ZZ1`, `ZZ2`, `ZZ3`) with actual table aliases
- Replace function/model IDs (`MYMOD01`, `MYMOD01M`) with actual routine names
- Add/remove fields, validations, and triggers as needed
- Adjust View layout proportions and structure
### Step 3: Validate Against Checklist
Run through the MVC Generation Checklist below to verify completeness.
---
## MVC Generation Checklist
### Model (ModelDef)
- [ ] `FWFormStruct(1, "XXX")` loaded for each table
- [ ] Fields removed/customized as needed
- [ ] Model created with `MPFormModel():New("UNIQUE_ID")`
- [ ] `AddFields` called for form sections
- [ ] `AddGrid` called for grid sections (master-detail)
- [ ] Relationship defined with `SetRelation` for grids
- [ ] Model and sub-model descriptions set
- [ ] `SetPrimaryKey({})` called
- [ ] Validation handlers registered (`SetVldActive`, `SetCommit`)
- [ ] Grid line validation registered (`SetVldLine`)
### View (ViewDef)
- [ ] Model loaded with `FWLoadModel("ROUTINE_NAME")`
- [ ] `FWFormStruct(2, "XXX")` loaded for each table
- [ ] `FWFormView():New()` created
- [ ] Model set with `SetModel(oModel)`
- [ ] `AddField` and/or `AddGrid` called for each visual section
- [ ] Layout boxes created (`CreateHorizontalBox`, `CreateVerticalBox`)
- [ ] Views assigned to boxes with `SetOwnerView`
- [ ] Screen proportions make sense (header vs. detail)
### MenuDef
- [ ] Standard CRUD operations included (1-5)
- [ ] Custom actions added if needed
- [ ] Menu item names match `VIEWDEF.ROUTINE_NAME`
### General
- [ ] `#include "fwmvcdef.ch"` present
- [ ] `#include "totvs.ch"` present
- [ ] Browse function creates `FWFormBrowse` and sets alias
- [ ] Legends added to browse if the table has status fields
- [ ] Validation messages use `Help()` function
- [ ] `FWFormCommit(oModel)` called in commit handler for standard persistence
- [ ] Custom tables registered in SX2/SX3 data dictionary before use
### SonarQube Compliance
- [ ] `FWFormCommit(oModel)` is used for persistence — never override the `FormCommit` method directly; use `FWModelEvent` to intercept commit behavior
- [ ] No UI calls (`MsgAlert`, `MsgYesNo`, `Aviso`, `Help`, `Pergunte`, `ParamBox`) inside commit/validation handlers that execute within a transaction
- [ ] Error handling uses `Try-Catch`, not `ErrorBlock`
- [ ] Logging via `FWLogMsg()`, not `ConOut()`
- [ ] No `IIF()` in expressions — use `If/Else/EndIf`
- [ ] Includes in lowercase (e.g., `#include "totvs.ch"`)
- [ ] `GetMV()` / `ExistBlock()` results cached before loops (especially in grid validations)
- [ ] No direct access to SX3 via `DbSelectArea` — use `FWFormStruct()` or `FWSX3Util()`
> Refer to [references/sonarqube-rules-reference.md](../references/sonarqube-rules-reference.md) for the complete SonarQube rules reference.
---
## Troubleshooting
- **"Field not found in SX3"**: The field referenced in `FWFormStruct` must exist in the data dictionary (SX3). Run `CFGX023()` or use SIGACFG to register missing fields.
- **ModelDef/ViewDef mismatch**: Every field ID added to `FWFormModel` must have a corresponding entry in `FWFormView`. Verify that model and view structures reference the same field set.
- **Grid rows not saving**: Ensure `FWFormCommit(oModel)` is called in the commit block. For master-detail, the grid model must be added with `AddGrid()` and linked via `SetOwner()`.
- **Browse shows no records**: Verify `FWFormBrowse():SetAlias()` points to the correct table alias and that the table is accessible from the current branch/company.
- **Validation not triggering**: Field-level validators must be registered in SX3 (X3_VALID) or via `SetFieldAction()` on the model. Check that the trigger field ID matches exactly.