# Ficha técnica

A **ficha técnica** é a estrela do MyBenchLab do lado das peças: um **documento de usinagem pronto para imprimir** que um profissional cota e torneia/fresa. Ela abre em `/parts/:id/spec` (botão **Ficha técnica**, `sketch-spec-open-btn`, ou "Ver ficha" numa peça salva) e é uma **projeção somente-leitura** da peça salva. É **por dono**: o servidor filtra por `userId` e recusa a peça de outro.

O ponto que sustenta a credibilidade da ficha: **nenhuma cota é digitada à mão**. Toda dimensão é **derivada do histórico paramétrico** por `buildSpecSheet` — se você mudar o desenho, a ficha muda junto. Material, massa e envelope vêm do snapshot avaliado pelo kernel; as únicas coisas que você *escreve* são as três anotações humanas (classe de tolerância, acabamento, observações).

## O que a ficha contém

### Bloco de título

Como o title block de um desenho técnico: **nome** da peça, **ID**, **data**, **material**, **massa** (kg), **envelope** (X × Y × Z mm) e a **tolerância geral** (ISO 2768). Subtítulo "Documento de usinagem".

### Tolerância geral ISO 2768

Uma linha de texto (`spec-sheet-tolerance-line`) traduz a classe escolhida no editor para a regra de fábrica:

- **f (fina)** — ISO 2768-f: cotas lineares ±0,05 a ±0,15 mm conforme a faixa.
- **m (média)** — ISO 2768-m: ±0,1 a ±0,3 mm.
- **c (grossa)** — ISO 2768-c: ±0,2 a ±0,5 mm.

Vale para **toda cota sem tolerância própria**.

### Cotas e tolerâncias

A tabela **Cotas e tolerâncias** (`spec-sheet-tolerances`) tem uma linha por cota autorada: **dimensão · nominal · tolerância**. Uma cota que recebeu **± próprio** no esboço mostra o valor exato (ex.: ±0,02 mm, em verde); as demais mostram "geral ISO 2768-…". É aqui que a tolerância ± anexada a uma Cota no esboço aparece.

### Operações (histórico de usinagem)

A tabela **Operações** (`spec-sheet-operations`) lista a pilha de features na ordem, em **linguagem de usinagem**: esboço (largura × altura, plano), pad (altura), revolução (ângulo, raio máx.), pocket (passante ou profundidade), furos, filete (raio), chanfro (tamanho). Um polígono regular lê "Polígono 6 lados · entre faces 13 mm".

### Desenho cotado (meridiano / superior, com hachura)

O desenho 2D (`spec-sheet-drawing`) escolhe a vista pela natureza da peça:

- **Vista meridiana (torno)** para peças **revolucionadas** — a meia-seção do perfil com **hachura** (seção cortada), a linha de centro e as cotas de diâmetro/comprimento.
- **Vista superior** para peças **prismáticas** — a planta do perfil com furos cotados.

O desenho é pulado com elegância quando a peça não tem um perfil-base utilizável. Escala e legenda saem de `buildSpecDrawing`.

### Anotações de usinagem (roscas, cone)

As anotações de furo viram *call-out* tanto na tabela quanto no líder do desenho, cobrindo:

