Receba novidades do Hedhog no seu e-mail
Novos lançamentos, receitas e breaking changes — sem spam.
Submódulo CRM
proposals
Ciclo de vida de propostas comerciais e contratos — rascunho, submeter para aprovação, aprovar/rejeitar/cancelar, converter em contrato e gerar documentos PDF.
Caminho de origem: libraries/crm/src/proposal
Arquivo do módulo: proposal.module.ts
Introdução
O submódulo Proposals modela o ciclo de vida completo de uma oferta comercial: criação de rascunho, aprovação interna, entrega ao cliente e conversão em contrato. Uma proposta percorre uma máquina de status fixa — draft, pending_approval, approved, rejected, cancelled, expired, contract_generated — e cada ação que altera o estado é exposta como seu próprio endpoint (submit, send, approve, reject, cancel, convert), em vez de um PATCH genérico de status, o que mantém a trilha de auditoria e os efeitos colaterais (notificações, registros de aprovação) atrelados a uma ação de negócio explícita, e não a uma escrita arbitrária de campo.
Internamente, cada proposta mantém um histórico de revisões. O PATCH /proposal/:id normalmente atualiza a revisão atual no lugar, mas passar create_new_revision: true bifurca uma nova revisão (incrementando current_revision_number) em vez de sobrescrever — isso permite que um representante de vendas itere sobre preços ou escopo depois que uma proposta já foi enviada, sem perder a versão que o cliente viu originalmente. Itens de linha (serviços, produtos, taxas, descontos, notas) e documentos anexados são filhos de uma revisão, não da proposta em si, de modo que cada revisão carrega seu próprio snapshot completo.
A aprovação é configurável, e não codificada de forma fixa: o número de aprovações necessárias antes de uma proposta ser considerada totalmente aprovada é lido da configuração crm-proposal-required-approvals (padrão 1), e cada aprovação é registrada como uma linha com seu próprio approver_user_id e status, de modo que múltiplos aprovadores possam se manifestar de forma independente. De maneira crítica, o POST /proposal/:id/approve é restrito por uma role dedicada proposal-approver, e não pela role geral admin-crm usada pelo restante do submódulo — isso permite que uma organização designe pessoas específicas (por exemplo, um líder financeiro ou chefe de departamento) como autoridades de aprovação sem lhes conceder direitos completos de administração do CRM. Submit e send atualmente passam pelo mesmo fluxo submitForApproval no serviço, de modo que "enviar" uma proposta a um cliente e "submetê-la" para revisão interna são funcionalmente idênticos hoje.
O POST /proposal/:id/generate-pdf renderiza a revisão atual em HTML e então em um buffer PDF, faz upload do arquivo resultante através do serviço File da plataforma (sob contact/proposals/generated) e o vincula de volta à proposta como um documento generated_pdf — o que significa que cada PDF que uma proposta já produziu permanece recuperável através de seu histórico de documentos, não apenas o mais recente. Documentos de proposta também podem se originar de um upload manual, de uma extração assistida por IA ou de uma importação, distinguidos por source_kind, e carregam seu próprio extraction_status para rastrear OCR/parsing de arquivos de origem enviados.
O POST /proposal/:id/convert solicita a conversão de uma proposta aprovada em um contrato; isso dispara um evento de integração ao qual listeners downstream (como os listeners de checkout/contrato conectados no CrmModule) podem reagir, mantendo o handoff de proposta para contrato desacoplado do próprio controller de Proposals.
Endpoints HTTP
13 endpoints
Lista paginada de propostas com filtros opcionais de status e pessoa. Cada item inclui required_approvals, approval_count e se o usuário atual já a aprovou.
- Query
- page, pageSize, search, status? (draft | pending_approval | approved | rejected | cancelled | expired | contract_generated), person_id?
Estatísticas resumidas de propostas (contagens por status, valores totais).
Obtém os detalhes completos da proposta, incluindo itens, documentos e histórico de aprovação/workflow da revisão atual.
- Params
- id (int)
Cria uma nova proposta (padrão status draft).
Body
| Field | Type | Required | Notes |
|---|---|---|---|
| person_id | int | yes | — |
| title | string (max 180) | yes | — |
| code | string (max 40) | no | — |
| status | ProposalStatus (draft | pending_approval | ...) | no | — |
| contract_category | ProposalContractCategory (employee | contractor | client | supplier | vendor | partner | internal | other) | no | — |
| contract_type | ProposalContractType (clt | pj | freelancer_agreement | service_agreement | fixed_term | recurring_service | nda | amendment | addendum | other) | no | — |
| billing_model | ProposalBillingModel (time_and_material | monthly_retainer | fixed_price) | no | — |
| currency_code | string | no | — |
| valid_from | date string | no | — |
| valid_until | date string | no | — |
| subtotal_amount_cents | int | no | — |
| discount_amount_cents | int | no | — |
| tax_amount_cents | int | no | — |
| total_amount_cents | int | no | — |
| notes | string | no | — |
| owner_user_id | int | no | — |
| generation_mode | ProposalGenerationMode (manual | ai_assisted | duplicated | imported) | no | — |
| summary | string | no | — |
| content_html | string | no | — |
| snapshot_json | object | no | — |
| items | ProposalItemDto[] | no | Line items (services, products, fees, discounts) |
| documents | ProposalDocumentDto[] | no | Attached documents |
Atualiza os campos da proposta (atualização parcial; todos os campos de CreateProposalDto são aceitos).
- Params
- id (int)
Body
| Field | Type | Required | Notes |
|---|---|---|---|
| create_new_revision | boolean | no | Fork a new revision instead of overwriting the current one |
Renderiza a revisão atual em PDF, faz upload através do serviço File e a anexa à proposta como um documento generated_pdf.
- Params
- id (int)
Submete a proposta para aprovação interna.
- Params
- id (int)
Body
| Field | Type | Required | Notes |
|---|---|---|---|
| approver_user_id | int | no | — |
| note | string | no | — |
Envia a proposta ao cliente (passa pelo mesmo fluxo submitForApproval de /submit).
- Params
- id (int)
Body
| Field | Type | Required | Notes |
|---|---|---|---|
| approver_user_id | int | no | — |
| note | string | no | — |
Aprova uma proposta que está pendente de aprovação. Restrito à role dedicada proposal-approver, e não à role geral admin-crm.
- Params
- id (int)
Body
| Field | Type | Required | Notes |
|---|---|---|---|
| note | string | no | — |
Rejeita uma proposta que está pendente de aprovação.
- Params
- id (int)
Body
| Field | Type | Required | Notes |
|---|---|---|---|
| note | string | no | — |
Cancela uma proposta.
- Params
- id (int)
Body
| Field | Type | Required | Notes |
|---|---|---|---|
| note | string | no | — |
Solicita a conversão de uma proposta aprovada em um contrato; dispara um evento de integração para listeners downstream.
- Params
- id (int)
Body
| Field | Type | Required | Notes |
|---|---|---|---|
| note | string | no | — |
Exclui uma ou mais propostas.
Body
| Field | Type | Required | Notes |
|---|---|---|---|
| ids | number[] | yes | IDs to delete |
Ferramentas MCP
Ferramentas nomeadas que podem ser chamadas por modelos de IA através do Model Context Protocol (MCP).
crm.proposals.listLista propostas com paginação e filtros opcionais
crm.proposals.statsRetorna estatísticas de propostas agrupadas por status
crm.proposals.getRetorna uma única proposta por ID com detalhes completos, incluindo itens e documentos
crm.proposals.createCria uma nova proposta para uma pessoa
crm.proposals.updateAtualiza uma proposta existente por ID
crm.proposals.submitSubmete uma proposta para aprovação
crm.proposals.sendEnvia uma proposta ao cliente
crm.proposals.approveAprova uma proposta. Requer a role proposal-approver
crm.proposals.rejectRejeita uma proposta com um motivo opcional
crm.proposals.cancelCancela uma proposta
crm.proposals.convertSolicita a conversão de uma proposta aprovada em um contrato
crm.proposals.deleteExclui uma ou mais propostas pelos seus IDs