@naisys/erp 3.0.0-beta.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.

Potentially problematic release.


This version of @naisys/erp might be problematic. Click here for more details.

Files changed (201) 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.d.ts +10 -0
  12. package/dist/api-reference.js +101 -0
  13. package/dist/audit.d.ts +5 -0
  14. package/dist/audit.js +14 -0
  15. package/dist/auth-middleware.d.ts +18 -0
  16. package/dist/auth-middleware.js +203 -0
  17. package/dist/dbConfig.d.ts +5 -0
  18. package/dist/dbConfig.js +10 -0
  19. package/dist/erpDb.d.ts +10 -0
  20. package/dist/erpDb.js +34 -0
  21. package/dist/erpServer.d.ts +10 -0
  22. package/dist/erpServer.js +321 -0
  23. package/dist/error-handler.d.ts +7 -0
  24. package/dist/error-handler.js +17 -0
  25. package/dist/generated/prisma/client.d.ts +154 -0
  26. package/dist/generated/prisma/client.js +35 -0
  27. package/dist/generated/prisma/commonInputTypes.d.ts +637 -0
  28. package/dist/generated/prisma/commonInputTypes.js +11 -0
  29. package/dist/generated/prisma/enums.d.ts +59 -0
  30. package/dist/generated/prisma/enums.js +60 -0
  31. package/dist/generated/prisma/internal/class.d.ts +406 -0
  32. package/dist/generated/prisma/internal/class.js +50 -0
  33. package/dist/generated/prisma/internal/prismaNamespace.d.ts +2722 -0
  34. package/dist/generated/prisma/internal/prismaNamespace.js +366 -0
  35. package/dist/generated/prisma/models/Attachment.d.ts +1455 -0
  36. package/dist/generated/prisma/models/Attachment.js +2 -0
  37. package/dist/generated/prisma/models/AuditLog.d.ts +1359 -0
  38. package/dist/generated/prisma/models/AuditLog.js +2 -0
  39. package/dist/generated/prisma/models/Field.d.ts +1880 -0
  40. package/dist/generated/prisma/models/Field.js +2 -0
  41. package/dist/generated/prisma/models/FieldAttachment.d.ts +1245 -0
  42. package/dist/generated/prisma/models/FieldAttachment.js +2 -0
  43. package/dist/generated/prisma/models/FieldRecord.d.ts +1625 -0
  44. package/dist/generated/prisma/models/FieldRecord.js +2 -0
  45. package/dist/generated/prisma/models/FieldSet.d.ts +1577 -0
  46. package/dist/generated/prisma/models/FieldSet.js +2 -0
  47. package/dist/generated/prisma/models/FieldValue.d.ts +1908 -0
  48. package/dist/generated/prisma/models/FieldValue.js +2 -0
  49. package/dist/generated/prisma/models/Item.d.ts +1858 -0
  50. package/dist/generated/prisma/models/Item.js +2 -0
  51. package/dist/generated/prisma/models/ItemInstance.d.ts +1987 -0
  52. package/dist/generated/prisma/models/ItemInstance.js +2 -0
  53. package/dist/generated/prisma/models/LaborTicket.d.ts +1867 -0
  54. package/dist/generated/prisma/models/LaborTicket.js +2 -0
  55. package/dist/generated/prisma/models/Operation.d.ts +2578 -0
  56. package/dist/generated/prisma/models/Operation.js +2 -0
  57. package/dist/generated/prisma/models/OperationDependency.d.ts +1434 -0
  58. package/dist/generated/prisma/models/OperationDependency.js +2 -0
  59. package/dist/generated/prisma/models/OperationFieldRef.d.ts +1539 -0
  60. package/dist/generated/prisma/models/OperationFieldRef.js +2 -0
  61. package/dist/generated/prisma/models/OperationRun.d.ts +2563 -0
  62. package/dist/generated/prisma/models/OperationRun.js +2 -0
  63. package/dist/generated/prisma/models/OperationRunComment.d.ts +1366 -0
  64. package/dist/generated/prisma/models/OperationRunComment.js +2 -0
  65. package/dist/generated/prisma/models/Order.d.ts +1931 -0
  66. package/dist/generated/prisma/models/Order.js +2 -0
  67. package/dist/generated/prisma/models/OrderRevision.d.ts +1962 -0
  68. package/dist/generated/prisma/models/OrderRevision.js +2 -0
  69. package/dist/generated/prisma/models/OrderRun.d.ts +2310 -0
  70. package/dist/generated/prisma/models/OrderRun.js +2 -0
  71. package/dist/generated/prisma/models/SchemaVersion.d.ts +985 -0
  72. package/dist/generated/prisma/models/SchemaVersion.js +2 -0
  73. package/dist/generated/prisma/models/Session.d.ts +1213 -0
  74. package/dist/generated/prisma/models/Session.js +2 -0
  75. package/dist/generated/prisma/models/Step.d.ts +2180 -0
  76. package/dist/generated/prisma/models/Step.js +2 -0
  77. package/dist/generated/prisma/models/StepRun.d.ts +1963 -0
  78. package/dist/generated/prisma/models/StepRun.js +2 -0
  79. package/dist/generated/prisma/models/User.d.ts +11819 -0
  80. package/dist/generated/prisma/models/User.js +2 -0
  81. package/dist/generated/prisma/models/UserPermission.d.ts +1348 -0
  82. package/dist/generated/prisma/models/UserPermission.js +2 -0
  83. package/dist/generated/prisma/models/WorkCenter.d.ts +1657 -0
  84. package/dist/generated/prisma/models/WorkCenter.js +2 -0
  85. package/dist/generated/prisma/models/WorkCenterUser.d.ts +1390 -0
  86. package/dist/generated/prisma/models/WorkCenterUser.js +2 -0
  87. package/dist/generated/prisma/models.d.ts +28 -0
  88. package/dist/generated/prisma/models.js +2 -0
  89. package/dist/hateoas.d.ts +7 -0
  90. package/dist/hateoas.js +61 -0
  91. package/dist/route-helpers.d.ts +318 -0
  92. package/dist/route-helpers.js +220 -0
  93. package/dist/routes/admin.d.ts +3 -0
  94. package/dist/routes/admin.js +147 -0
  95. package/dist/routes/audit.d.ts +3 -0
  96. package/dist/routes/audit.js +36 -0
  97. package/dist/routes/auth.d.ts +3 -0
  98. package/dist/routes/auth.js +112 -0
  99. package/dist/routes/dispatch.d.ts +3 -0
  100. package/dist/routes/dispatch.js +174 -0
  101. package/dist/routes/inventory.d.ts +3 -0
  102. package/dist/routes/inventory.js +70 -0
  103. package/dist/routes/item-fields.d.ts +3 -0
  104. package/dist/routes/item-fields.js +220 -0
  105. package/dist/routes/item-instances.d.ts +3 -0
  106. package/dist/routes/item-instances.js +426 -0
  107. package/dist/routes/items.d.ts +3 -0
  108. package/dist/routes/items.js +252 -0
  109. package/dist/routes/labor-tickets.d.ts +3 -0
  110. package/dist/routes/labor-tickets.js +268 -0
  111. package/dist/routes/operation-dependencies.d.ts +3 -0
  112. package/dist/routes/operation-dependencies.js +170 -0
  113. package/dist/routes/operation-field-refs.d.ts +3 -0
  114. package/dist/routes/operation-field-refs.js +263 -0
  115. package/dist/routes/operation-run-comments.d.ts +3 -0
  116. package/dist/routes/operation-run-comments.js +108 -0
  117. package/dist/routes/operation-run-transitions.d.ts +3 -0
  118. package/dist/routes/operation-run-transitions.js +249 -0
  119. package/dist/routes/operation-runs.d.ts +112 -0
  120. package/dist/routes/operation-runs.js +299 -0
  121. package/dist/routes/operations.d.ts +3 -0
  122. package/dist/routes/operations.js +283 -0
  123. package/dist/routes/order-revision-transitions.d.ts +3 -0
  124. package/dist/routes/order-revision-transitions.js +86 -0
  125. package/dist/routes/order-revisions.d.ts +51 -0
  126. package/dist/routes/order-revisions.js +327 -0
  127. package/dist/routes/order-run-transitions.d.ts +3 -0
  128. package/dist/routes/order-run-transitions.js +215 -0
  129. package/dist/routes/order-runs.d.ts +58 -0
  130. package/dist/routes/order-runs.js +335 -0
  131. package/dist/routes/orders.d.ts +3 -0
  132. package/dist/routes/orders.js +262 -0
  133. package/dist/routes/root.d.ts +3 -0
  134. package/dist/routes/root.js +123 -0
  135. package/dist/routes/schemas.d.ts +3 -0
  136. package/dist/routes/schemas.js +31 -0
  137. package/dist/routes/step-field-attachments.d.ts +3 -0
  138. package/dist/routes/step-field-attachments.js +231 -0
  139. package/dist/routes/step-fields.d.ts +100 -0
  140. package/dist/routes/step-fields.js +315 -0
  141. package/dist/routes/step-run-fields.d.ts +3 -0
  142. package/dist/routes/step-run-fields.js +438 -0
  143. package/dist/routes/step-run-transitions.d.ts +3 -0
  144. package/dist/routes/step-run-transitions.js +113 -0
  145. package/dist/routes/step-runs.d.ts +332 -0
  146. package/dist/routes/step-runs.js +324 -0
  147. package/dist/routes/steps.d.ts +3 -0
  148. package/dist/routes/steps.js +283 -0
  149. package/dist/routes/user-permissions.d.ts +3 -0
  150. package/dist/routes/user-permissions.js +100 -0
  151. package/dist/routes/users.d.ts +57 -0
  152. package/dist/routes/users.js +381 -0
  153. package/dist/routes/work-centers.d.ts +3 -0
  154. package/dist/routes/work-centers.js +280 -0
  155. package/dist/schema-registry.d.ts +3 -0
  156. package/dist/schema-registry.js +45 -0
  157. package/dist/services/attachment-service.d.ts +33 -0
  158. package/dist/services/attachment-service.js +118 -0
  159. package/dist/services/field-ref-service.d.ts +96 -0
  160. package/dist/services/field-ref-service.js +74 -0
  161. package/dist/services/field-service.d.ts +49 -0
  162. package/dist/services/field-service.js +114 -0
  163. package/dist/services/field-value-service.d.ts +61 -0
  164. package/dist/services/field-value-service.js +256 -0
  165. package/dist/services/item-instance-service.d.ts +152 -0
  166. package/dist/services/item-instance-service.js +155 -0
  167. package/dist/services/item-service.d.ts +47 -0
  168. package/dist/services/item-service.js +56 -0
  169. package/dist/services/labor-ticket-service.d.ts +40 -0
  170. package/dist/services/labor-ticket-service.js +148 -0
  171. package/dist/services/log-file-service.d.ts +4 -0
  172. package/dist/services/log-file-service.js +11 -0
  173. package/dist/services/operation-dependency-service.d.ts +33 -0
  174. package/dist/services/operation-dependency-service.js +30 -0
  175. package/dist/services/operation-run-comment-service.d.ts +17 -0
  176. package/dist/services/operation-run-comment-service.js +26 -0
  177. package/dist/services/operation-run-service.d.ts +126 -0
  178. package/dist/services/operation-run-service.js +347 -0
  179. package/dist/services/operation-service.d.ts +47 -0
  180. package/dist/services/operation-service.js +132 -0
  181. package/dist/services/order-revision-service.d.ts +53 -0
  182. package/dist/services/order-revision-service.js +264 -0
  183. package/dist/services/order-run-service.d.ts +138 -0
  184. package/dist/services/order-run-service.js +356 -0
  185. package/dist/services/order-service.d.ts +15 -0
  186. package/dist/services/order-service.js +68 -0
  187. package/dist/services/revision-diff-service.d.ts +3 -0
  188. package/dist/services/revision-diff-service.js +194 -0
  189. package/dist/services/step-run-service.d.ts +172 -0
  190. package/dist/services/step-run-service.js +106 -0
  191. package/dist/services/step-service.d.ts +104 -0
  192. package/dist/services/step-service.js +89 -0
  193. package/dist/services/user-service.d.ts +185 -0
  194. package/dist/services/user-service.js +132 -0
  195. package/dist/services/work-center-service.d.ts +29 -0
  196. package/dist/services/work-center-service.js +106 -0
  197. package/dist/supervisorAuth.d.ts +3 -0
  198. package/dist/supervisorAuth.js +16 -0
  199. package/dist/userService.d.ts +20 -0
  200. package/dist/userService.js +118 -0
  201. package/package.json +69 -0
