@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,40 @@
1
+ import type { LaborTicketModel } from "../generated/prisma/models/LaborTicket.js";
2
+ export declare const includeLaborTicket: {
3
+ readonly user: {
4
+ readonly select: {
5
+ readonly username: true;
6
+ };
7
+ };
8
+ readonly createdBy: {
9
+ readonly select: {
10
+ readonly username: true;
11
+ };
12
+ };
13
+ readonly updatedBy: {
14
+ readonly select: {
15
+ readonly username: true;
16
+ };
17
+ };
18
+ };
19
+ export type LaborTicketWithUser = LaborTicketModel & {
20
+ user: {
21
+ username: string;
22
+ };
23
+ createdBy: {
24
+ username: string;
25
+ };
26
+ updatedBy: {
27
+ username: string;
28
+ };
29
+ };
30
+ export declare function isUserClockedIn(operationRunId: number, userId: number): Promise<boolean>;
31
+ export declare function listLaborTickets(operationRunId: number): Promise<LaborTicketWithUser[]>;
32
+ export declare function clockIn(operationRunId: number, userId: number, actorId: number): Promise<LaborTicketWithUser>;
33
+ export declare function clockOut(operationRunId: number, opts: {
34
+ userId?: number;
35
+ ticketId?: number;
36
+ }, actorId: number): Promise<LaborTicketWithUser[]>;
37
+ export declare function clockOutAllForOpRun(operationRunId: number, actorId: number): Promise<void>;
38
+ export declare function sumLaborTicketCosts(operationRunId: number): Promise<number>;
39
+ export declare function deleteLaborTicket(ticketId: number, actorId: number): Promise<void>;
40
+ //# sourceMappingURL=labor-ticket-service.d.ts.map
@@ -0,0 +1,148 @@
1
+ import { getLatestRunInfoByUuid, sumCostsByUuid } from "@naisys/hub-database";
2
+ import { writeAuditEntry } from "../audit.js";
3
+ import erpDb from "../erpDb.js";
4
+ // --- Prisma include & result type ---
5
+ export const includeLaborTicket = {
6
+ user: { select: { username: true } },
7
+ createdBy: { select: { username: true } },
8
+ updatedBy: { select: { username: true } },
9
+ };
10
+ // --- Helpers ---
11
+ /**
12
+ * Compute the cost for a labor ticket at clock-out time.
13
+ * Agents: sum of hub cost entries for the user within the clock-in/out window.
14
+ * Non-agents: 0.
15
+ */
16
+ async function computeCost(userId, clockIn, clockOut) {
17
+ const user = await erpDb.user.findUnique({
18
+ where: { id: userId },
19
+ select: { isAgent: true, uuid: true },
20
+ });
21
+ if (!user?.isAgent)
22
+ return 0;
23
+ const cost = await sumCostsByUuid(user.uuid, clockIn, clockOut);
24
+ return Math.round(cost * 100) / 100;
25
+ }
26
+ /**
27
+ * Get the current hub run info (run_id + session start) for an agent user.
28
+ */
29
+ async function getAgentRunInfo(userId) {
30
+ const user = await erpDb.user.findUnique({
31
+ where: { id: userId },
32
+ select: { isAgent: true, uuid: true },
33
+ });
34
+ if (!user?.isAgent)
35
+ return null;
36
+ return getLatestRunInfoByUuid(user.uuid);
37
+ }
38
+ // --- Lookups ---
39
+ export async function isUserClockedIn(operationRunId, userId) {
40
+ const ticket = await erpDb.laborTicket.findFirst({
41
+ where: { operationRunId, userId, clockOut: null },
42
+ });
43
+ return !!ticket;
44
+ }
45
+ export async function listLaborTickets(operationRunId) {
46
+ return erpDb.laborTicket.findMany({
47
+ where: { operationRunId },
48
+ include: includeLaborTicket,
49
+ orderBy: { clockIn: "desc" },
50
+ });
51
+ }
52
+ // --- Mutations ---
53
+ export async function clockIn(operationRunId, userId, actorId) {
54
+ const now = new Date();
55
+ const runInfo = await getAgentRunInfo(userId);
56
+ const runId = runInfo?.runId ?? null;
57
+ // If already clocked into this op run, just return the existing ticket
58
+ const existing = await erpDb.laborTicket.findFirst({
59
+ where: { operationRunId, userId, clockOut: null },
60
+ include: includeLaborTicket,
61
+ });
62
+ if (existing)
63
+ return existing;
64
+ return erpDb.$transaction(async (tx) => {
65
+ // Auto clock-out all open tickets for this user (globally)
66
+ const openTickets = await tx.laborTicket.findMany({
67
+ where: { userId, clockOut: null },
68
+ });
69
+ for (const ticket of openTickets) {
70
+ const cost = await computeCost(userId, ticket.clockIn, now);
71
+ await tx.laborTicket.update({
72
+ where: { id: ticket.id },
73
+ data: { clockOut: now, cost, updatedById: actorId },
74
+ });
75
+ }
76
+ // If no tickets were auto-closed and this is the first ticket for the
77
+ // current run/session, backdate clockIn to the session start so that
78
+ // startup costs (before the agent called clock-in) are captured.
79
+ let clockInTime = now;
80
+ if (runInfo && openTickets.length === 0) {
81
+ const existingForRun = await tx.laborTicket.findFirst({
82
+ where: { userId, runId },
83
+ });
84
+ if (!existingForRun) {
85
+ clockInTime = runInfo.sessionStart;
86
+ }
87
+ }
88
+ // Create new ticket
89
+ return tx.laborTicket.create({
90
+ data: {
91
+ operationRunId,
92
+ userId,
93
+ runId,
94
+ clockIn: clockInTime,
95
+ createdById: actorId,
96
+ updatedById: actorId,
97
+ updatedAt: now,
98
+ },
99
+ include: includeLaborTicket,
100
+ });
101
+ });
102
+ }
103
+ export async function clockOut(operationRunId, opts, actorId) {
104
+ const now = new Date();
105
+ return erpDb.$transaction(async (tx) => {
106
+ // Build where clause based on opts
107
+ const where = {
108
+ operationRunId,
109
+ clockOut: null,
110
+ };
111
+ if (opts.ticketId) {
112
+ where.id = opts.ticketId;
113
+ }
114
+ else if (opts.userId) {
115
+ where.userId = opts.userId;
116
+ }
117
+ // If neither specified, clocks out ALL open tickets for the op run
118
+ const openTickets = await tx.laborTicket.findMany({ where });
119
+ const updated = [];
120
+ for (const ticket of openTickets) {
121
+ const cost = await computeCost(ticket.userId, ticket.clockIn, now);
122
+ const result = await tx.laborTicket.update({
123
+ where: { id: ticket.id },
124
+ data: { clockOut: now, cost, updatedById: actorId },
125
+ include: includeLaborTicket,
126
+ });
127
+ updated.push(result);
128
+ }
129
+ return updated;
130
+ });
131
+ }
132
+ export async function clockOutAllForOpRun(operationRunId, actorId) {
133
+ await clockOut(operationRunId, {}, actorId);
134
+ }
135
+ export async function sumLaborTicketCosts(operationRunId) {
136
+ const result = await erpDb.laborTicket.aggregate({
137
+ where: { operationRunId },
138
+ _sum: { cost: true },
139
+ });
140
+ return Math.round((result._sum.cost ?? 0) * 100) / 100;
141
+ }
142
+ export async function deleteLaborTicket(ticketId, actorId) {
143
+ await erpDb.$transaction(async (tx) => {
144
+ await tx.laborTicket.delete({ where: { id: ticketId } });
145
+ await writeAuditEntry(tx, "LaborTicket", ticketId, "delete", "id", String(ticketId), null, actorId);
146
+ });
147
+ }
148
+ //# sourceMappingURL=labor-ticket-service.js.map
@@ -0,0 +1,4 @@
1
+ import { tailLogFile } from "@naisys/common-node";
2
+ export { tailLogFile };
3
+ export declare function getErpLogPath(): string;
4
+ //# sourceMappingURL=log-file-service.d.ts.map
@@ -0,0 +1,11 @@
1
+ import path from "node:path";
2
+ import { tailLogFile } from "@naisys/common-node";
3
+ export { tailLogFile };
4
+ export function getErpLogPath() {
5
+ const naisysFolder = process.env.NAISYS_FOLDER;
6
+ if (!naisysFolder) {
7
+ throw new Error("NAISYS_FOLDER environment variable is not set.");
8
+ }
9
+ return path.join(naisysFolder, "logs", "erp.log");
10
+ }
11
+ //# sourceMappingURL=log-file-service.js.map
@@ -0,0 +1,33 @@
1
+ export type DependencyWithDetails = Awaited<ReturnType<typeof listDependencies>>[number];
2
+ export declare function listDependencies(operationId: number): Promise<({
3
+ createdBy: {
4
+ username: string;
5
+ };
6
+ predecessor: {
7
+ title: string;
8
+ seqNo: number;
9
+ };
10
+ } & {
11
+ createdAt: Date;
12
+ id: number;
13
+ createdById: number;
14
+ successorId: number;
15
+ predecessorId: number;
16
+ })[]>;
17
+ export declare function createDependency(successorId: number, predecessorId: number, userId: number): Promise<{
18
+ createdBy: {
19
+ username: string;
20
+ };
21
+ predecessor: {
22
+ title: string;
23
+ seqNo: number;
24
+ };
25
+ } & {
26
+ createdAt: Date;
27
+ id: number;
28
+ createdById: number;
29
+ successorId: number;
30
+ predecessorId: number;
31
+ }>;
32
+ export declare function deleteDependency(successorId: number, predecessorId: number): Promise<void>;
33
+ //# sourceMappingURL=operation-dependency-service.d.ts.map
@@ -0,0 +1,30 @@
1
+ import erpDb from "../erpDb.js";
2
+ const depInclude = {
3
+ predecessor: { select: { seqNo: true, title: true } },
4
+ createdBy: { select: { username: true } },
5
+ };
6
+ export async function listDependencies(operationId) {
7
+ return erpDb.operationDependency.findMany({
8
+ where: { successorId: operationId },
9
+ include: depInclude,
10
+ orderBy: { predecessor: { seqNo: "asc" } },
11
+ });
12
+ }
13
+ export async function createDependency(successorId, predecessorId, userId) {
14
+ return erpDb.operationDependency.create({
15
+ data: {
16
+ successorId,
17
+ predecessorId,
18
+ createdById: userId,
19
+ },
20
+ include: depInclude,
21
+ });
22
+ }
23
+ export async function deleteDependency(successorId, predecessorId) {
24
+ await erpDb.operationDependency.delete({
25
+ where: {
26
+ successorId_predecessorId: { successorId, predecessorId },
27
+ },
28
+ });
29
+ }
30
+ //# sourceMappingURL=operation-dependency-service.js.map
@@ -0,0 +1,17 @@
1
+ import type { OperationRunCommentType } from "@naisys/erp-shared";
2
+ import type { OperationRunCommentModel } from "../generated/prisma/models/OperationRunComment.js";
3
+ export declare const includeComment: {
4
+ readonly createdBy: {
5
+ readonly select: {
6
+ readonly username: true;
7
+ };
8
+ };
9
+ };
10
+ export type CommentWithUser = OperationRunCommentModel & {
11
+ createdBy: {
12
+ username: string;
13
+ };
14
+ };
15
+ export declare function listComments(operationRunId: number): Promise<CommentWithUser[]>;
16
+ export declare function createComment(operationRunId: number, type: OperationRunCommentType, body: string, userId: number): Promise<CommentWithUser>;
17
+ //# sourceMappingURL=operation-run-comment-service.d.ts.map
@@ -0,0 +1,26 @@
1
+ import erpDb from "../erpDb.js";
2
+ // --- Prisma include & result type ---
3
+ export const includeComment = {
4
+ createdBy: { select: { username: true } },
5
+ };
6
+ // --- Lookups ---
7
+ export async function listComments(operationRunId) {
8
+ return erpDb.operationRunComment.findMany({
9
+ where: { operationRunId },
10
+ include: includeComment,
11
+ orderBy: { createdAt: "asc" },
12
+ });
13
+ }
14
+ // --- Mutations ---
15
+ export async function createComment(operationRunId, type, body, userId) {
16
+ return erpDb.operationRunComment.create({
17
+ data: {
18
+ operationRunId,
19
+ type,
20
+ body,
21
+ createdById: userId,
22
+ },
23
+ include: includeComment,
24
+ });
25
+ }
26
+ //# sourceMappingURL=operation-run-comment-service.js.map
@@ -0,0 +1,126 @@
1
+ import { type OperationRunStatus } from "@naisys/erp-shared";
2
+ import { type FieldRefValueSummary } from "@naisys/erp-shared";
3
+ import type { OperationRunModel } from "../generated/prisma/models/OperationRun.js";
4
+ export declare const includeOp: {
5
+ readonly operation: {
6
+ readonly select: {
7
+ readonly seqNo: true;
8
+ readonly title: true;
9
+ readonly description: true;
10
+ readonly workCenter: {
11
+ readonly select: {
12
+ readonly key: true;
13
+ };
14
+ };
15
+ };
16
+ };
17
+ readonly assignedTo: {
18
+ readonly select: {
19
+ readonly username: true;
20
+ };
21
+ };
22
+ readonly createdBy: {
23
+ readonly select: {
24
+ readonly username: true;
25
+ };
26
+ };
27
+ readonly updatedBy: {
28
+ readonly select: {
29
+ readonly username: true;
30
+ };
31
+ };
32
+ };
33
+ export type OpRunWithOp = OperationRunModel & {
34
+ operation: {
35
+ seqNo: number;
36
+ title: string;
37
+ description: string;
38
+ workCenter: {
39
+ key: string;
40
+ } | null;
41
+ };
42
+ assignedTo: {
43
+ username: string;
44
+ } | null;
45
+ createdBy: {
46
+ username: string;
47
+ };
48
+ updatedBy: {
49
+ username: string;
50
+ };
51
+ };
52
+ export type OpRunWithSummary = OpRunWithOp & {
53
+ _count: {
54
+ stepRuns: number;
55
+ };
56
+ operation: {
57
+ seqNo: number;
58
+ title: string;
59
+ description: string;
60
+ workCenter: {
61
+ key: string;
62
+ } | null;
63
+ predecessors: Array<{
64
+ predecessor: {
65
+ seqNo: number;
66
+ title: string;
67
+ };
68
+ }>;
69
+ };
70
+ };
71
+ export declare function listOpRuns(runId: number): Promise<OpRunWithSummary[]>;
72
+ export declare function getOpRun(id: number): Promise<OpRunWithOp | null>;
73
+ export declare function findExisting(id: number, runId: number): Promise<({
74
+ operation: {
75
+ seqNo: number;
76
+ };
77
+ } & {
78
+ operationId: number;
79
+ createdAt: Date;
80
+ id: number;
81
+ updatedAt: Date;
82
+ orderRunId: number;
83
+ status: import("../generated/prisma/enums.js").OperationRunStatus;
84
+ assignedToId: number | null;
85
+ createdById: number;
86
+ updatedById: number;
87
+ cost: number | null;
88
+ statusNote: string | null;
89
+ completedAt: Date | null;
90
+ }) | null>;
91
+ export declare function getOpRunStepSummary(opRunId: number): Promise<{
92
+ step: {
93
+ title: string;
94
+ seqNo: number;
95
+ };
96
+ completed: boolean;
97
+ }[]>;
98
+ /**
99
+ * Resolve field reference values for an operation run.
100
+ * Looks up the plan-level field refs, finds the corresponding step runs
101
+ * in the same order run, and returns FieldValueEntry-shaped data
102
+ * compatible with the FieldValueRunList component.
103
+ */
104
+ export declare function getOpRunFieldRefSummary(operationId: number, orderRunId: number, orderKey: string, runNo: number): Promise<FieldRefValueSummary[]>;
105
+ export declare function validateStatusFor(action: string, currentStatus: string, allowedStatuses: string[]): string | null;
106
+ /**
107
+ * Check that all predecessor dependencies for this operation are complete.
108
+ * Uses the OperationDependency graph rather than seqNo ordering.
109
+ */
110
+ export declare function checkPredecessorsComplete(runId: number, operationId: number): Promise<string | null>;
111
+ /**
112
+ * After completing/skipping an operation, unblock successor ops
113
+ * whose predecessors are now all complete.
114
+ */
115
+ export declare function unblockSuccessors(runId: number, operationId: number, userId: number): Promise<void>;
116
+ /**
117
+ * After reopening an operation, re-block successor ops that are still pending
118
+ * (haven't been started yet) if this operation is one of their prerequisites.
119
+ */
120
+ export declare function reblockSuccessors(runId: number, operationId: number, userId: number): Promise<void>;
121
+ export declare function checkStepsComplete(opRunId: number): Promise<string | null>;
122
+ export declare function updateOpRun(id: number, data: {
123
+ assignedToId?: number | null;
124
+ }, userId: number): Promise<OpRunWithOp>;
125
+ export declare function transitionStatus(id: number, action: string, fromStatus: OperationRunStatus, toStatus: OperationRunStatus, userId: number, extraData?: Record<string, unknown>): Promise<OpRunWithOp>;
126
+ //# sourceMappingURL=operation-run-service.d.ts.map