@danielcok17/prisma-db 1.0.1 → 1.0.3

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.
Files changed (43) hide show
  1. package/README.md +99 -8
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +1 -0
  5. package/dist/index.js.map +1 -1
  6. package/dist/paths.d.ts +4 -0
  7. package/dist/paths.d.ts.map +1 -0
  8. package/dist/paths.js +12 -0
  9. package/dist/paths.js.map +1 -0
  10. package/package.json +3 -3
  11. package/prisma/app.prisma +148 -72
  12. package/prisma/generated/app/edge.js +67 -11
  13. package/prisma/generated/app/index-browser.js +62 -6
  14. package/prisma/generated/app/index.d.ts +5386 -292
  15. package/prisma/generated/app/index.js +67 -11
  16. package/prisma/generated/app/libquery_engine-darwin-arm64.dylib.node +0 -0
  17. package/prisma/generated/app/package.json +2 -2
  18. package/prisma/generated/app/runtime/edge-esm.js +3 -3
  19. package/prisma/generated/app/runtime/edge.js +3 -3
  20. package/prisma/generated/app/runtime/library.d.ts +66 -92
  21. package/prisma/generated/app/runtime/library.js +21 -21
  22. package/prisma/generated/app/runtime/react-native.js +13 -13
  23. package/prisma/generated/app/runtime/wasm-compiler-edge.js +27 -27
  24. package/prisma/generated/app/runtime/wasm-engine-edge.js +13 -13
  25. package/prisma/generated/app/schema.prisma +99 -21
  26. package/prisma/generated/app/wasm.js +62 -6
  27. package/prisma/generated/law/edge.js +6 -6
  28. package/prisma/generated/law/index-browser.js +4 -4
  29. package/prisma/generated/law/index.d.ts +2 -2
  30. package/prisma/generated/law/index.js +6 -6
  31. package/prisma/generated/law/libquery_engine-darwin-arm64.dylib.node +0 -0
  32. package/prisma/generated/law/package.json +1 -1
  33. package/prisma/generated/law/runtime/edge-esm.js +3 -3
  34. package/prisma/generated/law/runtime/edge.js +3 -3
  35. package/prisma/generated/law/runtime/library.d.ts +66 -92
  36. package/prisma/generated/law/runtime/library.js +21 -21
  37. package/prisma/generated/law/runtime/react-native.js +13 -13
  38. package/prisma/generated/law/runtime/wasm-compiler-edge.js +27 -27
  39. package/prisma/generated/law/runtime/wasm-engine-edge.js +13 -13
  40. package/prisma/generated/law/wasm.js +4 -4
  41. package/prisma/migrations/20250818134929_init/migration.sql +374 -0
  42. package/prisma/migrations/20250903104817_add_workflow_log/migration.sql +103 -0
  43. package/prisma/migrations/20250817194531_/migration.sql +0 -372
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # @legal-ai/prisma-db
1
+ # @danielcok17/prisma-db
2
2
 
3
3
  Shared Prisma setup with dual Prisma clients: one for your app tables (`app` schema), one for existing law tables (`public` schema).
4
4
 
@@ -22,17 +22,108 @@ import { AppPrismaClient, LawPrismaClient } from '@danielcok17/prisma-db';
22
22
  ```
23
23
 
24
24
  ## Environment
25
- Set the following env vars in your runtime/build:
25
+ Set the following env vars in your runtime/build (names match the `.prisma` files):
26
26
 
27
27
  ```
