Chama o Profissa — marketplace de serviços

Marketplace que liga cliente e prestador autônomo do pedido à avaliação, com o ciclo inteiro governado por uma máquina de estados no backend, frontend mobile-first em Next.js 16 e dois painéis Filament — gestão e profissional.

Next.js 16React 19Tailwind 4Laravel 11Filament 3SanctumMySQLDocker

O contexto

Marketplace de serviços domésticos: eletricista, encanador, técnico de refrigeração. De um lado o cliente com um problema em casa; do outro, o profissional autônomo que precisa de trabalho.

O ciclo real não é "pedir e receber". É: cliente solicita, profissional aceita, marcam visita técnica, o profissional vai até o local, mede o serviço, manda orçamento, o cliente aprova ou recusa, o serviço é executado, o cliente avalia. Cada uma dessas etapas pode travar, voltar ou ser abandonada.

O problema

Marketplace de serviço morre pelo estado do pedido. Se o cliente pode aprovar um orçamento que ainda não foi enviado, ou avaliar um serviço que não foi executado, ou se o profissional consegue mandar orçamento antes de ter feito a visita, o sistema perde a noção de onde cada pedido está — e a operação passa a resolver isso por telefone.

O erro comum é espalhar esse controle por booleanos: visita_confirmada, tem_orcamento, foi_pago, avaliado. Com quatro flags existem dezesseis combinações, e a maioria delas é inválida. Ninguém escreve a regra que impede as combinações inválidas, e elas acontecem.

Havia ainda dois públicos com necessidades opostas na administração: a operação da plataforma, que precisa ver tudo, e o profissional autônomo, que precisa ver só o que é dele.

Decisões técnicas

Máquina de estados explícita em vez de flags booleanas. O pedido tem um estado, um só: aguardando_confirmacaovisita_confirmadaaguardando_orcamentoorcamento_recebidoservico_em_andamentoconcluidoavaliado. As transições permitidas são declaradas, e qualquer tentativa fora delas é rejeitada no backend. Isso custa mais código no começo — é mais fácil escrever $pedido->avaliado = true. Paga depois: estado inválido deixa de ser possível, e o frontend não precisa reimplementar a regra para decidir qual botão mostrar. Ele pergunta o estado e renderiza o que aquele estado permite.

A máquina de estados mora no backend, não no frontend. O Next.js podia calcular a próxima etapa e a tela ficaria mais reativa. Mas regra que vive no cliente é regra que se contorna com o DevTools aberto, e teria que ser duplicada em qualquer app futuro. Backend decide, frontend exibe.

Dois painéis Filament separados em vez de um painel com permissões. /gestao para a operação, /painel para o profissional. A alternativa seria um painel único com controle de acesso por papel, o que é menos código e um risco maior: cada tela nova precisa lembrar de esconder o que o profissional não pode ver, e o dia em que alguém esquece é um vazamento entre prestadores. Painéis separados fazem do isolamento a configuração padrão, não uma checagem que precisa ser lembrada.

Filament em vez de painel administrativo à mão. Os dois painéis são CRUD sobre os mesmos models já usados pela API. Escrevê-los manualmente seriam semanas de formulário e tabela sem diferencial competitivo nenhum. O tempo foi para a máquina de estados e o fluxo de orçamento, que é o produto.

Frontend mobile-first, não app nativo. O cliente que precisa de encanador não instala aplicativo antes. Web mobile-first em Next.js 16 remove a barreira de instalação; app pode vir depois, consumindo a mesma API.

Sanctum. O frontend é primeiro-parte contra a própria API — token simples resolve, OAuth2 seria cerimônia sem terceiro consumindo.

O que ficou pronto

Marketplace com solicitação, agendamento de visita técnica, envio e aprovação de orçamento, execução e avaliação, com o ciclo inteiro governado pela máquina de estados. Painel de gestão e painel do profissional em Filament 3, API REST autenticada com Sanctum, deploy em Docker.

Voltar para projetos