changes
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
-- CreateEnum
|
||||
CREATE TYPE "ProposalStatus" AS ENUM ('DRAFT', 'IN_PROGRESS', 'SUBMITTED', 'ARCHIVED');
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Proposal" (
|
||||
"id" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"sourceLicitationId" TEXT,
|
||||
"title" TEXT NOT NULL,
|
||||
"issuingEntity" TEXT NOT NULL,
|
||||
"summary" TEXT NOT NULL DEFAULT '',
|
||||
"status" "ProposalStatus" NOT NULL DEFAULT 'DRAFT',
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "Proposal_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "ProposalDocument" (
|
||||
"id" TEXT NOT NULL,
|
||||
"proposalId" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"fileName" TEXT NOT NULL,
|
||||
"storedFileName" TEXT NOT NULL,
|
||||
"filePath" TEXT NOT NULL,
|
||||
"mimeType" TEXT NOT NULL,
|
||||
"sizeBytes" INTEGER NOT NULL,
|
||||
"checksumSha256" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "ProposalDocument_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Proposal_userId_status_idx" ON "Proposal"("userId", "status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Proposal_updatedAt_idx" ON "Proposal"("updatedAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Proposal_sourceLicitationId_idx" ON "Proposal"("sourceLicitationId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ProposalDocument_proposalId_createdAt_idx" ON "ProposalDocument"("proposalId", "createdAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ProposalDocument_userId_createdAt_idx" ON "ProposalDocument"("userId", "createdAt");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Proposal" ADD CONSTRAINT "Proposal_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ProposalDocument" ADD CONSTRAINT "ProposalDocument_proposalId_fkey" FOREIGN KEY ("proposalId") REFERENCES "Proposal"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ProposalDocument" ADD CONSTRAINT "ProposalDocument_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,2 @@
|
||||
-- AlterEnum
|
||||
ALTER TYPE "LicitationSource" ADD VALUE IF NOT EXISTS 'LICITAYA';
|
||||
@@ -0,0 +1,81 @@
|
||||
-- CreateEnum
|
||||
CREATE TYPE "LicitationReviewStatus" AS ENUM ('NEW', 'REVIEWED', 'INTERESTED', 'DISCARDED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "NormativeDocumentType" AS ENUM ('BASES_LICITACION', 'CONVOCATORIA', 'REGLAMENTO', 'LEY', 'OTRO');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "NormativeAnalysisMethod" AS ENUM ('DIRECT', 'OCR');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "NormativeConfidence" AS ENUM ('LOW', 'MEDIUM', 'HIGH');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "NormativeRiskLevel" AS ENUM ('ALTO', 'MEDIO', 'BAJO');
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "LicitationUserPreference" (
|
||||
"id" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"licitationId" TEXT NOT NULL,
|
||||
"status" "LicitationReviewStatus" NOT NULL DEFAULT 'NEW',
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "LicitationUserPreference_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "NormativeAnalysisHistory" (
|
||||
"id" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"sourceLicitationId" TEXT,
|
||||
"fileName" TEXT NOT NULL,
|
||||
"documentType" "NormativeDocumentType" NOT NULL,
|
||||
"issuingEntity" TEXT,
|
||||
"methodUsed" "NormativeAnalysisMethod" NOT NULL,
|
||||
"numPages" INTEGER NOT NULL,
|
||||
"warnings" JSONB,
|
||||
"extractedChars" INTEGER NOT NULL,
|
||||
"confidence" "NormativeConfidence" NOT NULL,
|
||||
"viabilityScore" INTEGER NOT NULL,
|
||||
"riskLevel" "NormativeRiskLevel" NOT NULL,
|
||||
"executiveSummary" TEXT NOT NULL,
|
||||
"result" JSONB NOT NULL,
|
||||
"analyzedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"deletedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "NormativeAnalysisHistory_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "LicitationUserPreference_userId_licitationId_key" ON "LicitationUserPreference"("userId", "licitationId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "LicitationUserPreference_userId_status_idx" ON "LicitationUserPreference"("userId", "status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "LicitationUserPreference_licitationId_status_idx" ON "LicitationUserPreference"("licitationId", "status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "NormativeAnalysisHistory_userId_analyzedAt_idx" ON "NormativeAnalysisHistory"("userId", "analyzedAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "NormativeAnalysisHistory_userId_deletedAt_idx" ON "NormativeAnalysisHistory"("userId", "deletedAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "NormativeAnalysisHistory_sourceLicitationId_idx" ON "NormativeAnalysisHistory"("sourceLicitationId");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "LicitationUserPreference" ADD CONSTRAINT "LicitationUserPreference_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "LicitationUserPreference" ADD CONSTRAINT "LicitationUserPreference_licitationId_fkey" FOREIGN KEY ("licitationId") REFERENCES "Licitation"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "NormativeAnalysisHistory" ADD CONSTRAINT "NormativeAnalysisHistory_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "NormativeAnalysisHistory" ADD CONSTRAINT "NormativeAnalysisHistory_sourceLicitationId_fkey" FOREIGN KEY ("sourceLicitationId") REFERENCES "Licitation"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,6 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Proposal"
|
||||
ADD COLUMN "workflowDraft" JSONB,
|
||||
ADD COLUMN "currentStep" INTEGER NOT NULL DEFAULT 1,
|
||||
ADD COLUMN "completionPercent" INTEGER NOT NULL DEFAULT 0,
|
||||
ADD COLUMN "readyForSubmissionAt" TIMESTAMP(3);
|
||||
@@ -0,0 +1,8 @@
|
||||
-- RenameIndex (safe guard for environments where the old truncated index never existed)
|
||||
DO $$
|
||||
BEGIN
|
||||
IF to_regclass('"OfficialNormativeSuggestion_stateCode_municipalityCode_createdA"') IS NOT NULL THEN
|
||||
ALTER INDEX "OfficialNormativeSuggestion_stateCode_municipalityCode_createdA"
|
||||
RENAME TO "OfficialNormativeSuggestion_stateCode_municipalityCode_crea_idx";
|
||||
END IF;
|
||||
END $$;
|
||||
@@ -0,0 +1,134 @@
|
||||
-- CreateEnum
|
||||
CREATE TYPE "OfficialNormativeSourceType" AS ENUM ('LEY', 'REGLAMENTO', 'LINEAMIENTO', 'PORTAL');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "NormativeVerificationStatus" AS ENUM ('SUCCESS', 'WARNING', 'FAILED');
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "OfficialNormativeSource" (
|
||||
"id" TEXT NOT NULL,
|
||||
"stateCode" TEXT NOT NULL,
|
||||
"stateName" TEXT NOT NULL,
|
||||
"municipalityCode" TEXT,
|
||||
"municipalityName" TEXT,
|
||||
"authorityName" TEXT NOT NULL,
|
||||
"title" TEXT NOT NULL,
|
||||
"officialUrl" TEXT NOT NULL,
|
||||
"sourceType" "OfficialNormativeSourceType" NOT NULL,
|
||||
"versionLabel" TEXT,
|
||||
"isPilot" BOOLEAN NOT NULL DEFAULT false,
|
||||
"lastKnownHash" TEXT,
|
||||
"lastVerifiedAt" TIMESTAMP(3),
|
||||
"nextCheckAt" TIMESTAMP(3),
|
||||
"lastStatus" "NormativeVerificationStatus",
|
||||
"lastMessage" TEXT,
|
||||
"lastChangedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "OfficialNormativeSource_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "OfficialNormativeSuggestion" (
|
||||
"id" TEXT NOT NULL,
|
||||
"stateCode" TEXT NOT NULL,
|
||||
"municipalityCode" TEXT,
|
||||
"authorityName" TEXT NOT NULL,
|
||||
"title" TEXT NOT NULL,
|
||||
"officialUrl" TEXT NOT NULL,
|
||||
"sourceType" "OfficialNormativeSourceType" NOT NULL,
|
||||
"notes" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "OfficialNormativeSuggestion_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "OfficialNormativeSource_stateCode_municipalityCode_isPilot_idx" ON "OfficialNormativeSource"("stateCode", "municipalityCode", "isPilot");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "OfficialNormativeSource_nextCheckAt_idx" ON "OfficialNormativeSource"("nextCheckAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "OfficialNormativeSource_lastStatus_lastVerifiedAt_idx" ON "OfficialNormativeSource"("lastStatus", "lastVerifiedAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "OfficialNormativeSuggestion_stateCode_municipalityCode_createdAt_idx" ON "OfficialNormativeSuggestion"("stateCode", "municipalityCode", "createdAt");
|
||||
|
||||
-- Seed pilot sources (Nuevo Leon)
|
||||
INSERT INTO "OfficialNormativeSource" (
|
||||
"id",
|
||||
"stateCode",
|
||||
"stateName",
|
||||
"municipalityCode",
|
||||
"municipalityName",
|
||||
"authorityName",
|
||||
"title",
|
||||
"officialUrl",
|
||||
"sourceType",
|
||||
"versionLabel",
|
||||
"isPilot",
|
||||
"createdAt",
|
||||
"updatedAt"
|
||||
)
|
||||
VALUES
|
||||
(
|
||||
'nl-ley-adquisiciones-estatal',
|
||||
'NL',
|
||||
'Nuevo Leon',
|
||||
NULL,
|
||||
NULL,
|
||||
'Gobierno del Estado de Nuevo Leon',
|
||||
'Ley de Adquisiciones, Arrendamientos y Contratacion de Servicios del Estado de Nuevo Leon',
|
||||
'https://www.hcnl.gob.mx/trabajo_legislativo/leyes/',
|
||||
'LEY',
|
||||
NULL,
|
||||
true,
|
||||
CURRENT_TIMESTAMP,
|
||||
CURRENT_TIMESTAMP
|
||||
),
|
||||
(
|
||||
'nl-reglamento-adquisiciones-estatal',
|
||||
'NL',
|
||||
'Nuevo Leon',
|
||||
NULL,
|
||||
NULL,
|
||||
'Gobierno del Estado de Nuevo Leon',
|
||||
'Reglamento de la Ley de Adquisiciones del Estado de Nuevo Leon',
|
||||
'https://www.nl.gob.mx/',
|
||||
'REGLAMENTO',
|
||||
NULL,
|
||||
true,
|
||||
CURRENT_TIMESTAMP,
|
||||
CURRENT_TIMESTAMP
|
||||
),
|
||||
(
|
||||
'spgg-reglamento-adquisiciones',
|
||||
'NL',
|
||||
'Nuevo Leon',
|
||||
'SPGG',
|
||||
'San Pedro Garza Garcia',
|
||||
'Municipio de San Pedro Garza Garcia',
|
||||
'Reglamento de Adquisiciones y Contratacion de Servicios de San Pedro Garza Garcia',
|
||||
'https://www.sanpedro.gob.mx/',
|
||||
'REGLAMENTO',
|
||||
NULL,
|
||||
true,
|
||||
CURRENT_TIMESTAMP,
|
||||
CURRENT_TIMESTAMP
|
||||
)
|
||||
ON CONFLICT ("id") DO UPDATE
|
||||
SET
|
||||
"stateCode" = EXCLUDED."stateCode",
|
||||
"stateName" = EXCLUDED."stateName",
|
||||
"municipalityCode" = EXCLUDED."municipalityCode",
|
||||
"municipalityName" = EXCLUDED."municipalityName",
|
||||
"authorityName" = EXCLUDED."authorityName",
|
||||
"title" = EXCLUDED."title",
|
||||
"officialUrl" = EXCLUDED."officialUrl",
|
||||
"sourceType" = EXCLUDED."sourceType",
|
||||
"versionLabel" = EXCLUDED."versionLabel",
|
||||
"isPilot" = EXCLUDED."isPilot",
|
||||
"updatedAt" = CURRENT_TIMESTAMP;
|
||||
376
prisma/migrations/20260406200000_modules8_9_10/migration.sql
Normal file
376
prisma/migrations/20260406200000_modules8_9_10/migration.sql
Normal file
@@ -0,0 +1,376 @@
|
||||
-- CreateEnum
|
||||
CREATE TYPE "ContractStatus" AS ENUM ('ACTIVE', 'COMPLETED', 'PAUSED', 'CANCELLED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "ContractDeliverableStatus" AS ENUM ('PENDING', 'DELIVERED', 'APPROVED', 'REJECTED', 'OVERDUE');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "ContractPaymentStatus" AS ENUM ('REGISTERED', 'CONFIRMED', 'DISPUTED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "ContractDocumentKind" AS ENUM ('SIGNED_CONTRACT', 'ADDENDUM', 'DELIVERABLE_EVIDENCE', 'PAYMENT_EVIDENCE', 'OTHER');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "LegalCaseType" AS ENUM ('CONTRACT_BREACH', 'PAYMENT_RETENTION', 'UNJUST_SANCTION', 'CONTRACT_DISPUTE');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "LegalCaseSeverity" AS ENUM ('LOW', 'MEDIUM', 'HIGH');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "LegalCaseStatus" AS ENUM ('OPEN', 'IN_PROGRESS', 'ESCALATED', 'RESOLVED', 'CLOSED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "LegalJurisdictionLevel" AS ENUM ('FEDERAL', 'STATE', 'MUNICIPAL');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "AuditSimulationStatus" AS ENUM ('DRAFT', 'COMPLETED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "AuditSimulationSectionStatus" AS ENUM ('READY', 'WARNING', 'CRITICAL');
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "ContractRecord" (
|
||||
"id" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"sourceProposalId" TEXT,
|
||||
"title" TEXT NOT NULL,
|
||||
"counterpartyEntity" TEXT NOT NULL,
|
||||
"contractNumber" TEXT,
|
||||
"contractType" TEXT NOT NULL,
|
||||
"startDate" TIMESTAMP(3),
|
||||
"endDate" TIMESTAMP(3),
|
||||
"totalAmount" DECIMAL(14,2),
|
||||
"currency" TEXT NOT NULL DEFAULT 'MXN',
|
||||
"status" "ContractStatus" NOT NULL DEFAULT 'ACTIVE',
|
||||
"description" TEXT NOT NULL DEFAULT '',
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "ContractRecord_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "ContractDeliverable" (
|
||||
"id" TEXT NOT NULL,
|
||||
"contractId" TEXT NOT NULL,
|
||||
"title" TEXT NOT NULL,
|
||||
"dueDate" TIMESTAMP(3),
|
||||
"amountLinked" DECIMAL(14,2),
|
||||
"status" "ContractDeliverableStatus" NOT NULL DEFAULT 'PENDING',
|
||||
"deliveredAt" TIMESTAMP(3),
|
||||
"approvedAt" TIMESTAMP(3),
|
||||
"notes" TEXT NOT NULL DEFAULT '',
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "ContractDeliverable_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "ContractPayment" (
|
||||
"id" TEXT NOT NULL,
|
||||
"contractId" TEXT NOT NULL,
|
||||
"amount" DECIMAL(14,2) NOT NULL,
|
||||
"paymentDate" TIMESTAMP(3) NOT NULL,
|
||||
"invoiceNumber" TEXT,
|
||||
"concept" TEXT NOT NULL DEFAULT '',
|
||||
"status" "ContractPaymentStatus" NOT NULL DEFAULT 'REGISTERED',
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "ContractPayment_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "ContractDocument" (
|
||||
"id" TEXT NOT NULL,
|
||||
"contractId" TEXT NOT NULL,
|
||||
"fileName" TEXT NOT NULL,
|
||||
"filePath" TEXT NOT NULL,
|
||||
"mimeType" TEXT NOT NULL,
|
||||
"sizeBytes" INTEGER NOT NULL,
|
||||
"checksumSha256" TEXT,
|
||||
"kind" "ContractDocumentKind" NOT NULL DEFAULT 'OTHER',
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "ContractDocument_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "ContractExtractionHistory" (
|
||||
"id" TEXT NOT NULL,
|
||||
"contractId" TEXT,
|
||||
"userId" TEXT NOT NULL,
|
||||
"engine" TEXT NOT NULL,
|
||||
"model" TEXT,
|
||||
"resultJson" JSONB NOT NULL,
|
||||
"warningsJson" JSONB,
|
||||
"analyzedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "ContractExtractionHistory_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "LegalCase" (
|
||||
"id" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"contractId" TEXT,
|
||||
"caseType" "LegalCaseType" NOT NULL,
|
||||
"severity" "LegalCaseSeverity" NOT NULL,
|
||||
"counterparty" TEXT NOT NULL,
|
||||
"description" TEXT NOT NULL,
|
||||
"amountAtRisk" DECIMAL(14,2),
|
||||
"status" "LegalCaseStatus" NOT NULL DEFAULT 'OPEN',
|
||||
"openedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"resolvedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "LegalCase_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "LegalDiagnosis" (
|
||||
"id" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"legalCaseId" TEXT,
|
||||
"stepIndex" INTEGER NOT NULL DEFAULT 1,
|
||||
"totalSteps" INTEGER NOT NULL DEFAULT 4,
|
||||
"answersJson" JSONB NOT NULL,
|
||||
"recommendedRouteJson" JSONB NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "LegalDiagnosis_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "LegalEscalationStepLog" (
|
||||
"id" TEXT NOT NULL,
|
||||
"legalCaseId" TEXT NOT NULL,
|
||||
"routeStepKey" TEXT NOT NULL,
|
||||
"completedAt" TIMESTAMP(3),
|
||||
"notes" TEXT NOT NULL DEFAULT '',
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "LegalEscalationStepLog_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "LegalDocument" (
|
||||
"id" TEXT NOT NULL,
|
||||
"legalCaseId" TEXT,
|
||||
"userId" TEXT NOT NULL,
|
||||
"templateKey" TEXT,
|
||||
"aiGenerated" BOOLEAN NOT NULL DEFAULT false,
|
||||
"title" TEXT NOT NULL,
|
||||
"content" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "LegalDocument_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "LegalDirectoryEntity" (
|
||||
"id" TEXT NOT NULL,
|
||||
"jurisdictionLevel" "LegalJurisdictionLevel" NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"scopeTagsJson" JSONB NOT NULL,
|
||||
"websiteUrl" TEXT,
|
||||
"phone" TEXT,
|
||||
"email" TEXT,
|
||||
"stateCode" TEXT,
|
||||
"municipalityCode" TEXT,
|
||||
"isActive" BOOLEAN NOT NULL DEFAULT true,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "LegalDirectoryEntity_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "AuditSimulation" (
|
||||
"id" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"auditType" TEXT NOT NULL,
|
||||
"status" "AuditSimulationStatus" NOT NULL DEFAULT 'DRAFT',
|
||||
"overallScore" INTEGER,
|
||||
"completedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "AuditSimulation_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "AuditSimulationSection" (
|
||||
"id" TEXT NOT NULL,
|
||||
"simulationId" TEXT NOT NULL,
|
||||
"key" TEXT NOT NULL,
|
||||
"score" INTEGER,
|
||||
"status" "AuditSimulationSectionStatus" NOT NULL DEFAULT 'READY',
|
||||
"findingsJson" JSONB,
|
||||
"recommendationsJson" JSONB,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "AuditSimulationSection_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "AuditChecklistResponse" (
|
||||
"id" TEXT NOT NULL,
|
||||
"simulationId" TEXT NOT NULL,
|
||||
"questionKey" TEXT NOT NULL,
|
||||
"answer" TEXT NOT NULL,
|
||||
"evidenceRefsJson" JSONB,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "AuditChecklistResponse_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "InstitutionalDossierSnapshot" (
|
||||
"id" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"generatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"payloadJson" JSONB NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "InstitutionalDossierSnapshot_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ContractRecord_userId_status_endDate_idx" ON "ContractRecord"("userId", "status", "endDate");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ContractRecord_sourceProposalId_idx" ON "ContractRecord"("sourceProposalId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ContractRecord_updatedAt_idx" ON "ContractRecord"("updatedAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ContractDeliverable_contractId_status_dueDate_idx" ON "ContractDeliverable"("contractId", "status", "dueDate");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ContractDeliverable_dueDate_idx" ON "ContractDeliverable"("dueDate");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ContractPayment_contractId_paymentDate_idx" ON "ContractPayment"("contractId", "paymentDate");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ContractPayment_status_paymentDate_idx" ON "ContractPayment"("status", "paymentDate");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ContractDocument_contractId_kind_createdAt_idx" ON "ContractDocument"("contractId", "kind", "createdAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ContractExtractionHistory_userId_analyzedAt_idx" ON "ContractExtractionHistory"("userId", "analyzedAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ContractExtractionHistory_contractId_analyzedAt_idx" ON "ContractExtractionHistory"("contractId", "analyzedAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "LegalCase_userId_status_severity_idx" ON "LegalCase"("userId", "status", "severity");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "LegalCase_contractId_idx" ON "LegalCase"("contractId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "LegalDiagnosis_userId_updatedAt_idx" ON "LegalDiagnosis"("userId", "updatedAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "LegalDiagnosis_legalCaseId_idx" ON "LegalDiagnosis"("legalCaseId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "LegalEscalationStepLog_legalCaseId_routeStepKey_key" ON "LegalEscalationStepLog"("legalCaseId", "routeStepKey");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "LegalEscalationStepLog_legalCaseId_completedAt_idx" ON "LegalEscalationStepLog"("legalCaseId", "completedAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "LegalDocument_userId_createdAt_idx" ON "LegalDocument"("userId", "createdAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "LegalDocument_legalCaseId_createdAt_idx" ON "LegalDocument"("legalCaseId", "createdAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "LegalDirectoryEntity_jurisdictionLevel_isActive_idx" ON "LegalDirectoryEntity"("jurisdictionLevel", "isActive");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "LegalDirectoryEntity_stateCode_municipalityCode_isActive_idx" ON "LegalDirectoryEntity"("stateCode", "municipalityCode", "isActive");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "AuditSimulation_userId_status_updatedAt_idx" ON "AuditSimulation"("userId", "status", "updatedAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "AuditSimulationSection_simulationId_key_key" ON "AuditSimulationSection"("simulationId", "key");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "AuditSimulationSection_status_idx" ON "AuditSimulationSection"("status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "AuditChecklistResponse_simulationId_questionKey_idx" ON "AuditChecklistResponse"("simulationId", "questionKey");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "InstitutionalDossierSnapshot_userId_generatedAt_idx" ON "InstitutionalDossierSnapshot"("userId", "generatedAt");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ContractRecord" ADD CONSTRAINT "ContractRecord_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ContractRecord" ADD CONSTRAINT "ContractRecord_sourceProposalId_fkey" FOREIGN KEY ("sourceProposalId") REFERENCES "Proposal"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ContractDeliverable" ADD CONSTRAINT "ContractDeliverable_contractId_fkey" FOREIGN KEY ("contractId") REFERENCES "ContractRecord"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ContractPayment" ADD CONSTRAINT "ContractPayment_contractId_fkey" FOREIGN KEY ("contractId") REFERENCES "ContractRecord"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ContractDocument" ADD CONSTRAINT "ContractDocument_contractId_fkey" FOREIGN KEY ("contractId") REFERENCES "ContractRecord"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ContractExtractionHistory" ADD CONSTRAINT "ContractExtractionHistory_contractId_fkey" FOREIGN KEY ("contractId") REFERENCES "ContractRecord"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ContractExtractionHistory" ADD CONSTRAINT "ContractExtractionHistory_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "LegalCase" ADD CONSTRAINT "LegalCase_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "LegalCase" ADD CONSTRAINT "LegalCase_contractId_fkey" FOREIGN KEY ("contractId") REFERENCES "ContractRecord"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "LegalDiagnosis" ADD CONSTRAINT "LegalDiagnosis_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "LegalDiagnosis" ADD CONSTRAINT "LegalDiagnosis_legalCaseId_fkey" FOREIGN KEY ("legalCaseId") REFERENCES "LegalCase"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "LegalEscalationStepLog" ADD CONSTRAINT "LegalEscalationStepLog_legalCaseId_fkey" FOREIGN KEY ("legalCaseId") REFERENCES "LegalCase"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "LegalDocument" ADD CONSTRAINT "LegalDocument_legalCaseId_fkey" FOREIGN KEY ("legalCaseId") REFERENCES "LegalCase"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "LegalDocument" ADD CONSTRAINT "LegalDocument_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "AuditSimulation" ADD CONSTRAINT "AuditSimulation_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "AuditSimulationSection" ADD CONSTRAINT "AuditSimulationSection_simulationId_fkey" FOREIGN KEY ("simulationId") REFERENCES "AuditSimulation"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "AuditChecklistResponse" ADD CONSTRAINT "AuditChecklistResponse_simulationId_fkey" FOREIGN KEY ("simulationId") REFERENCES "AuditSimulation"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "InstitutionalDossierSnapshot" ADD CONSTRAINT "InstitutionalDossierSnapshot_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,9 @@
|
||||
-- Normalize index name across environments where Postgres truncated long identifiers.
|
||||
DO $$
|
||||
BEGIN
|
||||
IF to_regclass('"OfficialNormativeSuggestion_stateCode_municipalityCode_createdA"') IS NOT NULL
|
||||
AND to_regclass('"OfficialNormativeSuggestion_stateCode_municipalityCode_crea_idx"') IS NULL THEN
|
||||
ALTER INDEX "OfficialNormativeSuggestion_stateCode_municipalityCode_createdA"
|
||||
RENAME TO "OfficialNormativeSuggestion_stateCode_municipalityCode_crea_idx";
|
||||
END IF;
|
||||
END $$;
|
||||
@@ -0,0 +1,42 @@
|
||||
-- CreateEnum
|
||||
CREATE TYPE "AiSuggestionStatus" AS ENUM ('GENERATED', 'ACCEPTED', 'DISMISSED', 'EXPIRED');
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "AiSuggestion" (
|
||||
"id" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"moduleKey" TEXT NOT NULL,
|
||||
"featureKey" TEXT NOT NULL,
|
||||
"subjectType" TEXT NOT NULL,
|
||||
"subjectId" TEXT NOT NULL,
|
||||
"inputHash" TEXT NOT NULL,
|
||||
"requestJson" JSONB NOT NULL,
|
||||
"responseJson" JSONB NOT NULL,
|
||||
"confidence" DOUBLE PRECISION,
|
||||
"engine" TEXT NOT NULL,
|
||||
"model" TEXT,
|
||||
"usageJson" JSONB,
|
||||
"warningsJson" JSONB,
|
||||
"promptVersion" TEXT NOT NULL,
|
||||
"status" "AiSuggestionStatus" NOT NULL DEFAULT 'GENERATED',
|
||||
"actedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "AiSuggestion_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "ai_suggestion_dedupe" ON "AiSuggestion"("userId", "moduleKey", "featureKey", "subjectType", "subjectId", "inputHash");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "AiSuggestion_userId_moduleKey_featureKey_createdAt_idx" ON "AiSuggestion"("userId", "moduleKey", "featureKey", "createdAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "AiSuggestion_status_updatedAt_idx" ON "AiSuggestion"("status", "updatedAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "AiSuggestion_inputHash_idx" ON "AiSuggestion"("inputHash");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "AiSuggestion" ADD CONSTRAINT "AiSuggestion_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,69 @@
|
||||
-- CreateEnum
|
||||
CREATE TYPE "ModulePlanKey" AS ENUM ('PLAN_2_4', 'PLAN_5_7', 'PLAN_8_10');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "ModulePlanPurchaseStatus" AS ENUM ('PENDING', 'APPROVED', 'REJECTED', 'CANCELLED', 'EXPIRED');
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "ModulePlanPurchase" (
|
||||
"id" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"planKey" "ModulePlanKey" NOT NULL,
|
||||
"status" "ModulePlanPurchaseStatus" NOT NULL DEFAULT 'PENDING',
|
||||
"externalReference" TEXT NOT NULL,
|
||||
"mercadoPreferenceId" TEXT,
|
||||
"mercadoPaymentId" TEXT,
|
||||
"mercadoOrderId" TEXT,
|
||||
"checkoutUrl" TEXT,
|
||||
"amount" DECIMAL(14,2) NOT NULL,
|
||||
"currency" TEXT NOT NULL DEFAULT 'MXN',
|
||||
"requestJson" JSONB,
|
||||
"responseJson" JSONB,
|
||||
"approvedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "ModulePlanPurchase_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "ModulePlanSubscription" (
|
||||
"id" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"planKey" "ModulePlanKey" NOT NULL,
|
||||
"sourcePurchaseId" TEXT,
|
||||
"isActive" BOOLEAN NOT NULL DEFAULT true,
|
||||
"startsAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"expiresAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "ModulePlanSubscription_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "ModulePlanPurchase_externalReference_key" ON "ModulePlanPurchase"("externalReference");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ModulePlanPurchase_userId_planKey_createdAt_idx" ON "ModulePlanPurchase"("userId", "planKey", "createdAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ModulePlanPurchase_status_updatedAt_idx" ON "ModulePlanPurchase"("status", "updatedAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ModulePlanPurchase_mercadoPaymentId_idx" ON "ModulePlanPurchase"("mercadoPaymentId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "ModulePlanSubscription_userId_planKey_key" ON "ModulePlanSubscription"("userId", "planKey");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ModulePlanSubscription_userId_isActive_expiresAt_idx" ON "ModulePlanSubscription"("userId", "isActive", "expiresAt");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ModulePlanPurchase" ADD CONSTRAINT "ModulePlanPurchase_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ModulePlanSubscription" ADD CONSTRAINT "ModulePlanSubscription_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ModulePlanSubscription" ADD CONSTRAINT "ModulePlanSubscription_sourcePurchaseId_fkey" FOREIGN KEY ("sourcePurchaseId") REFERENCES "ModulePlanPurchase"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
@@ -60,6 +60,7 @@ enum LicitationSource {
|
||||
MUNICIPAL_OPEN_PORTAL
|
||||
PNT
|
||||
MUNICIPAL_BACKUP
|
||||
LICITAYA
|
||||
}
|
||||
|
||||
enum LicitationProcedureType {
|
||||
@@ -83,11 +84,151 @@ enum SyncRunStatus {
|
||||
FAILED
|
||||
}
|
||||
|
||||
enum ProposalStatus {
|
||||
DRAFT
|
||||
IN_PROGRESS
|
||||
SUBMITTED
|
||||
ARCHIVED
|
||||
}
|
||||
|
||||
enum LicitationReviewStatus {
|
||||
NEW
|
||||
REVIEWED
|
||||
INTERESTED
|
||||
DISCARDED
|
||||
}
|
||||
|
||||
enum NormativeDocumentType {
|
||||
BASES_LICITACION
|
||||
CONVOCATORIA
|
||||
REGLAMENTO
|
||||
LEY
|
||||
OTRO
|
||||
}
|
||||
|
||||
enum NormativeAnalysisMethod {
|
||||
DIRECT
|
||||
OCR
|
||||
}
|
||||
|
||||
enum NormativeConfidence {
|
||||
LOW
|
||||
MEDIUM
|
||||
HIGH
|
||||
}
|
||||
|
||||
enum NormativeRiskLevel {
|
||||
ALTO
|
||||
MEDIO
|
||||
BAJO
|
||||
}
|
||||
|
||||
enum OfficialNormativeSourceType {
|
||||
LEY
|
||||
REGLAMENTO
|
||||
LINEAMIENTO
|
||||
PORTAL
|
||||
}
|
||||
|
||||
enum NormativeVerificationStatus {
|
||||
SUCCESS
|
||||
WARNING
|
||||
FAILED
|
||||
}
|
||||
|
||||
enum MunicipalOpenPortalType {
|
||||
GENERIC
|
||||
SAN_PEDRO_ASPX
|
||||
}
|
||||
|
||||
enum ContractStatus {
|
||||
ACTIVE
|
||||
COMPLETED
|
||||
PAUSED
|
||||
CANCELLED
|
||||
}
|
||||
|
||||
enum ContractDeliverableStatus {
|
||||
PENDING
|
||||
DELIVERED
|
||||
APPROVED
|
||||
REJECTED
|
||||
OVERDUE
|
||||
}
|
||||
|
||||
enum ContractPaymentStatus {
|
||||
REGISTERED
|
||||
CONFIRMED
|
||||
DISPUTED
|
||||
}
|
||||
|
||||
enum ContractDocumentKind {
|
||||
SIGNED_CONTRACT
|
||||
ADDENDUM
|
||||
DELIVERABLE_EVIDENCE
|
||||
PAYMENT_EVIDENCE
|
||||
OTHER
|
||||
}
|
||||
|
||||
enum LegalCaseType {
|
||||
CONTRACT_BREACH
|
||||
PAYMENT_RETENTION
|
||||
UNJUST_SANCTION
|
||||
CONTRACT_DISPUTE
|
||||
}
|
||||
|
||||
enum LegalCaseSeverity {
|
||||
LOW
|
||||
MEDIUM
|
||||
HIGH
|
||||
}
|
||||
|
||||
enum LegalCaseStatus {
|
||||
OPEN
|
||||
IN_PROGRESS
|
||||
ESCALATED
|
||||
RESOLVED
|
||||
CLOSED
|
||||
}
|
||||
|
||||
enum LegalJurisdictionLevel {
|
||||
FEDERAL
|
||||
STATE
|
||||
MUNICIPAL
|
||||
}
|
||||
|
||||
enum AuditSimulationStatus {
|
||||
DRAFT
|
||||
COMPLETED
|
||||
}
|
||||
|
||||
enum AuditSimulationSectionStatus {
|
||||
READY
|
||||
WARNING
|
||||
CRITICAL
|
||||
}
|
||||
|
||||
enum AiSuggestionStatus {
|
||||
GENERATED
|
||||
ACCEPTED
|
||||
DISMISSED
|
||||
EXPIRED
|
||||
}
|
||||
|
||||
enum ModulePlanKey {
|
||||
PLAN_2_4
|
||||
PLAN_5_7
|
||||
PLAN_8_10
|
||||
}
|
||||
|
||||
enum ModulePlanPurchaseStatus {
|
||||
PENDING
|
||||
APPROVED
|
||||
REJECTED
|
||||
CANCELLED
|
||||
EXPIRED
|
||||
}
|
||||
|
||||
model User {
|
||||
id String @id @default(cuid())
|
||||
email String @unique
|
||||
@@ -103,9 +244,23 @@ model User {
|
||||
strategicDiagnosticEvidenceDocs StrategicDiagnosticEvidenceDocument[]
|
||||
workshopProgresses DevelopmentWorkshopProgress[]
|
||||
workshopEvidenceDocs DevelopmentWorkshopEvidence[]
|
||||
proposals Proposal[]
|
||||
proposalDocuments ProposalDocument[]
|
||||
licitationPreferences LicitationUserPreference[]
|
||||
normativeAnalyses NormativeAnalysisHistory[]
|
||||
contracts ContractRecord[]
|
||||
contractExtractionHistories ContractExtractionHistory[]
|
||||
legalCases LegalCase[]
|
||||
legalDiagnoses LegalDiagnosis[]
|
||||
legalDocuments LegalDocument[]
|
||||
auditSimulations AuditSimulation[]
|
||||
institutionalDossierSnapshots InstitutionalDossierSnapshot[]
|
||||
verificationTokens EmailVerificationToken[]
|
||||
responses Response[]
|
||||
results AssessmentResult[]
|
||||
aiSuggestions AiSuggestion[]
|
||||
modulePlanPurchases ModulePlanPurchase[]
|
||||
modulePlanSubscriptions ModulePlanSubscription[]
|
||||
}
|
||||
|
||||
model Organization {
|
||||
@@ -192,13 +347,13 @@ model StrategicDiagnosticEvidenceDocument {
|
||||
}
|
||||
|
||||
model DiagnosticModule {
|
||||
id String @id @default(cuid())
|
||||
key String @unique
|
||||
id String @id @default(cuid())
|
||||
key String @unique
|
||||
name String
|
||||
description String?
|
||||
sortOrder Int @default(0)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
sortOrder Int @default(0)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
questions Question[]
|
||||
results AssessmentResult[]
|
||||
recommendations Recommendation[]
|
||||
@@ -206,39 +361,39 @@ model DiagnosticModule {
|
||||
}
|
||||
|
||||
model DevelopmentWorkshop {
|
||||
id String @id @default(cuid())
|
||||
key String @unique
|
||||
moduleId String
|
||||
title String
|
||||
summary String
|
||||
videoUrl String
|
||||
durationMinutes Int @default(0)
|
||||
evidenceRequired String
|
||||
id String @id @default(cuid())
|
||||
key String @unique
|
||||
moduleId String
|
||||
title String
|
||||
summary String
|
||||
videoUrl String
|
||||
durationMinutes Int @default(0)
|
||||
evidenceRequired String
|
||||
learningObjectives Json?
|
||||
sortOrder Int @default(0)
|
||||
isActive Boolean @default(true)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
module DiagnosticModule @relation(fields: [moduleId], references: [id], onDelete: Cascade)
|
||||
progresses DevelopmentWorkshopProgress[]
|
||||
evidences DevelopmentWorkshopEvidence[]
|
||||
sortOrder Int @default(0)
|
||||
isActive Boolean @default(true)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
module DiagnosticModule @relation(fields: [moduleId], references: [id], onDelete: Cascade)
|
||||
progresses DevelopmentWorkshopProgress[]
|
||||
evidences DevelopmentWorkshopEvidence[]
|
||||
|
||||
@@index([moduleId, sortOrder])
|
||||
@@index([isActive, sortOrder])
|
||||
}
|
||||
|
||||
model DevelopmentWorkshopProgress {
|
||||
id String @id @default(cuid())
|
||||
id String @id @default(cuid())
|
||||
workshopId String
|
||||
userId String
|
||||
status WorkshopProgressStatus @default(NOT_STARTED)
|
||||
watchedAt DateTime?
|
||||
skippedAt DateTime?
|
||||
completedAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
workshop DevelopmentWorkshop @relation(fields: [workshopId], references: [id], onDelete: Cascade)
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
workshop DevelopmentWorkshop @relation(fields: [workshopId], references: [id], onDelete: Cascade)
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([workshopId, userId])
|
||||
@@index([userId, status])
|
||||
@@ -384,6 +539,48 @@ model EmailVerificationToken {
|
||||
@@index([expiresAt])
|
||||
}
|
||||
|
||||
model ModulePlanPurchase {
|
||||
id String @id @default(cuid())
|
||||
userId String
|
||||
planKey ModulePlanKey
|
||||
status ModulePlanPurchaseStatus @default(PENDING)
|
||||
externalReference String @unique
|
||||
mercadoPreferenceId String?
|
||||
mercadoPaymentId String?
|
||||
mercadoOrderId String?
|
||||
checkoutUrl String?
|
||||
amount Decimal @db.Decimal(14, 2)
|
||||
currency String @default("MXN")
|
||||
requestJson Json?
|
||||
responseJson Json?
|
||||
approvedAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
subscriptions ModulePlanSubscription[]
|
||||
|
||||
@@index([userId, planKey, createdAt])
|
||||
@@index([status, updatedAt])
|
||||
@@index([mercadoPaymentId])
|
||||
}
|
||||
|
||||
model ModulePlanSubscription {
|
||||
id String @id @default(cuid())
|
||||
userId String
|
||||
planKey ModulePlanKey
|
||||
sourcePurchaseId String?
|
||||
isActive Boolean @default(true)
|
||||
startsAt DateTime @default(now())
|
||||
expiresAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
sourcePurchase ModulePlanPurchase? @relation(fields: [sourcePurchaseId], references: [id], onDelete: SetNull)
|
||||
|
||||
@@unique([userId, planKey])
|
||||
@@index([userId, isActive, expiresAt])
|
||||
}
|
||||
|
||||
model Municipality {
|
||||
id String @id @default(cuid())
|
||||
stateCode String
|
||||
@@ -412,31 +609,33 @@ model Municipality {
|
||||
}
|
||||
|
||||
model Licitation {
|
||||
id String @id @default(cuid())
|
||||
municipalityId String
|
||||
source LicitationSource
|
||||
sourceRecordId String
|
||||
tenderCode String?
|
||||
procedureType LicitationProcedureType @default(UNKNOWN)
|
||||
title String
|
||||
description String?
|
||||
category LicitationCategory? @default(UNKNOWN)
|
||||
isOpen Boolean @default(true)
|
||||
openingDate DateTime?
|
||||
closingDate DateTime?
|
||||
publishDate DateTime?
|
||||
eventDates Json?
|
||||
amount Decimal? @db.Decimal(14, 2)
|
||||
currency String?
|
||||
status String?
|
||||
supplierAwarded String?
|
||||
documents Json?
|
||||
rawSourceUrl String?
|
||||
rawPayload Json
|
||||
lastSeenAt DateTime @default(now())
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
municipality Municipality @relation(fields: [municipalityId], references: [id], onDelete: Cascade)
|
||||
id String @id @default(cuid())
|
||||
municipalityId String
|
||||
source LicitationSource
|
||||
sourceRecordId String
|
||||
tenderCode String?
|
||||
procedureType LicitationProcedureType @default(UNKNOWN)
|
||||
title String
|
||||
description String?
|
||||
category LicitationCategory? @default(UNKNOWN)
|
||||
isOpen Boolean @default(true)
|
||||
openingDate DateTime?
|
||||
closingDate DateTime?
|
||||
publishDate DateTime?
|
||||
eventDates Json?
|
||||
amount Decimal? @db.Decimal(14, 2)
|
||||
currency String?
|
||||
status String?
|
||||
supplierAwarded String?
|
||||
documents Json?
|
||||
rawSourceUrl String?
|
||||
rawPayload Json
|
||||
lastSeenAt DateTime @default(now())
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
municipality Municipality @relation(fields: [municipalityId], references: [id], onDelete: Cascade)
|
||||
userPreferences LicitationUserPreference[]
|
||||
normativeAnalyses NormativeAnalysisHistory[]
|
||||
|
||||
@@unique([municipalityId, source, sourceRecordId])
|
||||
@@index([municipalityId, isOpen, closingDate])
|
||||
@@ -475,3 +674,400 @@ model CompanyProfile {
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
organization Organization? @relation(fields: [organizationId], references: [id], onDelete: SetNull)
|
||||
}
|
||||
|
||||
model LicitationUserPreference {
|
||||
id String @id @default(cuid())
|
||||
userId String
|
||||
licitationId String
|
||||
status LicitationReviewStatus @default(NEW)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
licitation Licitation @relation(fields: [licitationId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([userId, licitationId])
|
||||
@@index([userId, status])
|
||||
@@index([licitationId, status])
|
||||
}
|
||||
|
||||
model NormativeAnalysisHistory {
|
||||
id String @id @default(cuid())
|
||||
userId String
|
||||
sourceLicitationId String?
|
||||
fileName String
|
||||
documentType NormativeDocumentType
|
||||
issuingEntity String?
|
||||
methodUsed NormativeAnalysisMethod
|
||||
numPages Int
|
||||
warnings Json?
|
||||
extractedChars Int
|
||||
confidence NormativeConfidence
|
||||
viabilityScore Int
|
||||
riskLevel NormativeRiskLevel
|
||||
executiveSummary String
|
||||
result Json
|
||||
analyzedAt DateTime @default(now())
|
||||
deletedAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
sourceLicitation Licitation? @relation(fields: [sourceLicitationId], references: [id], onDelete: SetNull)
|
||||
|
||||
@@index([userId, analyzedAt])
|
||||
@@index([userId, deletedAt])
|
||||
@@index([sourceLicitationId])
|
||||
}
|
||||
|
||||
model Proposal {
|
||||
id String @id @default(cuid())
|
||||
userId String
|
||||
sourceLicitationId String?
|
||||
title String
|
||||
issuingEntity String
|
||||
summary String @default("")
|
||||
workflowDraft Json?
|
||||
currentStep Int @default(1)
|
||||
completionPercent Int @default(0)
|
||||
readyForSubmissionAt DateTime?
|
||||
status ProposalStatus @default(DRAFT)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
documents ProposalDocument[]
|
||||
contracts ContractRecord[]
|
||||
|
||||
@@index([userId, status])
|
||||
@@index([updatedAt])
|
||||
@@index([sourceLicitationId])
|
||||
}
|
||||
|
||||
model ContractRecord {
|
||||
id String @id @default(cuid())
|
||||
userId String
|
||||
sourceProposalId String?
|
||||
title String
|
||||
counterpartyEntity String
|
||||
contractNumber String?
|
||||
contractType String
|
||||
startDate DateTime?
|
||||
endDate DateTime?
|
||||
totalAmount Decimal? @db.Decimal(14, 2)
|
||||
currency String @default("MXN")
|
||||
status ContractStatus @default(ACTIVE)
|
||||
description String @default("")
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
sourceProposal Proposal? @relation(fields: [sourceProposalId], references: [id], onDelete: SetNull)
|
||||
deliverables ContractDeliverable[]
|
||||
payments ContractPayment[]
|
||||
documents ContractDocument[]
|
||||
extractions ContractExtractionHistory[]
|
||||
legalCases LegalCase[]
|
||||
|
||||
@@index([userId, status, endDate])
|
||||
@@index([sourceProposalId])
|
||||
@@index([updatedAt])
|
||||
}
|
||||
|
||||
model ContractDeliverable {
|
||||
id String @id @default(cuid())
|
||||
contractId String
|
||||
title String
|
||||
dueDate DateTime?
|
||||
amountLinked Decimal? @db.Decimal(14, 2)
|
||||
status ContractDeliverableStatus @default(PENDING)
|
||||
deliveredAt DateTime?
|
||||
approvedAt DateTime?
|
||||
notes String @default("")
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
contract ContractRecord @relation(fields: [contractId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@index([contractId, status, dueDate])
|
||||
@@index([dueDate])
|
||||
}
|
||||
|
||||
model ContractPayment {
|
||||
id String @id @default(cuid())
|
||||
contractId String
|
||||
amount Decimal @db.Decimal(14, 2)
|
||||
paymentDate DateTime
|
||||
invoiceNumber String?
|
||||
concept String @default("")
|
||||
status ContractPaymentStatus @default(REGISTERED)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
contract ContractRecord @relation(fields: [contractId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@index([contractId, paymentDate])
|
||||
@@index([status, paymentDate])
|
||||
}
|
||||
|
||||
model ContractDocument {
|
||||
id String @id @default(cuid())
|
||||
contractId String
|
||||
fileName String
|
||||
filePath String
|
||||
mimeType String
|
||||
sizeBytes Int
|
||||
checksumSha256 String?
|
||||
kind ContractDocumentKind @default(OTHER)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
contract ContractRecord @relation(fields: [contractId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@index([contractId, kind, createdAt])
|
||||
}
|
||||
|
||||
model ContractExtractionHistory {
|
||||
id String @id @default(cuid())
|
||||
contractId String?
|
||||
userId String
|
||||
engine String
|
||||
model String?
|
||||
resultJson Json
|
||||
warningsJson Json?
|
||||
analyzedAt DateTime @default(now())
|
||||
createdAt DateTime @default(now())
|
||||
contract ContractRecord? @relation(fields: [contractId], references: [id], onDelete: SetNull)
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@index([userId, analyzedAt])
|
||||
@@index([contractId, analyzedAt])
|
||||
}
|
||||
|
||||
model LegalCase {
|
||||
id String @id @default(cuid())
|
||||
userId String
|
||||
contractId String?
|
||||
caseType LegalCaseType
|
||||
severity LegalCaseSeverity
|
||||
counterparty String
|
||||
description String
|
||||
amountAtRisk Decimal? @db.Decimal(14, 2)
|
||||
status LegalCaseStatus @default(OPEN)
|
||||
openedAt DateTime @default(now())
|
||||
resolvedAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
contract ContractRecord? @relation(fields: [contractId], references: [id], onDelete: SetNull)
|
||||
diagnoses LegalDiagnosis[]
|
||||
escalationLogs LegalEscalationStepLog[]
|
||||
documents LegalDocument[]
|
||||
|
||||
@@index([userId, status, severity])
|
||||
@@index([contractId])
|
||||
}
|
||||
|
||||
model LegalDiagnosis {
|
||||
id String @id @default(cuid())
|
||||
userId String
|
||||
legalCaseId String?
|
||||
stepIndex Int @default(1)
|
||||
totalSteps Int @default(4)
|
||||
answersJson Json
|
||||
recommendedRouteJson Json
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
legalCase LegalCase? @relation(fields: [legalCaseId], references: [id], onDelete: SetNull)
|
||||
|
||||
@@index([userId, updatedAt])
|
||||
@@index([legalCaseId])
|
||||
}
|
||||
|
||||
model LegalEscalationStepLog {
|
||||
id String @id @default(cuid())
|
||||
legalCaseId String
|
||||
routeStepKey String
|
||||
completedAt DateTime?
|
||||
notes String @default("")
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
legalCase LegalCase @relation(fields: [legalCaseId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([legalCaseId, routeStepKey])
|
||||
@@index([legalCaseId, completedAt])
|
||||
}
|
||||
|
||||
model LegalDocument {
|
||||
id String @id @default(cuid())
|
||||
legalCaseId String?
|
||||
userId String
|
||||
templateKey String?
|
||||
aiGenerated Boolean @default(false)
|
||||
title String
|
||||
content String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
legalCase LegalCase? @relation(fields: [legalCaseId], references: [id], onDelete: SetNull)
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@index([userId, createdAt])
|
||||
@@index([legalCaseId, createdAt])
|
||||
}
|
||||
|
||||
model LegalDirectoryEntity {
|
||||
id String @id @default(cuid())
|
||||
jurisdictionLevel LegalJurisdictionLevel
|
||||
name String
|
||||
scopeTagsJson Json
|
||||
websiteUrl String?
|
||||
phone String?
|
||||
email String?
|
||||
stateCode String?
|
||||
municipalityCode String?
|
||||
isActive Boolean @default(true)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([jurisdictionLevel, isActive])
|
||||
@@index([stateCode, municipalityCode, isActive])
|
||||
}
|
||||
|
||||
model AuditSimulation {
|
||||
id String @id @default(cuid())
|
||||
userId String
|
||||
name String
|
||||
auditType String
|
||||
status AuditSimulationStatus @default(DRAFT)
|
||||
overallScore Int?
|
||||
completedAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
sections AuditSimulationSection[]
|
||||
responses AuditChecklistResponse[]
|
||||
|
||||
@@index([userId, status, updatedAt])
|
||||
}
|
||||
|
||||
model AuditSimulationSection {
|
||||
id String @id @default(cuid())
|
||||
simulationId String
|
||||
key String
|
||||
score Int?
|
||||
status AuditSimulationSectionStatus @default(READY)
|
||||
findingsJson Json?
|
||||
recommendationsJson Json?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
simulation AuditSimulation @relation(fields: [simulationId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([simulationId, key])
|
||||
@@index([status])
|
||||
}
|
||||
|
||||
model AuditChecklistResponse {
|
||||
id String @id @default(cuid())
|
||||
simulationId String
|
||||
questionKey String
|
||||
answer String
|
||||
evidenceRefsJson Json?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
simulation AuditSimulation @relation(fields: [simulationId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@index([simulationId, questionKey])
|
||||
}
|
||||
|
||||
model InstitutionalDossierSnapshot {
|
||||
id String @id @default(cuid())
|
||||
userId String
|
||||
generatedAt DateTime @default(now())
|
||||
payloadJson Json
|
||||
createdAt DateTime @default(now())
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@index([userId, generatedAt])
|
||||
}
|
||||
|
||||
model ProposalDocument {
|
||||
id String @id @default(cuid())
|
||||
proposalId String
|
||||
userId String
|
||||
fileName String
|
||||
storedFileName String
|
||||
filePath String
|
||||
mimeType String
|
||||
sizeBytes Int
|
||||
checksumSha256 String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
proposal Proposal @relation(fields: [proposalId], references: [id], onDelete: Cascade)
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@index([proposalId, createdAt])
|
||||
@@index([userId, createdAt])
|
||||
}
|
||||
|
||||
model OfficialNormativeSource {
|
||||
id String @id
|
||||
stateCode String
|
||||
stateName String
|
||||
municipalityCode String?
|
||||
municipalityName String?
|
||||
authorityName String
|
||||
title String
|
||||
officialUrl String
|
||||
sourceType OfficialNormativeSourceType
|
||||
versionLabel String?
|
||||
isPilot Boolean @default(false)
|
||||
lastKnownHash String?
|
||||
lastVerifiedAt DateTime?
|
||||
nextCheckAt DateTime?
|
||||
lastStatus NormativeVerificationStatus?
|
||||
lastMessage String?
|
||||
lastChangedAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([stateCode, municipalityCode, isPilot])
|
||||
@@index([nextCheckAt])
|
||||
@@index([lastStatus, lastVerifiedAt])
|
||||
}
|
||||
|
||||
model OfficialNormativeSuggestion {
|
||||
id String @id @default(cuid())
|
||||
stateCode String
|
||||
municipalityCode String?
|
||||
authorityName String
|
||||
title String
|
||||
officialUrl String
|
||||
sourceType OfficialNormativeSourceType
|
||||
notes String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([stateCode, municipalityCode, createdAt])
|
||||
}
|
||||
|
||||
model AiSuggestion {
|
||||
id String @id @default(cuid())
|
||||
userId String
|
||||
moduleKey String
|
||||
featureKey String
|
||||
subjectType String
|
||||
subjectId String
|
||||
inputHash String
|
||||
requestJson Json
|
||||
responseJson Json
|
||||
confidence Float?
|
||||
engine String
|
||||
model String?
|
||||
usageJson Json?
|
||||
warningsJson Json?
|
||||
promptVersion String
|
||||
status AiSuggestionStatus @default(GENERATED)
|
||||
actedAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([userId, moduleKey, featureKey, subjectType, subjectId, inputHash], map: "ai_suggestion_dedupe")
|
||||
@@index([userId, moduleKey, featureKey, createdAt])
|
||||
@@index([status, updatedAt])
|
||||
@@index([inputHash])
|
||||
}
|
||||
|
||||
140
prisma/seed.mjs
140
prisma/seed.mjs
@@ -1,4 +1,4 @@
|
||||
import { PrismaClient, ContentPageType, OverallScoreMethod, PriorityLevel } from "@prisma/client";
|
||||
import { PrismaClient, ContentPageType, LegalJurisdictionLevel, OverallScoreMethod, PriorityLevel } from "@prisma/client";
|
||||
import { readFile } from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
@@ -389,6 +389,99 @@ const contentPageSeeds = [
|
||||
},
|
||||
];
|
||||
|
||||
const legalDirectorySeeds = [
|
||||
{
|
||||
jurisdictionLevel: LegalJurisdictionLevel.FEDERAL,
|
||||
name: "Secretaria de la Funcion Publica (SFP)",
|
||||
scopeTagsJson: ["inconformidades", "sanciones", "organo-interno-control"],
|
||||
websiteUrl: "https://www.gob.mx/sfp",
|
||||
phone: null,
|
||||
email: null,
|
||||
stateCode: null,
|
||||
municipalityCode: null,
|
||||
},
|
||||
{
|
||||
jurisdictionLevel: LegalJurisdictionLevel.FEDERAL,
|
||||
name: "Tribunal Federal de Justicia Administrativa (TFJA)",
|
||||
scopeTagsJson: ["juicio-contencioso", "nulidad", "sanciones-administrativas"],
|
||||
websiteUrl: "https://www.tfja.gob.mx",
|
||||
phone: null,
|
||||
email: null,
|
||||
stateCode: null,
|
||||
municipalityCode: null,
|
||||
},
|
||||
{
|
||||
jurisdictionLevel: LegalJurisdictionLevel.FEDERAL,
|
||||
name: "Auditoria Superior de la Federacion (ASF)",
|
||||
scopeTagsJson: ["auditoria", "fiscalizacion", "cuenta-publica"],
|
||||
websiteUrl: "https://www.asf.gob.mx",
|
||||
phone: null,
|
||||
email: null,
|
||||
stateCode: null,
|
||||
municipalityCode: null,
|
||||
},
|
||||
{
|
||||
jurisdictionLevel: LegalJurisdictionLevel.FEDERAL,
|
||||
name: "CompraNet",
|
||||
scopeTagsJson: ["contrataciones", "licitaciones", "expedientes"],
|
||||
websiteUrl: "https://compranet.hacienda.gob.mx",
|
||||
phone: null,
|
||||
email: null,
|
||||
stateCode: null,
|
||||
municipalityCode: null,
|
||||
},
|
||||
{
|
||||
jurisdictionLevel: LegalJurisdictionLevel.FEDERAL,
|
||||
name: "Sistema Nacional Anticorrupcion",
|
||||
scopeTagsJson: ["anticorrupcion", "denuncias", "integridad"],
|
||||
websiteUrl: "https://www.sna.org.mx",
|
||||
phone: null,
|
||||
email: null,
|
||||
stateCode: null,
|
||||
municipalityCode: null,
|
||||
},
|
||||
{
|
||||
jurisdictionLevel: LegalJurisdictionLevel.STATE,
|
||||
name: "Secretaria de la Contraloria y Transparencia Gubernamental de Nuevo Leon",
|
||||
scopeTagsJson: ["inconformidades", "contraloria", "responsabilidades"],
|
||||
websiteUrl: "https://www.nl.gob.mx/dependencias/contraloria",
|
||||
phone: null,
|
||||
email: null,
|
||||
stateCode: "NL",
|
||||
municipalityCode: null,
|
||||
},
|
||||
{
|
||||
jurisdictionLevel: LegalJurisdictionLevel.STATE,
|
||||
name: "Tribunal de Justicia Administrativa de Nuevo Leon",
|
||||
scopeTagsJson: ["juicio-administrativo", "sanciones", "nulidad"],
|
||||
websiteUrl: "https://tjanl.gob.mx",
|
||||
phone: null,
|
||||
email: null,
|
||||
stateCode: "NL",
|
||||
municipalityCode: null,
|
||||
},
|
||||
{
|
||||
jurisdictionLevel: LegalJurisdictionLevel.STATE,
|
||||
name: "Auditoria Superior del Estado de Nuevo Leon",
|
||||
scopeTagsJson: ["auditoria", "fiscalizacion", "cuenta-publica-estatal"],
|
||||
websiteUrl: "https://www.asenl.gob.mx",
|
||||
phone: null,
|
||||
email: null,
|
||||
stateCode: "NL",
|
||||
municipalityCode: null,
|
||||
},
|
||||
{
|
||||
jurisdictionLevel: LegalJurisdictionLevel.STATE,
|
||||
name: "Sistema Estatal Anticorrupcion de Nuevo Leon",
|
||||
scopeTagsJson: ["anticorrupcion", "politica-estatal", "coordinacion"],
|
||||
websiteUrl: "https://www.seanl.mx",
|
||||
phone: null,
|
||||
email: null,
|
||||
stateCode: "NL",
|
||||
municipalityCode: null,
|
||||
},
|
||||
];
|
||||
|
||||
async function upsertDiagnosticStructure() {
|
||||
const moduleKeys = moduleSeeds.map((moduleSeed) => moduleSeed.key);
|
||||
|
||||
@@ -605,6 +698,48 @@ async function upsertDefaultScoringConfig() {
|
||||
});
|
||||
}
|
||||
|
||||
async function upsertLegalDirectory() {
|
||||
for (const item of legalDirectorySeeds) {
|
||||
const existing = await prisma.legalDirectoryEntity.findFirst({
|
||||
where: {
|
||||
jurisdictionLevel: item.jurisdictionLevel,
|
||||
name: item.name,
|
||||
stateCode: item.stateCode,
|
||||
municipalityCode: item.municipalityCode,
|
||||
},
|
||||
select: { id: true },
|
||||
});
|
||||
|
||||
if (existing) {
|
||||
await prisma.legalDirectoryEntity.update({
|
||||
where: { id: existing.id },
|
||||
data: {
|
||||
scopeTagsJson: item.scopeTagsJson,
|
||||
websiteUrl: item.websiteUrl,
|
||||
phone: item.phone,
|
||||
email: item.email,
|
||||
isActive: true,
|
||||
},
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
await prisma.legalDirectoryEntity.create({
|
||||
data: {
|
||||
jurisdictionLevel: item.jurisdictionLevel,
|
||||
name: item.name,
|
||||
scopeTagsJson: item.scopeTagsJson,
|
||||
websiteUrl: item.websiteUrl,
|
||||
phone: item.phone,
|
||||
email: item.email,
|
||||
stateCode: item.stateCode,
|
||||
municipalityCode: item.municipalityCode,
|
||||
isActive: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function loadMunicipalitySeeds() {
|
||||
const filePath = path.join(__dirname, "data", "municipalities.json");
|
||||
const content = await readFile(filePath, "utf-8");
|
||||
@@ -697,6 +832,7 @@ async function main() {
|
||||
await upsertRecommendations();
|
||||
await upsertContentPages();
|
||||
await upsertDefaultScoringConfig();
|
||||
await upsertLegalDirectory();
|
||||
const municipalitySeedCount = await upsertMunicipalities();
|
||||
|
||||
const moduleCount = await prisma.diagnosticModule.count();
|
||||
@@ -705,6 +841,7 @@ async function main() {
|
||||
const workshopCount = await prisma.developmentWorkshop.count();
|
||||
const recommendationCount = await prisma.recommendation.count();
|
||||
const contentPageCount = await prisma.contentPage.count();
|
||||
const legalDirectoryCount = await prisma.legalDirectoryEntity.count({ where: { isActive: true } });
|
||||
const municipalityCount = await prisma.municipality.count({ where: { isActive: true } });
|
||||
|
||||
console.log("Seed completed", {
|
||||
@@ -714,6 +851,7 @@ async function main() {
|
||||
workshops: workshopCount,
|
||||
recommendations: recommendationCount,
|
||||
contentPages: contentPageCount,
|
||||
legalDirectory: legalDirectoryCount,
|
||||
municipalities: municipalityCount,
|
||||
municipalitySeedsProcessed: municipalitySeedCount,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user