28
- DATABASE_URL_APP=postgres://USER:PASS@HOST:PORT/DB?schema=app
29
- DATABASE_URL_APP_DIRECT=postgres://USER:PASS@HOST:PORT/DB?schema=app
30
- DATABASE_URL_LAW=postgres://READONLY_USER:PASS@HOST:PORT/DB
31
- DATABASE_URL_LAW_DIRECT=postgres://READONLY_USER:PASS@HOST:PORT/DB
28
+ POSTGRES_PRISMA_URL=postgres://USER:PASS@HOST:PORT/DB?schema=app
29
+ POSTGRES_URL_NON_POOLING=postgres://USER:PASS@HOST:PORT/DB?schema=app
30
+ POSTGRES_PRISMA_URL_LAW=postgres://READONLY_USER:PASS@HOST:PORT/DB
31
+ POSTGRES_URL_NON_POOLING_LAW=postgres://READONLY_USER:PASS@HOST:PORT/DB
32
32
  ```
33
33
 
34
34
  Notes:
35
- - Use a read-only role for `DATABASE_URL_LAW`.
36
- - Ensure DB has `CREATE SCHEMA IF NOT EXISTS app;` executed once.
35
+ - Use a read-only role for `POSTGRES_PRISMA_URL_LAW`.
36
+ - Ensure the DB has `CREATE SCHEMA IF NOT EXISTS app;` executed once.
37
37
 
38
+ ## Schema paths (for tooling / CI)
39
+ This package publishes the `prisma` directory. You can get absolute paths to the schemas programmatically:
38
40
 
41
+ ```ts
42
+ import { appPrismaSchemaPath, lawPrismaSchemaPath, prismaMigrationsPath } from '@danielcok17/prisma-db';
43
+ ```
44
+
45
+ Examples:
46
+
47
+ ```bash
48
+ # Use the packaged app schema with Prisma CLI
49
+ npx prisma migrate deploy --schema "$(node -e "console.log(require('@danielcok17/prisma-db').appPrismaSchemaPath)")"
50
+
51
+ # Or resolve directly to the file shipped in the package
52
+ APP_SCHEMA=$(node -e "console.log(require.resolve('@danielcok17/prisma-db/prisma/app.prisma'))")
53
+ npx prisma generate --schema "$APP_SCHEMA"
54
+ ```
55
+
56
+
57
+
58
+ ## Installation
59
+ ```bash
60
+ npm install @danielcok17/prisma-db
61
+ # or
62
+ yarn add @danielcok17/prisma-db
63
+ ```
64
+
65
+ The package runs Prisma generate on postinstall. If your environment blocks lifecycle scripts, run generate manually using `appPrismaSchemaPath` as shown below.
66
+
67
+ ## Quick start
68
+ 1) Set env vars (match the names used in `.prisma` files):
69
+ ```
70
+ POSTGRES_PRISMA_URL=postgres://USER:PASS@HOST:PORT/DB?schema=app
71
+ POSTGRES_URL_NON_POOLING=postgres://USER:PASS@HOST:PORT/DB?schema=app
72
+ POSTGRES_PRISMA_URL_LAW=postgres://READONLY_USER:PASS@HOST:PORT/DB
73
+ POSTGRES_URL_NON_POOLING_LAW=postgres://READONLY_USER:PASS@HOST:PORT/DB
74
+ ```
75
+
76
+ 2) Apply migrations for the `app` schema:
77
+ ```bash
78
+ APP_SCHEMA=$(node -e "console.log(require('@danielcok17/prisma-db').appPrismaSchemaPath)")
79
+ npx prisma migrate deploy --schema "$APP_SCHEMA"
80
+ ```
81
+
82
+ 3) Use the clients:
83
+ ```ts
84
+ import { appPrisma, lawPrisma } from '@danielcok17/prisma-db';
85
+
86
+ const users = await appPrisma.user.findMany();
87
+ const laws = await lawPrisma.lawVersion.findMany({ take: 5 });
88
+ ```
89
+
90
+ ## Upgrading to a new version
91
+ When you update the package, always apply migrations shipped with the new version.
92
+
93
+ ```bash
94
+ npm install @danielcok17/prisma-db@latest
95
+
96
+ # Regenerate client (if your CI blocks postinstall or you want to be explicit)
97
+ APP_SCHEMA=$(node -e "console.log(require('@danielcok17/prisma-db').appPrismaSchemaPath)")
98
+ npx prisma generate --schema "$APP_SCHEMA"
99
+
100
+ # Apply new migrations
101
+ npx prisma migrate deploy --schema "$APP_SCHEMA"
102
+ ```
103
+
104
+ Notes:
105
+ - Do not run `prisma migrate dev` in consumer apps. Schema changes are managed in this package and released via versions.
106
+ - If there are breaking changes, check the release notes for manual steps.
107
+
108
+ ## CI/CD snippet
109
+ Add a deploy step to apply migrations using the schema from this package:
110
+ ```bash
111
+ APP_SCHEMA=$(node -e "console.log(require('@danielcok17/prisma-db').appPrismaSchemaPath)")
112
+ npx prisma migrate deploy --schema "$APP_SCHEMA"
113
+ ```
114
+
115
+ Optionally regenerate the client at build/deploy time:
116
+ ```bash
117
+ npx prisma generate --schema "$APP_SCHEMA"
118
+ ```
119
+
120
+ ## Prisma Studio (optional)
121
+ ```bash
122
+ APP_SCHEMA=$(node -e "console.log(require('@danielcok17/prisma-db').appPrismaSchemaPath)")
123
+ npx prisma studio --schema "$APP_SCHEMA"
124
+ ```
125
+
126
+ ## Troubleshooting
127
+ - Missing client types/runtime: run `npx prisma generate --schema "$(node -e "console.log(require('@danielcok17/prisma-db').appPrismaSchemaPath)")"`.
128
+ - Migrate deploy fails: verify env vars and DB connectivity; ensure the `app` schema exists.
129
+ - Read-only access to law tables: use a user/role with SELECT-only permissions for `POSTGRES_PRISMA_URL_LAW`.
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export { PrismaClient as AppPrismaClient } from '../prisma/generated/app';
2
2
  export { PrismaClient as LawPrismaClient } from '../prisma/generated/law';
3
3
  export * from './utils';
4
+ export * from './paths';
4
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,IAAI,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1E,OAAO,EAAE,YAAY,IAAI,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1E,cAAc,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,IAAI,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1E,OAAO,EAAE,YAAY,IAAI,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1E,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC"}
package/dist/index.js CHANGED
@@ -20,4 +20,5 @@ Object.defineProperty(exports, "AppPrismaClient", { enumerable: true, get: funct
20
20
  var law_1 = require("../prisma/generated/law");
21
21
  Object.defineProperty(exports, "LawPrismaClient", { enumerable: true, get: function () { return law_1.PrismaClient; } });
22
22
  __exportStar(require("./utils"), exports);
23
+ __exportStar(require("./paths"), exports);
23
24
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,+CAA0E;AAAjE,sGAAA,YAAY,OAAmB;AACxC,+CAA0E;AAAjE,sGAAA,YAAY,OAAmB;AACxC,0CAAwB"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,+CAA0E;AAAjE,sGAAA,YAAY,OAAmB;AACxC,+CAA0E;AAAjE,sGAAA,YAAY,OAAmB;AACxC,0CAAwB;AACxB,0CAAwB"}
@@ -0,0 +1,4 @@
1
+ export declare const appPrismaSchemaPath: string;
2
+ export declare const lawPrismaSchemaPath: string;
3
+ export declare const prismaMigrationsPath: string;
4
+ //# sourceMappingURL=paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,mBAAmB,EAAE,MAA0D,CAAC;AAC7F,eAAO,MAAM,mBAAmB,EAAE,MAA0D,CAAC;AAC7F,eAAO,MAAM,oBAAoB,EAAE,MAA0D,CAAC"}
package/dist/paths.js ADDED
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.prismaMigrationsPath = exports.lawPrismaSchemaPath = exports.appPrismaSchemaPath = void 0;
7
+ const path_1 = __importDefault(require("path"));
8
+ const packageRootDir = path_1.default.resolve(__dirname, '..');
9
+ exports.appPrismaSchemaPath = path_1.default.join(packageRootDir, 'prisma', 'app.prisma');
10
+ exports.lawPrismaSchemaPath = path_1.default.join(packageRootDir, 'prisma', 'law.prisma');
11
+ exports.prismaMigrationsPath = path_1.default.join(packageRootDir, 'prisma', 'migrations');
12
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":";;;;;;AAAA,gDAAwB;AAExB,MAAM,cAAc,GAAG,cAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AAExC,QAAA,mBAAmB,GAAW,cAAI,CAAC,IAAI,CAAC,cAAc,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;AAChF,QAAA,mBAAmB,GAAW,cAAI,CAAC,IAAI,CAAC,cAAc,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;AAChF,QAAA,oBAAoB,GAAW,cAAI,CAAC,IAAI,CAAC,cAAc,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danielcok17/prisma-db",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "Shared Prisma schema for Legal AI applications",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -35,11 +35,11 @@
35
35
  "node": ">=18.18"
36
36
  },
37
37
  "dependencies": {
38
- "@prisma/client": "^6.14.0",
39
- "prisma": "^6.14.0"
38
+ "@prisma/client": "^6.15.0"
40
39
  },
41
40
  "devDependencies": {
42
41
  "@types/node": "^24.3.0",
42
+ "prisma": "^6.15.0",
43
43
  "tsx": "^4.0.0",
44
44
  "typescript": "^5.0.0"
45
45
  }
package/prisma/app.prisma CHANGED
@@ -28,28 +28,28 @@ model Account {
28
28
  }
29
29
 
30
30
  model User {
31
- id String @id @default(cuid())
31
+ id String @id @default(cuid())
32
32
  name String?
33
- email String? @unique
33
+ email String? @unique
34
34
  emailVerified DateTime?
35
35
  image String?
36
- createdAt DateTime @default(now())
37
- messageCount Int @default(100)
38
- agreedToTerms Boolean @default(false)
36
+ createdAt DateTime @default(now())
37
+ messageCount Int @default(100)
38
+ agreedToTerms Boolean @default(false)
39
39
  practiceArea String[]
40
40
  lawFirm String?
41
41
  yearsOfExperience Int?
42
42
  // Nové polia pre schvalovanie používateľov
43
- isApproved Boolean @default(false) // Či je používateľ schválený
44
- isRejected Boolean @default(false) // Či je používateľ zamietnutý
45
- approvedAt DateTime? // Kedy bol schválený
46
- rejectedAt DateTime? // Kedy bol zamietnutý
47
- approvedBy String? // ID admina, ktorý schválil
48
- rejectedBy String? // ID admina, ktorý zamietol
49
- rejectionReason String? // Dôvod zamietnutia
43
+ isApproved Boolean @default(false) // Či je používateľ schválený
44
+ isRejected Boolean @default(false) // Či je používateľ zamietnutý
45
+ approvedAt DateTime? // Kedy bol schválený
46
+ rejectedAt DateTime? // Kedy bol zamietnutý
47
+ approvedBy String? // ID admina, ktorý schválil
48
+ rejectedBy String? // ID admina, ktorý zamietol
49
+ rejectionReason String? // Dôvod zamietnutia
50
50
  // Nové polia pre tracking a žiadosť
51
- referralSource String? // Odkiaľ sa o nás dozvedel (Google, Facebook, LinkedIn, etc.)
52
- applicationText String? // Text žiadosti o prihlásenie
51
+ referralSource String? // Odkiaľ sa o nás dozvedel (Google, Facebook, LinkedIn, etc.)
52
+ applicationText String? // Text žiadosti o prihlásenie
53
53
  approvalRequest UserApprovalRequest?
54
54
  accounts Account[]
55
55
  answers Answer[]
@@ -57,18 +57,19 @@ model User {
57
57
  feedbacks Feedback[]
58
58
  pageViews PageView[]
59
59
  sessions Session[]
60
+ workflowLogs WorkflowLog[]
60
61
  }
61
62
 
62
63
  // Nový model pre žiadosti o schválenie
63
64
  model UserApprovalRequest {
64
- id String @id @default(cuid())
65
- userId String @unique
65
+ id String @id @default(cuid())
66
+ userId String @unique
66
67
  status ApprovalStatus @default(PENDING)
67
- submittedAt DateTime @default(now())
68
+ submittedAt DateTime @default(now())
68
69
  reviewedAt DateTime?
69
- reviewedBy String? // ID admina, ktorý preskúmal žiadosť
70
- notes String? // Poznámky admina
71
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
70
+ reviewedBy String? // ID admina, ktorý preskúmal žiadosť
71
+ notes String? // Poznámky admina
72
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
72
73
 
73
74
  @@index([status])
74
75
  @@index([submittedAt])
@@ -77,44 +78,48 @@ model UserApprovalRequest {
77
78
 
78
79
  // ZJEDNODUŠENÝ Conversation - len metadata, bez duplikátov
79
80
  model Conversation {
80
- id String @id @default(cuid())
81
- name String
82
- userId String
83
- isShareable Boolean @default(false)
84
- shareUrl String? @unique
85
- sharedAt DateTime?
86
- createdAt DateTime @default(now())
87
- updatedAt DateTime @updatedAt
81
+ id String @id @default(cuid())
82
+ name String
83
+ userId String
84
+ isShareable Boolean @default(false)
85
+ shareUrl String? @unique
86
+ sharedAt DateTime?
87
+ createdAt DateTime @default(now())
88
+ updatedAt DateTime @updatedAt
89
+ summary String?
90
+ messagesSinceLastSummary Int? @default(0)
88
91
  // Relácie
89
- answers Answer[]
90
- user User @relation(fields: [userId], references: [id])
91
-
92
+ answers Answer[]
93
+ user User @relation(fields: [userId], references: [id])
94
+ workflowLogs WorkflowLog[]
95
+
92
96
  @@index([userId])
93
97
  @@index([createdAt])
94
98
  }
95
99
 
96
100
  // Hlavný model - všetky správy, bez duplikátov
97
101
  model Answer {
98
- id String @id @default(cuid())
102
+ id String @id @default(cuid())
99
103
  conversationId String
100
- messageId String @unique
104
+ messageId String @unique
101
105
  role Role
102
106
  content String
103
107
  question String?
104
108
  answer String?
105
109
  evaluation String?
106
- isWelcome Boolean @default(false)
110
+ isWelcome Boolean @default(false)
107
111
  processingTime Int?
108
112
  model String?
109
113
  userId String?
110
- createdAt DateTime @default(now())
111
- updatedAt DateTime @updatedAt
114
+ createdAt DateTime @default(now())
115
+ updatedAt DateTime @updatedAt
112
116
  // Relácie
113
- conversation Conversation @relation(fields: [conversationId], references: [id], onDelete: Cascade)
114
- user User? @relation(fields: [userId], references: [id])
117
+ conversation Conversation @relation(fields: [conversationId], references: [id], onDelete: Cascade)
118
+ user User? @relation(fields: [userId], references: [id])
115
119
  feedback Feedback?
116
120
  references Reference[]
117
121
  metrics AnswerMetrics?
122
+ WorkflowLog WorkflowLog[]
118
123
 
119
124
  @@index([conversationId])
120
125
  @@index([messageId])
@@ -125,28 +130,28 @@ model Answer {
125
130
 
126
131
  // Nová tabuľka pre metriky odpovedí
127
132
  model AnswerMetrics {
128
- id String @id @default(cuid())
129
- answerId String @unique
133
+ id String @id @default(cuid())
134
+ answerId String @unique
130
135
  // Náklady
131
- apiCost Float? // Celkové náklady (ai_cost + rag_cost)
132
- aiCost Float? // Náklady len na AI provider volania
133
- ragCost Float? // Náklady na RAG operácie
136
+ apiCost Float? // Celkové náklady (ai_cost + rag_cost)
137
+ aiCost Float? // Náklady len na AI provider volania
138
+ ragCost Float? // Náklady na RAG operácie
134
139
  // Volania
135
- apiCalls Int? // Celkový počet volaní
136
- aiCalls Int? // Počet AI provider volaní
137
- ragCalls Int? // Počet RAG operácií
140
+ apiCalls Int? // Celkový počet volaní
141
+ aiCalls Int? // Počet AI provider volaní
142
+ ragCalls Int? // Počet RAG operácií
138
143
  // Čas a výkon
139
- apiDuration Int? // Doba spracovania v ms
144
+ apiDuration Int? // Doba spracovania v ms
140
145
  // AI Provider a Model
141
- aiProvider String? // Hlavný AI provider
142
- aiModel String? // Hlavný AI model
143
- aiProvidersUsed String[] // Všetky použité AI providery
144
- aiModelsUsed String[] // Všetky použité AI modely
146
+ aiProvider String? // Hlavný AI provider
147
+ aiModel String? // Hlavný AI model
148
+ aiProvidersUsed String[] // Všetky použité AI providery
149
+ aiModelsUsed String[] // Všetky použité AI modely
145
150
  // Timestamps
146
- createdAt DateTime @default(now())
147
- updatedAt DateTime @updatedAt
151
+ createdAt DateTime @default(now())
152
+ updatedAt DateTime @updatedAt
148
153
  // Relations
149
- answer Answer @relation(fields: [answerId], references: [id], onDelete: Cascade)
154
+ answer Answer @relation(fields: [answerId], references: [id], onDelete: Cascade)
150
155
 
151
156
  @@index([answerId])
152
157
  @@index([apiCost])
@@ -175,7 +180,7 @@ model Feedback {
175
180
  // ZJEDNODUŠENÝ Reference - len na Answer, bez duplikátov
176
181
  model Reference {
177
182
  id String @id @default(cuid())
178
- answerId String // Len answerId - konzistentné
183
+ answerId String // Len answerId - konzistentné
179
184
  type ReferenceType
180
185
  title String
181
186
  reference String
@@ -200,7 +205,7 @@ model Reference {
200
205
  model PageView {
201
206
  id String @id @default(cuid())
202
207
  userId String?
203
- sessionId String
208
+ sessionId String?
204
209
  page String
205
210
  path String
206
211
  referrer String?
@@ -216,7 +221,7 @@ model PageView {
216
221
  timeOnPage Int?
217
222
  isBounce Boolean @default(true)
218
223
  createdAt DateTime @default(now())
219
- session Session @relation(fields: [sessionId], references: [sessionId], onDelete: SetNull)
224
+ session Session? @relation(fields: [sessionId], references: [sessionId], onDelete: SetNull)
220
225
  user User? @relation(fields: [userId], references: [id])
221
226
 
222
227
  @@index([userId])
@@ -228,16 +233,16 @@ model PageView {
228
233
  }
229
234
 
230
235
  model Session {
231
- id String @id @default(cuid())
232
- sessionId String @unique
233
- userId String?
234
- startedAt DateTime @default(now())
235
- endedAt DateTime?
236
- duration Int?
237
- pageViews PageView[]
238
- user User? @relation(fields: [userId], references: [id])
236
+ id String @id @default(cuid())
237
+ sessionId String @unique
238
+ userId String?
239
+ startedAt DateTime @default(now())
240
+ endedAt DateTime?
241
+ duration Int?
242
+ pageViews PageView[]
243
+ user User? @relation(fields: [userId], references: [id])
244
+ workflowLogs WorkflowLog[]
239
245
 
240
- @@index([sessionId])
241
246
  @@index([userId])
242
247
  @@index([startedAt])
243
248
  }
@@ -270,12 +275,12 @@ enum ApprovalStatus {
270
275
 
271
276
  // Nový model pre logovanie admin akcií
272
277
  model AdminActionLog {
273
- id String @id @default(cuid())
274
- action String // APPROVE_USER, REJECT_USER, etc.
275
- targetUserId String // ID používateľa, na ktorého sa akcia vzťahuje
276
- adminEmail String // E-mail admina, ktorý vykonal akciu
277
- details Json? // Ďalšie detaily akcie (reason, notes, etc.)
278
- createdAt DateTime @default(now())
278
+ id String @id @default(cuid())
279
+ action String // APPROVE_USER, REJECT_USER, etc.
280
+ targetUserId String // ID používateľa, na ktorého sa akcia vzťahuje
281
+ adminEmail String // E-mail admina, ktorý vykonal akciu
282
+ details Json? // Ďalšie detaily akcie (reason, notes, etc.)
283
+ createdAt DateTime @default(now())
279
284
 
280
285
  @@index([action])
281
286
  @@index([targetUserId])
@@ -283,4 +288,75 @@ model AdminActionLog {
283
288
  @@index([createdAt])
284
289
  }
285
290
 
291
+ model WorkflowLog {
292
+ id String @id @default(cuid()) // Added @default(cuid())
293
+ conversationId String
294
+ messageId String?
295
+ userId String? // Made optional to preserve logs when users are deleted
296
+ sessionId String? // Removed @unique to allow multiple workflows per session
297
+ startedAt DateTime @default(now())
298
+ completedAt DateTime?
299
+ status WorkflowStatus @default(IN_PROGRESS)
300
+ totalDuration Int? // milliseconds
301
+ error String?
302
+ metadata Json?
303
+ steps WorkflowStep[] // Renamed from WorkflowStep to steps (lowerCamel, plural)
304
+ conversation Conversation @relation(fields: [conversationId], references: [id], onDelete: Cascade)
305
+ user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
306
+ session Session? @relation(fields: [sessionId], references: [sessionId], onDelete: SetNull)
307
+ answer Answer? @relation(fields: [messageId], references: [messageId])
308
+
309
+ @@index([conversationId])
310
+ @@index([userId])
311
+ @@index([sessionId])
312
+ @@index([startedAt])
313
+ @@index([status])
314
+ @@index([conversationId, startedAt]) // Composite index for timeline queries
315
+ @@index([messageId])
316
+ }
317
+
318
+ model WorkflowStep {
319
+ id String @id @default(cuid()) // Added @default(cuid())
320
+ workflowId String
321
+ stepName String // 'classify_question', 'rag_search', 'ai_processing', 'generate_response'
322
+ stepType StepType
323
+ startedAt DateTime @default(now())
324
+ completedAt DateTime?
325
+ duration Int? // milliseconds
326
+ status StepStatus @default(IN_PROGRESS)
327
+ inputData Json? // Sanitized input data
328
+ outputData Json? // Sanitized output data
329
+ error String?
330
+ metadata Json? // Provider used, model used, tokens, costs, etc.
331
+ workflow WorkflowLog @relation(fields: [workflowId], references: [id], onDelete: Cascade)
332
+
333
+ @@index([workflowId])
334
+ @@index([stepName])
335
+ @@index([stepType])
336
+ @@index([startedAt])
337
+ @@index([status])
338
+ @@index([workflowId, startedAt]) // Composite index for timeline queries
339
+ }
340
+
341
+ enum WorkflowStatus {
342
+ IN_PROGRESS
343
+ COMPLETED
344
+ FAILED
345
+ CANCELLED
346
+ }
347
+
348
+ enum StepStatus {
349
+ IN_PROGRESS
350
+ COMPLETED
351
+ FAILED
352
+ SKIPPED
353
+ }
286
354
 
355
+ enum StepType {
356
+ CLASSIFICATION
357
+ RAG_RETRIEVAL
358
+ AI_PROCESSING
359
+ RESPONSE_GENERATION
360
+ DATA_PERSISTENCE
361
+ ERROR_HANDLING
362
+ }