Rascunho — Modelo de Custo, Preço e Lucro
Modelo matemático preliminar para cálculo dinâmico de margem de lucro e precificação no e-commerce.
Status: rascunho para discussão (gerado a partir de entrevista em 2026-06-29). Todos os números são placeholders — você preenche com os valores reais.
1. Objetivo
Hoje o preço de venda está fixo no frontmatter de cada produto (price + precos).
Funciona, mas guarda o resultado e não os fatores que o geram — então não dá para
estimar lucro nem reagir à variação do preço de mercado da matéria-prima.
A proposta separa duas camadas:
- Custos (variam com o mercado) → matéria-prima, insumo de personalização, mão de obra, overhead.
- Política de preço (sua margem) → markup alvo por categoria.
O preço de venda passa a ser uma saída calculada, não um número digitado. As faixas por quantidade emergem do custo (o setup da personalização se dilui no lote), em vez de serem um desconto avulso.
2. Onde os dados vivem (catálogo central reutilizável)
Três arquivos versionados no git — fonte única de verdade, reaproveitada por todos os
produtos. Sugestão de local: src/data/pricing/.
materials.yaml — peça crua (preço de mercado, R$)
malha-30-1-penteada: { label: "Malha 30.1 Super Penteada", unit: "peça", cost: 18.00 }
malha-pv-vortex: { label: "Meia Malha 30x1 PV Vortex", unit: "peça", cost: 12.00 }
algodao-100: { label: "Malha 100% Algodão", unit: "peça", cost: 14.00 }
lona-crua: { label: "Lona Crua 100% Algodão", unit: "peça", cost: 9.00 }
moletom-5050: { label: "Moletom 50/50 c/ capuz", unit: "peça", cost: 38.00 }
helanca: { label: "Helanca (bandeira)", unit: "m²", cost: 22.00 }
methods.yaml — técnicas de personalização (drivers: técnica, área, nº de cores, setup)
dtf:
label: "DTF"
setup: 15.00 # custo fixo por PEDIDO (preparo) — diluído pela quantidade
per_unit_base: 4.00 # base por peça
per_cm2: 0.02 # acréscimo por cm² de arte (área)
serigrafia:
label: "Serigrafia"
setup_per_color: 25.00 # cada cor = uma tela (setup) → diluído pela quantidade
per_unit_per_color: 1.50 # por peça, por cor
bordado:
label: "Bordado"
setup: 20.00
per_1000_stitches: 1.20 # por peça, a cada mil pontos
policy.yaml — margem + mão de obra + overhead, por categoria
categories:
Vestuário: { margin: 0.60, labor: 5.00, overhead: 3.00 }
Acessórios: { margin: 0.80, labor: 3.00, overhead: 2.00 }
Exterior: { margin: 0.50, labor: 4.00, overhead: 4.00 }
rounding: commercial # arredonda para valor comercial (ex.: 34,20 → 34,90)
3. O que muda no frontmatter do produto
Sai o preço pronto; entram os insumos do cálculo:
# antes
price: 100.00
precos: [ { quantity: 1, value: 100.00 }, ... ]
# depois
material: malha-30-1-penteada
methods: [dtf, serigrafia, bordado] # técnicas oferecidas
artwork: { area_cm2: 300, colors: 3 } # arte de referência p/ o preço exibido
(Bandeira é caso especial: custo por m², sem methods — o preço é
custo_m² × área × repetições, já descrito no produto.)
4. A fórmula (por peça, na quantidade Q)
custo_material = materials[material].cost
custo_metodo_unit = base por peça do método (varia com área / nº de cores)
custo_metodo_setup = setup do método (fixo por pedido)
labor, overhead, margin = policy[categoria]
custo_direto_unit = custo_material + custo_metodo_unit + labor + overhead
custo_unit(Q) = custo_direto_unit + custo_metodo_setup / Q # setup diluído
preço(Q) = arredonda( custo_unit(Q) × (1 + margin) )
lucro_unit(Q) = preço(Q) − custo_unit(Q)
lucro_total(Q) = lucro_unit(Q) × Q
→ Quanto maior Q, menor o setup/Q, menor o custo unitário, menor o preço: as faixas
de quantidade nascem sozinhas, sem tabela manual.
Exemplo (números fictícios, DTF, Q=1 vs Q=200)
material 18,00 + dtf_unit (4,00 + 0,02×300=6,00) =10,00 + labor 5 + overhead 3 = 36,00 direto
Q=1 → 36,00 + 15,00/1 = 51,00 custo → ×1,60 → 81,60 → R$ 81,90 (lucro ~30,90)
Q=200 → 36,00 + 15,00/200 = 36,08 custo → ×1,60 → 57,72 → R$ 57,90 (lucro ~21,82)
5. Implementação faseada
Fase 1 — git (agora, sem infra nova)
- Criar os 3 YAML em
src/data/pricing/. src/lib/store/pricing/compute.ts: carrega os YAML, expõequote(product, qty)→{ unitCost, price, profit }. Tipagem forte + JSDoc (padrão do projeto).- A página de produto e o “total dinâmico” passam a chamar
quote()em vez de lerprecos. Migração: um script lê o frontmatter novo e (opcional) gera um cacheprecospara compatibilidade. - Relatório de lucro: página/admin que tabela
quote()por produto e faixa.
Fase 2 — painel admin (quando valer a pena)
- Mover
materials/policypara Supabase; tela em/admin/pricingpara editar custos e margens com recálculo ao vivo. Os YAML viram seed inicial. - Histórico de custo de matéria-prima → permite ver evolução de margem no tempo.
5b. Painel /admin/products — planejador de custos (decidido 2026-06-29)
Estado atual: /admin/products é um scaffold (sem tabela products migrada;
new.astro é mock de IA). A loja pública usa MDX (git).
Direção escolhida: planejador de custos em Supabase, propósito em fases (planejar lucro/precificação interno agora → conectar à loja depois), com MDX e Supabase convivendo em harmonia: por produto, escolhe-se a fonte do preço.
Modelo de dados (Supabase, a migrar — passo gated, confirmar antes de aplicar em prod):
materials— catálogo de matéria-prima (label, unidade, custo de mercado).product_costs— por produto (chave = id do MDX): material_id, mão de obra, overhead, margem (ou herda da categoria), e pricing_source: ‘mdx’ | ‘supabase’.pricing_policy— margem/labor/overhead por categoria (seed dos YAML do §2).
No admin, cada produto mostra: custo apurado, margem, preço Supabase calculado
vs preço MDX atual, e um seletor pricing_source (qual vale). Fase 2: a loja
lê o preço efetivo (sync ou leitura direta) conforme a fonte escolhida por produto.
6. Pontos a decidir depois
- Como medir área da arte e nº de pontos (entrada manual vs estimativa).
- Incluir frete de compra do fornecedor no custo do material? (sugiro sim, embutido).
- Câmbio/sazonalidade da matéria-prima — atualização manual basta no início.
- Impostos / taxa de cartão entram no custo ou saem da margem? (definir).