Frontend completo (Etapas 11-18) e extensões de backend (Etapas 13 e 18)

Adiciona o frontend Next.js em frontend/ (setup, design system,
autenticação/tema, layout/navegação, área master, área tenant completa:
clientes, produtos, vendas, recebimentos, whatsapp, e-mail, alertas,
equipe e perfil). Estende o backend de forma aditiva e autorizada:
cookie httpOnly para refresh token (Etapa 13) e CRUD de equipe +
edição de perfil do tenant (Etapa 18, módulo src/modules/equipe/ novo
e PUT /tenant/perfil). Detalhes completos em Etapas/V2/*.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-16 09:41:13 -03:00
co-authored by Claude Sonnet 5
parent f9738e54da
commit 323912748f
179 changed files with 29312 additions and 22 deletions
+74
View File
@@ -0,0 +1,74 @@
import { apiClient } from '@/lib/api/client';
export const WHATSAPP_INSTANCE_STATUSES = [
'desconectado',
'conectando',
'conectado',
'erro',
] as const;
export type WhatsappInstanceStatus = (typeof WHATSAPP_INSTANCE_STATUSES)[number];
/** Espelha o model `tenant_whatsapp_instances`. */
export interface WhatsappInstance {
id: string;
tenant_id: string;
evolution_config_id: string | null;
instance_name: string;
numero_conectado: string | null;
status: WhatsappInstanceStatus;
qr_code_gerado_em: string | null;
criado_em: string;
}
/**
* Espelha `EvolutionQrCode` — por comentário do próprio backend
* (`evolution-api.client.ts`), o prefixo exato de `base64` não é garantido
* (é o que a Evolution API real devolveu, repassado como veio). Renderizar
* defensivamente: se já começar com `data:`, usar como está; senão,
* prefixar `data:image/png;base64,`.
*/
export interface WhatsappQrCode {
base64?: string;
pairing_code?: string;
}
export interface TestarEnvioWhatsappInput {
numero: string;
mensagem?: string;
}
export function listWhatsappInstances() {
return apiClient.get<WhatsappInstance[]>('/tenant/whatsapp/instancias');
}
export function criarWhatsappInstance() {
return apiClient.post<WhatsappInstance>('/tenant/whatsapp/instancias');
}
export function obterWhatsappQrCode(id: string) {
return apiClient.get<WhatsappQrCode>(`/tenant/whatsapp/instancias/${id}/qrcode`);
}
export function consultarWhatsappStatus(id: string) {
return apiClient.get<WhatsappInstance>(`/tenant/whatsapp/instancias/${id}/status`);
}
export function removerWhatsappInstance(id: string) {
return apiClient.delete<void>(`/tenant/whatsapp/instancias/${id}`);
}
/**
* Espelha `DispatchResult` (`src/modules/alert-dispatch/alert-dispatch.service.ts`):
* o endpoint sempre responde HTTP 200 — falha de envio (instância não
* conectada, Evolution API indisponível etc) vem como
* `{ sucesso: false, erro }`, não como erro HTTP. Quem chama precisa checar
* `sucesso` explicitamente, não só o status da resposta.
*/
export interface TestarEnvioResult {
sucesso: boolean;
erro?: string;
}
export function testarEnvioWhatsapp(id: string, input: TestarEnvioWhatsappInput) {
return apiClient.post<TestarEnvioResult>(`/tenant/whatsapp/instancias/${id}/testar-envio`, input);
}