Appearance
Vigência e Renovação: Especificação de Endpoints
Visão Geral
API RESTful para vigência estruturada, renovação automática, rescisão programada, garantias e dashboard de risco. Implementada no contrasync-nest-api (módulo renewals). Tabelas isoladas (hub contracts_renew + alertas/execuções/garantias); a tabela contracts não recebe colunas novas. Migração additive-only.
Todos os endpoints exigem JWT (Bearer) + header x-company-id e são escopados pela empresa do usuário.
Endpoints
1. Configurar vigência/renovação
POST /contracts/:id/validityRequest:
ts
interface SetValidityRequest {
strategy: 'OFF' | 'SAME_TERMS' | 'INDEX_ADJUSTED' | 'NEGOTIATE';
index?: 'IPCA' | 'IGPM' | 'INPC';
alertOffsets?: number[]; // dias antes do vencimento; default [90,60,30,15,7,1]
renewalNoticeDays?: number; // default 30
autoRenewEnabled?: boolean;
autonomyLevel?: number; // 0..3 (gate L2/L3)
valueGate?: number;
responsibleUserId?: string; // uuid
}Response:
ts
interface RenewalResponse {
id: string;
contractId: string;
strategy: 'OFF' | 'SAME_TERMS' | 'INDEX_ADJUSTED' | 'NEGOTIATE';
index: 'IPCA' | 'IGPM' | 'INPC' | null;
alertOffsets: number[];
renewalNoticeDays: number;
autoRenewEnabled: boolean;
autonomyLevel: number;
valueGate: number | null;
responsibleUserId: string | null;
state:
| 'ACTIVE'
| 'RENEWAL_DUE_SOON'
| 'RENEWING'
| 'RENEWED'
| 'TERMINATING'
| 'TERMINATED'
| 'LAPSED'
| 'RENEWAL_FAILED'
| 'NEEDS_HUMAN';
terminationScheduledAt: string | null;
terminationNoticeDays: number;
nextRenewalAt: string | null;
}2. Agendar renovação
POST /contracts/:id/renewal/schedulets
interface ScheduleRenewalRequest {
strategy: 'OFF' | 'SAME_TERMS' | 'INDEX_ADJUSTED' | 'NEGOTIATE';
index?: 'IPCA' | 'IGPM' | 'INPC';
renewalNoticeDays?: number;
}Resposta: RenewalResponse.
3. Cancelar renovação
POST /contracts/:id/renewal/cancelSem body. Define strategy=OFF, state=ACTIVE, limpa nextRenewalAt. Resposta: RenewalResponse.
4. Simular renovação (preview de valor)
POST /contracts/:id/renewal/simulatets
interface SimulateRenewalRequest {
strategy?: 'OFF' | 'SAME_TERMS' | 'INDEX_ADJUSTED' | 'NEGOTIATE';
index?: 'IPCA' | 'IGPM' | 'INPC';
}
interface SimulateRenewalResponse {
contractId: string;
strategy: string;
oldValue: number | null;
newValue: number | null;
adjustmentPct: number;
index: 'IPCA' | 'IGPM' | 'INPC' | null;
referenceMonth: string | null;
breakdown: string;
}5. Executar renovação agora (manual / IA L2-L3)
POST /contracts/:id/renewal/executeSem body. Aplica o gate de política (L3 só com autoRenewEnabled, autonomyLevel>=3, valor abaixo do valueGate e sem garantia em risco; caso contrário rebaixa para L2 → NEEDS_HUMAN). NEGOTIATE nunca executa automaticamente. Resposta: RenewalResponse.
6. Agendar rescisão programada
POST /contracts/:id/termination/schedulets
interface ScheduleTerminationRequest {
terminationAt: string; // ISO date
terminationNoticeDays?: number; // >= 30
}Valida o aviso prévio mínimo (30 dias). Resposta: RenewalResponse.
7. Adicionar garantia/marco
POST /contracts/:id/warrantiests
interface CreateWarrantyRequest {
type: 'CAUCAO' | 'FIANCA' | 'SEGURO' | 'NOTA_PROMISSORIA';
description?: string;
amount?: number;
expiresAt?: string; // ISO date
}
interface WarrantyResponse {
id: string;
type: 'CAUCAO' | 'FIANCA' | 'SEGURO' | 'NOTA_PROMISSORIA';
description: string | null;
amount: number | null;
expiresAt: string | null;
releasedAt: string | null;
status: 'ACTIVE' | 'EXPIRING' | 'EXPIRED' | 'RELEASED';
}8. Contratos em risco
GET /contracts/at-risk?daysAhead=90ts
interface AtRiskItem {
contractId: string;
name: string;
endDate: string;
daysToEnd: number;
strategy: string;
state: string;
responsibleUserId: string | null;
hasOpenWarrantyRisk: boolean;
}
interface AtRiskResponse {
data: AtRiskItem[];
}9. Snapshot de vigência (dashboard)
GET /dashboard/validity-snapshotts
interface ValiditySnapshot {
total: number;
structured: number;
structuredPct: number;
dueSoon: number;
renewing: number;
lapsed: number;
terminated: number;
warrantiesExpiring: number;
}Jobs assíncronos
- Alerta de vencimento (
0 6 * * *): por config, calcula o offset corrente (D-90/60/30/15/7/1 e D+1 atrasado), idempotente por(renewalId, offsetDays), notifica e-mail/WhatsApp/in-app do responsável, auditaRENEWAL_ALERT_SENT. Mesmo job sinaliza garantias expirando em 30 dias (WARRANTY_EXPIRING). - Renovação devida (
0 7 * * *): executa rescisão programada vencida, dispara renovação quandonextRenewalAtchega (SAME_TERMS/INDEX_ADJUSTED), e marcaLAPSEDcontratos sem renovação comstrategy=OFFvencidos.
Ambos protegidos por DistributedLockService (lock distribuído via Redis).
Tools IA (acesso só via REST, token do usuário propagado)
schedule_renewal, simulate_renewal, list_contracts_at_risk, draft_renewal_communication, auto_renew_batch (WRITE, exige confirm=true; gate de política aplicado pelo produto). Definidas em contrasync-ai-api/src/modules/tools/contracts.tools.ts.
Auditoria
EntityHistory (entityType=CONTRACT): RENEWAL_SCHEDULED, RENEWAL_CANCELLED, RENEWAL_SIMULATED, CONTRACT_RENEWED, RENEWAL_FAILED, RENEWAL_ALERT_SENT, TERMINATION_SCHEDULED, CONTRACT_LAPSED, WARRANTY_ADDED, WARRANTY_EXPIRING, WARRANTY_RELEASED. Logs duráveis de execução em contracts_renew_executions (inclui policyGateApplied e aiToolCallId quando originado por IA).