@naisys/erp 3.0.0-beta.6

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 (150) hide show
  1. package/bin/naisys-erp +2 -0
  2. package/client-dist/android-chrome-192x192.png +0 -0
  3. package/client-dist/android-chrome-512x512.png +0 -0
  4. package/client-dist/apple-touch-icon.png +0 -0
  5. package/client-dist/assets/index-45dVo30p.css +1 -0
  6. package/client-dist/assets/index-Dffms7F_.js +168 -0
  7. package/client-dist/assets/naisys-logo-CzoPnn5I.webp +0 -0
  8. package/client-dist/favicon.ico +0 -0
  9. package/client-dist/index.html +42 -0
  10. package/client-dist/site.webmanifest +22 -0
  11. package/dist/api-reference.js +101 -0
  12. package/dist/audit.js +14 -0
  13. package/dist/auth-middleware.js +203 -0
  14. package/dist/dbConfig.js +10 -0
  15. package/dist/erpDb.js +34 -0
  16. package/dist/erpServer.js +321 -0
  17. package/dist/error-handler.js +17 -0
  18. package/dist/generated/prisma/client.js +35 -0
  19. package/dist/generated/prisma/commonInputTypes.js +11 -0
  20. package/dist/generated/prisma/enums.js +60 -0
  21. package/dist/generated/prisma/internal/class.js +50 -0
  22. package/dist/generated/prisma/internal/prismaNamespace.js +366 -0
  23. package/dist/generated/prisma/models/Attachment.js +2 -0
  24. package/dist/generated/prisma/models/AuditLog.js +2 -0
  25. package/dist/generated/prisma/models/Field.js +2 -0
  26. package/dist/generated/prisma/models/FieldAttachment.js +2 -0
  27. package/dist/generated/prisma/models/FieldRecord.js +2 -0
  28. package/dist/generated/prisma/models/FieldSet.js +2 -0
  29. package/dist/generated/prisma/models/FieldValue.js +2 -0
  30. package/dist/generated/prisma/models/Item.js +2 -0
  31. package/dist/generated/prisma/models/ItemInstance.js +2 -0
  32. package/dist/generated/prisma/models/LaborTicket.js +2 -0
  33. package/dist/generated/prisma/models/Operation.js +2 -0
  34. package/dist/generated/prisma/models/OperationDependency.js +2 -0
  35. package/dist/generated/prisma/models/OperationFieldRef.js +2 -0
  36. package/dist/generated/prisma/models/OperationRun.js +2 -0
  37. package/dist/generated/prisma/models/OperationRunComment.js +2 -0
  38. package/dist/generated/prisma/models/Order.js +2 -0
  39. package/dist/generated/prisma/models/OrderRevision.js +2 -0
  40. package/dist/generated/prisma/models/OrderRun.js +2 -0
  41. package/dist/generated/prisma/models/SchemaVersion.js +2 -0
  42. package/dist/generated/prisma/models/Session.js +2 -0
  43. package/dist/generated/prisma/models/Step.js +2 -0
  44. package/dist/generated/prisma/models/StepRun.js +2 -0
  45. package/dist/generated/prisma/models/User.js +2 -0
  46. package/dist/generated/prisma/models/UserPermission.js +2 -0
  47. package/dist/generated/prisma/models/WorkCenter.js +2 -0
  48. package/dist/generated/prisma/models/WorkCenterUser.js +2 -0
  49. package/dist/generated/prisma/models.js +2 -0
  50. package/dist/hateoas.js +61 -0
  51. package/dist/route-helpers.js +220 -0
  52. package/dist/routes/admin.js +147 -0
  53. package/dist/routes/audit.js +36 -0
  54. package/dist/routes/auth.js +112 -0
  55. package/dist/routes/dispatch.js +174 -0
  56. package/dist/routes/inventory.js +70 -0
  57. package/dist/routes/item-fields.js +220 -0
  58. package/dist/routes/item-instances.js +426 -0
  59. package/dist/routes/items.js +252 -0
  60. package/dist/routes/labor-tickets.js +268 -0
  61. package/dist/routes/operation-dependencies.js +170 -0
  62. package/dist/routes/operation-field-refs.js +263 -0
  63. package/dist/routes/operation-run-comments.js +108 -0
  64. package/dist/routes/operation-run-transitions.js +249 -0
  65. package/dist/routes/operation-runs.js +299 -0
  66. package/dist/routes/operations.js +283 -0
  67. package/dist/routes/order-revision-transitions.js +86 -0
  68. package/dist/routes/order-revisions.js +327 -0
  69. package/dist/routes/order-run-transitions.js +215 -0
  70. package/dist/routes/order-runs.js +335 -0
  71. package/dist/routes/orders.js +262 -0
  72. package/dist/routes/root.js +123 -0
  73. package/dist/routes/schemas.js +31 -0
  74. package/dist/routes/step-field-attachments.js +231 -0
  75. package/dist/routes/step-fields.js +315 -0
  76. package/dist/routes/step-run-fields.js +438 -0
  77. package/dist/routes/step-run-transitions.js +113 -0
  78. package/dist/routes/step-runs.js +324 -0
  79. package/dist/routes/steps.js +283 -0
  80. package/dist/routes/user-permissions.js +100 -0
  81. package/dist/routes/users.js +381 -0
  82. package/dist/routes/work-centers.js +280 -0
  83. package/dist/schema-registry.js +45 -0
  84. package/dist/services/attachment-service.js +118 -0
  85. package/dist/services/field-ref-service.js +74 -0
  86. package/dist/services/field-service.js +114 -0
  87. package/dist/services/field-value-service.js +256 -0
  88. package/dist/services/item-instance-service.js +155 -0
  89. package/dist/services/item-service.js +56 -0
  90. package/dist/services/labor-ticket-service.js +148 -0
  91. package/dist/services/log-file-service.js +11 -0
  92. package/dist/services/operation-dependency-service.js +30 -0
  93. package/dist/services/operation-run-comment-service.js +26 -0
  94. package/dist/services/operation-run-service.js +347 -0
  95. package/dist/services/operation-service.js +132 -0
  96. package/dist/services/order-revision-service.js +264 -0
  97. package/dist/services/order-run-service.js +356 -0
  98. package/dist/services/order-service.js +68 -0
  99. package/dist/services/revision-diff-service.js +194 -0
  100. package/dist/services/step-run-service.js +106 -0
  101. package/dist/services/step-service.js +89 -0
  102. package/dist/services/user-service.js +132 -0
  103. package/dist/services/work-center-service.js +106 -0
  104. package/dist/supervisorAuth.js +16 -0
  105. package/dist/userService.js +118 -0
  106. package/package.json +75 -0
  107. package/prisma/migrations/20260212170352_init/migration.sql +125 -0
  108. package/prisma/migrations/20260308000000_multi_session/migration.sql +23 -0
  109. package/prisma/migrations/20260309000000_add_user_api_key/migration.sql +5 -0
  110. package/prisma/migrations/20260309010000_add_plan_operations/migration.sql +21 -0
  111. package/prisma/migrations/20260309020000_rename_exec_orders_to_order_runs/migration.sql +13 -0
  112. package/prisma/migrations/20260310000000_rename_plan_order_revs_to_order_revisions/migration.sql +22 -0
  113. package/prisma/migrations/20260310100000_rename_plan_orders_to_orders/migration.sql +23 -0
  114. package/prisma/migrations/20260310200000_rename_order_no_to_run_no/migration.sql +3 -0
  115. package/prisma/migrations/20260312000000_add_user_permissions/migration.sql +16 -0
  116. package/prisma/migrations/20260313000000_rename_plan_operations_to_operations/migration.sql +2 -0
  117. package/prisma/migrations/20260313100000_add_steps/migration.sql +20 -0
  118. package/prisma/migrations/20260314000000_add_step_fields/migration.sql +22 -0
  119. package/prisma/migrations/20260315000000_add_operation_runs/migration.sql +24 -0
  120. package/prisma/migrations/20260315100000_add_step_runs/migration.sql +40 -0
  121. package/prisma/migrations/20260316000000_drop_order_name/migration.sql +12 -0
  122. package/prisma/migrations/20260317000000_add_attachments/migration.sql +28 -0
  123. package/prisma/migrations/20260317000000_add_items/migration.sql +21 -0
  124. package/prisma/migrations/20260317100000_add_order_item_id/migration.sql +8 -0
  125. package/prisma/migrations/20260318000000_add_labor_tickets/migration.sql +27 -0
  126. package/prisma/migrations/20260319000000_add_operation_dependencies/migration.sql +17 -0
  127. package/prisma/migrations/20260320000000_step_field_is_array/migration.sql +5 -0
  128. package/prisma/migrations/20260320100000_rename_is_array_to_multi_value/migration.sql +2 -0
  129. package/prisma/migrations/20260320200000_add_field_types/migration.sql +2 -0
  130. package/prisma/migrations/20260321000000_add_multi_set/migration.sql +13 -0
  131. package/prisma/migrations/20260322000000_add_field_sets/migration.sql +90 -0
  132. package/prisma/migrations/20260323000000_add_item_instances/migration.sql +18 -0
  133. package/prisma/migrations/20260324000000_add_field_records/migration.sql +77 -0
  134. package/prisma/migrations/20260325000000_add_run_costs/migration.sql +3 -0
  135. package/prisma/migrations/20260326000000_add_comments/migration.sql +16 -0
  136. package/prisma/migrations/20260327000000_move_assigned_to_op_run/migration.sql +3 -0
  137. package/prisma/migrations/20260328000000_add_step_completion_note/migration.sql +2 -0
  138. package/prisma/migrations/20260328000000_add_step_title/migration.sql +2 -0
  139. package/prisma/migrations/20260329000000_rename_notes_to_release_note/migration.sql +2 -0
  140. package/prisma/migrations/20260329000000_simplify_order_run_dates/migration.sql +5 -0
  141. package/prisma/migrations/20260330000000_add_operation_run_completion_note/migration.sql +2 -0
  142. package/prisma/migrations/20260331000000_add_work_centers/migration.sql +30 -0
  143. package/prisma/migrations/20260401000000_fix_field_values_column_shift/migration.sql +26 -0
  144. package/prisma/migrations/20260402000000_rename_completion_note_to_status_note/migration.sql +5 -0
  145. package/prisma/migrations/20260403000000_add_operation_field_refs/migration.sql +16 -0
  146. package/prisma/migrations/20260404000000_rename_multi_value_to_is_array/migration.sql +2 -0
  147. package/prisma/migrations/20260404100000_add_attachment_public_id/migration.sql +8 -0
  148. package/prisma/migrations/migration_lock.toml +3 -0
  149. package/prisma/schema.prisma +595 -0
  150. package/prisma.config.ts +18 -0
