feat(infra): triggers ERP + reset migrations Prisma para schema correto
Triggers SAR→ERP (scripts/sar-triggers.sql): - trg_pedido_aprovado: ao aprovar (situa 1→2) em sar.pedidos, replica automaticamente em sig.pedidos + sig.peditens e grava erp_id_pedido - trg_cliente_novo: INSERT em sar.clientes_novos replica em sig.corrent com todos os campos obrigatórios; grava id_corrent_erp e flag sincronizado - Corrige trigger tsvectorupdate do ERP para PG 18 (bpchar→text cast) - Adiciona coluna erp_id_pedido em sar.pedidos e tabela sar.clientes_novos Migrations Prisma: - Remove 5 migrations obsoletas com nomes PascalCase (Order, Client, etc.) que não batiam com os @@map snake_case do schema atual - Cria baseline 20260624000000_init_baseline apontando para estado correto Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,41 +0,0 @@
|
||||
-- CreateEnum
|
||||
CREATE TYPE "FinancialStatus" AS ENUM ('regular', 'attention', 'blocked');
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Client" (
|
||||
"id" UUID NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"tradeName" TEXT,
|
||||
"taxId" TEXT NOT NULL,
|
||||
"email" TEXT,
|
||||
"phone" TEXT,
|
||||
"address" JSONB,
|
||||
"financialStatus" "FinancialStatus" NOT NULL DEFAULT 'regular',
|
||||
"creditLimit" DECIMAL(15,2),
|
||||
"repId" TEXT NOT NULL,
|
||||
"lastOrderAt" TIMESTAMP(3),
|
||||
"lastOrderValue" DECIMAL(15,2),
|
||||
"openOrdersCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"erpCode" TEXT,
|
||||
"syncedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
"deletedAt" TIMESTAMP(3),
|
||||
|
||||
CONSTRAINT "Client_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Client_taxId_key" ON "Client"("taxId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Client_repId_idx" ON "Client"("repId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Client_taxId_idx" ON "Client"("taxId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Client_name_idx" ON "Client"("name");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Client_deletedAt_idx" ON "Client"("deletedAt");
|
||||
@@ -1,95 +0,0 @@
|
||||
-- CreateEnum
|
||||
CREATE TYPE "OrderStatus" AS ENUM ('budget', 'pending_approval', 'approved', 'invoiced', 'cancelled');
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Order" (
|
||||
"id" UUID NOT NULL,
|
||||
"number" TEXT NOT NULL,
|
||||
"clientId" UUID NOT NULL,
|
||||
"repId" TEXT NOT NULL,
|
||||
"status" "OrderStatus" NOT NULL DEFAULT 'budget',
|
||||
"discountPct" DECIMAL(5,2) NOT NULL DEFAULT 0,
|
||||
"subtotal" DECIMAL(15,2) NOT NULL,
|
||||
"total" DECIMAL(15,2) NOT NULL,
|
||||
"notes" TEXT,
|
||||
"approvedById" TEXT,
|
||||
"approvedAt" TIMESTAMP(3),
|
||||
"invoicedAt" TIMESTAMP(3),
|
||||
"cancelledAt" TIMESTAMP(3),
|
||||
"idempotencyKey" TEXT,
|
||||
"issuedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
"deletedAt" TIMESTAMP(3),
|
||||
|
||||
CONSTRAINT "Order_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "OrderItem" (
|
||||
"id" UUID NOT NULL,
|
||||
"orderId" UUID NOT NULL,
|
||||
"productCode" TEXT NOT NULL,
|
||||
"productName" TEXT NOT NULL,
|
||||
"quantity" DECIMAL(10,3) NOT NULL,
|
||||
"unitPrice" DECIMAL(15,2) NOT NULL,
|
||||
"discountPct" DECIMAL(5,2) NOT NULL DEFAULT 0,
|
||||
"subtotal" DECIMAL(15,2) NOT NULL,
|
||||
|
||||
CONSTRAINT "OrderItem_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "OrderStatusHistory" (
|
||||
"id" UUID NOT NULL,
|
||||
"orderId" UUID NOT NULL,
|
||||
"fromStatus" "OrderStatus",
|
||||
"toStatus" "OrderStatus" NOT NULL,
|
||||
"changedById" TEXT NOT NULL,
|
||||
"note" TEXT,
|
||||
"changedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "OrderStatusHistory_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Order_number_key" ON "Order"("number");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Order_idempotencyKey_key" ON "Order"("idempotencyKey");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Order_clientId_idx" ON "Order"("clientId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Order_repId_idx" ON "Order"("repId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Order_status_idx" ON "Order"("status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Order_issuedAt_idx" ON "Order"("issuedAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Order_number_idx" ON "Order"("number");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Order_deletedAt_idx" ON "Order"("deletedAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "OrderItem_orderId_idx" ON "OrderItem"("orderId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "OrderStatusHistory_orderId_idx" ON "OrderStatusHistory"("orderId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "OrderStatusHistory_changedAt_idx" ON "OrderStatusHistory"("changedAt");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Order" ADD CONSTRAINT "Order_clientId_fkey" FOREIGN KEY ("clientId") REFERENCES "Client"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "OrderItem" ADD CONSTRAINT "OrderItem_orderId_fkey" FOREIGN KEY ("orderId") REFERENCES "Order"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "OrderStatusHistory" ADD CONSTRAINT "OrderStatusHistory_orderId_fkey" FOREIGN KEY ("orderId") REFERENCES "Order"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -1,52 +0,0 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "OrderItem" ADD COLUMN "productCategory" TEXT NOT NULL DEFAULT 'geral';
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Product" (
|
||||
"id" UUID NOT NULL,
|
||||
"code" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"description" TEXT,
|
||||
"category" TEXT NOT NULL DEFAULT 'geral',
|
||||
"unitPrice" DECIMAL(15,2) NOT NULL,
|
||||
"stock" DECIMAL(10,3),
|
||||
"active" BOOLEAN NOT NULL DEFAULT true,
|
||||
"erpCode" TEXT,
|
||||
"syncedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
"deletedAt" TIMESTAMP(3),
|
||||
|
||||
CONSTRAINT "Product_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "RepDiscountLimit" (
|
||||
"repId" TEXT NOT NULL,
|
||||
"category" TEXT NOT NULL,
|
||||
"limit" DECIMAL(5,2) NOT NULL DEFAULT 5,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "RepDiscountLimit_pkey" PRIMARY KEY ("repId","category")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Product_code_key" ON "Product"("code");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Product_code_idx" ON "Product"("code");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Product_name_idx" ON "Product"("name");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Product_category_idx" ON "Product"("category");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Product_active_idx" ON "Product"("active");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Product_deletedAt_idx" ON "Product"("deletedAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "RepDiscountLimit_repId_idx" ON "RepDiscountLimit"("repId");
|
||||
@@ -1,15 +0,0 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE "RepTarget" (
|
||||
"repId" TEXT NOT NULL,
|
||||
"year" INTEGER NOT NULL,
|
||||
"month" INTEGER NOT NULL,
|
||||
"targetAmount" DECIMAL(15,2) NOT NULL,
|
||||
"commissionRate" DECIMAL(5,2) NOT NULL DEFAULT 3,
|
||||
"flexRate" DECIMAL(5,2) NOT NULL DEFAULT 1,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "RepTarget_pkey" PRIMARY KEY ("repId","year","month")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "RepTarget_repId_idx" ON "RepTarget"("repId");
|
||||
@@ -1,22 +0,0 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE "PushSubscription" (
|
||||
"id" UUID NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"role" TEXT NOT NULL,
|
||||
"endpoint" TEXT NOT NULL,
|
||||
"p256dh" TEXT NOT NULL,
|
||||
"auth" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "PushSubscription_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "PushSubscription_endpoint_key" ON "PushSubscription"("endpoint");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "PushSubscription_userId_idx" ON "PushSubscription"("userId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "PushSubscription_role_idx" ON "PushSubscription"("role");
|
||||
@@ -1,17 +1,13 @@
|
||||
import { Avatar, Badge, Button, Dropdown, Flex, Input, Typography } from 'antd';
|
||||
import { Avatar, Badge, Button, Dropdown, Flex, Typography } from 'antd';
|
||||
import { PlusOutlined } from '@ant-design/icons';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import {
|
||||
faBell,
|
||||
faMagnifyingGlass,
|
||||
faBars,
|
||||
faRightFromBracket,
|
||||
} from '@fortawesome/free-solid-svg-icons';
|
||||
import { faBell, faBars, faBuilding, faRightFromBracket } from '@fortawesome/free-solid-svg-icons';
|
||||
import { useNavigate } from '@tanstack/react-router';
|
||||
import { brandTokens } from '../../lib/theme';
|
||||
import { FoundationStatus } from './FoundationStatus';
|
||||
import { usePendingCount } from '../../lib/queries/notifications';
|
||||
import { useCurrentUser } from '../../lib/queries/auth';
|
||||
import { useCompany } from '../../lib/queries/company';
|
||||
import { authStore } from '../../lib/auth-store';
|
||||
|
||||
interface TopbarProps {
|
||||
@@ -33,6 +29,11 @@ export function Topbar({ onToggleSidebar }: TopbarProps) {
|
||||
const { data: pendingData } = usePendingCount();
|
||||
const pendingCount = pendingData?.count ?? 0;
|
||||
const { data: user } = useCurrentUser();
|
||||
const { data: company } = useCompany();
|
||||
const nomeFantasia = company?.nomeFantasia?.trim() ?? null;
|
||||
const razaoSocial = company?.razaoSocial?.trim() ?? null;
|
||||
const nomeEmpresa = nomeFantasia ?? razaoSocial ?? '—';
|
||||
const mostrarRazao = nomeFantasia && razaoSocial && nomeFantasia !== razaoSocial;
|
||||
const initials = user?.nome
|
||||
? user.nome
|
||||
.split(' ')
|
||||
@@ -121,17 +122,39 @@ export function Topbar({ onToggleSidebar }: TopbarProps) {
|
||||
</Flex>
|
||||
</Flex>
|
||||
|
||||
{/* Centro: search (Supervisor/Admin) */}
|
||||
<Flex flex={1} justify="center" style={{ maxWidth: 480, margin: '0 var(--space-2xl)' }}>
|
||||
<Input
|
||||
size="large"
|
||||
placeholder="Buscar cliente, pedido, produto..."
|
||||
prefix={
|
||||
<FontAwesomeIcon icon={faMagnifyingGlass} style={{ color: 'var(--text-muted)' }} />
|
||||
}
|
||||
style={{ borderRadius: 12 }}
|
||||
aria-label="Buscar"
|
||||
/>
|
||||
{/* Centro: empresa ativa */}
|
||||
<Flex flex={1} justify="center" style={{ margin: '0 var(--space-2xl)' }}>
|
||||
<Flex align="center" gap={10}>
|
||||
<FontAwesomeIcon
|
||||
icon={faBuilding}
|
||||
style={{ color: 'var(--text-muted)', fontSize: 16, flexShrink: 0 }}
|
||||
/>
|
||||
<Flex vertical gap={0}>
|
||||
<Typography.Text
|
||||
style={{
|
||||
fontSize: 'var(--text-xl)',
|
||||
fontWeight: 'var(--font-weight-semibold)',
|
||||
color: 'var(--text-main)',
|
||||
lineHeight: 1.2,
|
||||
whiteSpace: 'nowrap',
|
||||
}}
|
||||
>
|
||||
{nomeEmpresa}
|
||||
</Typography.Text>
|
||||
{mostrarRazao && (
|
||||
<Typography.Text
|
||||
style={{
|
||||
fontSize: 'var(--text-2xs)',
|
||||
color: 'var(--text-muted)',
|
||||
lineHeight: 1.3,
|
||||
whiteSpace: 'nowrap',
|
||||
}}
|
||||
>
|
||||
{razaoSocial}
|
||||
</Typography.Text>
|
||||
)}
|
||||
</Flex>
|
||||
</Flex>
|
||||
</Flex>
|
||||
|
||||
{/* Lado direito: novo pedido + status fundação + notificações + perfil */}
|
||||
|
||||
Reference in New Issue
Block a user