@danielcok17/prisma-db 1.14.0 → 1.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/prisma/app.prisma +83 -18
- package/prisma/migrations/20260307120000_add_phone_occupation_preferred_language/migration.sql +17 -0
- package/prisma/migrations/20260314233018_change_default_message_count_to_4/migration.sql +5 -0
- package/prisma/migrations/20260319200000_add_ingested_document/migration.sql +49 -0
package/package.json
CHANGED
package/prisma/app.prisma
CHANGED
|
@@ -55,10 +55,10 @@ model User {
|
|
|
55
55
|
referralSource String? // Odkiaľ sa o nás dozvedel (Google, Facebook, LinkedIn, etc.)
|
|
56
56
|
applicationText String? // Text žiadosti o prihlásenie
|
|
57
57
|
// ✨ STRIPE FIELDS (B2C - len pre individuálnych používateľov)
|
|
58
|
-
subscriptionTier
|
|
59
|
-
messageCount
|
|
60
|
-
messageCountResetAt
|
|
61
|
-
adminGrantExpiresAt
|
|
58
|
+
subscriptionTier SubscriptionTier @default(FREE) // Aktuálny subscription tier (cache)
|
|
59
|
+
messageCount Int @default(4) // Free tier default
|
|
60
|
+
messageCountResetAt DateTime? // Kedy sa má resetovať message count
|
|
61
|
+
adminGrantExpiresAt DateTime? // Kedy admin grant expiruje
|
|
62
62
|
// ✨ COMPANY FIELDS (pre SZČO - samostatne zárobkovo činná osoba)
|
|
63
63
|
customerType CustomerType @default(INDIVIDUAL) // Typ zákazníka: fyzická osoba alebo SZČO
|
|
64
64
|
companyName String? // Obchodné meno (pre SZČO)
|
|
@@ -78,11 +78,15 @@ model User {
|
|
|
78
78
|
firstUtmTerm String? // Prvé keywords
|
|
79
79
|
firstVisitAt DateTime? // Kedy prvýkrát navštívil web
|
|
80
80
|
// Registration attribution
|
|
81
|
-
registrationUtmSource String?
|
|
82
|
-
registrationUtmMedium String?
|
|
83
|
-
registrationUtmCampaign String?
|
|
84
|
-
registrationUtmContent String?
|
|
85
|
-
registrationUtmTerm String?
|
|
81
|
+
registrationUtmSource String? // UTM source pri registrácii
|
|
82
|
+
registrationUtmMedium String? // UTM medium pri registrácii
|
|
83
|
+
registrationUtmCampaign String? // Kampaň pri registrácii
|
|
84
|
+
registrationUtmContent String? // Content/variant pri registrácii
|
|
85
|
+
registrationUtmTerm String? // Keywords pri registrácii
|
|
86
|
+
// Profile fields
|
|
87
|
+
phone String? // Mobilný telefón
|
|
88
|
+
occupation String? // Povolanie (Právnik, Účtovník, etc.)
|
|
89
|
+
preferredLanguage String? @default("sk") // Jazyk odpovedi (sk, cs, en)
|
|
86
90
|
// Relations
|
|
87
91
|
approvalRequest UserApprovalRequest?
|
|
88
92
|
stripeCustomer StripeCustomer? // ✨ B2C Stripe customer
|
|
@@ -98,6 +102,7 @@ model User {
|
|
|
98
102
|
workflowLogs WorkflowLog[]
|
|
99
103
|
verificationTokens VerificationToken[]
|
|
100
104
|
passwordResetTokens PasswordResetToken[]
|
|
105
|
+
phoneOtps PhoneOtp[]
|
|
101
106
|
canvasDocuments CanvasDocument[]
|
|
102
107
|
canvasDocumentVersions CanvasDocumentVersion[]
|
|
103
108
|
// Folder system relations
|
|
@@ -109,6 +114,8 @@ model User {
|
|
|
109
114
|
// UTM tracking relations
|
|
110
115
|
touchPoints TouchPoint[]
|
|
111
116
|
conversions Conversion[]
|
|
117
|
+
// Ingestion pipeline
|
|
118
|
+
ingestedDocuments IngestedDocument[]
|
|
112
119
|
|
|
113
120
|
// Multi-brand: compound unique allows same email across brands
|
|
114
121
|
@@unique([email, brand])
|
|
@@ -116,6 +123,8 @@ model User {
|
|
|
116
123
|
@@index([customerType])
|
|
117
124
|
@@index([companyNumber])
|
|
118
125
|
@@index([email, customerType])
|
|
126
|
+
// Phone verification index
|
|
127
|
+
@@index([phone])
|
|
119
128
|
// UTM tracking indexes
|
|
120
129
|
@@index([firstUtmSource])
|
|
121
130
|
@@index([firstUtmCampaign])
|
|
@@ -164,10 +173,10 @@ model Organization {
|
|
|
164
173
|
|
|
165
174
|
// Subscription (B2B)
|
|
166
175
|
subscriptionTier SubscriptionTier @default(FREE) // Tier organizácie (cache)
|
|
167
|
-
messageCount Int @default(0)
|
|
168
|
-
messageLimit Int @default(
|
|
169
|
-
messageCountResetAt DateTime?
|
|
170
|
-
adminGrantExpiresAt DateTime?
|
|
176
|
+
messageCount Int @default(0) // Spoločný pool správ pre všetkých členov
|
|
177
|
+
messageLimit Int @default(4) // Free tier default
|
|
178
|
+
messageCountResetAt DateTime? // Kedy sa má resetovať pool
|
|
179
|
+
adminGrantExpiresAt DateTime? // Kedy admin grant expiruje
|
|
171
180
|
|
|
172
181
|
// Settings
|
|
173
182
|
isActive Boolean @default(true)
|
|
@@ -811,11 +820,11 @@ enum CustomerType {
|
|
|
811
820
|
|
|
812
821
|
// Stripe: Tier predplatného
|
|
813
822
|
enum SubscriptionTier {
|
|
814
|
-
FREE
|
|
815
|
-
LAWYER
|
|
816
|
-
LAWYER_PRO
|
|
817
|
-
LAW_FIRM
|
|
818
|
-
ENTERPRISE
|
|
823
|
+
FREE // Free tier (4 messages/month)
|
|
824
|
+
LAWYER // Lawyer tier (1000 messages/month, €29/month, 1 user)
|
|
825
|
+
LAWYER_PRO // Lawyer Pro tier (3000 messages/month, €49/month, 1 user) - RECOMMENDED
|
|
826
|
+
LAW_FIRM // Law Firm tier (10000 messages/month, €129/month, up to 5 users)
|
|
827
|
+
ENTERPRISE // Enterprise tier (unlimited messages, unlimited users, custom pricing)
|
|
819
828
|
}
|
|
820
829
|
|
|
821
830
|
// Stripe: Billing interval
|
|
@@ -995,6 +1004,62 @@ model PasswordResetToken {
|
|
|
995
1004
|
@@index([expires])
|
|
996
1005
|
}
|
|
997
1006
|
|
|
1007
|
+
// Phone OTP verification (BulkGate)
|
|
1008
|
+
model PhoneOtp {
|
|
1009
|
+
id String @id @default(cuid())
|
|
1010
|
+
userId String
|
|
1011
|
+
phone String
|
|
1012
|
+
bulkgateId String @unique // OTP ID from BulkGate API response
|
|
1013
|
+
expiresAt DateTime
|
|
1014
|
+
createdAt DateTime @default(now())
|
|
1015
|
+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
1016
|
+
|
|
1017
|
+
@@index([userId])
|
|
1018
|
+
@@index([bulkgateId])
|
|
1019
|
+
@@index([expiresAt])
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
// ============================================
|
|
1023
|
+
// INGESTION PIPELINE MODELS
|
|
1024
|
+
// ============================================
|
|
1025
|
+
|
|
1026
|
+
// User-uploaded documents processed through the ingestion pipeline
|
|
1027
|
+
// Stores metadata, classification results, and links to Qdrant vectors
|
|
1028
|
+
model IngestedDocument {
|
|
1029
|
+
id String @id @default(cuid())
|
|
1030
|
+
userId String
|
|
1031
|
+
fileName String
|
|
1032
|
+
fileType String // MIME type
|
|
1033
|
+
fileSize Int // bytes
|
|
1034
|
+
status IngestionStatus @default(PROCESSING)
|
|
1035
|
+
docType String? // zakon, zmluva, rozhodnutie, vyhlasky, nariadenie, podanie, iny
|
|
1036
|
+
legalArea String? // Občianske právo, Trestné právo, etc.
|
|
1037
|
+
summary String? // LLM-generated summary
|
|
1038
|
+
references String[] // Legal references from classification
|
|
1039
|
+
chunkCount Int?
|
|
1040
|
+
embeddingCost Float? // EUR
|
|
1041
|
+
qdrantDocId String? @unique // doc_id used in Qdrant vector payloads
|
|
1042
|
+
folderId String? // Optional folder association
|
|
1043
|
+
error String?
|
|
1044
|
+
createdAt DateTime @default(now())
|
|
1045
|
+
updatedAt DateTime @updatedAt
|
|
1046
|
+
|
|
1047
|
+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
1048
|
+
|
|
1049
|
+
@@index([userId])
|
|
1050
|
+
@@index([status])
|
|
1051
|
+
@@index([docType])
|
|
1052
|
+
@@index([userId, status])
|
|
1053
|
+
@@index([createdAt])
|
|
1054
|
+
@@index([qdrantDocId])
|
|
1055
|
+
}
|
|
1056
|
+
|
|
1057
|
+
enum IngestionStatus {
|
|
1058
|
+
PROCESSING
|
|
1059
|
+
COMPLETED
|
|
1060
|
+
ERROR
|
|
1061
|
+
}
|
|
1062
|
+
|
|
998
1063
|
// ============================================
|
|
999
1064
|
// CANVAS DOCUMENT MODELS
|
|
1000
1065
|
// ============================================
|
package/prisma/migrations/20260307120000_add_phone_occupation_preferred_language/migration.sql
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
-- Add LEGAL_OPINION to ReferenceType enum (if not exists)
|
|
2
|
+
DO $$
|
|
3
|
+
BEGIN
|
|
4
|
+
IF NOT EXISTS (
|
|
5
|
+
SELECT 1 FROM pg_enum
|
|
6
|
+
WHERE enumtypid = (SELECT oid FROM pg_type WHERE typname = 'ReferenceType')
|
|
7
|
+
AND enumlabel = 'LEGAL_OPINION'
|
|
8
|
+
) THEN
|
|
9
|
+
ALTER TYPE "ReferenceType" ADD VALUE 'LEGAL_OPINION';
|
|
10
|
+
END IF;
|
|
11
|
+
END
|
|
12
|
+
$$;
|
|
13
|
+
|
|
14
|
+
-- AlterTable: Add new profile fields to User (if not exist)
|
|
15
|
+
ALTER TABLE "User" ADD COLUMN IF NOT EXISTS "phone" TEXT;
|
|
16
|
+
ALTER TABLE "User" ADD COLUMN IF NOT EXISTS "occupation" TEXT;
|
|
17
|
+
ALTER TABLE "User" ADD COLUMN IF NOT EXISTS "preferredLanguage" TEXT DEFAULT 'sk';
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
-- CreateEnum
|
|
2
|
+
CREATE TYPE "IngestionStatus" AS ENUM ('PROCESSING', 'COMPLETED', 'ERROR');
|
|
3
|
+
|
|
4
|
+
-- CreateTable
|
|
5
|
+
CREATE TABLE "IngestedDocument" (
|
|
6
|
+
"id" TEXT NOT NULL,
|
|
7
|
+
"userId" TEXT NOT NULL,
|
|
8
|
+
"fileName" TEXT NOT NULL,
|
|
9
|
+
"fileType" TEXT NOT NULL,
|
|
10
|
+
"fileSize" INTEGER NOT NULL,
|
|
11
|
+
"status" "IngestionStatus" NOT NULL DEFAULT 'PROCESSING',
|
|
12
|
+
"docType" TEXT,
|
|
13
|
+
"legalArea" TEXT,
|
|
14
|
+
"summary" TEXT,
|
|
15
|
+
"references" TEXT[],
|
|
16
|
+
"chunkCount" INTEGER,
|
|
17
|
+
"embeddingCost" DOUBLE PRECISION,
|
|
18
|
+
"qdrantDocId" TEXT,
|
|
19
|
+
"folderId" TEXT,
|
|
20
|
+
"error" TEXT,
|
|
21
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
22
|
+
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
23
|
+
|
|
24
|
+
CONSTRAINT "IngestedDocument_pkey" PRIMARY KEY ("id")
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
-- CreateIndex
|
|
28
|
+
CREATE UNIQUE INDEX "IngestedDocument_qdrantDocId_key" ON "IngestedDocument"("qdrantDocId");
|
|
29
|
+
|
|
30
|
+
-- CreateIndex
|
|
31
|
+
CREATE INDEX "IngestedDocument_userId_idx" ON "IngestedDocument"("userId");
|
|
32
|
+
|
|
33
|
+
-- CreateIndex
|
|
34
|
+
CREATE INDEX "IngestedDocument_status_idx" ON "IngestedDocument"("status");
|
|
35
|
+
|
|
36
|
+
-- CreateIndex
|
|
37
|
+
CREATE INDEX "IngestedDocument_docType_idx" ON "IngestedDocument"("docType");
|
|
38
|
+
|
|
39
|
+
-- CreateIndex
|
|
40
|
+
CREATE INDEX "IngestedDocument_userId_status_idx" ON "IngestedDocument"("userId", "status");
|
|
41
|
+
|
|
42
|
+
-- CreateIndex
|
|
43
|
+
CREATE INDEX "IngestedDocument_createdAt_idx" ON "IngestedDocument"("createdAt");
|
|
44
|
+
|
|
45
|
+
-- CreateIndex
|
|
46
|
+
CREATE INDEX "IngestedDocument_qdrantDocId_idx" ON "IngestedDocument"("qdrantDocId");
|
|
47
|
+
|
|
48
|
+
-- AddForeignKey
|
|
49
|
+
ALTER TABLE "IngestedDocument" ADD CONSTRAINT "IngestedDocument_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|