@@ -0,0 +1,595 @@
1
+ // NOTE: After adding a migration, update ERP_DB_VERSION in src/dbConfig.ts
2
+ // to match the new schema version number in the migration SQL.
3
+
4
+ datasource db {
5
+ provider = "sqlite"
6
+ }
7
+
8
+ generator client {
9
+ provider = "prisma-client"
10
+ output = "../src/generated/prisma"
11
+ }
12
+
13
+ enum OrderStatus {
14
+ active
15
+ archived
16
+ }
17
+
18
+ enum RevisionStatus {
19
+ draft
20
+ approved
21
+ obsolete
22
+ }
23
+
24
+ enum OrderRunStatus {
25
+ released
26
+ started
27
+ closed
28
+ cancelled
29
+ }
30
+
31
+ enum OrderRunPriority {
32
+ low
33
+ medium
34
+ high
35
+ critical
36
+ }
37
+
38
+ enum OperationRunStatus {
39
+ blocked
40
+ pending
41
+ in_progress
42
+ completed
43
+ skipped
44
+ failed
45
+ }
46
+
47
+ enum OperationRunCommentType {
48
+ note
49
+ issue
50
+ feedback
51
+ }
52
+
53
+ enum FieldType {
54
+ string
55
+ number
56
+ date
57
+ datetime
58
+ yesNo
59
+ checkbox
60
+ attachment
61
+ }
62
+
63
+ model Order {
64
+ id Int @id @default(autoincrement())
65
+ key String @unique
66
+ description String @default("")
67
+ status OrderStatus @default(active)
68
+ itemId Int? @map("item_id")
69
+ createdById Int @map("created_by")
70
+ createdAt DateTime @default(now()) @map("created_at")
71
+ updatedById Int @map("updated_by")
72
+ updatedAt DateTime @updatedAt @map("updated_at")
73
+
74
+ item Item? @relation(fields: [itemId], references: [id], onDelete: Restrict)
75
+ createdBy User @relation("orderCreatedBy", fields: [createdById], references: [id], onDelete: Restrict)
76
+ updatedBy User @relation("orderUpdatedBy", fields: [updatedById], references: [id], onDelete: Restrict)
77
+ revisions OrderRevision[]
78
+ orderRuns OrderRun[]
79
+
80
+ @@index([status]) // LIST filter in orders.ts
81
+ @@index([createdAt]) // LIST orderBy in orders.ts
82
+ @@index([itemId]) // FK lookup for item relation
83
+ @@map("orders")
84
+ }
85
+
86
+ model OrderRevision {
87
+ id Int @id @default(autoincrement())
88
+ orderId Int @map("order_id")
89
+ revNo Int @map("rev_no")
90
+ status RevisionStatus @default(draft)
91
+ description String @default("")
92
+ changeSummary String? @map("change_summary")
93
+ createdAt DateTime @default(now()) @map("created_at")
94
+ createdById Int @map("created_by")
95
+ updatedAt DateTime @updatedAt @map("updated_at")
96
+ updatedById Int @map("updated_by")
97
+ createdBy User @relation("orderRevCreatedBy", fields: [createdById], references: [id], onDelete: Restrict)
98
+ updatedBy User @relation("orderRevUpdatedBy", fields: [updatedById], references: [id], onDelete: Restrict)
99
+ order Order @relation(fields: [orderId], references: [id], onDelete: Restrict)
100
+ orderRuns OrderRun[]
101
+ operations Operation[]
102
+
103
+ @@unique([orderId, revNo])
104
+ @@map("order_revisions")
105
+ }
106
+
107
+ model Operation {
108
+ id Int @id @default(autoincrement())
109
+ orderRevId Int @map("order_rev_id")
110
+ workCenterId Int? @map("work_center_id")
111
+ seqNo Int @map("seq_no")
112
+ title String
113
+ description String @default("")
114
+ createdAt DateTime @default(now()) @map("created_at")
115
+ createdById Int @map("created_by")
116
+ updatedAt DateTime @updatedAt @map("updated_at")
117
+ updatedById Int @map("updated_by")
118
+
119
+ createdBy User @relation("opCreatedBy", fields: [createdById], references: [id], onDelete: Restrict)
120
+ updatedBy User @relation("opUpdatedBy", fields: [updatedById], references: [id], onDelete: Restrict)
121
+ orderRev OrderRevision @relation(fields: [orderRevId], references: [id], onDelete: Restrict)
122
+ workCenter WorkCenter? @relation(fields: [workCenterId], references: [id], onDelete: SetNull)
123
+ steps Step[]
124
+ fieldRefs OperationFieldRef[] @relation("opFieldRefs")
125
+ operationRuns OperationRun[]
126
+ predecessors OperationDependency[] @relation("opSuccessor")
127
+ successors OperationDependency[] @relation("opPredecessor")
128
+
129
+ @@unique([orderRevId, seqNo])
130
+ @@map("operations")
131
+ }
132
+
133
+ model OperationFieldRef {
134
+ id Int @id @default(autoincrement())
135
+ operationId Int @map("operation_id")
136
+ seqNo Int @map("seq_no")
137
+ title String
138
+ sourceStepId Int @map("source_step_id")
139
+ createdAt DateTime @default(now()) @map("created_at")
140
+ createdById Int @map("created_by")
141
+
142
+ operation Operation @relation("opFieldRefs", fields: [operationId], references: [id], onDelete: Cascade)
143
+ sourceStep Step @relation("fieldRefSource", fields: [sourceStepId], references: [id], onDelete: Restrict)
144
+ createdBy User @relation("fieldRefCreatedBy", fields: [createdById], references: [id], onDelete: Restrict)
145
+
146
+ @@unique([operationId, seqNo])
147
+ @@unique([operationId, sourceStepId])
148
+ @@map("operation_field_refs")
149
+ }
150
+
151
+ model OperationDependency {
152
+ id Int @id @default(autoincrement())
153
+ successorId Int @map("successor_id")
154
+ predecessorId Int @map("predecessor_id")
155
+ createdAt DateTime @default(now()) @map("created_at")
156
+ createdById Int @map("created_by")
157
+
158
+ successor Operation @relation("opSuccessor", fields: [successorId], references: [id], onDelete: Cascade)
159
+ predecessor Operation @relation("opPredecessor", fields: [predecessorId], references: [id], onDelete: Cascade)
160
+ createdBy User @relation("opDepCreatedBy", fields: [createdById], references: [id], onDelete: Restrict)
161
+
162
+ @@unique([successorId, predecessorId])
163
+ @@map("operation_dependencies")
164
+ }
165
+
166
+ model WorkCenter {
167
+ id Int @id @default(autoincrement())
168
+ key String @unique
169
+ description String @default("")
170
+ createdAt DateTime @default(now()) @map("created_at")
171
+ createdById Int @map("created_by")
172
+ updatedAt DateTime @updatedAt @map("updated_at")
173
+ updatedById Int @map("updated_by")
174
+
175
+ createdBy User @relation("workCenterCreatedBy", fields: [createdById], references: [id], onDelete: Restrict)
176
+ updatedBy User @relation("workCenterUpdatedBy", fields: [updatedById], references: [id], onDelete: Restrict)
177
+ userAssignments WorkCenterUser[]
178
+ operations Operation[]
179
+
180
+ @@index([createdAt])
181
+ @@map("work_centers")
182
+ }
183
+
184
+ model WorkCenterUser {
185
+ workCenterId Int @map("work_center_id")
186
+ userId Int @map("user_id")
187
+ createdAt DateTime @default(now()) @map("created_at")
188
+ createdById Int @map("created_by")
189
+
190
+ workCenter WorkCenter @relation(fields: [workCenterId], references: [id], onDelete: Cascade)
191
+ user User @relation("workCenterAssignment", fields: [userId], references: [id], onDelete: Cascade)
192
+ createdBy User @relation("workCenterUserCreatedBy", fields: [createdById], references: [id], onDelete: Restrict)
193
+
194
+ @@id([workCenterId, userId])
195
+ @@map("work_center_users")
196
+ }
197
+
198
+ model FieldSet {
199
+ id Int @id @default(autoincrement())
200
+ createdAt DateTime @default(now()) @map("created_at")
201
+ createdById Int @map("created_by")
202
+
203
+ createdBy User @relation("fieldSetCreatedBy", fields: [createdById], references: [id], onDelete: Restrict)
204
+ fields Field[]
205
+ fieldRecords FieldRecord[]
206
+ steps Step[]
207
+ items Item[]
208
+
209
+ @@map("field_sets")
210
+ }
211
+
212
+ model FieldRecord {
213
+ id Int @id @default(autoincrement())
214
+ fieldSetId Int @map("field_set_id")
215
+ createdAt DateTime @default(now()) @map("created_at")
216
+ createdById Int @map("created_by")
217
+
218
+ createdBy User @relation("fieldRecordCreatedBy", fields: [createdById], references: [id], onDelete: Restrict)
219
+ fieldSet FieldSet @relation(fields: [fieldSetId], references: [id])
220
+ fieldValues FieldValue[]
221
+ stepRuns StepRun[]
222
+ itemInstances ItemInstance[]
223
+
224
+ @@map("field_records")
225
+ }
226
+
227
+ model Field {
228
+ id Int @id @default(autoincrement())
229
+ fieldSetId Int @map("field_set_id")
230
+ seqNo Int @map("seq_no")
231
+ label String
232
+ type FieldType @default(string)
233
+ isArray Boolean @default(false) @map("is_array")
234
+ required Boolean @default(false)
235
+ createdAt DateTime @default(now()) @map("created_at")
236
+ createdById Int @map("created_by")
237
+ updatedAt DateTime @updatedAt @map("updated_at")
238
+ updatedById Int @map("updated_by")
239
+
240
+ createdBy User @relation("fieldCreatedBy", fields: [createdById], references: [id], onDelete: Restrict)
241
+ updatedBy User @relation("fieldUpdatedBy", fields: [updatedById], references: [id], onDelete: Restrict)
242
+ fieldSet FieldSet @relation(fields: [fieldSetId], references: [id], onDelete: Cascade)
243
+ fieldValues FieldValue[]
244
+
245
+ @@unique([fieldSetId, seqNo])
246
+ @@map("fields")
247
+ }
248
+
249
+ model Step {
250
+ id Int @id @default(autoincrement())
251
+ operationId Int @map("operation_id")
252
+ fieldSetId Int? @map("field_set_id")
253
+ seqNo Int @map("seq_no")
254
+ title String @default("")
255
+ instructions String @default("")
256
+ multiSet Boolean @default(false) @map("multi_set")
257
+ createdAt DateTime @default(now()) @map("created_at")
258
+ createdById Int @map("created_by")
259
+ updatedAt DateTime @updatedAt @map("updated_at")
260
+ updatedById Int @map("updated_by")
261
+
262
+ createdBy User @relation("stepCreatedBy", fields: [createdById], references: [id], onDelete: Restrict)
263
+ updatedBy User @relation("stepUpdatedBy", fields: [updatedById], references: [id], onDelete: Restrict)
264
+ operation Operation @relation(fields: [operationId], references: [id], onDelete: Cascade)
265
+ fieldSet FieldSet? @relation(fields: [fieldSetId], references: [id])
266
+ stepRuns StepRun[]
267
+ fieldRefSources OperationFieldRef[] @relation("fieldRefSource")
268
+
269
+ @@unique([operationId, seqNo])
270
+ @@map("steps")
271
+ }
272
+
273
+ model OrderRun {
274
+ id Int @id @default(autoincrement())
275
+ runNo Int @map("run_no")
276
+ orderId Int @map("order_id")
277
+ orderRevId Int @map("order_rev_id")
278
+ status OrderRunStatus @default(released)
279
+ priority OrderRunPriority @default(medium)
280
+ cost Float?
281
+ dueAt String? @map("due_at")
282
+ releaseNote String? @map("release_note")
283
+ createdAt DateTime @default(now()) @map("created_at")
284
+ createdById Int @map("created_by")
285
+ updatedAt DateTime @updatedAt @map("updated_at")
286
+ updatedById Int @map("updated_by")
287
+
288
+ createdBy User @relation("orderRunCreatedBy", fields: [createdById], references: [id], onDelete: Restrict)
289
+ updatedBy User @relation("orderRunUpdatedBy", fields: [updatedById], references: [id], onDelete: Restrict)
290
+ order Order @relation(fields: [orderId], references: [id], onDelete: Restrict)
291
+ orderRev OrderRevision @relation(fields: [orderRevId], references: [id], onDelete: Restrict)
292
+ operationRuns OperationRun[]
293
+ itemInstances ItemInstance[]
294
+
295
+ @@unique([orderId, runNo])
296
+ @@index([status]) // LIST filter in order-runs.ts
297
+ @@index([priority]) // LIST filter in order-runs.ts
298
+ @@index([createdAt]) // LIST orderBy in order-runs.ts
299
+ @@index([orderRevId]) // FK lookup for orderRev relation
300
+ @@map("order_runs")
301
+ }
302
+
303
+ model OperationRun {
304
+ id Int @id @default(autoincrement())
305
+ orderRunId Int @map("order_run_id")
306
+ operationId Int @map("operation_id")
307
+ status OperationRunStatus @default(pending)
308
+ assignedToId Int? @map("assigned_to_id")
309
+ cost Float?
310
+ statusNote String? @map("status_note")
311
+ completedAt DateTime? @map("completed_at")
312
+ createdAt DateTime @default(now()) @map("created_at")
313
+ createdById Int @map("created_by")
314
+ updatedAt DateTime @updatedAt @map("updated_at")
315
+ updatedById Int @map("updated_by")
316
+
317
+ assignedTo User? @relation("opRunAssignedTo", fields: [assignedToId], references: [id], onDelete: Restrict)
318
+ createdBy User @relation("opRunCreatedBy", fields: [createdById], references: [id], onDelete: Restrict)
319
+ updatedBy User @relation("opRunUpdatedBy", fields: [updatedById], references: [id], onDelete: Restrict)
320
+ orderRun OrderRun @relation(fields: [orderRunId], references: [id], onDelete: Restrict)
321
+ operation Operation @relation(fields: [operationId], references: [id], onDelete: Restrict)
322
+ stepRuns StepRun[]
323
+ laborTickets LaborTicket[]
324
+ comments OperationRunComment[]
325
+
326
+ @@unique([orderRunId, operationId])
327
+ @@index([status])
328
+ @@map("operation_runs")
329
+ }
330
+
331
+ model StepRun {
332
+ id Int @id @default(autoincrement())
333
+ operationRunId Int @map("operation_run_id")
334
+ stepId Int @map("step_id")
335
+ fieldRecordId Int? @map("field_record_id")
336
+ completed Boolean @default(false)
337
+ statusNote String? @map("status_note")
338
+ createdAt DateTime @default(now()) @map("created_at")
339
+ createdById Int @map("created_by")
340
+ updatedAt DateTime @updatedAt @map("updated_at")
341
+ updatedById Int @map("updated_by")
342
+
343
+ createdBy User @relation("stepRunCreatedBy", fields: [createdById], references: [id], onDelete: Restrict)
344
+ updatedBy User @relation("stepRunUpdatedBy", fields: [updatedById], references: [id], onDelete: Restrict)
345
+ operationRun OperationRun @relation(fields: [operationRunId], references: [id], onDelete: Restrict)
346
+ step Step @relation(fields: [stepId], references: [id], onDelete: Restrict)
347
+ fieldRecord FieldRecord? @relation(fields: [fieldRecordId], references: [id])
348
+
349
+ @@unique([operationRunId, stepId])
350
+ @@map("step_runs")
351
+ }
352
+
353
+ model FieldValue {
354
+ id Int @id @default(autoincrement())
355
+ fieldRecordId Int @map("field_record_id")
356
+ fieldId Int @map("field_id")
357
+ setIndex Int @default(0) @map("set_index")
358
+ value String @default("")
359
+ createdAt DateTime @default(now()) @map("created_at")
360
+ createdById Int @map("created_by")
361
+ updatedAt DateTime @updatedAt @map("updated_at")
362
+ updatedById Int @map("updated_by")
363
+
364
+ createdBy User @relation("fieldValueCreatedBy", fields: [createdById], references: [id], onDelete: Restrict)
365
+ updatedBy User @relation("fieldValueUpdatedBy", fields: [updatedById], references: [id], onDelete: Restrict)
366
+ fieldRecord FieldRecord @relation(fields: [fieldRecordId], references: [id], onDelete: Restrict)
367
+ field Field @relation(fields: [fieldId], references: [id], onDelete: Restrict)
368
+ fieldAttachments FieldAttachment[]
369
+
370
+ @@unique([fieldRecordId, fieldId, setIndex])
371
+ @@map("field_values")
372
+ }
373
+
374
+ model Item {
375
+ id Int @id @default(autoincrement())
376
+ key String @unique
377
+ description String @default("")
378
+ fieldSetId Int? @map("field_set_id")
379
+ createdAt DateTime @default(now()) @map("created_at")
380
+ createdById Int @map("created_by")
381
+ updatedAt DateTime @updatedAt @map("updated_at")
382
+ updatedById Int @map("updated_by")
383
+
384
+ createdBy User @relation("itemCreatedBy", fields: [createdById], references: [id], onDelete: Restrict)
385
+ updatedBy User @relation("itemUpdatedBy", fields: [updatedById], references: [id], onDelete: Restrict)
386
+ fieldSet FieldSet? @relation(fields: [fieldSetId], references: [id])
387
+ orders Order[]
388
+ itemInstances ItemInstance[]
389
+
390
+ @@index([createdAt])
391
+ @@map("items")
392
+ }
393
+
394
+ model ItemInstance {
395
+ id Int @id @default(autoincrement())
396
+ itemId Int @map("item_id")
397
+ orderRunId Int? @map("order_run_id")
398
+ fieldRecordId Int? @map("field_record_id")
399
+ key String
400
+ quantity Float?
401
+ createdAt DateTime @default(now()) @map("created_at")
402
+ createdById Int @map("created_by")
403
+ updatedAt DateTime @updatedAt @map("updated_at")
404
+ updatedById Int @map("updated_by")
405
+
406
+ item Item @relation(fields: [itemId], references: [id], onDelete: Restrict)
407
+ orderRun OrderRun? @relation(fields: [orderRunId], references: [id], onDelete: Restrict)
408
+ fieldRecord FieldRecord? @relation(fields: [fieldRecordId], references: [id])
409
+ createdBy User @relation("itemInstanceCreatedBy", fields: [createdById], references: [id], onDelete: Restrict)
410
+ updatedBy User @relation("itemInstanceUpdatedBy", fields: [updatedById], references: [id], onDelete: Restrict)
411
+
412
+ @@unique([itemId, key])
413
+ @@index([orderRunId])
414
+ @@map("item_instances")
415
+ }
416
+
417
+ model User {
418
+ id Int @id @default(autoincrement())
419
+ uuid String @unique
420
+ username String @unique
421
+ passwordHash String @map("password_hash")
422
+ apiKey String? @unique @map("api_key")
423
+ isAgent Boolean @default(false) @map("is_agent")
424
+ createdAt DateTime @default(now()) @map("created_at")
425
+ updatedAt DateTime @updatedAt @map("updated_at")
426
+ deletedAt DateTime? @map("deleted_at")
427
+
428
+ itemsCreated Item[] @relation("itemCreatedBy")
429
+ itemsUpdated Item[] @relation("itemUpdatedBy")
430
+ ordersCreated Order[] @relation("orderCreatedBy")
431
+ ordersUpdated Order[] @relation("orderUpdatedBy")
432
+ orderRevsCreated OrderRevision[] @relation("orderRevCreatedBy")
433
+ orderRevsUpdated OrderRevision[] @relation("orderRevUpdatedBy")
434
+ orderRunsCreated OrderRun[] @relation("orderRunCreatedBy")
435
+ orderRunsUpdated OrderRun[] @relation("orderRunUpdatedBy")
436
+ opsCreated Operation[] @relation("opCreatedBy")
437
+ opsUpdated Operation[] @relation("opUpdatedBy")
438
+ opDepsCreated OperationDependency[] @relation("opDepCreatedBy")
439
+ fieldRefsCreated OperationFieldRef[] @relation("fieldRefCreatedBy")
440
+ fieldSetsCreated FieldSet[] @relation("fieldSetCreatedBy")
441
+ stepsCreated Step[] @relation("stepCreatedBy")
442
+ stepsUpdated Step[] @relation("stepUpdatedBy")
443
+ fieldsCreated Field[] @relation("fieldCreatedBy")
444
+ fieldsUpdated Field[] @relation("fieldUpdatedBy")
445
+ opRunsCreated OperationRun[] @relation("opRunCreatedBy")
446
+ opRunsUpdated OperationRun[] @relation("opRunUpdatedBy")
447
+ stepRunsCreated StepRun[] @relation("stepRunCreatedBy")
448
+ stepRunsUpdated StepRun[] @relation("stepRunUpdatedBy")
449
+ fieldRecordsCreated FieldRecord[] @relation("fieldRecordCreatedBy")
450
+ fieldValuesCreated FieldValue[] @relation("fieldValueCreatedBy")
451
+ fieldValuesUpdated FieldValue[] @relation("fieldValueUpdatedBy")
452
+ itemInstancesCreated ItemInstance[] @relation("itemInstanceCreatedBy")
453
+ itemInstancesUpdated ItemInstance[] @relation("itemInstanceUpdatedBy")
454
+ laborTicketsWorked LaborTicket[] @relation("laborTicketUser")
455
+ laborTicketsCreated LaborTicket[] @relation("laborTicketCreatedBy")
456
+ laborTicketsUpdated LaborTicket[] @relation("laborTicketUpdatedBy")
457
+ auditLogs AuditLog[]
458
+ sessions Session[]
459
+ permissions UserPermission[] @relation("userPermissions")
460
+ grantedPermissions UserPermission[] @relation("permissionGrantedBy")
461
+ attachmentsUploaded Attachment[] @relation("attachmentUploadedBy")
462
+ commentsCreated OperationRunComment[] @relation("commentCreatedBy")
463
+ opRunsAssigned OperationRun[] @relation("opRunAssignedTo")
464
+ workCentersCreated WorkCenter[] @relation("workCenterCreatedBy")
465
+ workCentersUpdated WorkCenter[] @relation("workCenterUpdatedBy")
466
+ workCenterAssignments WorkCenterUser[] @relation("workCenterAssignment")
467
+ workCenterUsersCreated WorkCenterUser[] @relation("workCenterUserCreatedBy")
468
+
469
+ @@map("users")
470
+ }
471
+
472
+ enum ErpPermission {
473
+ erp_admin
474
+ order_planner
475
+ order_executor
476
+ order_manager
477
+ item_manager
478
+ }
479
+
480
+ model UserPermission {
481
+ id Int @id @default(autoincrement())
482
+ userId Int @map("user_id")
483
+ permission ErpPermission
484
+ grantedAt DateTime @default(now()) @map("granted_at")
485
+ grantedBy Int? @map("granted_by")
486
+
487
+ user User @relation("userPermissions", fields: [userId], references: [id], onDelete: Cascade)
488
+ grantedByUser User? @relation("permissionGrantedBy", fields: [grantedBy], references: [id], onDelete: SetNull)
489
+
490
+ @@unique([userId, permission])
491
+ @@map("user_permissions")
492
+ }
493
+
494
+ model Session {
495
+ id Int @id @default(autoincrement())
496
+ userId Int @map("user_id")
497
+ tokenHash String @unique @map("token_hash")
498
+ expiresAt DateTime @map("expires_at")
499
+ createdAt DateTime @default(now()) @map("created_at")
500
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
501
+
502
+ @@map("sessions")
503
+ }
504
+
505
+ model SchemaVersion {
506
+ id Int @id @default(1)
507
+ version Int
508
+ updated String
509
+
510
+ @@map("schema_version")
511
+ }
512
+
513
+ model LaborTicket {
514
+ id Int @id @default(autoincrement())
515
+ operationRunId Int @map("operation_run_id")
516
+ userId Int @map("user_id")
517
+ runId Int? @map("run_id")
518
+ clockIn DateTime @map("clock_in")
519
+ clockOut DateTime? @map("clock_out")
520
+ cost Float?
521
+ createdAt DateTime @default(now()) @map("created_at")
522
+ createdById Int @map("created_by")
523
+ updatedAt DateTime @updatedAt @map("updated_at")
524
+ updatedById Int @map("updated_by")
525
+
526
+ operationRun OperationRun @relation(fields: [operationRunId], references: [id], onDelete: Restrict)
527
+ user User @relation("laborTicketUser", fields: [userId], references: [id], onDelete: Restrict)
528
+ createdBy User @relation("laborTicketCreatedBy", fields: [createdById], references: [id], onDelete: Restrict)
529
+ updatedBy User @relation("laborTicketUpdatedBy", fields: [updatedById], references: [id], onDelete: Restrict)
530
+
531
+ @@index([operationRunId])
532
+ @@index([userId, clockOut])
533
+ @@map("labor_tickets")
534
+ }
535
+
536
+ model AuditLog {
537
+ id Int @id @default(autoincrement())
538
+ entityType String @map("entity_type")
539
+ entityId Int @map("entity_id")
540
+ action String
541
+ field String
542
+ oldValue String? @map("old_value")
543
+ newValue String? @map("new_value")
544
+ userId Int @map("user_id")
545
+ createdAt DateTime @default(now()) @map("created_at")
546
+
547
+ user User @relation(fields: [userId], references: [id], onDelete: Restrict)
548
+
549
+ @@index([entityType, entityId])
550
+ @@map("audit_log")
551
+ }
552
+
553
+ model Attachment {
554
+ id Int @id @default(autoincrement())
555
+ publicId String @unique @map("public_id")
556
+ filepath String
557
+ filename String
558
+ fileSize Int @map("file_size")
559
+ fileHash String @map("file_hash")
560
+ uploadedById Int @map("uploaded_by")
561
+ createdAt DateTime @default(now()) @map("created_at")
562
+
563
+ uploadedBy User @relation("attachmentUploadedBy", fields: [uploadedById], references: [id], onDelete: Restrict)
564
+ fieldAttachments FieldAttachment[]
565
+
566
+ @@index([fileHash])
567
+ @@map("attachments")
568
+ }
569
+
570
+ model FieldAttachment {
571
+ fieldValueId Int @map("field_value_id")
572
+ attachmentId Int @map("attachment_id")
573
+ createdAt DateTime @default(now()) @map("created_at")
574
+
575
+ fieldValue FieldValue @relation(fields: [fieldValueId], references: [id], onDelete: Cascade)
576
+ attachment Attachment @relation(fields: [attachmentId], references: [id], onDelete: Restrict)
577
+
578
+ @@id([fieldValueId, attachmentId])
579
+ @@map("field_attachments")
580
+ }
581
+
582
+ model OperationRunComment {
583
+ id Int @id @default(autoincrement())
584
+ operationRunId Int @map("operation_run_id")
585
+ type OperationRunCommentType @default(note)
586
+ body String
587
+ createdAt DateTime @default(now()) @map("created_at")
588
+ createdById Int @map("created_by")
589
+
590
+ operationRun OperationRun @relation(fields: [operationRunId], references: [id], onDelete: Restrict)
591
+ createdBy User @relation("commentCreatedBy", fields: [createdById], references: [id], onDelete: Restrict)
592
+
593
+ @@index([operationRunId])
594
+ @@map("operation_run_comments")
595
+ }
@@ -0,0 +1,18 @@
1
+ import "dotenv/config";
2
+ import { join } from "path";
3
+ import { defineConfig } from "prisma/config";
4
+
5
+ // Use placeholder during generation, actual path provided at runtime
6
+ const naisysFolder = process.env.NAISYS_FOLDER || "";
7
+
8
+ export default defineConfig({
9
+ schema: "prisma/schema.prisma",
10
+ migrations: {
11
+ path: "prisma/migrations",
12
+ },
13
+ datasource: {
14
+ // Used in dev when we run migrate manually to generate migration scripts
15
+ // Used in prod when self-migrating an existing database
16
+ url: `file:` + join(naisysFolder, "database", `naisys_erp.db`),
17
+ },
18
+ });