Para devs y CTOs

Él escribe el CRUD. Tú escribes el resto.

Tablas, pantallas y reglas armadas en lo visual, en el código o con el agente. Sale Eloquent, Blade y Alpine en un proyecto Laravel estándar, que tú revisas, versionas y mantienes.

app/Control/VendaForm.php
El controller VendaForm generado, con las áreas bloqueadas y los bloques editables marcados

Lee lo que genera antes de confiar.

Un formulario y los tres archivos que produce. Pasa el mouse sobre un campo y mira sus líneas en el Blade, en el model y en el controller.

Registro de venta
Registro de venta
Persona * Panadería Pão da Vila
Fecha * 12/06/2026
Total $ 13.386,62
Estado Facturada
Guardar

app/Models/App/Venda.php

<?phpnamespace App\Models\App;use Illuminate\Database\Eloquent\Model;use Illuminate\Database\Eloquent\Relations\BelongsTo;use Illuminate\Database\Eloquent\Relations\HasMany;use Mad\Database\Concerns\HasIdPolicy;use Mad\Database\Concerns\HasMadAudit;class Venda extends Model{use HasIdPolicy, HasMadAudit;protected $connection = 'app';protected $table      = 'venda';// Colunas de auditoria/soft-delete desta tabela (chave ausente = desligada).protected array $madAudit = ['created_at' => 'created_at','updated_at' => 'updated_at',];protected $fillable = ['pessoa_id','data','total','status',];public static function rules($id = null): array{return ['pessoa_id' => 'required|integer','data' => 'required','total' => 'nullable|numeric','status' => 'nullable|max:20',];}public function pessoa(): BelongsTo{return $this->belongsTo(Pessoa::class, 'pessoa_id');}public function vendaItems(): HasMany{return $this->hasMany(VendaItem::class, 'venda_id');}protected static function booted(): void{static::deleting(function (self $model) {if (VendaItem::where('venda_id', '=', $model->id)->exists()) {throw new \Exception('Não é possível deletar este registro pois ele está sendo utilizado em outra parte do sistema');}});}}

Tu código sobrevive a la próxima generación.

El controller generado se divide en bloques. Los que controla la interfaz quedan bloqueados. Los @mad-block:user son tuyos: cuando la pantalla cambia y el archivo se genera de nuevo, quedan como los dejaste.

  • Imports, propiedades y funciones tuyas en bloques propios
  • Validación con el rules() del model, guardado en transacción
  • Un componente PHP que lees de arriba abajo, sobre el MadComponent del framework
app/Control/VendaForm.php
<?phpuse Mad\Component\MadComponent;use Mad\Form\MadForm;use Mad\Form\MadValidationException;use Mad\Http\MadResponse;use Mad\Ui\MadMessage;use App\Models\App\Venda;use Illuminate\Support\Facades\DB;// use App\Control\VendaList;// @mad-block:user:uses {// @mad-block:user:uses }/*** @mad-generated* @mad-entity-id 693*/class VendaForm extends MadComponent{// @mad-block:config:properties {protected static string $wrapper = self::DRAWER;protected static string $title   = 'Cadastro de Venda';protected static string $size    = '600px';protected static string $side    = 'right';public MadForm $form;// int|string: tabela cuja PK é varchar/char (código, matrícula) tem chave// de texto — `int` transformaria 'ABC-1' em 0 e salvaria no registro errado.public int|string|null $recordId = null;// @mad-block:config:properties }// @mad-block:user:properties {// @mad-block:user:properties }// @mad-block:lifecycle:mount {public function mount(array $params = []): void{$this->form = new MadForm('form');if (! empty($params['id'])) {$this->onEdit($params['id']);}}// @mad-block:lifecycle:mount }// @mad-block:lifecycle:onEdit {public function onEdit(int|string $id): void{// @mad-block:locked:onEdit:master {$venda = Venda::findOrFail($id);$this->recordId = $venda->getKey();// @mad-block:locked:onEdit:master }// @mad-block:detail-load-hooks {// @mad-block:detail-load-hooks }$this->form->fill($venda);}// @mad-block:lifecycle:onEdit }// @mad-block:lifecycle:onSave {public function onSave(): MadResponse{try {$this->form->validate(Venda::rules($this->recordId));$venda = DB::connection('app')->transaction(function () {// @mad-block:locked:onSave:master {$venda = Venda::findOrNew($this->recordId);// @mad-block:locked:onSave:master }// @mad-block:detail-save-hooks {// @mad-block:detail-save-hooks }$this->form->save($venda);$this->recordId = $venda->getKey();return $venda;});// @mad-block:combo-origin {// Tela aberta por um combo ("Sem resultados → Cadastrar novo"):// devolve a option nova selecionada e fecha o overlay. Fora desse// caso returnToCombo() responde null e o fluxo normal segue.if (($__combo = $this->returnToCombo($this->recordId)) !== null) {return $__combo;}// @mad-block:combo-origin }// @mad-block:after-save {return (new MadResponse())->toast('Registro salvo com sucesso!', 'success')->closeDrawer()->manageRow($this->recordId, VendaList::class);// @mad-block:after-save }} catch (MadValidationException $e) {return $e->asInline();} catch (\Throwable $e) {return MadMessage::error('Erro ao salvar', $e->getMessage());}}// @mad-block:lifecycle:onSave }// Caminho da view gerado pela plataforma a partir da PASTA DO MÓDULO.// Bloco byte-exact: NÃO edite — trocar o módulo regenera este path sozinho.// @mad-block:locked:view-name {protected function viewName(): string{return 'venda-form';}// @mad-block:locked:view-name }// @mad-block:lifecycle:view {protected function view(): string|array{$replaces = [];return [$this->viewName(), $replaces];}// @mad-block:lifecycle:view }// @mad-block:user:functions {// @mad-block:user:functions }}

Trae tu agente. O usa el nuestro.

El agente de MadBuilder lee la base de datos, crea tablas y genera pantallas en el mismo proyecto que tú editas. Escribe la tag del componente MAD, no el HTML, el CSS y el JS que hay detrás, por eso gasta de 65% a 75% menos tokens.

$ claude mcp add madbuilder --token mgw_•••• --project 1042
  • Claude Code, Cursor o cualquier cliente MCP
  • Token exclusivo por proyecto, con revocación al instante
  • Permisos por herramienta y auditoría de cada llamada
  • Tu clave de Anthropic, OpenRouter, xAI, Z.AI o Ark, o el Mad Coding Plan

Tú 14:05

Crea un CRUD de venta con ítems (maestro-detalle): la venta tiene cliente, fecha y valor total; cada ítem tiene producto, cantidad y valor unitario. Genera el listado y el formulario.

Agente 14:08

  1. Voy a crear el CRUD maestro-detalle de venta. Primero necesito revisar la base de datos y crear las tablas que todavía no existen.
  2. mad_db_inspect list_tables17 tablas en el modelo, ninguna de venta
  3. Necesito crear produto, venda y venda_item. Dejaré pessoa como cliente.
  4. mad_db_table create produtonome, preco_venda, unidade, ativo y el model Produto
  5. mad_db_table create vendacliente_id, data_venda, valor_total y el model Venda
  6. mad_db_table create venda_itemvenda_id, produto_id, quantidade, valor_unitario, valor_total y el model VendaItem
  7. Tablas creadas. Ahora voy a cargar la skill del framework MAD y generar el CRUD maestro-detalle.
  8. skill mad-frameworkskill cargada
  9. crud_generate venda + detalhe venda_item2 pantallas creadas: VendaList y VendaForm

Sin motor propietario de por medio.

Lo que corre en producción es tu proyecto Laravel. MadBuilder queda en tu flujo de trabajo, no en tu servidor.

composer.json

Laravel, Eloquent, Blade y Alpine

La app generada declara laravel/framework ^13.8 y el framework MAD viene dentro del proyecto.

.env

Seis bases de datos

MySQL o MariaDB, PostgreSQL, SQLite, Oracle, SQL Server y Firebird.

deploy

SSH, Git o ZIP

El deploy por SSH guarda los últimos 5 backups. El Git va a GitHub, GitLab o Bitbucket.

prueba online

Entorno de prueba en un clic

PHP 8.4 u 8.5, con PostgreSQL, MySQL, MariaDB o SQLite, aislado por proyecto.

MADTRACE_ENABLED

Errores y APM integrados

Rastreo opt-in, sin contratar Sentry o New Relic aparte.

routes/

Rutas limpias

Una URL por pantalla, con unicidad validada y rutas reservadas protegidas.

Preguntas de quien va a mantener el código

¿Y si quiero salir de MadBuilder?

Descarga el ZIP o haz push a tu Git. Es un proyecto Laravel común, con el framework MAD dentro de la carpeta packages. Corre sin MadBuilder y cualquier dev Laravel puede mantenerlo.

¿Qué pasa con el código que escribo a mano?

Queda dentro de los bloques @mad-block:user. Cuando alguien cambia la pantalla y el archivo se genera de nuevo, esos bloques se preservan. Las partes que controla la interfaz quedan bloqueadas y marcadas en el editor.

¿Puedo editar directamente el PHP y el Blade?

Puedes. Visual, PHP y Blade son tres vistas del mismo archivo. Lo que cambias en una aparece en las otras.

¿Se puede versionar en Git?

Sí. El Git Deploy hace push a GitHub, GitLab o Bitbucket, y tú eliges las carpetas que no suben, como vendor y storage.

¿Qué bases de datos se soportan?

MySQL o MariaDB, PostgreSQL, SQLite, Oracle, SQL Server y Firebird.

¿Puedo usar mi propio agente de IA en lugar del de ustedes?

Puedes. El proyecto expone un servidor MCP: Claude Code, Cursor o cualquier cliente MCP crea pantallas, modela datos y publica, con un token por proyecto y cada llamada registrada.

Descarga el .zip antes de agendar una reunión.

Crea la cuenta, arma una pantalla y abre el proyecto en tu editor. Si el código no pasa la revisión de tu equipo, perdiste una tarde.

  1. Crea la cuentaBeta abierta, sin tarjeta.
  2. Arma una pantallaEn el editor visual, en código o pidiéndoselo a la IA.
  3. Descarga el .zipUn proyecto Laravel que corre donde quieras.