尚未检测到更新。GitHub 发布版本后会显示在这里。
正在加载完整 README。 以下为已保存的摘录。
Site de calculadoras de cozinha em gramas — pães, picles e massa fresca — em que toda proporção exibida tem citação bibliográfica (livro, autor e página ou capítulo). Quando as fontes divergem, a diferença é explicada em vez de escondida. Produção: calculadorasculinarias.com.br · pt-BR na raiz, inglês em /en. Números novos entram primeiro em docs/research/, com citação, e só depois no código. Um valor sem fonte não vai para a tela.查看完整 README ↗
Site de calculadoras de cozinha em gramas — pães, picles e massa fresca — em que toda proporção exibida tem citação bibliográfica (livro, autor e página ou capítulo). Quando as fontes divergem, a diferença é explicada em vez de escondida.
Produção: calculadorasculinarias.com.br ·
pt-BR na raiz, inglês em /en.
pnpm install
pnpm dev # servidor de desenvolvimento
pnpm verify # lint + typecheck + testes + build (rodar antes de todo commit)
pnpm test:e2e # Playwright (desktop e mobile); precisa de `pnpm exec playwright install chromium`
pnpm build # gera out/
pnpm start # serve out/ localmente
| Documento | Para quê |
|---|---|
docs/prd/prd-calculadoras-culinarias.md | Requisitos, escopo e as decisões de trade-off (TD-001 a TD-005) |
docs/prd/stories-calculadoras-culinarias.md | Stories com critérios de aceite em Gherkin |
docs/research/*.md | Fonte de verdade numérica. Proporções extraídas dos livros, com citação item a item |
Números novos entram primeiro em docs/research/, com citação, e só depois no
código. Um valor sem fonte não vai para a tela.
Build 100% estático (output: 'export'). Não existe API route, servidor nem
banco: todo cálculo roda no navegador e a persistência é localStorage, link
compartilhável e impressão. É o TD-001 do PRD — o que mantém o custo em zero e o
deploy trivial.
Sem middleware (site estático não tem), então cada página existe fisicamente:
src/app/
├── (pt)/ → <html lang="pt-BR">, home em /
├── (en)/en/ → <html lang="en">, home em /en
└── global-not-found.tsx
Dois root layouts via route groups — é o que permite servir o lang certo em
cada idioma sem negociação em tempo de request.
src/i18n/routes.ts — registro único de rotas. Links
internos, seletor de idioma, hreflang e sitemap saem todos daqui.
PUBLISHED_ROUTES controla o que já existe: rota fora da lista não é linkada
nem entra no sitemap.src/i18n/dictionaries/ — pt-BR.ts é o dicionário
canônico e o tipo Dictionary é derivado dele, então acrescentar uma chave
em português quebra a compilação do inglês até ser traduzida.src/data/, nunca nos
dicionários.src/data/books.ts é a estante. Cada obra declara locator
(page para PDF/impresso, chapter para EPUB, que não tem paginação física) —
citar "página" de um EPUB seria mentira.
Nenhuma página escreve openGraph à mão. O Next substitui campos aninhados
em vez de fundi-los, então uma página que declarasse só openGraph.title
perderia siteName e locale do layout em silêncio. Quem monta o bloco inteiro
é pageMetadata, e a página só passa título, descrição,
palavras-chave e o texto alternativo da imagem.
src/app/og/[slug]/image.png/, uma por rota e por idioma, na
paleta da própria calculadora. É route handler, e não a convenção
opengraph-image, porque esta grava arquivo sem extensão no export
estático, e aí o Content-Type sai como binário genérico e o card não aparece.
As fontes em assets/fonts/ existem só para isso: o gerador não lê WOFF2.src/lib/structured-data.ts:
WebApplication gratuita, BreadcrumbList, FAQPage e, o que interessa de
verdade aqui, citation com a estante. É a promessa do site dita em formato
que a máquina lê./llms.txt: o site resumido para assistentes de IA, com as páginas, a
bibliografia e as respostas diretas nos dois idiomas.src/lib/palette.ts, porque o cartão é gerado fora do
navegador. palette.test.ts compara os dois e falha se divergirem.canonical, e sitemap, og:url e JSON-LD seguem ela via
absoluteUrl.As três saídas de uma receita calculada (FR-040 a FR-042) saem do mesmo par, e é o que as mantém coerentes entre si:
| Peça | Papel |
|---|---|
Estado (src/lib/<calc>/state.ts) | Tudo o que reconstrói a calculadora, num objeto só e serializável. Cada módulo exporta um parse…State que valida entrada não confiável |
RecipeCard (src/lib/recipes/card.ts) | O resultado já formatado: linhas, avisos e fontes. Cada calculadora monta o seu em components/<calc>/recipe-card.ts |
Em cima desse par:
src/lib/recipes/store.ts, localStorage
por calculadora, 20 receitas, mesmo nome substitui. Sem storage o recurso some
em vez de quebrar.?r=, num envelope
versionado (snapshot.ts). Link de versão
que não sabemos ler diz isso; link corrompido também. O canonical continua
apontando para a página limpa, e o ?r= sai da barra assim que a receita muda.PrintSheet monta a folha
num portal no body, e o CSS de impressão esconde a aplicação inteira. Isso
garante o que a regra do projeto exige — o aviso de segurança acompanha o
resultado, inclusive impresso.O que entra por
?r=é texto que qualquer pessoa escreve. Nada dali chega ao motor de cálculo sem passar por umparse…State, que recusa o estado inteiro ao primeiro campo inválido — meia receita na tela é pior que nenhuma.
以上为 README 的开头部分。其余内容请阅读原文。 查看完整 README ↗