# Source of Truth — Gerador de Propostas EloPro — MVP ## 1. Decisões consolidadas - Produto standalone dentro do ecossistema EloPro. - Integração com CRO é opcional e serve para pré-preenchimento quando houver contexto explícito de cliente. - Tenant técnico = `workspace_id`; isolamento por RLS. CNPJ é dado comercial, não chave de tenant. - Papéis funcionais: Superadmin, Administrador, Gestor e Usuário. Mapeamento atual EloPro: `profiles.is_superadmin`, `owner/admin`, `gestor`, `agent`. - Modelos são importados por Admin/Gestor a partir de PDF, PPTX ou DOCX. - Marcadores variáveis: `[campo]`. O sistema não infere trechos variáveis. - Limite: 10 modelos por workspace; Rascunho, Ativo e Arquivado contam. Versões internas não ocupam nova vaga. - Status de proposta: apenas `Rascunho` e `Gerada`. - Estados de UI da criação: `Preencher → Validar → Gerar`; são estados da mesma experiência, não status persistidos independentes. - Primeira geração bem-sucedida cria `PROP-######` e `V1`. - Versões formais são imutáveis. Edição posterior cria/retoma o rascunho da próxima versão. - Download e envio por e-mail usam exatamente o PDF da versão exibida. - Lock: um editor por recurso, TTL funcional de 10 minutos, sem force takeover no MVP. - Autosave obrigatório. - Contrato fica visível/desabilitado nesta fase. Apresentação permanece pendente. ## 2. Regras de negócio - RN-001 Standalone — fluxo principal funciona sem Calculadora, Contratos, Planilhas ou outros produtos. - RN-002 Brasil/BRL — pt-BR, BRL; sem seletor obrigatório de moeda. - RN-003 Segurança server-side — permissão, entitlement, limite e estado também no backend/RLS. - RN-004 Autosave — autosave não substitui Salvar/Salvar e sair. - RN-005 Limite de modelos — máximo 10 por workspace; draft/active/archived contam. - RN-006 Modelo ativo — somente modelo Ativo inicia proposta. - RN-007 Marcadores — somente `[campo]` explícito origina campo. - RN-008 Tipos de campo — Texto e Número/moeda; default Texto, obrigatório=Não. - RN-009 Estrutura do modelo — marcador não é criado/excluído/renomeado na tela de validação; correção estrutural exige reenvio. - RN-010 Versão de modelo — primeira ativação V1; alterações V2+ preservam histórico. - RN-011 Criação de rascunho — abrir 4.2 não cria rascunho; nasce no primeiro persist válido. - RN-012 Status — apenas Rascunho/Gerada; edição em andamento é indicador. - RN-013 Fluxo 4.2 — Preencher/Validar/Gerar são estados da mesma página. - RN-014 Salvar — com pendências salva e fica em Preencher; sem pendências cria checkpoint e vai para Validar. - RN-015 Salvar e sair — persiste/checkpoint; libera lock somente após sucesso. - RN-016 Lock — um editor; 10 min; sem tomada forçada; observador vê último persistido. - RN-017 Geração formal — só existe sucesso se PDF formal existir; falha não cria número/versão formal. - RN-018 Numeração — primeira geração cria PROP-###### e V1; escopo da sequência ainda precisa de decisão técnica formal. - RN-019 Imutabilidade — versão formal gerada é imutável. - RN-020 Nova versão — somente com alteração de conteúdo + nova geração bem-sucedida. - RN-021 Histórico — versões antigas podem ser vistas/baixadas/enviadas, nunca editadas/excluídas/usadas como base. - RN-022 E-mail — usa exatamente PDF exibido; não muda status Gerada. - RN-023 Auditoria — autoria e eventos críticos rastreáveis. - RN-024 Logo — logo da empresa obrigatório para identidade da proposta; cores opcionais. - RN-025 Erros — erros são estados das telas existentes, sem criar novas páginas numeradas. ## 3. Requisitos funcionais RF-001 autenticar/resolver workspace; RF-002 listar propostas por escopo; RF-003 listar modelos ativos; RF-004 confirmar seleção sem criar draft; RF-005 abrir 4.2 sem draft vazio; RF-006 prefill CRO quando aplicável; RF-007 campos dinâmicos; RF-008 validação durante edição; RF-009 autosave; RF-010 draft no primeiro persist; RF-011 Salvar; RF-012 Salvar e sair; RF-013 trocar modelo; RF-014 lock; RF-015 validar antes de gerar; RF-016 gerar PDF; RF-017 reconciliar geração assíncrona; RF-018 número comercial; RF-019 versionar; RF-020 detectar ausência de alteração; RF-021 visualizar vigente/histórica; RF-022 baixar PDF; RF-023 enviar e-mail; RF-024 registrar envio; RF-025 excluir draft elegível; RF-026 listar modelos; RF-027 limite 10/10; RF-028 upload PDF/PPTX/DOCX; RF-029 analisar marcadores; RF-030 draft de modelo após upload+análise técnica; RF-031 reprocessar correção no mesmo draft; RF-032 configurar campos; RF-033 autosave/lock de modelo; RF-034 ativar V1; RF-035 versionar modelo V2+; RF-036 arquivar; RF-037 excluir modelo nunca usado (Admin); RF-038 auditoria; RF-039 RLS; RF-040 Sentry. ## 4. Requisitos não funcionais - Segurança: RLS + autorização server-side; fail-closed. - Privacidade: nenhum documento/template cross-tenant; Sentry/logs sem documento integral/PII desnecessária. - Confiabilidade: geração/ativação idempotentes; sem efeitos parciais. - Concorrência: lock TTL 10 min + renovação por atividade; sem force takeover. - Recuperação: autosave e retomada respeitando lock. - Performance: carregamento progressivo; paginação/virtualização quando necessário; metas numéricas ainda abertas. - Acessibilidade: alvo WCAG 2.1 AA, teclado, foco, labels, contraste, status não apenas por cor. - Responsividade: web adaptada; mobile não é mera redução proporcional. - Observabilidade: Sentry client/server/edge + correlação request/job. - Auditabilidade: eventos mínimos imutáveis; retenção ainda aberta. - Manutenibilidade: TS strict recomendado, lint, testes, separação por domínio. - Integridade documental: versão formal referencia versão exata do modelo e artefato. - Segurança de arquivos: MIME/extensão/conteúdo; tamanho/antivírus/sandbox ainda abertos. ## 5. Modelo de dados proposto - `proposal_models`: id, workspace_id, name, status, current_version, created_by, archived_at. - `proposal_model_versions`: id, model_id, version_no, source_file_ref, normalized_template, analysis_json, activated_at, activated_by. - `proposal_model_fields`: id, model_version_id, field_key, display_name, type, required, order. - `proposals`: id, workspace_id, created_by, owner_user_id, status, commercial_number, current_version_no, model_id, client_ref?, created_at. - `proposal_drafts`: id, proposal_id, based_on_version_no?, model_version_id, data_json, content_hash, lock_owner?, updated_at. - `proposal_versions`: id, proposal_id, version_no, model_version_id, content_snapshot, content_hash, pdf_ref, generated_by, generated_at. - `proposal_email_events`: id, proposal_version_id, actor_id, to_email, subject, result, provider_message_id?, created_at. - `proposal_audit_events`: id, workspace_id, proposal_id?, model_id?, actor_id, event_type, metadata, created_at. - locks preferencialmente no Redis. - `workspace_branding`: workspace_id, logo_ref, brand colors opcionais, contact email. ## 6. Design System EloPro V2.1 - Base predominante: Cloud White `#FBFBFE`, 65–75% superfícies claras. - Texto/âncora: Midnight Ink `#071B45`. - Primary Blue `#1F6FFF`; botão primário deve usar token de contraste do DS, Blue 600 `#225EDB` quando aplicável. - Bright Blue `#2F8FFF`; Aqua Signal `#00C2A8`; Soft Blue `#DCEBFF`; Warning `#F39A2D`; Error `#E63946`. - Manrope para UI. Source Serif 4 apenas institucional/editorial. - Spacing 4px base; radius input 10, button 18, card 14, panel 18, modal 24. - Motion 120/200/320ms, easing `cubic-bezier(.2,.8,.2,1)`. - Proibido: neon, cyberpunk, holograma, glassmorphism, dark page dominante, grid decorativo, robôs/cérebros futuristas. - Estados sempre por cor + texto + ícone/semântica; nunca cor isolada. - Componentes globais: Button, IconButton, Badge, Tag, Card, Input, Select, Checkbox, Radio, Switch, DateField/DateRangeField, Tabs, CapsuleTabs, ContextGroup, SectionPill, Toast, Tooltip, Dialog. - Preservar quando fizer sentido: ContextLayers, JourneyTrail, OpenFramePanel, SemanticMarker. - `JourneyTrail` não é Stepper genérico. - Lacunas de DS: Search, Table, Stepper, Empty State, Pagination, Skeleton, File Upload, Avatar. Compor localmente usando tokens/primitivos e não promover como componente global sem decisão. - Iconografia EloPro é prioridade; Lucide apenas fallback técnico. ## 7. Pendências que NÃO podem ser inventadas - P-001 fallback de Reply-To sem e-mail comercial. - P-002 fonte definitiva de Cliente no uso independente. - P-003 Tipo no MVP e opções definitivas. - P-004 Apresentação. - P-005 Gerador de Contratos. - P-006 tamanho máximo/antivírus/sandbox/extração parcial de arquivo. - P-007 retenção da auditoria. - P-008 fonte/lifecycle de entitlements. - P-009 escopo definitivo da sequência PROP (recomendação técnica atual: workspace, mas não assumir sem ADR/aprovação). - P-010 motor de ingestão/conversão PDF/PPTX/DOCX. - P-011 provider de e-mail (EloPro documenta Resend, mas formalizar uso no módulo). - P-012 metas quantitativas de performance/SLO/document size/generation time. ## 8. Critérios críticos de aceite - Nenhum P0/P1 bloqueador aberto. - Workspace A nunca acessa B por UI, URL manipulada, API/Action direta ou storage. - Falha de geração não consome PROP nem versão. - Duplo clique/retry não cria duas versões. - Versão formal é imutável. - Lock funcional expira em 10 min e impede edição concorrente. - Usuário Final não acessa Modelos nem por rota direta. - 10/10 bloqueia upload antes do processamento. - PDF baixado/enviado é o mesmo da versão exibida. - UI segue EloPro V2.1 sem inventar regra funcional.