// SAR — Workspace Database Schema // Stack canon: Prisma 7 · PostgreSQL 18 · BD-por-workspace (ADR 0006) // // Este schema roda em CADA workspace DB (sar_workspace_). // NÃO há workspaceId/tenantId em nenhum modelo — o isolamento é físico. // O banco master (sar_master) é gerenciado pelo master-login (IdP JCS), não por este schema. // // CODING-RULES PGD-DB-004: moduleFormat = "cjs" (NestJS é CJS) // CODING-RULES PGD-DB-001: MIGRATION_DATABASE_URL aponta direto ao PG (sem PgBouncer) generator client { provider = "prisma-client-js" output = "../../../node_modules/.prisma/client" moduleFormat = "cjs" } // Prisma 7: url removida do schema — conexão em prisma.config.ts (migrate) // e no WorkspacePrismaPool via PrismaPg adapter (runtime). datasource db { provider = "postgresql" } // ─── Enums ─────────────────────────────────────────────────────────────────── // Situação financeira resumida do cliente — cacheável offline (FR-2.4, FR-2.5). // Valor numérico de crédito e inadimplência requerem conexão. enum FinancialStatus { regular attention blocked } // ─── Client (C2) ───────────────────────────────────────────────────────────── // // Cadastro sincronizado do ERP legado (FR-2.6). Rep não cria/edita no MVP. // creditLimit: gerenciado no SAR — admin/supervisor define (OQ-4 resolvido 2026-05-27). // lastOrderAt/lastOrderValue: desnormalizados, atualizados ao sincronizar Orders (C3/C4). // activityStatus: calculado em runtime a partir de lastOrderAt (não persiste — evita drift). model Client { id String @id @default(uuid()) @db.Uuid name String // razão social / nome completo tradeName String? // nome fantasia taxId String @unique // CNPJ (14 dígitos) ou CPF (11 dígitos), sem máscara email String? phone String? address Json? // { street, number, complement?, district, city, state, zip } // Situação financeira — resumo cacheável; detalhes numéricos requerem conexão financialStatus FinancialStatus @default(regular) creditLimit Decimal? @db.Decimal(15, 2) // Desnormalizados de Orders (atualizados em C3/C4) repId String // userId do Rep responsável (JWT sub) lastOrderAt DateTime? lastOrderValue Decimal? @db.Decimal(15, 2) openOrdersCount Int @default(0) // Controle de sync com ERP erpCode String? // código no ERP legado syncedAt DateTime? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt deletedAt DateTime? // soft delete — não remove fisicamente @@index([repId]) @@index([taxId]) @@index([name]) @@index([deletedAt]) // filtragem de soft delete eficiente }