- **Roscas** — métrica (M6×1), fina, **UNC**/**UNF** (polegada), fuso **Tr** (Tr20×4) e **quadrada**. Ex.: "Furo Ø5 → rosca M6×1".
- **Escareado** — "Furo Ø8 escareado 90° Ø12" (líder ⌵ 90° Ø12).
- **Rebaixado** — "Furo Ø6 rebaixado Ø11×5" (líder ⌴ Ø11 ×5).
- **Cone** — uma aresta diagonal torneada emite a cota de conicidade ("Ø40→Ø30 × 5") no meio da aresta, mais a nota de meio-ângulo ("Cone 45°") quando o perfil tem ≤ 2 arestas diagonais.

A tabela **Cotas e tolerâncias** mantém o Ø **perfurado** inalterado — as roscas/escareados são anotações, não geometria.

Fecham a ficha o **resumo dimensional** (envelope, nº de furos, raio máx., massa) e o bloco **Acabamento e observações** (os dois campos de texto livre do editor).

## Como as cotas derivam do histórico

Este é o contrato central. `buildSpecSheet({ body })` percorre a **lista de features** da peça salva e emite as cotas — nunca remede o sólido nem aceita número digitado na ficha:

- larguras/alturas e diâmetros vêm dos **contornos** do esboço (as cotas nomeadas);
- alturas de pad, ângulos/raios de revolução e profundidades de pocket vêm dos **parâmetros das operações**;
- envelope, massa e volume vêm do **snapshot** que o kernel avaliou ao salvar;
- as **arestas** do perfil já são rotuladas L1, L2… a partir da geometria dos cantos, então comprimentos nomeados aparecem sem trabalho extra.

Consequência prática: a ficha é sempre coerente com a peça. Corrigiu um furo no esboço, salvou — a linha da tabela acompanha. Não há caminho para uma ficha "mentir" sobre a peça.

## Fluxo de impressão

O botão **Imprimir** (`spec-sheet-print-btn`) chama `window.print()`. Na tela a ficha usa o tema escuro do MBL; um `@media print` embutido vira **fundo branco / texto preto** e some com a barra de ações e o rodapé, para a cópia impressa/PDF ler como um desenho de verdade. Salve como PDF pela própria caixa de impressão do navegador. **Salve a peça antes** — a ficha da peça só abre para uma peça já persistida (`isSaved`).

## Ficha a partir de uma bancada (por peça ou todas)

Numa bancada montada você gera a ficha sem precisar salvar cada peça na biblioteca — o histórico paramétrico viaja embutido em cada peça colocada:

- **Uma peça** — na árvore **Estrutura**, o ícone de ficha na linha da peça (`outliner-part-spec-<id>`) abre a ficha daquela peça. Se a peça veio da biblioteca, abre a ficha salva; senão, a ficha é derivada das features embutidas na bancada (rota `/benches/:id/parts/:componentId/spec`).
- **Todas as peças** — no painel **Materiais**, o botão **Ficha técnica (todas)** (`bom-spec-all`) abre `/benches/:id/spec`: um documento único com **uma ficha por peça distinta** (peças geometricamente idênticas são agrupadas com a quantidade, igual ao BOM), cada uma numa página (`break-after: page` na impressão). Um `window.print()` gera o PDF de várias páginas.

## Limitações desta ficha (declaradas na própria folha)

A folha é honesta sobre seus limites, no bloco **Limitações desta ficha**:

- Roscas, escareados e rebaixados são **anotações** (nível de especificação): a geometria modelada segue o furo cilíndrico perfurado, não a feature usinada.
- **Acabamento por face** e **GD&T** ainda não são modelados.
- Vale a **tolerância geral** acima mais as **cotas nominais derivadas** do histórico paramétrico.

## Compartilhar e receber pedidos

A ficha não precisa ficar só com você: dá para **publicar um link público** dela e **receber pedidos de orçamento** direto de quem a abrir. É o passo de negócio do MyBenchLab — alguém desenha a peça, compartilha a ficha, e um profissional (o torneiro/fresador) recebe o pedido e cota.

### Publicar o link

Numa peça salva — tanto na linha em **Minhas peças** quanto no cabeçalho da própria ficha — o botão **Compartilhar** (`part-share-btn`) gera um link **`/p/<token>`** e já copia para a área de transferência (aviso "Link copiado!"). O token é aleatório e longo (base64url, 32 caracteres): quem tem o link vê a ficha; quem não tem, não descobre. Uma vez ativado, aparecem **Copiar link** e **Desativar link** (`part-share-disable-btn`) — desativar não apaga o token, então reativar devolve **a mesma URL**.

A página pública abre **sem barra do app**, no mesmo tema escuro na tela e branco na impressão, e mostra **exatamente a mesma ficha** (o `SpecSheetView` é reaproveitado). Ela expõe **apenas** os campos da ficha (nome, features, material, massa, envelope, tolerâncias) — nunca o seu `userId`, o id interno, o token ou a proveniência.

### Solicitar orçamento

Abaixo da ficha pública há um formulário **Solicitar orçamento** (`quote-form`): **nome**, **e-mail**, **quantidade**, **prazo desejado** (opcional) e **observações**. Ao enviar, o dono da peça recebe um **e-mail** ("Orçamento solicitado — <peça>") com os dados do solicitante e o link da ficha; em desenvolvimento (ou sem e-mail configurado) o pedido é **registrado no console do servidor** como fallback. Há um limite simples de **5 pedidos por hora por link** para conter abuso.

### Caixa de orçamentos

Cada peça em **Minhas peças** ganha um botão **Orçamentos** (`quote-requests-toggle-btn-…`) com o **número de pedidos novos** em destaque. Ele abre a lista (nome, e-mail, quantidade, prazo, observações e data), e cada pedido novo pode ser **marcado como visto** (`quote-requests-markseen-btn-…`). Tudo é **por dono**: o servidor filtra por `ownerUserId`, então você só enxerga os pedidos das suas peças.

## Próximos passos

- Como a peça e as cotas nascem: [Peças — desenho paramétrico](/docs/pecas).
- Colocar a peça numa estrutura: [Static workbench](/docs/static-workbench).
