Para devs e CTOs

Ele escreve o CRUD. Você escreve o resto.

Tabelas, telas e regras montadas no visual, no código ou pelo agente. Sai Eloquent, Blade e Alpine num projeto Laravel padrão, que você revisa, versiona e mantém.

app/Control/VendaForm.php
O controller VendaForm gerado, com as áreas travadas e os blocos editáveis marcados

Leia o que ele gera antes de confiar.

Um formulário, os três arquivos que ele produz. Passe o mouse num campo e veja as linhas dele no Blade, no model e no controller.

Cadastro de Venda
Cadastro de Venda
Pessoa * Padaria Pão da Vila
Data * 12/06/2026
Total R$ 13.386,62
Status Faturada
Salvar

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');}});}}

Seu código sobrevive à próxima geração.

O controller gerado é dividido em blocos. Os que a interface controla ficam travados. Os @mad-block:user são seus: quando a tela muda e o arquivo é gerado de novo, eles ficam como você deixou.

  • Imports, propriedades e funções suas em blocos próprios
  • Validação pelo rules() do model, salvamento em transação
  • Um componente PHP que você lê de cima a baixo, sobre o MadComponent do 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 }}

Traga o seu agente. Ou use o nosso.

O agente do MadBuilder lê o banco, cria tabelas e gera telas no mesmo projeto que você edita. Ele escreve a tag do componente MAD, não o HTML, o CSS e o JS por trás dela, por isso gasta de 65% a 75% menos tokens.

$ claude mcp add madbuilder --token mgw_•••• --project 1042
  • Claude Code, Cursor ou qualquer cliente MCP
  • Token exclusivo por projeto, com revogação na hora
  • Permissão por ferramenta e auditoria de cada chamada
  • Sua chave da Anthropic, OpenRouter, xAI, Z.AI ou Ark, ou o Mad Coding Plan

Você 14:05

Crie um CRUD de venda com itens (mestre-detalhe): venda tem cliente, data e valor total; cada item tem produto, quantidade e valor unitário. Gere a listagem e o formulário.

Agente 14:08

  1. Vou criar o CRUD mestre-detalhe de venda. Primeiro preciso verificar o banco de dados e criar as tabelas que ainda não existem.
  2. mad_db_inspect list_tables17 tabelas no modelo, nenhuma de venda
  3. Preciso criar produto, venda e venda_item. Deixarei pessoa como cliente.
  4. mad_db_table create produtonome, preco_venda, unidade, ativo e o model Produto
  5. mad_db_table create vendacliente_id, data_venda, valor_total e o model Venda
  6. mad_db_table create venda_itemvenda_id, produto_id, quantidade, valor_unitario, valor_total e o model VendaItem
  7. Tabelas criadas. Agora vou carregar a skill do framework MAD e gerar o CRUD mestre-detalhe.
  8. skill mad-frameworkskill carregada
  9. crud_generate venda + detalhe venda_item2 telas criadas: VendaList e VendaForm

Sem motor proprietário no meio.

O que roda em produção é o seu projeto Laravel. O MadBuilder fica no seu fluxo de trabalho, não no seu servidor.

composer.json

Laravel, Eloquent, Blade e Alpine

O app gerado declara laravel/framework ^13.8 e o framework MAD vem dentro do projeto.

.env

Seis bancos

MySQL ou MariaDB, PostgreSQL, SQLite, Oracle, SQL Server e Firebird.

deploy

SSH, Git ou ZIP

O deploy por SSH guarda os últimos 5 backups. O Git vai pro GitHub, GitLab ou Bitbucket.

teste online

Ambiente de teste num clique

PHP 8.4 ou 8.5, com PostgreSQL, MySQL, MariaDB ou SQLite, isolado por projeto.

MADTRACE_ENABLED

Erros e APM embutidos

Rastreamento opt-in, sem contratar Sentry ou New Relic à parte.

routes/

Rotas limpas

Uma URL por tela, com unicidade validada e rotas reservadas protegidas.

Perguntas de quem vai manter o código

E se eu quiser sair do MadBuilder?

Baixe o ZIP ou faça push pro seu Git. É um projeto Laravel comum, com o framework MAD dentro da pasta packages. Roda sem o MadBuilder e qualquer dev Laravel mantém.

O que acontece com o código que eu escrevo à mão?

Ele fica dentro dos blocos @mad-block:user. Quando alguém muda a tela e o arquivo é gerado de novo, esses blocos são preservados. As partes que a interface controla ficam travadas e marcadas no editor.

Posso editar direto no PHP e no Blade?

Pode. Visual, PHP e Blade são três vistas do mesmo arquivo. O que você muda numa aparece nas outras.

Dá pra versionar no Git?

Sim. O Git Deploy faz push pro GitHub, GitLab ou Bitbucket, e você escolhe as pastas que não sobem, como vendor e storage.

Quais bancos são suportados?

MySQL ou MariaDB, PostgreSQL, SQLite, Oracle, SQL Server e Firebird.

Posso usar o meu agente de IA em vez do de vocês?

Pode. O projeto expõe um servidor MCP: o Claude Code, o Cursor ou qualquer cliente MCP cria telas, modela dados e publica, com um token por projeto e cada chamada registrada.

Baixe o .zip antes de marcar reunião.

Crie a conta, monte uma tela e abra o projeto no seu editor. Se o código não passar na revisão do seu time, você perdeu uma tarde.

  1. Crie a contaBeta aberto, sem cartão.
  2. Monte uma telaNo visual, no código ou pedindo à IA.
  3. Baixe o .zipUm projeto Laravel que roda onde você quiser.