diff --git a/.gitignore b/.gitignore index e638584ec..cbeb8d275 100644 --- a/.gitignore +++ b/.gitignore @@ -99,7 +99,19 @@ loop/run-session.sh # graphify (análise local de knowledge graph) graphify-out/ + +# Lockfiles de OUTRO gerenciador. O `pnpm-lock.yaml` é o único versionado, e +# não é preferência de estilo: os pisos de segurança do projeto vivem em +# `pnpm.overrides` do package.json, que o npm e o bun NÃO leem. Um `bun install` +# aqui move `overrides` para o topo do package.json (formato bun/npm), o pnpm +# deixa de enxergá-lo, e o `pnpm-lock.yaml` perde o bloco `overrides` inteiro — +# `path-to-regexp@6.1.0` volta para a árvore com `pnpm audit` ainda verde. +# Aconteceu em 2026-08-26. Ignorar o lock não impede o estrago; impede que ele +# viaje no commit sem ninguém notar. package-lock.json +bun.lock +bun.lockb +yarn.lock .e2e-invite.json .e2e-owner.json .e2e-invite-url.json diff --git a/.prettierrc b/.prettierrc index e28b33552..66fc63d05 100644 --- a/.prettierrc +++ b/.prettierrc @@ -7,5 +7,6 @@ "useTabs": false, "arrowParens": "always", "endOfLine": "lf", - "plugins": ["prettier-plugin-tailwindcss"] + "plugins": ["prettier-plugin-tailwindcss"], + "tailwindStylesheet": "./app/globals.css" } diff --git a/AGENTS.md b/AGENTS.md index 0e5a72d47..7ca48a535 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -19,7 +19,7 @@ quebra no clone fresco é um bug de produto, não um detalhe de ambiente. ## Stack (CONFIRMADO em `package.json`) -Next.js 16 (App Router) · React 19 · TypeScript 6 estrito · Tailwind 3 · +Next.js 16 (App Router) · React 19 · TypeScript 6 estrito · Tailwind 4 · shadcn/ui · Supabase (Postgres + Auth + Realtime + Storage) · Upstash Redis · Vercel AI Gateway (`@ai-sdk/anthropic|openai|google`) · WAHA Plus (engine NOWEB) · Zod 4 · Vitest 4 · Playwright 1 · Sentry 10. diff --git a/CLAUDE.md b/CLAUDE.md index 33226430e..83018c9bc 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -20,7 +20,7 @@ DeskcommCRM é um sistema operacional de vendas open source com agentes de IA na ## Stack canônica -- **Frontend:** Next.js 16 App Router (Turbopack) + React 19 + TypeScript 6 estrito + Tailwind + shadcn/ui (style: `new-york`, neutral) +- **Frontend:** Next.js 16 App Router (Turbopack) + React 19 + TypeScript 6 estrito + Tailwind 4 (config em CSS — ver abaixo) + shadcn/ui (style: `new-york`, neutral) - **Backend:** Next.js Route Handlers (mesmo repo); workers via `event_log` table + cron - **DB:** Supabase (Postgres). RLS em toda tabela tenant-aware. Extensions: `uuid-ossp`, `pgcrypto`, `vector` - **Auth:** Supabase Auth via `@supabase/ssr`. Cookie SameSite=Strict, HttpOnly, Secure @@ -181,6 +181,7 @@ DeskcommCRM é um sistema operacional de vendas open source com agentes de IA na | `docs/business-rules/` | Regras de negócio fora do código | | `docs/research/reference-synthesis.md` | Arquitetura herdada do curso WAHA | | `tasks/todo.md` | Workflow de construção atual | +| `app/globals.css` | **Tailwind 4 é CSS-first: não existe `tailwind.config.ts`.** Tokens em `:root` / `[data-theme]`, ponte token → utilitário no `@theme inline`, alcance do scanner nos `@source`. Vigiado por `tests/unit/tailwind-tokens.test.ts` | | `lib/api/wrappers.ts` | `ok()`, `fail()`, tipos `ApiSuccess` / `ApiError` | | `lib/api/errors.ts` | Códigos de erro canônicos | | `lib/env.ts` | Validação Zod das env vars (lança no startup se faltar crítica) | diff --git a/app/admin/(protected)/inbox/_components/AdminSidePanel.tsx b/app/admin/(protected)/inbox/_components/AdminSidePanel.tsx index 744fbb4c7..015c03067 100644 --- a/app/admin/(protected)/inbox/_components/AdminSidePanel.tsx +++ b/app/admin/(protected)/inbox/_components/AdminSidePanel.tsx @@ -44,7 +44,7 @@ export function AdminSidePanel({ data }: Props) {
{maskEmail(contact.email)}
)} {contact.is_blocked && ( - + Bloqueado )} diff --git a/app/admin/(protected)/incidents/[id]/_client.tsx b/app/admin/(protected)/incidents/[id]/_client.tsx index c2da9651e..1d9c67f98 100644 --- a/app/admin/(protected)/incidents/[id]/_client.tsx +++ b/app/admin/(protected)/incidents/[id]/_client.tsx @@ -164,7 +164,7 @@ export function IncidentDetailClient({ id }: IncidentDetailClientProps) { key={entry.id} className="flex items-start gap-2 text-xs" > - +
{entry.action} diff --git a/app/admin/(protected)/tenants/[id]/layout.tsx b/app/admin/(protected)/tenants/[id]/layout.tsx index b6fcecd66..854a10ddc 100644 --- a/app/admin/(protected)/tenants/[id]/layout.tsx +++ b/app/admin/(protected)/tenants/[id]/layout.tsx @@ -92,7 +92,7 @@ export default async function TenantDetailLayout({ {org?.display_name ?? id} {org?.slug && ( - + {org.slug} )} diff --git a/app/admin/(protected)/users/[id]/_client.tsx b/app/admin/(protected)/users/[id]/_client.tsx index 785dfa2bc..25b06ca00 100644 --- a/app/admin/(protected)/users/[id]/_client.tsx +++ b/app/admin/(protected)/users/[id]/_client.tsx @@ -246,7 +246,7 @@ export function UserDetailClient({ id }: UserDetailClientProps) {
{recent_audit.map((entry) => (
- +
diff --git a/app/app/ai/agents/[id]/_components/FollowupFlowPicker.tsx b/app/app/ai/agents/[id]/_components/FollowupFlowPicker.tsx index 15e200368..5067f32af 100644 --- a/app/app/ai/agents/[id]/_components/FollowupFlowPicker.tsx +++ b/app/app/ai/agents/[id]/_components/FollowupFlowPicker.tsx @@ -58,11 +58,11 @@ export function FollowupFlowPicker({ value, onChange, disabled }: Props) { return (