Files
DeskcommCRM/hooks/useAdminLGPDRequests.ts
Rafael MelgaçoandClaude Opus 5 090c59e2f4 fix(crm-vivo): o LGPD passa a falar o vocabulário do banco
O CHECK de lgpd_requests aceita 'data_request' | 'redact' | 'store_redact'. A
UI, as rotas, os webhooks da Nuvemshop e os workers usavam
'customer_data_request' | 'customer_redact' — palavras que o banco REJEITA.
Provado com insert lado a lado: o vocabulário da UI viola a constraint, o do
banco entra.

O estrago era maior que o rótulo errado na tela:
- criar pedido pelos caminhos que usam esse vocabulário estourava no INSERT
  (inclui os webhooks da Nuvemshop, que são obrigação de plataforma);
- o filtro por tipo na tela nunca casava com nenhuma linha;
- e os WORKERS descartavam pedido legítimo com "wrong_request_type" — o
  redact-worker aceitava store_redact e recusava 'redact', que é o caso comum
  (anonimizar um cliente). O banco tem uma linha 'redact' parada aí.

Havia TRÊS declarações do tipo (lib/lgpd/types.ts, hooks/useLgpdRequests,
hooks/useAdminLGPDRequests), todas com o vocabulário errado — três lugares para
divergir. Agora os hooks reexportam o tipo canônico, e o rótulo em pt-BR sai de
LGPD_REQUEST_TYPE_LABELS na mesma fonte, em vez de cinco mapas locais.

typecheck 0, lint 0 errors, 848 unitários.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013dxBNZMjUzBx8xWs8DvGvP
2026-07-24 20:47:03 -03:00

70 lines
2.5 KiB
TypeScript

"use client";
import { useInfiniteQuery } from "@tanstack/react-query";
import { apiClient } from "@/lib/api/client";
// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------
export type AdminLgpdRiskLevel = "expired" | "at_risk" | "warning" | "ok";
export type AdminLgpdStatus = "received" | "processing" | "completed" | "failed" | "pending_review";
// Alias do tipo canônico (lib/lgpd/types.ts): o admin e o app falam o MESMO
// vocabulário do banco. Duas listas era como uma podia divergir sozinha.
import type { LgpdRequestType } from "@/lib/lgpd/types";
export type AdminLgpdRequestType = LgpdRequestType;
export interface AdminLgpdRequest {
id: string;
organization_id: string;
request_type: AdminLgpdRequestType;
status: AdminLgpdStatus;
received_at: string;
due_at: string | null;
completed_at: string | null;
contact_id: string | null;
external_customer_id: string | null;
attempts: number;
emergency: boolean;
scope: string;
error_message: string | null;
tenant_name: string | null;
tenant_slug: string | null;
risk_level: AdminLgpdRiskLevel;
}
export interface AdminLgpdFilters {
status?: AdminLgpdStatus;
request_type?: AdminLgpdRequestType;
risk_level?: AdminLgpdRiskLevel;
tenant_id?: string;
}
interface ListResponse {
data: AdminLgpdRequest[];
meta?: { cursor?: string | null; has_more?: boolean };
}
// ---------------------------------------------------------------------------
// Hook
// ---------------------------------------------------------------------------
export function useAdminLGPDRequests(filters: AdminLgpdFilters = {}) {
return useInfiniteQuery({
queryKey: ["admin", "lgpd", filters] as const,
initialPageParam: undefined as string | undefined,
queryFn: async ({ pageParam }) => {
const qs = new URLSearchParams();
if (filters.status) qs.set("status", filters.status);
if (filters.request_type) qs.set("request_type", filters.request_type);
if (filters.risk_level) qs.set("risk_level", filters.risk_level);
if (filters.tenant_id) qs.set("tenant_id", filters.tenant_id);
if (pageParam) qs.set("cursor", pageParam);
qs.set("limit", "50");
return apiClient.get<ListResponse>(`/api/v1/admin/lgpd/requests?${qs.toString()}`);
},
getNextPageParam: (last) =>
last.meta?.has_more && last.meta.cursor ? last.meta.cursor : undefined,
staleTime: 60_000,
});
}