Prompt de migração
Prompt oficial para migrar qualquer projeto Lovable existente ao padrão Sancruza. Cole na conversa do projeto-alvo e o agente fará a adequação completa.
Como usar
Abra cada um dos sistemas no Lovable, cole este prompt e siga as confirmações que o agente pedir.
- Abra o projeto Lovable que será migrado.
- Garanta que ele está em uma branch nova (ou versão salva) — a migração toca em autenticação e banco.
- Cole o prompt abaixo no chat do projeto.
- Aprove as migrations quando o agente solicitar (criação de
profiles,user_roles, triggers e funções). - Ao final, confirme manualmente que login com Gmail pessoal é rejeitado e que usuário desativado perde acesso imediato.
Prompt oficial
Versão 4.4 · Design system agora é PASSO 1 (antes do login), com auditoria executada no terminal e screenshots obrigatórios. Bloqueia entregas que só refatoram o login e deixam o resto do app no visual antigo.
sc-core / migracao-padrao / v4.4
Migre este projeto para o padrão oficial Sancruza (Sancruza Core) — ARQUITETURA FEDERADA v4.4.
CONTEXTO
- Empresa: Sancruza (imobiliária).
- Domínio corporativo único: @sancruza.com.br. Não existem usuários externos. Nunca terão.
- Sancruza Core (https://coresancruza.lovable.app) é o PORTAL DE IDENTIDADE da empresa. Ele NÃO armazena os dados deste sistema — ele só responde "quem é esse usuário e o que ele pode fazer aqui".
- Cada sistema mantém seu PRÓPRIO Lovable Cloud (banco isolado, dados isolados, sem migração entre bancos).
- Este sistema continua dono dos seus dados. Só a CAMADA DE PERMISSÃO consulta o Sancruza Core via API pública.
OBJETIVO
Adequar este projeto ao padrão SC em quatro frentes, SEM MEXER EM DADOS:
1) Login Google corporativo (só @sancruza.com.br).
2) Gate de acesso que consulta Sancruza Core pra decidir se o usuário pode entrar e com qual papel.
3) Identidade visual (Login SC + tokens do design system).
4) Remoção de qualquer gestão local de usuários/papéis (tudo no Sancruza Core).
IMPORTANTE: este prompt NÃO toca em nenhuma tabela de dados existente. NÃO desabilita Lovable Cloud. NÃO conecta em Supabase externo. Zero risco de perda de dados.
================================================================
REGRA INVIOLÁVEL — PRESERVAÇÃO DE DADOS
================================================================
A sincronização com o Sancruza Core (seção 4.2) NUNCA pode causar perda de dados, nem de cadastro nem de histórico. Isso é regra dura, não recomendação:
- NUNCA execute DELETE em tabelas que armazenam pessoas (usuários, colaboradores, corretores, vistoriadores). Sem exceção.
- NUNCA execute DELETE em tabelas de trabalho realizado (vistorias, propostas, atendimentos, leads, atividades, comentários, anexos, logs, históricos).
- NUNCA quebre FKs apontando pra pessoa que saiu da empresa. O registro de "Maria fez essa vistoria em 2023" tem que continuar existindo e legível, mesmo que Maria não trabalhe mais na Sancruza.
- Pessoa que sumiu do Sancruza Core → marca active=false na tabela espelho local. Continua existindo no banco, continua sendo referenciada pelas FKs antigas, só não aparece em listas/seletores ativos.
- Pessoa que volta ao Sancruza Core (mesmo email/id) → reativa (active=true). Não cria duplicata.
- Migração de sistema existente NUNCA "limpa" a tabela atual de usuários pra recriar do zero a partir do Core. Sempre faz match por id/email, faz upsert, e marca o restante como inativo.
- Tabelas locais antigas de gestão de papel/permissão → renomear pra _legacy_<nome> (backup), NUNCA dropar.
Se a sincronização teria que apagar algo pra "ficar consistente com o Core", a sincronização está ERRADA. O modelo correto é aditivo: Core manda quem existe, sistema local desativa quem sumiu, e ponto. Histórico é sagrado.
(Essa regra existe porque já migramos 8 sistemas tratando o Sancruza Core só como login e mantendo cadastro local divergente — agora que estamos corrigindo isso, NÃO pode acontecer de a "correção" virar perda de dados acumulados.)
ATENÇÃO — LEITURA OBRIGATÓRIA ANTES DE COMEÇAR:
"NÃO MEXER EM DADOS" ≠ "NÃO MEXER NO VISUAL". O visual TEM QUE mudar.
A entrega DEVE refatorar o app inteiro pro design system (header, sidebar, cards,
tabs, badges, tabelas, modais, formulários, dashboards, telas de listagem, telas
de detalhe — TUDO). Se você terminar e o app continuar com as cores antigas
(azul, rosa, roxo, verde aleatório, gradientes custom, branco/cinza hardcoded),
a migração ESTÁ REPROVADA, mesmo que o login esteja perfeito.
Reclamação real recebida do dono do produto: "fez o login errado e não mudou
nada do design — que merda fez então". Não repita esse erro.
================================================================
0. PRÉ-REQUISITOS — me confirme ANTES de começar
================================================================
a) Qual é o SLUG deste sistema em Sancruza Core? (ex: "robust-crm", "mapa-lancamentos"). Se não souber, peça pro humano abrir coresancruza.lovable.app → Sistemas → e copiar o slug. Se ainda não está cadastrado, PARE e peça pro humano cadastrar primeiro.
b) Qual é o NOME LEGÍVEL do sistema (ex: "Robust CRM") e a CATEGORIA? Valores válidos: operacao, comercial, marketing, inteligencia, administrativo, publico, outros.
c) Detecte o stack — NÃO PARE por causa do stack:
- Existe src/router.tsx + src/routes/__root.tsx → STACK = "tanstack".
- Caso contrário (existe src/App.tsx com BrowserRouter) → STACK = "vite-spa".
Reporte qual stack foi detectado e siga as seções marcadas [TANSTACK] / [VITE-SPA].
d) Versão atual salva no Lovable? Instrua o humano a salvar a versão antes de começar.
NÃO PERGUNTE sobre export de dados, desabilitar Cloud, ou conectar em outro Supabase. Este sistema continua com seu Cloud próprio. Confirme isso ao humano explicitamente: "Este prompt mantém o Lovable Cloud deste projeto intacto. Seus dados não serão tocados."
================================================================
1. DESIGN SYSTEM — REFATORAÇÃO COMPLETA (FAÇA ISSO PRIMEIRO)
================================================================
Esta seção vem ANTES de tudo de propósito. Sem isso aplicado, qualquer outra
coisa que você fizer está reprovada. Execute na ordem:
1.1 Importe os tokens canônicos do Sancruza Core. No src/styles.css (ou src/index.css),
coloque NA PRIMEIRA LINHA, antes de qualquer @import "tailwindcss":
@import url("https://coresancruza.lovable.app/api/public/design-tokens.css");
@import "tailwindcss";
1.2 REMOVA do styles.css local toda redefinição destes tokens (eles vêm do Sancruza Core):
--primary, --background, --foreground, --border, --warning, --destructive,
--success, --info, --muted, --accent, --card, --sidebar-*, --sc-orange,
--sc-green-deep, --category-1..6, --font-sans, --font-display.
Pode MANTER variáveis 100% específicas deste sistema (ex.: --kanban-column-bg)
desde que não colidam com os nomes acima.
1.3 Registre as variáveis no bloco @theme inline do Tailwind v4 pra virarem
utilities (bg-primary, text-muted-foreground, border-border, bg-category-1, etc.).
Tailwind v4 não enxerga tokens carregados em runtime sem isso.
1.4 Refatore o app INTEIRO substituindo cor por token. Não é opcional, não é
"se der tempo". Passe por cada arquivo em src/components e src/routes e troque:
- bg-blue-*, bg-green-*, bg-purple-*, bg-pink-*, bg-red-*, bg-yellow-*,
bg-orange-*, bg-indigo-*, bg-cyan-*, bg-teal-* → use o token semântico
apropriado (bg-primary, bg-category-N, bg-warning, bg-destructive…).
- text-white → text-primary-foreground (ou text-foreground sobre fundo claro).
- bg-white → bg-background ou bg-card.
- bg-black → bg-foreground.
- text-gray-*, text-slate-*, text-zinc-* → text-muted-foreground / text-foreground.
- border-gray-*, border-slate-* → border-border.
- Qualquer #hex / rgb() / hsl() em style={{}} fora da tela de Login → REMOVA
e troque por classe Tailwind do token.
- Gradientes decorativos (from-blue-500 to-pink-500) → from-primary to-sc-green-deep,
ou remova.
1.5 Header autenticado padrão (substitui qualquer header custom):
- h-16, bg-background, border-b border-border. NUNCA gradiente verde escuro
(esse verde é EXCLUSIVO da tela de Login).
- Esquerda: logo Sancruza branca sobre quadrado bg-primary 40x40 rounded-md
+ nome do sistema text-foreground font-semibold + tagline curta text-muted-foreground text-xs.
- Direita: link "← Sancruza Core" (text-muted-foreground hover:text-foreground),
email do usuário text-sm text-muted-foreground, botão "Sair" variant outline size-sm.
1.6 Componentes shadcn — padrão obrigatório (refatore todos):
- Button default: bg-primary text-primary-foreground. Outline: border-border bg-background.
Ghost: transparente hover:bg-muted. NUNCA bg-blue/green/purple-*.
- Card: bg-card text-card-foreground border-border shadow-sm rounded-md.
Sem gradiente colorido no fundo.
- Input/Select/Textarea: bg-background border-input focus:ring-ring.
- Tabs: TabsList bg-muted; TabsTrigger ativo bg-background text-foreground shadow-sm.
- Badge default: bg-primary/10 text-primary. Destructive: bg-destructive/10 text-destructive.
Warning: bg-warning/10 text-warning-foreground. Categoria: bg-category-N/10 text-category-N.
- Table: thead bg-muted/50 text-muted-foreground; linhas hover:bg-muted/30; border border-border.
- Dialog/Modal: bg-background border-border; overlay bg-foreground/40.
- Toast: success/destructive/warning vindo dos tokens. Nunca hex.
1.7 ESTADO vs DECORAÇÃO (regra dura, causa de reprovação):
- --destructive = ERRO (excluir, falha, validação). --warning = ALERTA (estoque baixo,
pendência, prazo). --success = CONFIRMAÇÃO. Esses três NUNCA viram cor de marca,
acento de categoria, header decorativo, fundo de seção ou cor de grupo.
- Categorias visuais (gênero, tipo, segmento, linha, divisão, status de funil)
OBRIGATORIAMENTE usam --category-1..6 do Sancruza Core, na ordem de aparição.
Mais de 6 categorias: cicla ou agrupa — NÃO invente cor.
1.8 AUDITORIA OBRIGATÓRIA — rode no terminal e cole o output do número de matches.
Se QUALQUER um dos comandos 1-4 retornar > 0, REFATORE antes de prosseguir.
NÃO comece a seção 2 enquanto não estiver tudo zerado.
# 1) cores arbitrárias do Tailwind
rg -n "bg-(red|blue|green|yellow|pink|purple|orange|indigo|cyan|teal)-[0-9]" src/ | wc -l
# 2) preto/branco/cinza hardcoded
rg -n "text-white|bg-white|bg-black|text-black|text-gray-|text-slate-|text-zinc-" src/ | wc -l
# 3) hex/rgb/hsl em JSX (fora da tela de Login)
rg -n "#[0-9a-fA-F]{3,8}" src/components src/routes | rg -v "login-sg|sem-acesso" | wc -l
# 4) redefinição local de tokens do Sancruza Core
rg -n "^\s*--(primary|background|foreground|border|warning|destructive|success|muted|accent|card|sidebar|category-[1-6])\s*:" src/ | wc -l
# 5) ESTADO usado como DECORAÇÃO — inspecione cada match manualmente
rg -n "bg-destructive|bg-warning|bg-success|border-destructive|border-warning" src/components src/routes
1.9 Auditoria visual: tire screenshot de pelo menos 3 telas internas (dashboard,
uma listagem, uma tela de detalhe) e confirme que NÃO HÁ nenhuma cor estranha
ao design system. Se a tela continua "com cara do projeto antigo", você não
refatorou — volte e refatore.
SÓ DEPOIS DA SEÇÃO 1 INTEIRA APLICADA, prossiga pra seção 2.
================================================================
2. BACKEND — Lovable Cloud deste sistema permanece
================================================================
- NÃO desabilite Lovable Cloud. NÃO conecte em Supabase externo. NÃO mexa em src/integrations/supabase/client.ts.
- As tabelas de dados deste sistema (clientes, propostas, uniformes, processos, etc.) ficam onde estão.
- A ÚNICA mudança no banco LOCAL é remover/limpar qualquer tabela de gestão de usuários/papéis local (ver seção 5).
================================================================
3. AUTENTICAÇÃO — email + senha corporativo é a ÚNICA porta (v3.0)
================================================================
- Login via supabase.auth.signInWithPassword. NÃO use signInWithOAuth, NÃO use magic link.
- Rode configure_auth com disable_signup=true, auto_confirm_email=false, password_hibp_enabled=true.
- Se o provider Google estiver ativo (legado v2.x), DESATIVE via configure_social_auth disable_providers: ["google"].
- REMOVA da UI: botão "Entrar com Google", "criar conta", "magic link", "acesso administrativo", qualquer fallback alternativo. O componente LoginSC v3 já renderiza email+senha + "Esqueci minha senha".
- Defesa em profundidade do domínio. Crie/garanta trigger handle_new_user no AUTH deste sistema:
Se NEW.email NÃO terminar em '@sancruza.com.br', RAISE EXCEPTION 'Acesso restrito ao domínio @sancruza.com.br'.
- Crie a página /reset-password (fora do gate) — sem ela o link "Esqueci minha senha" abre sessão sem trocar senha.
================================================================
4. CONSULTA DE PERMISSÃO — API pública do Sancruza Core
================================================================
Sancruza Core expõe um endpoint público read-only que responde "esse email tem acesso a esse sistema, com qual papel":
GET https://coresancruza.lovable.app/api/public/access?email=<email>&slug=<slug>
Resposta (200 OK):
{
"allowed": true | false, // true = perfil ativo E (is_admin OU tem user_app_access.can_access=true) pra esse slug
"role": "admin" | "presidente" | "diretor" | "gestor" | "corretor" | "colaborador" | "marketing" | "administrativo" | "financeiro" | "juridico" | "vistoriador" | "visualizador" | null,
"is_admin": true | false, // role 'admin' global em Sancruza Core (super-admin de todos os sistemas)
"user": { "id": "...", "email": "...", "name": "...", "photo_url": "...", "department": "...", "position": "..." } | null,
"system": { "slug": "...", "name": "..." } | null
}
Quando o email não é @sancruza.com.br, não existe, está desativado ou o slug não existe: { "allowed": false, "role": null, "is_admin": false, "user": null, "system": null }.
Regras:
- O endpoint é público (não exige token) MAS só retorna allowed=true pra emails @sancruza.com.br ativos e autorizados pra esse slug.
- O papel "presidente" tem exatamente as mesmas permissões de "diretor" — trate os dois como equivalentes em qualquer regra de autorização.
- Se o serviço estiver fora do ar (timeout, 5xx), assuma allowed=false e mostre "Sancruza Core indisponível, tente novamente" — NUNCA libere acesso por dúvida.
- Cache a resposta no client por no máximo 60s (react-query staleTime). Revalide no onAuthStateChange.
--- 4.1 LISTAGEM/IMPORTAÇÃO DE COLABORADORES ---
Pra sincronizar/importar usuários do Sancruza Core pro sistema local (ex.: replicar a lista de corretores), use:
GET https://coresancruza.lovable.app/api/public/system-users?slug=<slug>
Resposta (200 OK):
{
"system": { "slug": "...", "name": "..." },
"users": [
{ "id": "...", "name": "...", "email": "...", "photo_url": "...",
"department": "...", "position": "...", "role": "corretor", "is_admin": false }
]
}
Filtros opcionais (combinam com AND, todos via querystring):
- roles=corretor,gestor → filtra por user_app_access.role naquele sistema
- departments=Vendas,Marketing → filtra por profiles.department
- positions=Corretor → filtra por profiles.position
- emails=a@x.com,b@x.com → restringe a esses emails
- ids=uuid1,uuid2 → restringe a esses user_ids do Sancruza Core
- include_admins=false → não trazer os admins globais do Sancruza Core (default true)
- q=joao → busca livre por nome/email
Use isso para a UI "Importar/Sincronizar do Sancruza Core" — sempre por slug + filtro de grupo (role/department), nunca duplicando cadastro à mão no sistema local. O endpoint só lista perfis ATIVOS no Sancruza Core; ao sincronizar localmente, marque como inativos os que sumirem da resposta.
--- 4.2 SINCRONIZAÇÃO PERIÓDICA (FONTE DA VERDADE = SC CORE) ---
REGRA DE OURO: Sancruza Core é a fonte da verdade de colaboradores. O sistema local NUNCA mantém cadastro divergente. Toda mudança de pessoa (entrou, saiu, mudou cargo/departamento/role) acontece no Sancruza Core e propaga via sincronização.
Implementação obrigatória em TODO sistema (novo OU existente sendo migrado):
A) Tabela espelho local (ex.: public.team_members ou broker_profiles — escolha conforme o domínio):
- PK: id uuid REFERENCES auth.users(id) (mesmo id do Sancruza Core, que é o mesmo do auth.users do sistema local — Google OAuth garante).
- Colunas espelhadas do Core: name, email, photo_url, department, position, role (text), is_admin (bool).
- Colunas locais: active bool DEFAULT true, last_synced_at timestamptz, created_at, updated_at.
- NUNCA tem coluna "password", "invited_by", "created_by_admin" etc. — não há criação local.
- RLS: SELECT liberado pra authenticated; INSERT/UPDATE/DELETE só via service_role (a sincronização é server-side).
B) Endpoint local de sincronização (TanStack: src/routes/api/public/hooks/sync-from-core.ts):
- POST, em /api/public/hooks/sync-from-core (prefixo /api/public/* dispensa auth de edge — implemente a segurança no handler).
- Valida apikey no header == SUPABASE_ANON_KEY do próprio sistema (header "apikey").
- Aceita body opcional { filters?: { roles?: string[], departments?: string[] } } pra restringir o escopo (ex.: sistema de corretagem sincroniza só roles=corretor,gestor).
- Chama GET https://coresancruza.lovable.app/api/public/system-users?slug=<SLUG-DESTE-SISTEMA>&<filtros> com fetch nativo (sem service_role, é endpoint público).
- Lógica:
1. recebe data.users (lista do Core).
2. UPSERT cada um na tabela espelho usando id como conflito: atualiza name/email/photo_url/department/position/role/is_admin/active=true/last_synced_at=now().
3. UPDATE active=false WHERE id NOT IN (ids recebidos) AND active=true — quem sumiu vira inativo.
4. NUNCA DELETE. NUNCA. Histórico (vistorias feitas, propostas criadas, leads atribuídos, comentários, anexos, logs, FKs apontando pro user) tem que sobreviver pra sempre. Veja a "REGRA INVIOLÁVEL — PRESERVAÇÃO DE DADOS" no topo deste prompt: se você está prestes a escrever um DELETE em qualquer tabela durante a sincronização, PARE — está fazendo errado. O caminho certo é sempre UPDATE active=false.
- Retorna { ok: true, upserted: N, deactivated: M, synced_at: <iso> }.
- Loga no console o resumo pra aparecer no logs do worker.
C) Cron pg_cron + pg_net (rodar UMA vez na configuração do sistema, via insert tool, NÃO via migration):
CREATE EXTENSION IF NOT EXISTS pg_cron;
CREATE EXTENSION IF NOT EXISTS pg_net;
SELECT cron.schedule(
'sync-from-sc-core-daily',
'0 6 * * *', -- todo dia 06:00 UTC (03:00 BRT)
$$
SELECT net.http_post(
url := 'https://project--<PROJECT_ID-DESTE-SISTEMA>.lovable.app/api/public/hooks/sync-from-core',
headers := '{"Content-Type":"application/json","apikey":"<ANON_KEY-DESTE-SISTEMA>"}'::jsonb,
body := '{}'::jsonb
) AS request_id;
$$
);
Use a URL estável project--<id>.lovable.app (não muda em rename). Substitua <PROJECT_ID> e <ANON_KEY> pelos valores do sistema sendo configurado.
D) UI no sistema local:
- Adicione um botão "Sincronizar com Sancruza Core" na tela de admin (visível só pra is_admin). Chama o mesmo endpoint da letra B, mostra toast com "{upserted} atualizados, {deactivated} desativados".
- REMOVA da UI: "Convidar usuário", "Criar colaborador", "Editar cargo/departamento", "Promover a admin", "Desativar usuário". Tudo isso só no Sancruza Core (coresancruza.lovable.app).
- Listas de pessoas (corretores, vistoriadores, gestores) leem SEMPRE da tabela espelho local filtrando active=true.
E) Tratamento de quem fez login mas não está na tabela espelho:
- Pode acontecer entre uma sincronização e outra (pessoa cadastrada no Core agora, cron só roda amanhã).
- Solução: no callback do OAuth (ou no handle_new_user trigger), além de validar /api/public/access, dispara um POST /api/public/hooks/sync-from-core (com filters por email da pessoa logada se quiser otimizar) pra garantir que ela aparece na tabela espelho imediatamente.
CHECKLIST DE MIGRAÇÃO (sistemas existentes):
- [ ] Criar tabela espelho (ou renomear a atual de usuários pra espelho, mantendo só colunas válidas).
- [ ] Criar endpoint /api/public/hooks/sync-from-core.
- [ ] Agendar cron diário (insert tool, NÃO migration).
- [ ] Rodar UMA sincronização manual pra popular.
- [ ] Conferir: tabela espelho contém só quem o Core retornou; quem saiu da empresa está active=false; FKs antigas continuam apontando.
- [ ] Remover telas locais de gestão de usuário.
Sem isso, o sistema vai continuar tendo "fantasmas" (gente desligada que ainda aparece em listas, atribuições, relatórios).
================================================================
5. HOOK useSystemRole — leitura única de papel
================================================================
Crie src/hooks/use-system-role.ts que:
- Lê supabase.auth.getUser() → pega email do usuário logado neste sistema.
- Faz fetch GET no endpoint da seção 4 com email + slug "<SLUG-DESTE-SISTEMA>".
- Usa react-query (useQuery) com queryKey ['sc-access', email, slug] e staleTime 60_000.
- Devolve { isLoading, authenticated, allowed, role, isAdmin, email, user }.
isAdmin = data.is_admin === true || data.role === 'admin'.
allowed = data.allowed === true.
- USE useSystemRole em TODA decisão de UI (esconder botão, bloquear aba, permitir ação destrutiva).
- Se a aplicação tem RLS, as policies continuam validando por auth.uid() local do próprio Cloud (não dependem de Sancruza Core). A camada do Sancruza Core decide se a pessoa ENTRA; o que ela faz depois é RLS local.
- NUNCA crie endpoint/admin local de "promover a admin", "criar usuário", "alterar departamento". Tudo isso só em coresancruza.lovable.app.
================================================================
6. REMOÇÃO DE GESTÃO LOCAL DE USUÁRIOS (se houver)
================================================================
- Se este sistema tem tabelas locais tipo user_profiles, app_users, permissions, user_roles: NÃO apague os dados, mas REMOVA da UI qualquer tela de gestão (criar usuário, listar usuários, alterar papel, etc.).
- Migração de banco LOCAL: renomeie tabelas de gestão pra _legacy_<nome>. Não dropa. Vira backup.
- Se houver RLS policies que dependem de uma tabela local de papéis: reescreva para depender APENAS do auth.uid() + tabelas do próprio sistema. Não dependa do Sancruza Core no banco — só na camada de UI (via useSystemRole).
- Reporte: "X tabelas locais de gestão renomeadas pra _legacy_. Y telas de gestão removidas."
================================================================
7. GATE DE ROTAS PROTEGIDAS (componente SCSystemGate)
================================================================
- Crie src/components/sc-system-gate.tsx com props { slug: string; systemName: string; children: ReactNode }:
a) Em mount, consulta useSystemRole(slug).
b) Enquanto isLoading, renderiza skeleton neutro (NUNCA o conteúdo protegido antes da validação).
c) Se !authenticated → redireciona para /auth.
d) Se !allowed → redireciona para /sem-acesso?slug=<slug>. (O Sancruza Core já considera perfil desativado como allowed=false; se quiser distinguir, use a página /sem-acesso pra ambos os casos.)
f) Revalida no onAuthStateChange.
- [TANSTACK] Envolva TODAS as rotas protegidas com <SCSystemGate slug="<SLUG>" systemName="<Nome>">.
- [VITE-SPA] Envolva o <Routes> protegido em src/App.tsx. Mantenha /auth e /sem-acesso FORA do gate.
================================================================
7.1 PÁGINA /sem-acesso (obrigatória)
================================================================
- [TANSTACK] Crie src/routes/sem-acesso.tsx. [VITE-SPA] Crie src/pages/SemAcesso.tsx + rota /sem-acesso. Conteúdo idêntico:
Fundo igual ao Login SC (#0B3022 com SCAurora).
Card central branco: ícone de cadeado, título "Você não tem acesso a este sistema", texto "Sua conta @sancruza.com.br não tem permissão para acessar <Nome do sistema>. Procure o administrador no Sancruza Core para liberar.".
Dois botões: "Voltar ao Sancruza Core" (link https://coresancruza.lovable.app) e "Sair" (signOut → /auth).
Mostra o email logado em fonte pequena pra facilitar pedido ao admin.
================================================================
8. LOGIN SC E LOGOUT — identidade visual obrigatória
================================================================
REGRA ZERO — NÃO RECRIE O LOGIN SC DO ZERO.
O componente canônico LoginSC já existe, é mantido pelo Sancruza Core e é servido como
arquivo TSX puro num endpoint público. Você DEVE baixá-lo literalmente para este
projeto e usar como está. Recriar à mão = retrabalho garantido (já aconteceu N vezes).
PASSO 1 — Baixe o componente canônico (rode no terminal do sandbox):
mkdir -p src/components
curl -sSf https://coresancruza.lovable.app/api/public/login-sc.tsx \
-o src/components/login-sc.tsx
PASSO 2 — Baixe a logo branca (se ainda não estiver no projeto). Use a URL canônica
direto no src do <img />, sem baixar como asset local:
https://coresancruza.lovable.app/__l5e/assets-v1/5e5fa776-7050-4be1-a8be-4e2ca7aa7256/imobiliaria-core-logo-white.png
PASSO 3 — Use o componente na sua tela de Auth. Os ÚNICOS valores que você muda
por sistema são: systemName, systemDescription, category. Mais nada.
import { LoginSC } from "@/components/login-sc";
import { supabase } from "@/integrations/supabase/client";
<LoginSC
logoUrl="https://coresancruza.lovable.app/__l5e/assets-v1/5e5fa776-7050-4be1-a8be-4e2ca7aa7256/imobiliaria-core-logo-white.png"
systemName="<NOME LEGÍVEL DESTE SISTEMA>"
systemDescription="<UMA FRASE CURTA E PERMANENTE — sem métricas, sem números>"
category="<operacao | comercial | marketing | inteligencia>"
emailDomain="@sancruza.com.br"
onSignIn={async (email, password) => {
const { error } = await supabase.auth.signInWithPassword({ email, password });
return error ? { error: error.message } : undefined;
}}
onForgotPassword={async (email) => {
const { error } = await supabase.auth.resetPasswordForEmail(email, {
redirectTo: window.location.origin + "/reset-password",
});
return error ? { error: error.message } : undefined;
}}
/>
PROIBIDO:
- Editar o arquivo src/components/login-sc.tsx baixado. Se precisar mudar algo
estrutural, mude no Sancruza Core (e todos herdam no próximo curl). Aqui não.
- Trocar qualquer texto, classe, cor, tamanho ou estrutura do componente.
- "Adaptar pro estilo do projeto". O Login SC é igual em TODO sistema. Esse é o ponto.
- Recriar o LoginSC manualmente porque "ficou mais bonito do meu jeito" — REPROVADO.
ANTI-PADRÕES QUE INVALIDAM A ENTREGA (se qualquer um aparecer, você NÃO baixou o
componente canônico — volte ao PASSO 1):
X Tela inteira verde (painel direito também verde escuro). ERRADO. O painel direito é SEMPRE neutro claro (bg-background, off-white/cinza muito claro). Só o painel ESQUERDO é #0B3022.
X Quadrado branco com as letras "SC" + texto "SANCRUZA" ao lado + "Ecossistema interno" embaixo. ERRADO. Isso NÃO é a logo da Sancruza — é um placeholder genérico do agente. A logo oficial é uma imagem PNG (link abaixo) que JÁ contém o nome.
X Botão "Entrar com Google" laranja em projeto que não é da categoria "marketing". A cor do botão segue a CATEGORIA do sistema (mapa abaixo), não é sempre laranja.
X Card branco flutuante no centro com o login dentro. ERRADO. Autenticação é INLINE no painel direito, sem card.
X Logo grande centralizada no meio da tela como hero. ERRADO. Logo fica pequena no canto superior esquerdo do painel esquerdo (h-5 a h-6, no máximo).
ESTRUTURA OBRIGATÓRIA (split 40/60, lado a lado em desktop, empilhado em mobile):
+----------------------------------+---------------------------------+
| PAINEL ESQUERDO 40% | PAINEL DIREITO 60% |
| bg #0B3022 + SCAurora (orbes) | bg-background (claro/neutro) |
| | |
| [logo Sancruza branca h-5] | |
| | Acesse sua conta |
| | Entre com sua conta Souza... |
| <Nome do sistema> (display 48px) | |
| <Descrição curta 1 frase> | [ G Entrar com Google ] |
| | (cor = categoria do sistema) |
| | |
| | Apenas contas @sancruza... |
| Sistema interno Sancruza · | |
| Acesso restrito | |
+----------------------------------+---------------------------------+
- Implemente LoginSC EXATAMENTE conforme o diagrama acima: 40% identidade (verde) + 60% autenticação (FUNDO CLARO bg-background, NÃO verde), logo Sancruza branca no topo do painel esquerdo, nome do sistema + descrição curta permanente, rodapé "Sistema interno Sancruza · Acesso restrito".
- O painel direito NUNCA é verde. NUNCA. Se você está pensando em deixar o fundo direito verde "pra combinar", PARE — é bg-background (a cor neutra clara do design system) e ponto.
- LOGO OFICIAL (obrigatória, NUNCA usar quadrado "SC" + texto ao lado): use a URL canônica hospedada no Sancruza Core:
https://coresancruza.lovable.app/__l5e/assets-v1/5e5fa776-7050-4be1-a8be-4e2ca7aa7256/imobiliaria-core-logo-white.png
Aplique em <img src="..." alt="Imobiliária Core" className="h-5 w-auto object-contain" /> tanto no painel esquerdo do Login quanto no header autenticado (sobre fundo escuro). Para fundo claro, use a versão colorida:
https://coresancruza.lovable.app/__l5e/assets-v1/a7d8d471-23ff-4e86-8700-143664b7d640/imobiliaria-core-logo-color.png
PROIBIDO em qualquer hipótese: criar um badge/quadrado com as letras "SC" e escrever "Sancruza" ao lado (mesmo "estilizado", mesmo "como placeholder", mesmo "porque a imagem não carregou"). A logo já contém o nome. Se a imagem não carregar, NÃO renderize fallback de texto — deixe vazio e investigue o link.
- Categorias (cor do botão "Entrar com Google"): operacao #0F4C3A, comercial #2F6FEB, marketing #F28C28, inteligencia #7C5CD3, administrativo #6B7280, publico #14B8A6, outros #64748B.
- Título FIXO: "Acesse sua conta". Subtítulo FIXO: "Entre com sua conta Sancruza.".
- Sem card flutuando à direita. Autenticação inline. Sem métricas/dados dinâmicos no painel esquerdo.
- Auditoria visual antes de entregar: tire um print da tela de login e confirme: (1) metade direita é CLARA, não verde; (2) a logo Sancruza aparece como imagem (não como letras "SC"); (3) o botão Google está na cor da categoria correta; (4) o arquivo src/components/login-sc.tsx existe e tem o mesmo md5 do servido em https://coresancruza.lovable.app/api/public/login-sc.tsx (sinal de que você baixou e não recriou).
- Logout: após signOut, redireciona pra /auth.
- No layout autenticado (sidebar/header), inclua link discreto "← Sancruza Core" apontando pra https://coresancruza.lovable.app.
================================================================
9. ENTREGÁVEL FINAL
================================================================
Ao final, me mostre, em ordem:
1) Stack detectado, slug, nome legível, categoria.
2) Confirmação explícita: "Lovable Cloud deste projeto NÃO foi tocado. Dados intactos."
3) Output literal dos 5 comandos da auditoria 1.8 (com os números). Se qualquer
um for > 0 nos comandos 1-4, você NÃO terminou — volte pra seção 1.
4) Screenshots de pelo menos 3 telas internas (dashboard + uma listagem + uma de
detalhe) confirmando que o visual está no padrão SC. Se ainda parecem o app
antigo, REPROVADO — refatore.
5) Arquivos criados/alterados (espera-se DEZENAS de arquivos refatorados na seção 1.4,
não só o login. Se a lista tem só 3-4 arquivos, você não fez o trabalho).
6) Migrations geradas no banco LOCAL (lista — só renomes de _legacy_ e trigger de domínio).
7) Telas locais de gestão de usuários/papéis removidas (lista).
8) Checklist, item por item, OK ou explicação do que faltou:
(a) Design system aplicado ao app inteiro — auditoria 1.8 com 0 nos comandos 1-4.
(b) Header autenticado refatorado conforme 1.5.
(c) Login só aceita @sancruza.com.br via Google (testado com Gmail pessoal e rejeitou).
(d) Sem email/senha, signup, recuperação de senha em lugar nenhum.
(e) src/components/login-sc.tsx baixado via curl do Sancruza Core (não recriado à mão).
(f) useSystemRole consulta o endpoint público do Sancruza Core e cacheia 60s.
(g) Rota protegida nunca renderiza antes da validação (skeleton primeiro).
(h) Sem permissão no slug = redirect pra /sem-acesso.
(i) Usuário desativado em Sancruza Core perde acesso na próxima revalidação.
(j) Endpoint do Sancruza Core fora do ar = bloqueia acesso (fail-closed), nunca libera.
(k) Não existe mais tela local de gestão de usuários/papéis.
(l) Página /sem-acesso existe com visual do Login SC.
Só dê GO se os 12 itens estiverem confirmados E a auditoria 1.8 estiver zerada.
Se algum falhar, PARE, reporte e espere instrução. NÃO entregue parcial dizendo
"login pronto, design fica pra depois" — isso é reprovação automática.O que esperar do resultado
Checklist do que cada projeto deve apresentar após a migração.
- · Login com botão único "Entrar com Google", restrito a @sancruza.com.br.
- · Sem qualquer formulário de email/senha, signup ou recuperação de senha.
- · Tabelas
profiles,user_roles,user_app_accessesystemsalinhadas ao Sancruza Core. - · Trigger de revogação de sessão ativo em
profiles. - · Rotas protegidas envolvidas por
SCSystemGatecom o slug do sistema. - · Identidade visual do login idêntica ao padrão Login SC.
- · Tokens de design system (cores, tipografia) consumidos de
src/styles.css.