+
+ ) : null}
{isEditing && id ? (
diff --git a/docs/progress.md b/docs/progress.md
index 7ba8f8e..33ae6d5 100644
--- a/docs/progress.md
+++ b/docs/progress.md
@@ -775,3 +775,21 @@ Data: 2026-09-18. Frontend da leva anterior (agente `eden-frontend`), construíd
### Verificação
`pnpm turbo run typecheck build` 28/28 (antes e depois da correção). Suíte 106/106 (inalterada, mudança de frontend). Testado ao vivo em navegador real via Playwright, incluindo o cenário exato do bug (digitar 14 dígitos antes de qualquer busca — botão permanece "Buscar CNPJ" corretamente agora) e o ciclo completo com CNPJ real (Petrobras, nome fantasia e sócio confirmados). Revendas de teste desativadas ao final.
+
+---
+
+## Representante legal da Revenda — preparação pra contrato com revenda
+
+Data: 2026-09-18. Usuário: "o cadastro da revenda tem que ser completo pq depois vamos usar esses dados para fazer o contrato com a revenda tb por dentro do erp". Implementado diretamente (mudança pequena e bem entendida, mesmo padrão já estabelecido).
+
+Investigando antes de mudar: o módulo de Assinatura Eletrônica já aceita `resellerId` como origem de um envelope (`CreateEnvelopeDto`, alternativa a `clientRegistrationId`), mas os `contratante.signers` de um envelope hoje vêm sempre digitados manualmente no corpo da requisição — não existe ainda nenhuma derivação automática a partir de `client_registration_partners`/`reseller_partners` (achado que vale registrar para quando essa integração for construída de verdade, não resolvido aqui — fora do pedido desta leva). O que faltava de concreto e imediato: `resellers`, ao contrário de `client_registrations`, não tinha um bloco de **representante legal** dedicado (`pj_rep_*` em client_registrations) — só a lista geral de sócios. Um contrato precisa de um signatário nomeado e autorizado, não só uma lista de sócios.
+
+Migration `packages/database/migrations/1789700100000_resellers-legal-representative.cjs`: `resellers` ganha `rep_full_name`, `rep_cpf`, `rep_role`, `rep_email`, `rep_mobile_phone`, `rep_authorization_ack` — mesmo shape de `client_registrations.pj_rep_*`. **Divergência deliberada**: lá `pj_rep_cpf` é estruturalmente bloqueado do PATCH genérico (só seria setável pelo fluxo de submissão pública original do legado, que o EDEN ainda não construiu — hoje é uma lacuna conhecida, o campo nunca é preenchido de fato). Revenda não tem esse fluxo de submissão pública (é sempre cadastro de backoffice), então não existe "momento de submissão original" pra travar atrás — `rep_cpf` aqui é um campo comum, livremente editável via `PATCH`, sem repetir uma trava que só faria sentido lá.
+
+Backend (`CreateResellerDto`, `resellers.service.ts`, repositório) e frontend (`ResellerFormPage.tsx`, novo card "Representante legal" entre "Dados da revenda" e "Sócios") seguindo o mesmo padrão já usado no resto do módulo.
+
+### Verificação
+`pnpm db:migrate`/`down`/`migrate` de novo — limpo. `pnpm turbo run typecheck build` 28/28. Suíte 107/107 (106→107, 1 teste novo cobrindo set+update dos campos). Testado ao vivo em navegador real: ordem confirmada (`Dados da revenda → Representante legal → Sócios → Endereço → Contatos → Status`), Nome/CPF do representante preenchidos e confirmados persistentes após reload da página. Revenda de teste desativada ao final.
+
+### Pendências
+A derivação automática de signatários de contrato a partir de `client_registration_partners`/`reseller_partners`/representante legal (pra realmente "usar na confecção do contrato") ainda não existe — hoje `CreateEnvelopeDto.signers` continua sendo preenchido manualmente independente da origem. Esse é o trabalho real que fecha o ciclo que o usuário descreveu; os dados já ficam prontos e completos esperando por ele.
diff --git a/packages/database/migrations/1789700100000_resellers-legal-representative.cjs b/packages/database/migrations/1789700100000_resellers-legal-representative.cjs
new file mode 100644
index 0000000..34c4fe0
--- /dev/null
+++ b/packages/database/migrations/1789700100000_resellers-legal-representative.cjs
@@ -0,0 +1,49 @@
+/**
+ * Representante legal da revenda — mirrors `client_registrations.pj_rep_*`
+ * (packages/database/migrations/1788447739229_client-registrations.cjs).
+ * Motivation (user, 2026-09-18): reseller registration data will later
+ * feed reseller contract creation inside the ERP, same as
+ * client_registrations already does for client contracts — a contract
+ * needs a named, authorized signer for the legal entity, not just the
+ * general Sócios list (`reseller_partners`, added in
+ * 1789700000000_resellers-expansion.cjs).
+ *
+ * Deliberate deviation from `client_registrations.pj_rep_cpf`: there it's
+ * structurally excluded from the generic admin PATCH (`UpdateClientRegistrationDto`)
+ * because in the legacy it's only ever set during the public self-service
+ * submission flow, which EDEN hasn't built yet — so it stays permanently
+ * unset there today, a known pre-existing gap, not something to replicate.
+ * Resellers have no such public submission flow (always backoffice-created)
+ * and no "original submission" moment to lock behind, so `rep_cpf` here is
+ * a plain, freely-PATCH-able column like every other reseller field — see
+ * `resellers.service.ts`, no new DTO exclusion added for it.
+ */
+
+exports.shorthands = undefined;
+
+exports.up = (pgm) => {
+ pgm.sql(`
+ ALTER TABLE resellers
+ ADD COLUMN rep_full_name TEXT,
+ ADD COLUMN rep_cpf TEXT,
+ ADD COLUMN rep_role TEXT,
+ ADD COLUMN rep_email TEXT,
+ ADD COLUMN rep_mobile_phone TEXT,
+ ADD COLUMN rep_authorization_ack BOOLEAN NOT NULL DEFAULT false;
+
+ COMMENT ON COLUMN resellers.rep_authorization_ack IS
+ 'Confirmação de que o representante está autorizado a agir pela revenda — mesmo campo de intenção que client_registrations.pj_rep_authorization_ack, sem o mesmo bloqueio estrutural de edição (ver cabeçalho da migration).';
+ `);
+};
+
+exports.down = (pgm) => {
+ pgm.sql(`
+ ALTER TABLE resellers
+ DROP COLUMN IF EXISTS rep_full_name,
+ DROP COLUMN IF EXISTS rep_cpf,
+ DROP COLUMN IF EXISTS rep_role,
+ DROP COLUMN IF EXISTS rep_email,
+ DROP COLUMN IF EXISTS rep_mobile_phone,
+ DROP COLUMN IF EXISTS rep_authorization_ack;
+ `);
+};
diff --git a/packages/database/src/repositories/resellers.ts b/packages/database/src/repositories/resellers.ts
index 530cca4..4a5ea81 100644
--- a/packages/database/src/repositories/resellers.ts
+++ b/packages/database/src/repositories/resellers.ts
@@ -33,6 +33,12 @@ export interface Reseller {
contact_technical_name: string | null;
contact_technical_email: string | null;
contact_technical_phone: string | null;
+ rep_full_name: string | null;
+ rep_cpf: string | null;
+ rep_role: string | null;
+ rep_email: string | null;
+ rep_mobile_phone: string | null;
+ rep_authorization_ack: boolean;
}
export async function listResellers(includeInactive = false): Promise {
@@ -79,6 +85,12 @@ export interface CreateResellerInput {
contactTechnicalName?: string | null;
contactTechnicalEmail?: string | null;
contactTechnicalPhone?: string | null;
+ repFullName?: string | null;
+ repCpf?: string | null;
+ repRole?: string | null;
+ repEmail?: string | null;
+ repMobilePhone?: string | null;
+ repAuthorizationAck?: boolean;
}
export async function createReseller(input: CreateResellerInput): Promise {
@@ -91,7 +103,8 @@ export async function createReseller(input: CreateResellerInput): Promise