@@ -0,0 +1,332 @@
1
+ import type { FastifyInstance } from "fastify";
2
+ import type { ErpUser } from "../auth-middleware.js";
3
+ import { validateFieldValue } from "../services/field-value-service.js";
4
+ import { type StepRunWithStepAndFields } from "../services/step-run-service.js";
5
+ export declare function stepRunResource(orderKey: string, runNo: number, seqNo: number): string;
6
+ export declare function buildStepRunActionTemplates(stepRunHref: string, canUpdate: boolean, multiSet: boolean, hasAttachmentFields: boolean, hasArrayFields: boolean): ({
7
+ rel: string;
8
+ hrefTemplate: string;
9
+ method: "PUT";
10
+ title: string;
11
+ schema: string;
12
+ body: {
13
+ value: string | string[];
14
+ fieldValues?: undefined;
15
+ };
16
+ alternateEncoding?: undefined;
17
+ } | {
18
+ rel: string;
19
+ hrefTemplate: string;
20
+ method: "PUT";
21
+ title: string;
22
+ schema: string;
23
+ body: {
24
+ fieldValues: ({
25
+ fieldSeqNo: number;
26
+ value: string;
27
+ } | {
28
+ fieldSeqNo: number;
29
+ value: string[];
30
+ })[];
31
+ value?: undefined;
32
+ };
33
+ alternateEncoding?: undefined;
34
+ } | {
35
+ rel: string;
36
+ hrefTemplate: string;
37
+ method: "DELETE";
38
+ title: string;
39
+ schema?: undefined;
40
+ body?: undefined;
41
+ alternateEncoding?: undefined;
42
+ } | {
43
+ rel: string;
44
+ hrefTemplate: string;
45
+ method: "POST";
46
+ title: string;
47
+ alternateEncoding: {
48
+ contentType: string;
49
+ description: string;
50
+ fileFields: string[];
51
+ };
52
+ schema?: undefined;
53
+ body?: undefined;
54
+ } | {
55
+ rel: string;
56
+ hrefTemplate: string;
57
+ method: "GET";
58
+ title: string;
59
+ schema?: undefined;
60
+ body?: undefined;
61
+ alternateEncoding?: undefined;
62
+ })[];
63
+ /** Compute just the HATEOAS actions + action templates for a step run */
64
+ export declare function computeStepRunHateoas(orderKey: string, runNo: number, seqNo: number, stepSeqNo: number, opRunId: number, operationId: number, opRunStatus: string, completed: boolean, stepRunId: number, multiSet: boolean, hasAttachmentFields: boolean, hasArrayFields: boolean, user: ErpUser | undefined): Promise<{
65
+ _actions: {
66
+ rel: string;
67
+ href: string;
68
+ method: string;
69
+ title?: string | undefined;
70
+ schema?: string | undefined;
71
+ body?: Record<string, unknown> | undefined;
72
+ alternateEncoding?: {
73
+ contentType: string;
74
+ fileFields: string[];
75
+ description?: string | undefined;
76
+ } | undefined;
77
+ disabled?: boolean | undefined;
78
+ disabledReason?: string | string[] | undefined;
79
+ }[];
80
+ _actionTemplates: ({
81
+ rel: string;
82
+ hrefTemplate: string;
83
+ method: "PUT";
84
+ title: string;
85
+ schema: string;
86
+ body: {
87
+ value: string | string[];
88
+ fieldValues?: undefined;
89
+ };
90
+ alternateEncoding?: undefined;
91
+ } | {
92
+ rel: string;
93
+ hrefTemplate: string;
94
+ method: "PUT";
95
+ title: string;
96
+ schema: string;
97
+ body: {
98
+ fieldValues: ({
99
+ fieldSeqNo: number;
100
+ value: string;
101
+ } | {
102
+ fieldSeqNo: number;
103
+ value: string[];
104
+ })[];
105
+ value?: undefined;
106
+ };
107
+ alternateEncoding?: undefined;
108
+ } | {
109
+ rel: string;
110
+ hrefTemplate: string;
111
+ method: "DELETE";
112
+ title: string;
113
+ schema?: undefined;
114
+ body?: undefined;
115
+ alternateEncoding?: undefined;
116
+ } | {
117
+ rel: string;
118
+ hrefTemplate: string;
119
+ method: "POST";
120
+ title: string;
121
+ alternateEncoding: {
122
+ contentType: string;
123
+ description: string;
124
+ fileFields: string[];
125
+ };
126
+ schema?: undefined;
127
+ body?: undefined;
128
+ } | {
129
+ rel: string;
130
+ hrefTemplate: string;
131
+ method: "GET";
132
+ title: string;
133
+ schema?: undefined;
134
+ body?: undefined;
135
+ alternateEncoding?: undefined;
136
+ })[];
137
+ }>;
138
+ export declare function formatStepRunTransition(orderKey: string, runNo: number, seqNo: number, opRunId: number, operationId: number, opRunStatus: string, user: ErpUser | undefined, stepRun: StepRunWithStepAndFields): Promise<{
139
+ _actions: {
140
+ rel: string;
141
+ href: string;
142
+ method: string;
143
+ title?: string | undefined;
144
+ schema?: string | undefined;
145
+ body?: Record<string, unknown> | undefined;
146
+ alternateEncoding?: {
147
+ contentType: string;
148
+ fileFields: string[];
149
+ description?: string | undefined;
150
+ } | undefined;
151
+ disabled?: boolean | undefined;
152
+ disabledReason?: string | string[] | undefined;
153
+ }[];
154
+ _actionTemplates: ({
155
+ rel: string;
156
+ hrefTemplate: string;
157
+ method: "PUT";
158
+ title: string;
159
+ schema: string;
160
+ body: {
161
+ value: string | string[];
162
+ fieldValues?: undefined;
163
+ };
164
+ alternateEncoding?: undefined;
165
+ } | {
166
+ rel: string;
167
+ hrefTemplate: string;
168
+ method: "PUT";
169
+ title: string;
170
+ schema: string;
171
+ body: {
172
+ fieldValues: ({
173
+ fieldSeqNo: number;
174
+ value: string;
175
+ } | {
176
+ fieldSeqNo: number;
177
+ value: string[];
178
+ })[];
179
+ value?: undefined;
180
+ };
181
+ alternateEncoding?: undefined;
182
+ } | {
183
+ rel: string;
184
+ hrefTemplate: string;
185
+ method: "DELETE";
186
+ title: string;
187
+ schema?: undefined;
188
+ body?: undefined;
189
+ alternateEncoding?: undefined;
190
+ } | {
191
+ rel: string;
192
+ hrefTemplate: string;
193
+ method: "POST";
194
+ title: string;
195
+ alternateEncoding: {
196
+ contentType: string;
197
+ description: string;
198
+ fileFields: string[];
199
+ };
200
+ schema?: undefined;
201
+ body?: undefined;
202
+ } | {
203
+ rel: string;
204
+ hrefTemplate: string;
205
+ method: "GET";
206
+ title: string;
207
+ schema?: undefined;
208
+ body?: undefined;
209
+ alternateEncoding?: undefined;
210
+ })[];
211
+ createdAt: string;
212
+ createdBy: string;
213
+ updatedAt: string;
214
+ updatedBy: string;
215
+ id: number;
216
+ completed: boolean;
217
+ note: string | null;
218
+ }>;
219
+ export declare function formatStepRunWithFields(orderKey: string, runNo: number, seqNo: number, opRunId: number, operationId: number, opRunStatus: string, user: ErpUser | undefined, stepRun: StepRunWithStepAndFields): Promise<{
220
+ _actions: {
221
+ rel: string;
222
+ href: string;
223
+ method: string;
224
+ title?: string | undefined;
225
+ schema?: string | undefined;
226
+ body?: Record<string, unknown> | undefined;
227
+ alternateEncoding?: {
228
+ contentType: string;
229
+ fileFields: string[];
230
+ description?: string | undefined;
231
+ } | undefined;
232
+ disabled?: boolean | undefined;
233
+ disabledReason?: string | string[] | undefined;
234
+ }[];
235
+ _actionTemplates: ({
236
+ rel: string;
237
+ hrefTemplate: string;
238
+ method: "PUT";
239
+ title: string;
240
+ schema: string;
241
+ body: {
242
+ value: string | string[];
243
+ fieldValues?: undefined;
244
+ };
245
+ alternateEncoding?: undefined;
246
+ } | {
247
+ rel: string;
248
+ hrefTemplate: string;
249
+ method: "PUT";
250
+ title: string;
251
+ schema: string;
252
+ body: {
253
+ fieldValues: ({
254
+ fieldSeqNo: number;
255
+ value: string;
256
+ } | {
257
+ fieldSeqNo: number;
258
+ value: string[];
259
+ })[];
260
+ value?: undefined;
261
+ };
262
+ alternateEncoding?: undefined;
263
+ } | {
264
+ rel: string;
265
+ hrefTemplate: string;
266
+ method: "DELETE";
267
+ title: string;
268
+ schema?: undefined;
269
+ body?: undefined;
270
+ alternateEncoding?: undefined;
271
+ } | {
272
+ rel: string;
273
+ hrefTemplate: string;
274
+ method: "POST";
275
+ title: string;
276
+ alternateEncoding: {
277
+ contentType: string;
278
+ description: string;
279
+ fileFields: string[];
280
+ };
281
+ schema?: undefined;
282
+ body?: undefined;
283
+ } | {
284
+ rel: string;
285
+ hrefTemplate: string;
286
+ method: "GET";
287
+ title: string;
288
+ schema?: undefined;
289
+ body?: undefined;
290
+ alternateEncoding?: undefined;
291
+ })[];
292
+ _links: {
293
+ rel: string;
294
+ href: string;
295
+ method?: string | undefined;
296
+ title?: string | undefined;
297
+ schema?: string | undefined;
298
+ }[];
299
+ createdAt: string;
300
+ createdBy: string;
301
+ updatedAt: string;
302
+ updatedBy: string;
303
+ id: number;
304
+ operationRunId: number;
305
+ stepId: number;
306
+ seqNo: number;
307
+ title: string;
308
+ instructions: string;
309
+ multiSet: boolean;
310
+ completed: boolean;
311
+ note: string | null;
312
+ fieldCount: number;
313
+ fieldValues: {
314
+ fieldId: number;
315
+ fieldSeqNo: number;
316
+ label: string;
317
+ type: string;
318
+ valueFormat: string;
319
+ required: boolean;
320
+ setIndex: number;
321
+ value: string | string[];
322
+ attachments?: {
323
+ id: string;
324
+ filename: string;
325
+ fileSize: number;
326
+ downloadHref?: string;
327
+ }[];
328
+ validation: ReturnType<typeof validateFieldValue>;
329
+ }[];
330
+ }>;
331
+ export default function stepRunRoutes(fastify: FastifyInstance): void;
332
+ //# sourceMappingURL=step-runs.d.ts.map
@@ -0,0 +1,324 @@
1
+ import { ErrorResponseSchema, fieldTypeString, getValueFormatHint, OperationRunStatus, StepRunListQuerySchema, StepRunListResponseSchema, StepRunSchema, } from "@naisys/erp-shared";
2
+ import { z } from "zod/v4";
3
+ import { hasPermission } from "../auth-middleware.js";
4
+ import { notFound } from "../error-handler.js";
5
+ import { API_PREFIX, selfLink } from "../hateoas.js";
6
+ import { checkWorkCenterAccess, childItemLinks, formatAuditFields, resolveActions, resolveOpRun, resolveStepRun, } from "../route-helpers.js";
7
+ import { deserializeFieldValue, validateCompletionFields, validateFieldValue, } from "../services/field-value-service.js";
8
+ import { isUserClockedIn } from "../services/labor-ticket-service.js";
9
+ import { getStepRunWithFields, listStepRuns, listStepRunsWithFields, } from "../services/step-run-service.js";
10
+ export function stepRunResource(orderKey, runNo, seqNo) {
11
+ return `orders/${orderKey}/runs/${runNo}/ops/${seqNo}/steps`;
12
+ }
13
+ async function stepRunItemActions(orderKey, runNo, seqNo, stepSeqNo, opRunId, operationId, opRunStatus, completed, stepRunId, user) {
14
+ const href = `${API_PREFIX}/${stepRunResource(orderKey, runNo, seqNo)}/${stepSeqNo}`;
15
+ const isExecutor = hasPermission(user, "order_executor");
16
+ const isInProgress = opRunStatus === OperationRunStatus.in_progress;
17
+ // Pre-compute disabled reasons for complete action
18
+ const wcErr = user ? await checkWorkCenterAccess(operationId, user) : null;
19
+ const clockedInErr = isExecutor && isInProgress && !completed
20
+ ? (await isUserClockedIn(opRunId, user.id))
21
+ ? null
22
+ : "You must be clocked in to complete steps"
23
+ : null;
24
+ const fieldsErr = isExecutor && isInProgress && !completed
25
+ ? await (async () => {
26
+ const existing = await getStepRunWithFields(stepRunId);
27
+ return existing ? validateCompletionFields(existing) : null;
28
+ })()
29
+ : null;
30
+ return resolveActions([
31
+ {
32
+ rel: "complete",
33
+ path: "/complete",
34
+ method: "POST",
35
+ title: "Complete",
36
+ schema: `${API_PREFIX}/schemas/CompleteStepRun`,
37
+ body: { note: "" },
38
+ permission: "order_executor",
39
+ visibleWhen: () => !completed,
40
+ disabledWhen: () => !isInProgress
41
+ ? "Parent operation must be in progress"
42
+ : (wcErr ?? clockedInErr ?? fieldsErr),
43
+ },
44
+ {
45
+ rel: "reopen",
46
+ path: "/reopen",
47
+ method: "POST",
48
+ title: "Reopen",
49
+ permission: "order_executor",
50
+ visibleWhen: () => completed,
51
+ disabledWhen: () => !isInProgress ? "Parent operation must be in progress" : wcErr,
52
+ },
53
+ ], href, { status: opRunStatus, user });
54
+ }
55
+ export function buildStepRunActionTemplates(stepRunHref, canUpdate, multiSet, hasAttachmentFields, hasArrayFields) {
56
+ if (!canUpdate)
57
+ return [];
58
+ // Show array example in body hints when there are array fields
59
+ const valueHint = hasArrayFields ? [""] : "";
60
+ const batchValueHint = hasArrayFields
61
+ ? [
62
+ { fieldSeqNo: 0, value: "" },
63
+ { fieldSeqNo: 0, value: [""] },
64
+ ]
65
+ : [{ fieldSeqNo: 0, value: "" }];
66
+ return [
67
+ {
68
+ rel: "updateField",
69
+ hrefTemplate: multiSet
70
+ ? `${stepRunHref}/sets/{setIndex}/fields/{fieldSeqNo}`
71
+ : `${stepRunHref}/fields/{fieldSeqNo}`,
72
+ method: "PUT",
73
+ title: "Update Field Value",
74
+ schema: `${API_PREFIX}/schemas/UpdateFieldValue`,
75
+ body: { value: valueHint },
76
+ },
77
+ {
78
+ rel: "batchUpdateFields",
79
+ hrefTemplate: multiSet
80
+ ? `${stepRunHref}/sets/{setIndex}/fields`
81
+ : `${stepRunHref}/fields`,
82
+ method: "PUT",
83
+ title: "Batch Update Field Values",
84
+ schema: `${API_PREFIX}/schemas/BatchUpdateFieldValues`,
85
+ body: { fieldValues: batchValueHint },
86
+ },
87
+ ...(multiSet
88
+ ? [
89
+ {
90
+ rel: "deleteSet",
91
+ hrefTemplate: `${stepRunHref}/sets/{setIndex}`,
92
+ method: "DELETE",
93
+ title: "Delete Set",
94
+ },
95
+ ]
96
+ : []),
97
+ ...(hasAttachmentFields
98
+ ? [
99
+ {
100
+ rel: "uploadAttachment",
101
+ hrefTemplate: multiSet
102
+ ? `${stepRunHref}/sets/{setIndex}/fields/{fieldSeqNo}/attachments`
103
+ : `${stepRunHref}/fields/{fieldSeqNo}/attachments`,
104
+ method: "POST",
105
+ title: "Upload Attachment",
106
+ alternateEncoding: {
107
+ contentType: "multipart/form-data",
108
+ description: "Upload file as multipart/form-data with field 'file'",
109
+ fileFields: ["file"],
110
+ },
111
+ },
112
+ {
113
+ rel: "downloadAttachment",
114
+ hrefTemplate: multiSet
115
+ ? `${stepRunHref}/sets/{setIndex}/fields/{fieldSeqNo}/attachments/{attachmentId}`
116
+ : `${stepRunHref}/fields/{fieldSeqNo}/attachments/{attachmentId}`,
117
+ method: "GET",
118
+ title: "Download Attachment",
119
+ },
120
+ {
121
+ rel: "deleteAttachment",
122
+ hrefTemplate: multiSet
123
+ ? `${stepRunHref}/sets/{setIndex}/fields/{fieldSeqNo}/attachments/{attachmentId}`
124
+ : `${stepRunHref}/fields/{fieldSeqNo}/attachments/{attachmentId}`,
125
+ method: "DELETE",
126
+ title: "Delete Attachment",
127
+ },
128
+ ]
129
+ : []),
130
+ ];
131
+ }
132
+ /** Compute just the HATEOAS actions + action templates for a step run */
133
+ export async function computeStepRunHateoas(orderKey, runNo, seqNo, stepSeqNo, opRunId, operationId, opRunStatus, completed, stepRunId, multiSet, hasAttachmentFields, hasArrayFields, user) {
134
+ const canUpdate = hasPermission(user, "order_executor") &&
135
+ opRunStatus === OperationRunStatus.in_progress;
136
+ const stepRunHref = `${API_PREFIX}/${stepRunResource(orderKey, runNo, seqNo)}/${stepSeqNo}`;
137
+ return {
138
+ _actions: await stepRunItemActions(orderKey, runNo, seqNo, stepSeqNo, opRunId, operationId, opRunStatus, completed, stepRunId, user),
139
+ _actionTemplates: buildStepRunActionTemplates(stepRunHref, canUpdate, multiSet, hasAttachmentFields, hasArrayFields),
140
+ };
141
+ }
142
+ const OpSeqNoParamsSchema = z.object({
143
+ orderKey: z.string(),
144
+ runNo: z.coerce.number().int(),
145
+ seqNo: z.coerce.number().int(),
146
+ });
147
+ const StepSeqNoParamsSchema = z.object({
148
+ orderKey: z.string(),
149
+ runNo: z.coerce.number().int(),
150
+ seqNo: z.coerce.number().int(),
151
+ stepSeqNo: z.coerce.number().int(),
152
+ });
153
+ export async function formatStepRunTransition(orderKey, runNo, seqNo, opRunId, operationId, opRunStatus, user, stepRun) {
154
+ const stepSeqNo = stepRun.step.seqNo;
155
+ const multiSet = stepRun.step.multiSet;
156
+ const fields = stepRun.step.fieldSet?.fields ?? [];
157
+ const hasAttachmentFields = fields.some((f) => f.type === "attachment");
158
+ const hasArrayFields = fields.some((f) => f.isArray);
159
+ const hateoas = await computeStepRunHateoas(orderKey, runNo, seqNo, stepSeqNo, opRunId, operationId, opRunStatus, stepRun.completed, stepRun.id, multiSet, hasAttachmentFields, hasArrayFields, user);
160
+ return {
161
+ id: stepRun.id,
162
+ completed: stepRun.completed,
163
+ note: stepRun.statusNote ?? null,
164
+ ...formatAuditFields(stepRun),
165
+ ...hateoas,
166
+ };
167
+ }
168
+ export async function formatStepRunWithFields(orderKey, runNo, seqNo, opRunId, operationId, opRunStatus, user, stepRun) {
169
+ const stepSeqNo = stepRun.step.seqNo;
170
+ const multiSet = stepRun.step.multiSet;
171
+ // Determine how many sets exist
172
+ const storedFieldValues = stepRun.fieldRecord?.fieldValues ?? [];
173
+ const maxSetIndex = storedFieldValues.reduce((max, fv) => Math.max(max, fv.setIndex), -1);
174
+ const setCount = Math.max(1, maxSetIndex + 1);
175
+ // Merge field definitions with stored values + validation + attachments
176
+ const fieldValues = [];
177
+ const stepRunHref = `${API_PREFIX}/${stepRunResource(orderKey, runNo, seqNo)}/${stepSeqNo}`;
178
+ for (let si = 0; si < setCount; si++) {
179
+ for (const field of stepRun.step.fieldSet?.fields ?? []) {
180
+ const stored = storedFieldValues.find((fv) => fv.fieldId === field.id && fv.setIndex === si);
181
+ const value = deserializeFieldValue(stored?.value ?? "", field.isArray);
182
+ const setPath = multiSet
183
+ ? `/sets/${si}/fields/${field.seqNo}`
184
+ : `/fields/${field.seqNo}`;
185
+ const attachments = field.type === "attachment" && stored
186
+ ? stored.fieldAttachments.map((sfa) => ({
187
+ id: sfa.attachment.publicId,
188
+ filename: sfa.attachment.filename,
189
+ fileSize: sfa.attachment.fileSize,
190
+ downloadHref: `${stepRunHref}${setPath}/attachments/${sfa.attachment.publicId}`,
191
+ }))
192
+ : undefined;
193
+ const fieldType = fieldTypeString(field.type, field.isArray);
194
+ fieldValues.push({
195
+ fieldId: field.id,
196
+ fieldSeqNo: field.seqNo,
197
+ label: field.label,
198
+ type: fieldType,
199
+ valueFormat: getValueFormatHint(fieldType),
200
+ required: field.required,
201
+ setIndex: si,
202
+ value,
203
+ attachments,
204
+ validation: validateFieldValue(field.type, field.isArray, field.required, value),
205
+ });
206
+ }
207
+ }
208
+ const allFields = stepRun.step.fieldSet?.fields ?? [];
209
+ const hasAttachmentFields = allFields.some((f) => f.type === "attachment");
210
+ const hasArrayFields = allFields.some((f) => f.isArray);
211
+ const hateoas = await computeStepRunHateoas(orderKey, runNo, seqNo, stepSeqNo, opRunId, operationId, opRunStatus, stepRun.completed, stepRun.id, multiSet, hasAttachmentFields, hasArrayFields, user);
212
+ return {
213
+ id: stepRun.id,
214
+ operationRunId: stepRun.operationRunId,
215
+ stepId: stepRun.stepId,
216
+ seqNo: stepSeqNo,
217
+ title: stepRun.step.title,
218
+ instructions: stepRun.step.instructions,
219
+ multiSet,
220
+ completed: stepRun.completed,
221
+ note: stepRun.statusNote ?? null,
222
+ fieldCount: stepRun.step.fieldSet?.fields.length ?? 0,
223
+ fieldValues,
224
+ ...formatAuditFields(stepRun),
225
+ _links: childItemLinks("/" + stepRunResource(orderKey, runNo, seqNo), stepSeqNo, "Step Runs", "/orders/" + orderKey + "/runs/" + runNo + "/ops/" + seqNo, "Operation Run", "StepRun", "operationRun"),
226
+ ...hateoas,
227
+ };
228
+ }
229
+ function formatListStepRun(stepRun) {
230
+ const stepSeqNo = stepRun.step.seqNo;
231
+ const fieldCount = stepRun.step.fieldSet?._count.fields ?? 0;
232
+ return {
233
+ id: stepRun.id,
234
+ operationRunId: stepRun.operationRunId,
235
+ stepId: stepRun.stepId,
236
+ seqNo: stepSeqNo,
237
+ title: stepRun.step.title,
238
+ instructions: stepRun.step.instructions,
239
+ multiSet: stepRun.step.multiSet,
240
+ completed: stepRun.completed,
241
+ note: stepRun.statusNote ?? null,
242
+ fieldCount,
243
+ ...formatAuditFields(stepRun),
244
+ };
245
+ }
246
+ export default function stepRunRoutes(fastify) {
247
+ const app = fastify.withTypeProvider();
248
+ // LIST
249
+ app.get("/", {
250
+ schema: {
251
+ description: "List step runs for an operation run",
252
+ tags: ["Step Runs"],
253
+ params: OpSeqNoParamsSchema,
254
+ querystring: StepRunListQuerySchema,
255
+ response: {
256
+ 200: StepRunListResponseSchema,
257
+ 404: ErrorResponseSchema,
258
+ },
259
+ },
260
+ handler: async (request, reply) => {
261
+ const { orderKey, runNo, seqNo } = request.params;
262
+ const { includeFields } = request.query;
263
+ const resolved = await resolveOpRun(orderKey, runNo, seqNo);
264
+ if (!resolved) {
265
+ return notFound(reply, `Operation run not found`);
266
+ }
267
+ if (includeFields) {
268
+ const items = await listStepRunsWithFields(resolved.opRun.id);
269
+ const formatted = await Promise.all(items.map(async (stepRun) => {
270
+ const { _links, ...rest } = await formatStepRunWithFields(orderKey, runNo, seqNo, resolved.opRun.id, resolved.opRun.operationId, resolved.opRun.status, request.erpUser, stepRun);
271
+ return rest;
272
+ }));
273
+ return {
274
+ items: formatted,
275
+ total: items.length,
276
+ _links: [selfLink(`/${stepRunResource(orderKey, runNo, seqNo)}`)],
277
+ _linkTemplates: [
278
+ {
279
+ rel: "item",
280
+ hrefTemplate: `${API_PREFIX}/${stepRunResource(orderKey, runNo, seqNo)}/{seqNo}`,
281
+ },
282
+ ],
283
+ };
284
+ }
285
+ const items = await listStepRuns(resolved.opRun.id);
286
+ return {
287
+ items: items.map((stepRun) => formatListStepRun(stepRun)),
288
+ total: items.length,
289
+ _links: [selfLink(`/${stepRunResource(orderKey, runNo, seqNo)}`)],
290
+ _linkTemplates: [
291
+ {
292
+ rel: "item",
293
+ hrefTemplate: `${API_PREFIX}/${stepRunResource(orderKey, runNo, seqNo)}/{seqNo}`,
294
+ },
295
+ ],
296
+ };
297
+ },
298
+ });
299
+ // GET by stepSeqNo
300
+ app.get("/:stepSeqNo", {
301
+ schema: {
302
+ description: "Get a single step run by step sequence number",
303
+ tags: ["Step Runs"],
304
+ params: StepSeqNoParamsSchema,
305
+ response: {
306
+ 200: StepRunSchema,
307
+ 404: ErrorResponseSchema,
308
+ },
309
+ },
310
+ handler: async (request, reply) => {
311
+ const { orderKey, runNo, seqNo, stepSeqNo } = request.params;
312
+ const resolved = await resolveStepRun(orderKey, runNo, seqNo, stepSeqNo);
313
+ if (!resolved) {
314
+ return notFound(reply, `Step run not found`);
315
+ }
316
+ const stepRun = await getStepRunWithFields(resolved.stepRun.id);
317
+ if (!stepRun) {
318
+ return notFound(reply, `Step run not found`);
319
+ }
320
+ return formatStepRunWithFields(orderKey, runNo, seqNo, resolved.opRun.id, resolved.opRun.operationId, resolved.opRun.status, request.erpUser, stepRun);
321
+ },
322
+ });
323
+ }
324
+ //# sourceMappingURL=step-runs.js.map
@@ -0,0 +1,3 @@
1
+ import type { FastifyInstance } from "fastify";
2
+ export default function stepRoutes(fastify: FastifyInstance): void;
3
+ //# sourceMappingURL=steps.d.ts.map