Initial commit: LexMind - Plataforma Jurídica Inteligente

This commit is contained in:
bigtux
2026-02-10 15:46:26 -03:00
commit 08bd4f039d
108 changed files with 75782 additions and 0 deletions

BIN
prisma/dev.db Normal file

Binary file not shown.

View File

@@ -0,0 +1,176 @@
-- CreateEnum
CREATE TYPE "UserRole" AS ENUM ('ADMIN', 'ADVOGADO', 'FREE');
-- CreateEnum
CREATE TYPE "Plan" AS ENUM ('FREE', 'PRO', 'ENTERPRISE');
-- CreateEnum
CREATE TYPE "DocumentType" AS ENUM ('PETICAO_INICIAL', 'CONTESTACAO', 'APELACAO', 'RECURSO', 'CONTRATO', 'PARECER', 'IMPUGNACAO', 'HABEAS_CORPUS', 'MANDADO_SEGURANCA', 'OUTROS');
-- CreateEnum
CREATE TYPE "LegalArea" AS ENUM ('CIVIL', 'TRABALHISTA', 'PENAL', 'TRIBUTARIO', 'FAMILIA', 'EMPRESARIAL', 'CONSUMIDOR', 'ADMINISTRATIVO');
-- CreateEnum
CREATE TYPE "DocumentStatus" AS ENUM ('GENERATING', 'COMPLETED', 'ERROR');
-- CreateEnum
CREATE TYPE "MessageRole" AS ENUM ('USER', 'ASSISTANT');
-- CreateEnum
CREATE TYPE "SubscriptionStatus" AS ENUM ('ACTIVE', 'CANCELLED', 'EXPIRED');
-- CreateEnum
CREATE TYPE "UsageType" AS ENUM ('DOCUMENT', 'CHAT', 'JURISPRUDENCIA');
-- CreateTable
CREATE TABLE "User" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"email" TEXT NOT NULL,
"password" TEXT NOT NULL,
"role" "UserRole" NOT NULL DEFAULT 'FREE',
"plan" "Plan" NOT NULL DEFAULT 'FREE',
"oabNumber" TEXT,
"oabState" TEXT,
"phone" TEXT,
"avatar" TEXT,
"credits" INTEGER NOT NULL DEFAULT 5,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "User_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "ApiKey" (
"id" TEXT NOT NULL,
"key" TEXT NOT NULL,
"name" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"active" BOOLEAN NOT NULL DEFAULT true,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "ApiKey_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Document" (
"id" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"type" "DocumentType" NOT NULL,
"title" TEXT NOT NULL,
"prompt" TEXT NOT NULL,
"content" TEXT NOT NULL,
"wordCount" INTEGER NOT NULL DEFAULT 0,
"status" "DocumentStatus" NOT NULL DEFAULT 'GENERATING',
"area" "LegalArea" NOT NULL,
"tokens" INTEGER NOT NULL DEFAULT 0,
"cost" DOUBLE PRECISION NOT NULL DEFAULT 0,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "Document_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Template" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"description" TEXT NOT NULL,
"type" "DocumentType" NOT NULL,
"area" "LegalArea" NOT NULL,
"prompt" TEXT NOT NULL,
"isPublic" BOOLEAN NOT NULL DEFAULT false,
"userId" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "Template_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Jurisprudencia" (
"id" TEXT NOT NULL,
"tribunal" TEXT NOT NULL,
"numero" TEXT NOT NULL,
"ementa" TEXT NOT NULL,
"data" TEXT NOT NULL,
"area" TEXT NOT NULL,
"relator" TEXT NOT NULL,
"orgaoJulgador" TEXT NOT NULL,
"tags" TEXT NOT NULL,
CONSTRAINT "Jurisprudencia_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Chat" (
"id" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"title" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "Chat_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "ChatMessage" (
"id" TEXT NOT NULL,
"chatId" TEXT NOT NULL,
"role" "MessageRole" NOT NULL,
"content" TEXT NOT NULL,
"tokens" INTEGER NOT NULL DEFAULT 0,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "ChatMessage_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Subscription" (
"id" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"plan" "Plan" NOT NULL,
"status" "SubscriptionStatus" NOT NULL DEFAULT 'ACTIVE',
"startDate" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"endDate" TIMESTAMP(3),
"stripeId" TEXT,
CONSTRAINT "Subscription_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "UsageLog" (
"id" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"type" "UsageType" NOT NULL,
"tokens" INTEGER NOT NULL DEFAULT 0,
"cost" DOUBLE PRECISION NOT NULL DEFAULT 0,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "UsageLog_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
-- CreateIndex
CREATE UNIQUE INDEX "ApiKey_key_key" ON "ApiKey"("key");
-- AddForeignKey
ALTER TABLE "ApiKey" ADD CONSTRAINT "ApiKey_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Document" ADD CONSTRAINT "Document_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Template" ADD CONSTRAINT "Template_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Chat" ADD CONSTRAINT "Chat_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "ChatMessage" ADD CONSTRAINT "ChatMessage_chatId_fkey" FOREIGN KEY ("chatId") REFERENCES "Chat"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Subscription" ADD CONSTRAINT "Subscription_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "UsageLog" ADD CONSTRAINT "UsageLog_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@@ -0,0 +1,47 @@
-- CreateEnum
CREATE TYPE "PrazoStatus" AS ENUM ('PENDENTE', 'CONCLUIDO', 'VENCIDO', 'CANCELADO');
-- CreateEnum
CREATE TYPE "PrazoPriority" AS ENUM ('ALTA', 'MEDIA', 'BAIXA');
-- CreateEnum
CREATE TYPE "AuditStatus" AS ENUM ('PENDING', 'ANALYZING', 'DONE', 'ERROR');
-- CreateTable
CREATE TABLE "Prazo" (
"id" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"title" TEXT NOT NULL,
"description" TEXT,
"processNumber" TEXT,
"court" TEXT,
"deadline" TIMESTAMP(3) NOT NULL,
"alertDays" INTEGER NOT NULL DEFAULT 3,
"status" "PrazoStatus" NOT NULL DEFAULT 'PENDENTE',
"priority" "PrazoPriority" NOT NULL DEFAULT 'MEDIA',
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "Prazo_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "ContractAudit" (
"id" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"title" TEXT NOT NULL,
"content" TEXT NOT NULL,
"analysis" JSONB,
"status" "AuditStatus" NOT NULL DEFAULT 'PENDING',
"riskScore" INTEGER,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "ContractAudit_pkey" PRIMARY KEY ("id")
);
-- AddForeignKey
ALTER TABLE "Prazo" ADD CONSTRAINT "Prazo_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "ContractAudit" ADD CONSTRAINT "ContractAudit_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@@ -0,0 +1,7 @@
-- AlterEnum
ALTER TYPE "Plan" ADD VALUE 'STARTER';
-- AlterTable
ALTER TABLE "User" ADD COLUMN "stripeCustomerId" TEXT,
ADD COLUMN "stripePriceId" TEXT,
ADD COLUMN "stripeSubscriptionId" TEXT;

View File

@@ -0,0 +1,15 @@
-- CreateTable
CREATE TABLE "Upload" (
"id" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"filename" TEXT NOT NULL,
"key" TEXT NOT NULL,
"size" INTEGER NOT NULL,
"mimeType" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "Upload_pkey" PRIMARY KEY ("id")
);
-- AddForeignKey
ALTER TABLE "Upload" ADD CONSTRAINT "Upload_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@@ -0,0 +1,20 @@
-- CreateTable
CREATE TABLE "ProcessAnalysis" (
"id" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"title" TEXT NOT NULL,
"filename" TEXT NOT NULL,
"fileKey" TEXT NOT NULL,
"fileSize" INTEGER NOT NULL,
"extractedText" TEXT NOT NULL,
"analysis" TEXT NOT NULL,
"summary" TEXT,
"status" TEXT NOT NULL DEFAULT 'PENDING',
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "ProcessAnalysis_pkey" PRIMARY KEY ("id")
);
-- AddForeignKey
ALTER TABLE "ProcessAnalysis" ADD CONSTRAINT "ProcessAnalysis_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@@ -0,0 +1,3 @@
# Please do not edit this file manually
# It should be added in your version-control system (e.g., Git)
provider = "postgresql"

BIN
prisma/prisma/dev.db Normal file

Binary file not shown.

View File

@@ -0,0 +1,71 @@
// ===== MONITORAMENTO DE PUBLICAÇÕES =====
model ProcessoMonitorado {
id String @id @default(cuid())
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
numeroProcesso String // Ex: 0001234-56.2024.8.26.0100
tribunal String // Ex: TJSP, TRF3, STJ
vara String?
comarca String?
parteAutora String?
parteRe String?
status ProcessoStatus @default(ATIVO)
// Dados do processo (buscados da API DataJud)
classe String?
assunto String?
dataAjuizamento DateTime?
orgaoJulgador String?
grau String?
valorCausa Float?
ultimaAtualizacao DateTime?
dadosCompletos Json? // JSON com todos os dados brutos da API
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
publicacoes Publicacao[]
andamentos Andamento[]
}
model Andamento {
id String @id @default(cuid())
processoId String
processo ProcessoMonitorado @relation(fields: [processoId], references: [id], onDelete: Cascade)
codigo Int
nome String
dataHora DateTime
complemento String?
createdAt DateTime @default(now())
@@unique([processoId, codigo, dataHora])
}
model Publicacao {
id String @id @default(cuid())
processoId String
processo ProcessoMonitorado @relation(fields: [processoId], references: [id], onDelete: Cascade)
dataPublicacao DateTime
diario String // Ex: DJe, DOU, DOESP
conteudo String @db.Text
tipo TipoPublicacao
prazoCalculado DateTime?
prazoTipo String? // Ex: "15 dias úteis", "5 dias"
visualizado Boolean @default(false)
createdAt DateTime @default(now())
}
enum ProcessoStatus {
ATIVO
ARQUIVADO
SUSPENSO
}
enum TipoPublicacao {
INTIMACAO
CITACAO
SENTENCA
DESPACHO
ACORDAO
OUTROS
}

338
prisma/schema.prisma Normal file
View File

@@ -0,0 +1,338 @@
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id String @id @default(cuid())
name String
email String @unique
password String
role UserRole @default(FREE)
plan Plan @default(FREE)
oabNumber String?
oabState String?
phone String?
avatar String?
credits Int @default(5)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
stripeCustomerId String?
stripePriceId String?
stripeSubscriptionId String?
apiKeys ApiKey[]
chats Chat[]
contractAudits ContractAudit[]
documents Document[]
prazos Prazo[]
subscriptions Subscription[]
templates Template[]
usageLogs UsageLog[]
uploads Upload[]
processAnalyses ProcessAnalysis[]
processosMonitorados ProcessoMonitorado[]
}
model ApiKey {
id String @id @default(cuid())
key String @unique
name String
userId String
active Boolean @default(true)
createdAt DateTime @default(now())
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
}
model Document {
id String @id @default(cuid())
userId String
type DocumentType
title String
prompt String
content String
wordCount Int @default(0)
status DocumentStatus @default(GENERATING)
area LegalArea
tokens Int @default(0)
cost Float @default(0)
createdAt DateTime @default(now())
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
}
model Template {
id String @id @default(cuid())
name String
description String
type DocumentType
area LegalArea
prompt String
isPublic Boolean @default(false)
userId String?
createdAt DateTime @default(now())
user User? @relation(fields: [userId], references: [id])
}
model Jurisprudencia {
id String @id @default(cuid())
tribunal String
numero String
ementa String
data String
area String
relator String
orgaoJulgador String
tags String
}
model Chat {
id String @id @default(cuid())
userId String
title String
createdAt DateTime @default(now())
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
messages ChatMessage[]
}
model ChatMessage {
id String @id @default(cuid())
chatId String
role MessageRole
content String
tokens Int @default(0)
createdAt DateTime @default(now())
chat Chat @relation(fields: [chatId], references: [id], onDelete: Cascade)
}
model Subscription {
id String @id @default(cuid())
userId String
plan Plan
status SubscriptionStatus @default(ACTIVE)
startDate DateTime @default(now())
endDate DateTime?
stripeId String?
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
}
model UsageLog {
id String @id @default(cuid())
userId String
type UsageType
tokens Int @default(0)
cost Float @default(0)
createdAt DateTime @default(now())
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
}
model Prazo {
id String @id @default(cuid())
userId String
title String
description String?
processNumber String?
court String?
deadline DateTime
alertDays Int @default(3)
status PrazoStatus @default(PENDENTE)
priority PrazoPriority @default(MEDIA)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
}
model ContractAudit {
id String @id @default(cuid())
userId String
title String
content String
analysis Json?
status AuditStatus @default(PENDING)
riskScore Int?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
}
model Upload {
id String @id @default(cuid())
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
filename String
key String
size Int
mimeType String
createdAt DateTime @default(now())
}
enum UserRole {
ADMIN
ADVOGADO
FREE
}
enum Plan {
FREE
PRO
ENTERPRISE
STARTER
}
enum DocumentType {
PETICAO_INICIAL
CONTESTACAO
APELACAO
RECURSO
CONTRATO
PARECER
IMPUGNACAO
HABEAS_CORPUS
MANDADO_SEGURANCA
OUTROS
}
enum LegalArea {
CIVIL
TRABALHISTA
PENAL
TRIBUTARIO
FAMILIA
EMPRESARIAL
CONSUMIDOR
ADMINISTRATIVO
}
enum DocumentStatus {
GENERATING
COMPLETED
ERROR
}
enum MessageRole {
USER
ASSISTANT
}
enum SubscriptionStatus {
ACTIVE
CANCELLED
EXPIRED
}
enum UsageType {
DOCUMENT
CHAT
JURISPRUDENCIA
}
enum PrazoStatus {
PENDENTE
CONCLUIDO
VENCIDO
CANCELADO
}
enum PrazoPriority {
ALTA
MEDIA
BAIXA
}
enum AuditStatus {
PENDING
ANALYZING
DONE
ERROR
}
model ProcessAnalysis {
id String @id @default(cuid())
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
title String
filename String
fileKey String
fileSize Int
extractedText String @db.Text
analysis String @db.Text
summary String? @db.Text
status String @default("PENDING")
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
// ===== MONITORAMENTO DE PUBLICAÇÕES =====
model ProcessoMonitorado {
id String @id @default(cuid())
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
numeroProcesso String // Ex: 0001234-56.2024.8.26.0100
tribunal String // Ex: TJSP, TRF3, STJ
vara String?
comarca String?
parteAutora String?
parteRe String?
status ProcessoStatus @default(ATIVO)
// Dados do processo (buscados da API DataJud)
classe String?
assunto String?
dataAjuizamento DateTime?
orgaoJulgador String?
grau String?
valorCausa Float?
ultimaAtualizacao DateTime?
dadosCompletos Json? // JSON com todos os dados brutos da API
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
publicacoes Publicacao[]
andamentos Andamento[]
}
model Publicacao {
id String @id @default(cuid())
processoId String
processo ProcessoMonitorado @relation(fields: [processoId], references: [id], onDelete: Cascade)
dataPublicacao DateTime
diario String // Ex: DJe, DOU, DOESP
conteudo String @db.Text
tipo TipoPublicacao
prazoCalculado DateTime?
prazoTipo String? // Ex: "15 dias úteis", "5 dias"
visualizado Boolean @default(false)
createdAt DateTime @default(now())
}
enum ProcessoStatus {
ATIVO
ARQUIVADO
SUSPENSO
}
enum TipoPublicacao {
INTIMACAO
CITACAO
SENTENCA
DESPACHO
ACORDAO
OUTROS
}
model Andamento {
id String @id @default(cuid())
processoId String
processo ProcessoMonitorado @relation(fields: [processoId], references: [id], onDelete: Cascade)
codigo Int
nome String
dataHora DateTime
complemento String?
createdAt DateTime @default(now())
@@unique([processoId, codigo, dataHora])
}

367
prisma/seed.ts Normal file
View File

@@ -0,0 +1,367 @@
import { PrismaClient } from '@prisma/client'
import bcrypt from 'bcryptjs'
const prisma = new PrismaClient()
async function main() {
console.log('🌱 Seeding database...')
// ── Users ──
const passwordHash = await bcrypt.hash('123456', 10)
const admin = await prisma.user.upsert({
where: { email: 'admin@juridico.ai' },
update: {},
create: {
name: 'Admin Sistema',
email: 'admin@juridico.ai',
password: passwordHash,
role: 'ADMIN',
plan: 'ENTERPRISE',
credits: 9999,
phone: '11999999999',
},
})
const advogadoPro = await prisma.user.upsert({
where: { email: 'maria@advocacia.com' },
update: {},
create: {
name: 'Maria Silva',
email: 'maria@advocacia.com',
password: passwordHash,
role: 'ADVOGADO',
plan: 'PRO',
oabNumber: '123456',
oabState: 'SP',
credits: 100,
phone: '11988888888',
},
})
const advogadoFree = await prisma.user.upsert({
where: { email: 'joao@email.com' },
update: {},
create: {
name: 'João Santos',
email: 'joao@email.com',
password: passwordHash,
role: 'ADVOGADO',
plan: 'FREE',
oabNumber: '654321',
oabState: 'RJ',
credits: 5,
phone: '21977777777',
},
})
console.log('✅ Users created:', admin.name, advogadoPro.name, advogadoFree.name)
// ── Subscriptions ──
await prisma.subscription.createMany({
data: [
{ userId: admin.id, plan: 'ENTERPRISE', status: 'ACTIVE' },
{ userId: advogadoPro.id, plan: 'PRO', status: 'ACTIVE', stripeId: 'sub_mock_pro_001' },
{ userId: advogadoFree.id, plan: 'FREE', status: 'ACTIVE' },
],
})
// ── Templates ──
const templates = await Promise.all([
prisma.template.create({
data: {
name: 'Petição Inicial Cível',
description: 'Modelo de petição inicial para ações cíveis com fundamentação completa',
type: 'PETICAO_INICIAL',
area: 'CIVIL',
prompt: 'Elabore uma petição inicial cível com os seguintes dados: {{fatos}}. Inclua fundamentação jurídica com base no CPC e CC, pedidos e valor da causa.',
isPublic: true,
userId: admin.id,
},
}),
prisma.template.create({
data: {
name: 'Contestação Trabalhista',
description: 'Modelo de contestação para reclamações trabalhistas',
type: 'CONTESTACAO',
area: 'TRABALHISTA',
prompt: 'Elabore uma contestação trabalhista para a reclamação: {{fatos}}. Inclua preliminares, mérito e impugnação aos pedidos com base na CLT.',
isPublic: true,
userId: admin.id,
},
}),
prisma.template.create({
data: {
name: 'Recurso de Apelação',
description: 'Modelo de recurso de apelação com razões recursais',
type: 'APELACAO',
area: 'CIVIL',
prompt: 'Elabore um recurso de apelação com base na sentença: {{sentenca}}. Apresente razões recursais, error in judicando/procedendo e pedido de reforma.',
isPublic: true,
userId: admin.id,
},
}),
prisma.template.create({
data: {
name: 'Contrato de Prestação de Serviços',
description: 'Modelo de contrato de prestação de serviços advocatícios',
type: 'CONTRATO',
area: 'CIVIL',
prompt: 'Elabore um contrato de prestação de serviços entre {{contratante}} e {{contratado}}. Escopo: {{escopo}}. Valor: {{valor}}. Inclua cláusulas de confidencialidade, rescisão e foro.',
isPublic: true,
userId: admin.id,
},
}),
prisma.template.create({
data: {
name: 'Habeas Corpus',
description: 'Modelo de habeas corpus preventivo ou liberatório',
type: 'HABEAS_CORPUS',
area: 'PENAL',
prompt: 'Elabore um habeas corpus {{tipo}} em favor de {{paciente}}, contra ato de {{autoridade_coatora}}. Fatos: {{fatos}}. Fundamente no art. 5º, LXVIII da CF e arts. 647-667 do CPP.',
isPublic: true,
userId: admin.id,
},
}),
])
console.log('✅ Templates created:', templates.length)
// ── Jurisprudências ──
const jurisprudencias = await Promise.all([
prisma.jurisprudencia.create({
data: {
tribunal: 'STF',
numero: 'RE 1.322.076/SP',
ementa: 'RECURSO EXTRAORDINÁRIO. DIREITO DO CONSUMIDOR. RESPONSABILIDADE CIVIL. DANO MORAL. INSCRIÇÃO INDEVIDA EM CADASTRO DE INADIMPLENTES. A inscrição indevida do nome do consumidor em cadastros de proteção ao crédito configura dano moral in re ipsa, dispensando a comprovação do prejuízo efetivo. Recurso extraordinário não provido.',
data: '2024-03-15',
area: 'CONSUMIDOR',
relator: 'Min. Luís Roberto Barroso',
orgaoJulgador: 'Primeira Turma',
tags: JSON.stringify(['dano moral', 'consumidor', 'cadastro inadimplentes', 'SPC', 'Serasa']),
},
}),
prisma.jurisprudencia.create({
data: {
tribunal: 'STJ',
numero: 'REsp 2.045.123/RJ',
ementa: 'RECURSO ESPECIAL. DIREITO CIVIL. RESPONSABILIDADE CIVIL. ACIDENTE DE TRÂNSITO. DANOS MATERIAIS E MORAIS. QUANTUM INDENIZATÓRIO. Revisão do valor da indenização por danos morais quando se mostrar irrisório ou excessivo. Manutenção do quantum fixado pelo Tribunal de origem dentro dos parâmetros de razoabilidade.',
data: '2024-05-20',
area: 'CIVIL',
relator: 'Min. Nancy Andrighi',
orgaoJulgador: 'Terceira Turma',
tags: JSON.stringify(['acidente trânsito', 'dano moral', 'dano material', 'quantum indenizatório']),
},
}),
prisma.jurisprudencia.create({
data: {
tribunal: 'STF',
numero: 'ADI 6.341/DF',
ementa: 'AÇÃO DIRETA DE INCONSTITUCIONALIDADE. DIREITO ADMINISTRATIVO. COMPETÊNCIA CONCORRENTE. ESTADOS E MUNICÍPIOS. MEDIDAS SANITÁRIAS. Reconhecimento da competência concorrente de estados e municípios para adoção de medidas restritivas durante emergência sanitária. Interpretação conforme à Constituição.',
data: '2024-01-10',
area: 'ADMINISTRATIVO',
relator: 'Min. Marco Aurélio',
orgaoJulgador: 'Tribunal Pleno',
tags: JSON.stringify(['competência concorrente', 'saúde pública', 'federalismo', 'autonomia']),
},
}),
prisma.jurisprudencia.create({
data: {
tribunal: 'STJ',
numero: 'RHC 163.334/SC',
ementa: 'RECURSO EM HABEAS CORPUS. DIREITO PENAL. FURTO. PRINCÍPIO DA INSIGNIFICÂNCIA. CRIME DE BAGATELA. Aplicação do princípio da insignificância ao furto de bem avaliado em valor inferior a 10% do salário mínimo. Atipicidade material da conduta. Recurso provido.',
data: '2024-04-18',
area: 'PENAL',
relator: 'Min. Sebastião Reis Júnior',
orgaoJulgador: 'Sexta Turma',
tags: JSON.stringify(['furto', 'insignificância', 'bagatela', 'atipicidade']),
},
}),
prisma.jurisprudencia.create({
data: {
tribunal: 'STF',
numero: 'ARE 1.121.633/GO',
ementa: 'AGRAVO EM RECURSO EXTRAORDINÁRIO. DIREITO DO TRABALHO. TERCEIRIZAÇÃO. ATIVIDADE-FIM. LICITUDE. É lícita a terceirização ou qualquer outra forma de divisão do trabalho entre pessoas jurídicas distintas, independentemente do objeto social das empresas envolvidas, mantida a responsabilidade subsidiária da empresa contratante. Tema 725 de repercussão geral.',
data: '2024-02-28',
area: 'TRABALHISTA',
relator: 'Min. Gilmar Mendes',
orgaoJulgador: 'Tribunal Pleno',
tags: JSON.stringify(['terceirização', 'atividade-fim', 'responsabilidade subsidiária', 'tema 725']),
},
}),
prisma.jurisprudencia.create({
data: {
tribunal: 'STJ',
numero: 'REsp 1.869.043/SP',
ementa: 'RECURSO ESPECIAL. DIREITO TRIBUTÁRIO. ICMS. BASE DE CÁLCULO. EXCLUSÃO DO PIS E COFINS. Em consonância com o entendimento firmado pelo STF no Tema 69, o ICMS a ser excluído da base de cálculo do PIS e da COFINS é o destacado na nota fiscal. Recurso especial não provido.',
data: '2024-06-05',
area: 'TRIBUTARIO',
relator: 'Min. Herman Benjamin',
orgaoJulgador: 'Segunda Turma',
tags: JSON.stringify(['ICMS', 'PIS', 'COFINS', 'base de cálculo', 'tema 69']),
},
}),
prisma.jurisprudencia.create({
data: {
tribunal: 'STF',
numero: 'RE 898.060/SC',
ementa: 'RECURSO EXTRAORDINÁRIO. DIREITO DE FAMÍLIA. PATERNIDADE SOCIOAFETIVA. MULTIPARENTALIDADE. A paternidade socioafetiva, declarada ou não em registro público, não impede o reconhecimento do vínculo de filiação concomitante baseado na origem biológica, com os efeitos jurídicos próprios. Tema 622.',
data: '2024-03-22',
area: 'FAMILIA',
relator: 'Min. Luiz Fux',
orgaoJulgador: 'Tribunal Pleno',
tags: JSON.stringify(['paternidade socioafetiva', 'multiparentalidade', 'filiação', 'tema 622']),
},
}),
prisma.jurisprudencia.create({
data: {
tribunal: 'STJ',
numero: 'REsp 1.951.532/RS',
ementa: 'RECURSO ESPECIAL. DIREITO EMPRESARIAL. RECUPERAÇÃO JUDICIAL. PLANO DE RECUPERAÇÃO. CRAM DOWN. Possibilidade de aprovação do plano de recuperação judicial pelo juiz mesmo sem a concordância de todas as classes de credores, desde que preenchidos os requisitos do art. 58, §1º da Lei 11.101/2005.',
data: '2024-07-12',
area: 'EMPRESARIAL',
relator: 'Min. Ricardo Villas Bôas Cueva',
orgaoJulgador: 'Terceira Turma',
tags: JSON.stringify(['recuperação judicial', 'cram down', 'plano recuperação', 'credores']),
},
}),
prisma.jurisprudencia.create({
data: {
tribunal: 'STF',
numero: 'HC 124.306/RJ',
ementa: 'HABEAS CORPUS. DIREITO PENAL. ABORTO. INTERRUPÇÃO VOLUNTÁRIA DA GESTAÇÃO. PRIMEIRO TRIMESTRE. É preciso conferir interpretação conforme a Constituição aos arts. 124 a 126 do Código Penal para excluir do seu âmbito de incidência a interrupção voluntária da gestação efetivada no primeiro trimestre.',
data: '2024-08-01',
area: 'PENAL',
relator: 'Min. Luís Roberto Barroso',
orgaoJulgador: 'Primeira Turma',
tags: JSON.stringify(['aborto', 'primeiro trimestre', 'interpretação conforme', 'direitos fundamentais']),
},
}),
prisma.jurisprudencia.create({
data: {
tribunal: 'STJ',
numero: 'REsp 1.733.013/PR',
ementa: 'RECURSO ESPECIAL. DIREITO DO CONSUMIDOR. COMÉRCIO ELETRÔNICO. RESPONSABILIDADE DO MARKETPLACE. A plataforma digital que intermedia a venda de produtos responde solidariamente pelos vícios e defeitos dos produtos comercializados por terceiros em seu ambiente virtual, nos termos do CDC.',
data: '2024-09-10',
area: 'CONSUMIDOR',
relator: 'Min. Paulo de Tarso Sanseverino',
orgaoJulgador: 'Terceira Turma',
tags: JSON.stringify(['marketplace', 'comércio eletrônico', 'responsabilidade solidária', 'CDC', 'plataforma digital']),
},
}),
])
console.log('✅ Jurisprudências created:', jurisprudencias.length)
// ── Sample Documents ──
const documents = await Promise.all([
prisma.document.create({
data: {
userId: advogadoPro.id,
type: 'PETICAO_INICIAL',
title: 'Petição Inicial - Ação de Indenização por Danos Morais',
prompt: 'Elaborar petição inicial para ação de indenização por danos morais decorrente de inscrição indevida no SPC',
content: 'EXCELENTÍSSIMO SENHOR DOUTOR JUIZ DE DIREITO DA ___ VARA CÍVEL DA COMARCA DE SÃO PAULO/SP\n\nMARIA DA SILVA, brasileira, solteira, professora, portadora do RG nº 12.345.678-9 e CPF nº 123.456.789-00, residente e domiciliada na Rua das Flores, nº 100, Jardim Primavera, São Paulo/SP, CEP 01234-567, vem, respeitosamente, à presença de Vossa Excelência, por intermédio de seus procuradores que esta subscrevem, propor a presente AÇÃO DE INDENIZAÇÃO POR DANOS MORAIS em face de BANCO XYZ S/A...\n\n[Documento completo gerado pela IA]',
wordCount: 2500,
status: 'COMPLETED',
area: 'CONSUMIDOR',
tokens: 3200,
cost: 0.032,
},
}),
prisma.document.create({
data: {
userId: advogadoPro.id,
type: 'CONTESTACAO',
title: 'Contestação - Reclamação Trabalhista',
prompt: 'Elaborar contestação para reclamação trabalhista sobre horas extras e adicional noturno',
content: 'EXCELENTÍSSIMO SENHOR DOUTOR JUIZ DO TRABALHO DA ___ VARA DO TRABALHO DE SÃO PAULO/SP\n\nProcesso nº 0001234-56.2024.5.02.0001\n\nEMPRESA ABC LTDA, pessoa jurídica de direito privado, inscrita no CNPJ sob nº 12.345.678/0001-90, com sede na Avenida Paulista, nº 1000, São Paulo/SP, vem, respeitosamente, apresentar CONTESTAÇÃO à reclamação trabalhista movida por JOÃO CARLOS SOUZA...\n\n[Documento completo gerado pela IA]',
wordCount: 3100,
status: 'COMPLETED',
area: 'TRABALHISTA',
tokens: 4100,
cost: 0.041,
},
}),
prisma.document.create({
data: {
userId: advogadoFree.id,
type: 'CONTRATO',
title: 'Contrato de Honorários Advocatícios',
prompt: 'Elaborar contrato de honorários para consultoria jurídica empresarial mensal',
content: 'CONTRATO DE PRESTAÇÃO DE SERVIÇOS ADVOCATÍCIOS\n\nPelo presente instrumento particular, de um lado EMPRESA DELTA COMÉRCIO LTDA como CONTRATANTE e de outro a DRA. JOÃO SANTOS - OAB/RJ 654321 como CONTRATADO...\n\n[Documento completo gerado pela IA]',
wordCount: 1800,
status: 'COMPLETED',
area: 'EMPRESARIAL',
tokens: 2200,
cost: 0.022,
},
}),
])
console.log('✅ Documents created:', documents.length)
// ── Sample Chat ──
const chat = await prisma.chat.create({
data: {
userId: advogadoPro.id,
title: 'Dúvida sobre prescrição em ação de cobrança',
messages: {
create: [
{
role: 'USER',
content: 'Qual o prazo prescricional para ação de cobrança de dívida por contrato verbal?',
tokens: 25,
},
{
role: 'ASSISTANT',
content: 'O prazo prescricional para ação de cobrança de dívida originada de contrato verbal é de **10 anos**, conforme o art. 205 do Código Civil de 2002, que estabelece o prazo prescricional genérico. Contudo, se houver documento escrito (como um título de crédito), o prazo pode ser diferente:\n\n- **Cheque:** 6 meses (art. 59, Lei 7.357/85)\n- **Nota promissória:** 3 anos (art. 70, LUG)\n- **Duplicata:** 3 anos (art. 18, Lei 5.474/68)\n\nImportante: O prazo começa a contar da data do vencimento da dívida (art. 199, CC).',
tokens: 180,
},
],
},
},
})
console.log('✅ Chat created:', chat.title)
// ── Usage Logs ──
await prisma.usageLog.createMany({
data: [
{ userId: advogadoPro.id, type: 'DOCUMENT', tokens: 3200, cost: 0.032 },
{ userId: advogadoPro.id, type: 'DOCUMENT', tokens: 4100, cost: 0.041 },
{ userId: advogadoPro.id, type: 'CHAT', tokens: 205, cost: 0.002 },
{ userId: advogadoFree.id, type: 'DOCUMENT', tokens: 2200, cost: 0.022 },
{ userId: advogadoPro.id, type: 'JURISPRUDENCIA', tokens: 150, cost: 0.001 },
],
})
console.log('✅ Usage logs created')
// ── API Keys ──
await prisma.apiKey.create({
data: {
key: 'jur_live_sk_' + 'a'.repeat(32),
name: 'API Principal',
userId: advogadoPro.id,
active: true,
},
})
console.log('✅ API keys created')
console.log('\n🎉 Seed completed successfully!')
console.log('\n📋 Login credentials (all passwords: 123456):')
console.log(' Admin: admin@juridico.ai')
console.log(' Pro: maria@advocacia.com')
console.log(' Free: joao@email.com')
}
main()
.then(async () => {
await prisma.$disconnect()
})
.catch(async (e) => {
console.error(e)
await prisma.$disconnect()
process.exit(1)
})