1074 lines
33 KiB
Plaintext
1074 lines
33 KiB
Plaintext
generator client {
|
|
provider = "prisma-client-js"
|
|
}
|
|
|
|
datasource db {
|
|
provider = "postgresql"
|
|
url = env("DATABASE_URL")
|
|
}
|
|
|
|
enum PriorityLevel {
|
|
LOW
|
|
MEDIUM
|
|
HIGH
|
|
}
|
|
|
|
enum UserRole {
|
|
USER
|
|
ADMIN
|
|
}
|
|
|
|
enum ContentPageType {
|
|
FAQ
|
|
MANUAL
|
|
}
|
|
|
|
enum OverallScoreMethod {
|
|
EQUAL_ALL_MODULES
|
|
EQUAL_ANSWERED_MODULES
|
|
WEIGHTED_ANSWERED_MODULES
|
|
}
|
|
|
|
enum OrganizationDocumentType {
|
|
ACTA_CONSTITUTIVA
|
|
}
|
|
|
|
enum StrategicDiagnosticEvidenceSection {
|
|
TECHNICAL
|
|
EXPERIENCE
|
|
ORGANIZATION
|
|
PUBLIC_PROCUREMENT
|
|
}
|
|
|
|
enum WorkshopProgressStatus {
|
|
NOT_STARTED
|
|
WATCHED
|
|
EVIDENCE_SUBMITTED
|
|
APPROVED
|
|
REJECTED
|
|
SKIPPED
|
|
}
|
|
|
|
enum WorkshopEvidenceValidationStatus {
|
|
PENDING
|
|
APPROVED
|
|
REJECTED
|
|
ERROR
|
|
}
|
|
|
|
enum LicitationSource {
|
|
MUNICIPAL_OPEN_PORTAL
|
|
PNT
|
|
MUNICIPAL_BACKUP
|
|
LICITAYA
|
|
}
|
|
|
|
enum LicitationProcedureType {
|
|
LICITACION_PUBLICA
|
|
INVITACION_RESTRINGIDA
|
|
ADJUDICACION_DIRECTA
|
|
UNKNOWN
|
|
}
|
|
|
|
enum LicitationCategory {
|
|
GOODS
|
|
SERVICES
|
|
WORKS
|
|
MIXED
|
|
UNKNOWN
|
|
}
|
|
|
|
enum SyncRunStatus {
|
|
SUCCESS
|
|
PARTIAL
|
|
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
|
|
passwordHash String
|
|
name String?
|
|
role UserRole @default(USER)
|
|
emailVerifiedAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
organization Organization?
|
|
companyProfile CompanyProfile?
|
|
organizationDocs OrganizationDocument[]
|
|
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 {
|
|
id String @id @default(cuid())
|
|
userId String @unique
|
|
name String
|
|
tradeName String?
|
|
rfc String?
|
|
legalRepresentative String?
|
|
incorporationDate String?
|
|
deedNumber String?
|
|
notaryName String?
|
|
stateOfIncorporation String?
|
|
companyType String?
|
|
fiscalAddress String?
|
|
businessPurpose String?
|
|
industry String?
|
|
operatingState String?
|
|
municipality String?
|
|
companySize String?
|
|
yearsOfOperation String?
|
|
annualRevenueRange String?
|
|
hasGovernmentContracts Boolean?
|
|
country String?
|
|
primaryObjective String?
|
|
actaExtractedData Json?
|
|
actaLookupDictionary Json?
|
|
actaUploadedAt DateTime?
|
|
onboardingCompletedAt DateTime?
|
|
strategicDiagnosticData Json?
|
|
strategicDiagnosticScores Json?
|
|
strategicDiagnosticCompletedAt DateTime?
|
|
companyProfile CompanyProfile?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
documents OrganizationDocument[]
|
|
strategicDiagnosticEvidenceDocs StrategicDiagnosticEvidenceDocument[]
|
|
}
|
|
|
|
model OrganizationDocument {
|
|
id String @id @default(cuid())
|
|
organizationId String
|
|
userId String
|
|
type OrganizationDocumentType
|
|
fileName String
|
|
storedFileName String
|
|
filePath String
|
|
mimeType String
|
|
sizeBytes Int
|
|
checksumSha256 String?
|
|
extractedData Json?
|
|
extractedTextSnippet String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([organizationId, type])
|
|
@@unique([userId, type])
|
|
@@index([type])
|
|
}
|
|
|
|
model StrategicDiagnosticEvidenceDocument {
|
|
id String @id @default(cuid())
|
|
organizationId String
|
|
userId String
|
|
section StrategicDiagnosticEvidenceSection
|
|
category String
|
|
fileName String
|
|
storedFileName String
|
|
filePath String
|
|
mimeType String
|
|
sizeBytes Int
|
|
checksumSha256 String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([organizationId, section])
|
|
@@index([userId, section])
|
|
@@index([createdAt])
|
|
}
|
|
|
|
model DiagnosticModule {
|
|
id String @id @default(cuid())
|
|
key String @unique
|
|
name String
|
|
description String?
|
|
sortOrder Int @default(0)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
questions Question[]
|
|
results AssessmentResult[]
|
|
recommendations Recommendation[]
|
|
workshops DevelopmentWorkshop[]
|
|
}
|
|
|
|
model DevelopmentWorkshop {
|
|
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[]
|
|
|
|
@@index([moduleId, sortOrder])
|
|
@@index([isActive, sortOrder])
|
|
}
|
|
|
|
model DevelopmentWorkshopProgress {
|
|
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)
|
|
|
|
@@unique([workshopId, userId])
|
|
@@index([userId, status])
|
|
@@index([workshopId, status])
|
|
}
|
|
|
|
model DevelopmentWorkshopEvidence {
|
|
id String @id @default(cuid())
|
|
workshopId String
|
|
userId String
|
|
validationStatus WorkshopEvidenceValidationStatus @default(PENDING)
|
|
validationReason String?
|
|
validationConfidence Float?
|
|
validatedAt DateTime?
|
|
fileName String
|
|
storedFileName String
|
|
filePath String
|
|
mimeType String
|
|
sizeBytes Int
|
|
checksumSha256 String?
|
|
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)
|
|
|
|
@@index([userId, workshopId, createdAt])
|
|
@@index([workshopId, validationStatus])
|
|
}
|
|
|
|
model Question {
|
|
id String @id @default(cuid())
|
|
key String @unique
|
|
moduleId String
|
|
prompt String
|
|
helpText String?
|
|
sortOrder Int @default(0)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
module DiagnosticModule @relation(fields: [moduleId], references: [id], onDelete: Cascade)
|
|
answerOptions AnswerOption[]
|
|
responses Response[]
|
|
|
|
@@index([moduleId, sortOrder])
|
|
}
|
|
|
|
model AnswerOption {
|
|
id String @id @default(cuid())
|
|
key String @unique
|
|
questionId String
|
|
label String
|
|
weight Int
|
|
sortOrder Int @default(0)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
question Question @relation(fields: [questionId], references: [id], onDelete: Cascade)
|
|
responses Response[]
|
|
|
|
@@index([questionId, sortOrder])
|
|
}
|
|
|
|
model Response {
|
|
id String @id @default(cuid())
|
|
userId String
|
|
questionId String
|
|
answerOptionId String
|
|
evidence Json?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
question Question @relation(fields: [questionId], references: [id], onDelete: Cascade)
|
|
answerOption AnswerOption @relation(fields: [answerOptionId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([userId, questionId])
|
|
@@index([userId])
|
|
}
|
|
|
|
model AssessmentResult {
|
|
id String @id @default(cuid())
|
|
userId String
|
|
moduleId String?
|
|
overallScore Float?
|
|
moduleScore Float?
|
|
metadata Json?
|
|
calculatedAt DateTime @default(now())
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
module DiagnosticModule? @relation(fields: [moduleId], references: [id], onDelete: SetNull)
|
|
|
|
@@index([userId, calculatedAt])
|
|
@@index([moduleId])
|
|
}
|
|
|
|
model Recommendation {
|
|
id String @id @default(cuid())
|
|
key String @unique
|
|
moduleId String?
|
|
title String
|
|
description String
|
|
priority PriorityLevel @default(MEDIUM)
|
|
isTemplate Boolean @default(true)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
module DiagnosticModule? @relation(fields: [moduleId], references: [id], onDelete: SetNull)
|
|
|
|
@@index([moduleId])
|
|
}
|
|
|
|
model ContentPage {
|
|
id String @id @default(cuid())
|
|
type ContentPageType
|
|
slug String @unique
|
|
title String
|
|
content String
|
|
sortOrder Int @default(0)
|
|
isPublished Boolean @default(true)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@index([type, sortOrder])
|
|
}
|
|
|
|
model ScoringConfig {
|
|
id String @id @default(cuid())
|
|
key String @unique
|
|
lowScoreThreshold Int @default(70)
|
|
overallScoreMethod OverallScoreMethod @default(EQUAL_ALL_MODULES)
|
|
moduleWeights Json?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
}
|
|
|
|
model EmailVerificationToken {
|
|
id String @id @default(cuid())
|
|
userId String
|
|
token String @unique
|
|
expiresAt DateTime
|
|
consumedAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([userId])
|
|
@@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
|
|
stateName String
|
|
municipalityCode String
|
|
municipalityName String
|
|
openPortalUrl String?
|
|
openPortalType MunicipalOpenPortalType @default(GENERIC)
|
|
openSyncIntervalDays Int @default(7)
|
|
lastOpenSyncAt DateTime?
|
|
pntSubjectId String?
|
|
pntEntityId String?
|
|
pntSectorId String?
|
|
pntEntryUrl String?
|
|
backupUrl String?
|
|
scrapingEnabled Boolean @default(true)
|
|
isActive Boolean @default(true)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
licitations Licitation[]
|
|
syncRuns SyncRun[]
|
|
|
|
@@unique([stateCode, municipalityCode])
|
|
@@index([stateCode, municipalityName])
|
|
@@index([isActive, scrapingEnabled])
|
|
}
|
|
|
|
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)
|
|
userPreferences LicitationUserPreference[]
|
|
normativeAnalyses NormativeAnalysisHistory[]
|
|
|
|
@@unique([municipalityId, source, sourceRecordId])
|
|
@@index([municipalityId, isOpen, closingDate])
|
|
@@index([municipalityId, publishDate])
|
|
@@index([procedureType, category])
|
|
@@index([amount])
|
|
@@index([createdAt])
|
|
}
|
|
|
|
model SyncRun {
|
|
id String @id @default(cuid())
|
|
startedAt DateTime @default(now())
|
|
finishedAt DateTime?
|
|
municipalityId String?
|
|
source LicitationSource
|
|
status SyncRunStatus @default(SUCCESS)
|
|
stats Json?
|
|
error String?
|
|
municipality Municipality? @relation(fields: [municipalityId], references: [id], onDelete: SetNull)
|
|
|
|
@@index([municipalityId, startedAt])
|
|
@@index([source, status, startedAt])
|
|
}
|
|
|
|
model CompanyProfile {
|
|
id String @id @default(cuid())
|
|
userId String @unique
|
|
organizationId String? @unique
|
|
locations Json?
|
|
categoriesSupported Json?
|
|
keywords Json?
|
|
minAmount Decimal? @db.Decimal(14, 2)
|
|
maxAmount Decimal? @db.Decimal(14, 2)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
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])
|
|
}
|