@naisys/erp 3.0.0-beta.17 → 3.0.0-beta.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.env.example CHANGED
@@ -1,5 +1,5 @@
1
1
  NODE_ENV=development
2
- ERP_PORT=3201
2
+ SERVER_PORT=3201
3
3
  PUBLIC_READ=true
4
4
  SUPERVISOR_AUTH=false
5
5
  NAISYS_FOLDER=~/.naisys
@@ -0,0 +1,114 @@
1
+ import adminRoutes from "./routes/admin.js";
2
+ import auditRoutes from "./routes/audit.js";
3
+ import authRoutes from "./routes/auth.js";
4
+ import dispatchRoutes from "./routes/dispatch.js";
5
+ import inventoryRoutes from "./routes/inventory.js";
6
+ import itemFieldRoutes from "./routes/item-fields.js";
7
+ import itemInstanceRoutes from "./routes/item-instances.js";
8
+ import itemRoutes from "./routes/items.js";
9
+ import laborTicketRoutes from "./routes/labor-tickets.js";
10
+ import operationDependencyRoutes from "./routes/operation-dependencies.js";
11
+ import operationFieldRefRoutes from "./routes/operation-field-refs.js";
12
+ import operationRunCommentRoutes from "./routes/operation-run-comments.js";
13
+ import operationRunTransitionRoutes from "./routes/operation-run-transitions.js";
14
+ import operationRunRoutes from "./routes/operation-runs.js";
15
+ import operationRoutes from "./routes/operations.js";
16
+ import orderRevisionTransitionRoutes from "./routes/order-revision-transitions.js";
17
+ import orderRevisionRoutes from "./routes/order-revisions.js";
18
+ import orderRunTransitionRoutes from "./routes/order-run-transitions.js";
19
+ import orderRunRoutes from "./routes/order-runs.js";
20
+ import orderRoutes from "./routes/orders.js";
21
+ import rootRoute from "./routes/root.js";
22
+ import schemaRoutes from "./routes/schemas.js";
23
+ import stepFieldAttachmentRoutes from "./routes/step-field-attachments.js";
24
+ import stepFieldRoutes from "./routes/step-fields.js";
25
+ import stepRunFieldRoutes from "./routes/step-run-fields.js";
26
+ import stepRunTransitionRoutes from "./routes/step-run-transitions.js";
27
+ import stepRunRoutes from "./routes/step-runs.js";
28
+ import stepRoutes from "./routes/steps.js";
29
+ import { isSupervisorAuth } from "./supervisorAuth.js";
30
+ import userPermissionRoutes from "./routes/user-permissions.js";
31
+ import userRoutes from "./routes/users.js";
32
+ import workCenterRoutes from "./routes/work-centers.js";
33
+ export const erpRoutes = async (fastify) => {
34
+ fastify.register(adminRoutes, { prefix: "/erp/api/admin" });
35
+ fastify.register(auditRoutes, { prefix: "/erp/api/audit" });
36
+ fastify.register(authRoutes, { prefix: "/erp/api/auth" });
37
+ fastify.register(dispatchRoutes, { prefix: "/erp/api/dispatch" });
38
+ fastify.register(inventoryRoutes, { prefix: "/erp/api/inventory" });
39
+ fastify.register(rootRoute, { prefix: "/erp/api" });
40
+ fastify.register(itemRoutes, { prefix: "/erp/api/items" });
41
+ fastify.register(itemFieldRoutes, {
42
+ prefix: "/erp/api/items/:key/fields",
43
+ });
44
+ fastify.register(itemInstanceRoutes, {
45
+ prefix: "/erp/api/items/:key/instances",
46
+ });
47
+ fastify.register(orderRoutes, {
48
+ prefix: "/erp/api/orders",
49
+ });
50
+ fastify.register(orderRevisionRoutes, {
51
+ prefix: "/erp/api/orders/:orderKey/revs",
52
+ });
53
+ fastify.register(orderRevisionTransitionRoutes, {
54
+ prefix: "/erp/api/orders/:orderKey/revs",
55
+ });
56
+ fastify.register(orderRunRoutes, {
57
+ prefix: "/erp/api/orders/:orderKey/runs",
58
+ });
59
+ fastify.register(orderRunTransitionRoutes, {
60
+ prefix: "/erp/api/orders/:orderKey/runs",
61
+ });
62
+ fastify.register(operationRoutes, {
63
+ prefix: "/erp/api/orders/:orderKey/revs/:revNo/ops",
64
+ });
65
+ fastify.register(operationDependencyRoutes, {
66
+ prefix: "/erp/api/orders/:orderKey/revs/:revNo/ops/:seqNo/deps",
67
+ });
68
+ fastify.register(operationFieldRefRoutes, {
69
+ prefix: "/erp/api/orders/:orderKey/revs/:revNo/ops/:seqNo/field-refs",
70
+ });
71
+ fastify.register(operationRunRoutes, {
72
+ prefix: "/erp/api/orders/:orderKey/runs/:runNo/ops",
73
+ });
74
+ fastify.register(operationRunTransitionRoutes, {
75
+ prefix: "/erp/api/orders/:orderKey/runs/:runNo/ops",
76
+ });
77
+ fastify.register(laborTicketRoutes, {
78
+ prefix: "/erp/api/orders/:orderKey/runs/:runNo/ops/:seqNo/labor",
79
+ });
80
+ fastify.register(operationRunCommentRoutes, {
81
+ prefix: "/erp/api/orders/:orderKey/runs/:runNo/ops/:seqNo/comments",
82
+ });
83
+ fastify.register(stepRunRoutes, {
84
+ prefix: "/erp/api/orders/:orderKey/runs/:runNo/ops/:seqNo/steps",
85
+ });
86
+ fastify.register(stepRunTransitionRoutes, {
87
+ prefix: "/erp/api/orders/:orderKey/runs/:runNo/ops/:seqNo/steps",
88
+ });
89
+ fastify.register(stepRunFieldRoutes, {
90
+ prefix: "/erp/api/orders/:orderKey/runs/:runNo/ops/:seqNo/steps",
91
+ });
92
+ fastify.register(stepFieldAttachmentRoutes, {
93
+ prefix: "/erp/api/orders/:orderKey/runs/:runNo/ops/:seqNo/steps/:stepSeqNo/fields/:fieldSeqNo/attachments",
94
+ });
95
+ fastify.register(stepFieldAttachmentRoutes, {
96
+ prefix: "/erp/api/orders/:orderKey/runs/:runNo/ops/:seqNo/steps/:stepSeqNo/sets/:setIndex/fields/:fieldSeqNo/attachments",
97
+ });
98
+ fastify.register(stepRoutes, {
99
+ prefix: "/erp/api/orders/:orderKey/revs/:revNo/ops/:seqNo/steps",
100
+ });
101
+ fastify.register(stepFieldRoutes, {
102
+ prefix: "/erp/api/orders/:orderKey/revs/:revNo/ops/:seqNo/steps/:stepSeqNo/fields",
103
+ });
104
+ fastify.register(schemaRoutes, { prefix: "/erp/api/schemas" });
105
+ fastify.register(userRoutes, { prefix: "/erp/api/users" });
106
+ fastify.register(userPermissionRoutes, { prefix: "/erp/api/users" });
107
+ fastify.register(workCenterRoutes, { prefix: "/erp/api/work-centers" });
108
+ // Public endpoint to expose client configuration
109
+ fastify.get("/erp/api/client-config", { schema: { hide: true } }, () => ({
110
+ publicRead: process.env.PUBLIC_READ === "true",
111
+ supervisorAuth: isSupervisorAuth(),
112
+ }));
113
+ };
114
+ //# sourceMappingURL=erpRoutes.js.map
package/dist/erpServer.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import "dotenv/config";
2
2
  import "./schema-registry.js";
3
- import { ensureDotEnv, expandNaisysFolder } from "@naisys/common-node";
3
+ import { ensureDotEnv, expandNaisysFolder, runSetupWizard, } from "@naisys/common-node";
4
4
  expandNaisysFolder();
5
5
  // Important to load dotenv before any other imports, to ensure environment variables are available
6
6
  import cookie from "@fastify/cookie";
@@ -10,48 +10,18 @@ import { fastifyRateLimit as rateLimit } from "@fastify/rate-limit";
10
10
  import staticFiles from "@fastify/static";
11
11
  import swagger from "@fastify/swagger";
12
12
  import { commonErrorHandler, registerLenientJsonParser, registerSecurityHeaders, } from "@naisys/common";
13
+ import { createFileLogger } from "@naisys/common-node";
13
14
  import { createHubDatabaseClient, deployPrismaMigrations, } from "@naisys/hub-database";
14
15
  import { createSupervisorDatabaseClient, handleResetPassword, } from "@naisys/supervisor-database";
15
16
  import Fastify from "fastify";
16
17
  import { jsonSchemaTransform, jsonSchemaTransformObject, serializerCompiler, validatorCompiler, } from "fastify-type-provider-zod";
17
18
  import path from "path";
18
- import pino from "pino";
19
19
  import { fileURLToPath } from "url";
20
20
  import { registerApiReference } from "./api-reference.js";
21
21
  import { registerAuthMiddleware } from "./auth-middleware.js";
22
22
  import { ERP_DB_VERSION, erpDbPath } from "./dbConfig.js";
23
23
  import { initErpDb } from "./erpDb.js";
24
- import adminRoutes from "./routes/admin.js";
25
- import auditRoutes from "./routes/audit.js";
26
- import authRoutes from "./routes/auth.js";
27
- import dispatchRoutes from "./routes/dispatch.js";
28
- import inventoryRoutes from "./routes/inventory.js";
29
- import itemFieldRoutes from "./routes/item-fields.js";
30
- import itemInstanceRoutes from "./routes/item-instances.js";
31
- import itemRoutes from "./routes/items.js";
32
- import laborTicketRoutes from "./routes/labor-tickets.js";
33
- import operationDependencyRoutes from "./routes/operation-dependencies.js";
34
- import operationFieldRefRoutes from "./routes/operation-field-refs.js";
35
- import operationRunCommentRoutes from "./routes/operation-run-comments.js";
36
- import operationRunTransitionRoutes from "./routes/operation-run-transitions.js";
37
- import operationRunRoutes from "./routes/operation-runs.js";
38
- import operationRoutes from "./routes/operations.js";
39
- import orderRevisionTransitionRoutes from "./routes/order-revision-transitions.js";
40
- import orderRevisionRoutes from "./routes/order-revisions.js";
41
- import orderRunTransitionRoutes from "./routes/order-run-transitions.js";
42
- import orderRunRoutes from "./routes/order-runs.js";
43
- import orderRoutes from "./routes/orders.js";
44
- import rootRoute from "./routes/root.js";
45
- import schemaRoutes from "./routes/schemas.js";
46
- import stepFieldAttachmentRoutes from "./routes/step-field-attachments.js";
47
- import stepFieldRoutes from "./routes/step-fields.js";
48
- import stepRunFieldRoutes from "./routes/step-run-fields.js";
49
- import stepRunTransitionRoutes from "./routes/step-run-transitions.js";
50
- import stepRunRoutes from "./routes/step-runs.js";
51
- import stepRoutes from "./routes/steps.js";
52
- import userPermissionRoutes from "./routes/user-permissions.js";
53
- import userRoutes from "./routes/users.js";
54
- import workCenterRoutes from "./routes/work-centers.js";
24
+ import { erpRoutes } from "./erpRoutes.js";
55
25
  import { isSupervisorAuth } from "./supervisorAuth.js";
56
26
  import { ensureLocalSuperAdmin, ensureSupervisorSuperAdmin, resetLocalPassword, } from "./userService.js";
57
27
  export { enableSupervisorAuth } from "./supervisorAuth.js";
@@ -103,8 +73,7 @@ export const erpPlugin = async (fastify) => {
103
73
  // ERP-specific file logger (works in both standalone and hosted mode)
104
74
  const naisysFolder = process.env.NAISYS_FOLDER;
105
75
  if (naisysFolder) {
106
- const erpLogDest = path.join(naisysFolder, "logs", "erp.log");
107
- const erpFileLogger = pino({ level: "info" }, pino.destination({ dest: erpLogDest, mkdir: true }));
76
+ const erpFileLogger = createFileLogger("erp.log");
108
77
  erpFileLogger.info("ERP plugin initialized");
109
78
  fastify.addHook("onResponse", async (request, reply) => {
110
79
  if (!request.url.startsWith("/erp/api"))
@@ -123,86 +92,8 @@ export const erpPlugin = async (fastify) => {
123
92
  }, `${request.method} ${request.url} error`);
124
93
  });
125
94
  }
126
- // API routes under /erp/api prefix
127
- fastify.register(adminRoutes, { prefix: "/erp/api/admin" });
128
- fastify.register(auditRoutes, { prefix: "/erp/api/audit" });
129
- fastify.register(authRoutes, { prefix: "/erp/api/auth" });
130
- fastify.register(dispatchRoutes, { prefix: "/erp/api/dispatch" });
131
- fastify.register(inventoryRoutes, { prefix: "/erp/api/inventory" });
132
- fastify.register(rootRoute, { prefix: "/erp/api" });
133
- fastify.register(itemRoutes, { prefix: "/erp/api/items" });
134
- fastify.register(itemFieldRoutes, {
135
- prefix: "/erp/api/items/:key/fields",
136
- });
137
- fastify.register(itemInstanceRoutes, {
138
- prefix: "/erp/api/items/:key/instances",
139
- });
140
- fastify.register(orderRoutes, {
141
- prefix: "/erp/api/orders",
142
- });
143
- fastify.register(orderRevisionRoutes, {
144
- prefix: "/erp/api/orders/:orderKey/revs",
145
- });
146
- fastify.register(orderRevisionTransitionRoutes, {
147
- prefix: "/erp/api/orders/:orderKey/revs",
148
- });
149
- fastify.register(orderRunRoutes, {
150
- prefix: "/erp/api/orders/:orderKey/runs",
151
- });
152
- fastify.register(orderRunTransitionRoutes, {
153
- prefix: "/erp/api/orders/:orderKey/runs",
154
- });
155
- fastify.register(operationRoutes, {
156
- prefix: "/erp/api/orders/:orderKey/revs/:revNo/ops",
157
- });
158
- fastify.register(operationDependencyRoutes, {
159
- prefix: "/erp/api/orders/:orderKey/revs/:revNo/ops/:seqNo/deps",
160
- });
161
- fastify.register(operationFieldRefRoutes, {
162
- prefix: "/erp/api/orders/:orderKey/revs/:revNo/ops/:seqNo/field-refs",
163
- });
164
- fastify.register(operationRunRoutes, {
165
- prefix: "/erp/api/orders/:orderKey/runs/:runNo/ops",
166
- });
167
- fastify.register(operationRunTransitionRoutes, {
168
- prefix: "/erp/api/orders/:orderKey/runs/:runNo/ops",
169
- });
170
- fastify.register(laborTicketRoutes, {
171
- prefix: "/erp/api/orders/:orderKey/runs/:runNo/ops/:seqNo/labor",
172
- });
173
- fastify.register(operationRunCommentRoutes, {
174
- prefix: "/erp/api/orders/:orderKey/runs/:runNo/ops/:seqNo/comments",
175
- });
176
- fastify.register(stepRunRoutes, {
177
- prefix: "/erp/api/orders/:orderKey/runs/:runNo/ops/:seqNo/steps",
178
- });
179
- fastify.register(stepRunTransitionRoutes, {
180
- prefix: "/erp/api/orders/:orderKey/runs/:runNo/ops/:seqNo/steps",
181
- });
182
- fastify.register(stepRunFieldRoutes, {
183
- prefix: "/erp/api/orders/:orderKey/runs/:runNo/ops/:seqNo/steps",
184
- });
185
- fastify.register(stepFieldAttachmentRoutes, {
186
- prefix: "/erp/api/orders/:orderKey/runs/:runNo/ops/:seqNo/steps/:stepSeqNo/fields/:fieldSeqNo/attachments",
187
- });
188
- fastify.register(stepFieldAttachmentRoutes, {
189
- prefix: "/erp/api/orders/:orderKey/runs/:runNo/ops/:seqNo/steps/:stepSeqNo/sets/:setIndex/fields/:fieldSeqNo/attachments",
190
- });
191
- fastify.register(stepRoutes, {
192
- prefix: "/erp/api/orders/:orderKey/revs/:revNo/ops/:seqNo/steps",
193
- });
194
- fastify.register(stepFieldRoutes, {
195
- prefix: "/erp/api/orders/:orderKey/revs/:revNo/ops/:seqNo/steps/:stepSeqNo/fields",
196
- });
197
- fastify.register(schemaRoutes, { prefix: "/erp/api/schemas" });
198
- fastify.register(userRoutes, { prefix: "/erp/api/users" });
199
- fastify.register(userPermissionRoutes, { prefix: "/erp/api/users" });
200
- fastify.register(workCenterRoutes, { prefix: "/erp/api/work-centers" });
201
- // Public endpoint to expose client configuration (publicRead, etc.)
202
- fastify.get("/erp/api/client-config", { schema: { hide: true } }, () => ({
203
- publicRead: process.env.PUBLIC_READ === "true",
204
- supervisorAuth: isSupervisorAuth(),
205
- }));
95
+ // API routes
96
+ await fastify.register(erpRoutes);
206
97
  registerApiReference(fastify);
207
98
  // In production, serve the client build
208
99
  if (isProd) {
@@ -269,7 +160,7 @@ async function startServer() {
269
160
  return reply.redirect("/erp/");
270
161
  });
271
162
  await fastify.register(erpPlugin);
272
- const port = Number(process.env.ERP_PORT) || 3201;
163
+ const port = Number(process.env.SERVER_PORT) || 3201;
273
164
  const host = isProd ? "0.0.0.0" : "localhost";
274
165
  try {
275
166
  await fastify.listen({ port, host });
@@ -284,7 +175,27 @@ async function startServer() {
284
175
  }
285
176
  // Start server if this file is run directly
286
177
  if (process.argv[1] === fileURLToPath(import.meta.url)) {
287
- if (process.argv.includes("--reset-password")) {
178
+ const erpWizardConfig = {
179
+ title: "NAISYS ERP Setup",
180
+ sections: [
181
+ {
182
+ type: "fields",
183
+ comment: "ERP configuration",
184
+ fields: [
185
+ { key: "NAISYS_FOLDER", label: "NAISYS Data Folder" },
186
+ { key: "SERVER_PORT", label: "Server Port" },
187
+ { key: "SUPERVISOR_AUTH", label: "Use Supervisor for Auth" },
188
+ { key: "PUBLIC_READ", label: "Public Read Access" },
189
+ ],
190
+ },
191
+ ],
192
+ };
193
+ const erpExampleUrl = new URL("../.env.example", import.meta.url);
194
+ if (process.argv.includes("--setup")) {
195
+ await runSetupWizard(path.resolve(".env"), erpExampleUrl, erpWizardConfig);
196
+ process.exit(0);
197
+ }
198
+ else if (process.argv.includes("--reset-password")) {
288
199
  const usernameIdx = process.argv.indexOf("--username");
289
200
  const passwordIdx = process.argv.indexOf("--password");
290
201
  const username = usernameIdx !== -1 ? process.argv[usernameIdx + 1] : undefined;
@@ -315,7 +226,7 @@ if (process.argv[1] === fileURLToPath(import.meta.url)) {
315
226
  }
316
227
  }
317
228
  else {
318
- await ensureDotEnv(new URL("../.env.example", import.meta.url));
229
+ await ensureDotEnv(erpExampleUrl, erpWizardConfig);
319
230
  void startServer();
320
231
  }
321
232
  }
package/dist/version.js CHANGED
@@ -1,7 +1,7 @@
1
- import { getGitCommitHash } from "@naisys/common-node";
2
1
  import { readFileSync } from "node:fs";
3
2
  import { dirname, join } from "node:path";
4
3
  import { fileURLToPath } from "node:url";
4
+ import { getGitCommitHash } from "@naisys/common-node";
5
5
  const __dirname = dirname(fileURLToPath(import.meta.url));
6
6
  // Read the server's own package.json (one level up from dist/)
7
7
  const pkg = JSON.parse(readFileSync(join(__dirname, "..", "package.json"), "utf-8"));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@naisys/erp",
3
- "version": "3.0.0-beta.17",
3
+ "version": "3.0.0-beta.19",
4
4
  "description": "NAISYS ERP - Web UI for AI-driven order and work management",
5
5
  "type": "module",
6
6
  "main": "dist/erpServer.js",
@@ -46,11 +46,11 @@
46
46
  "@fastify/rate-limit": "^10.3.0",
47
47
  "@fastify/static": "^9.0.0",
48
48
  "@fastify/swagger": "^9.7.0",
49
- "@naisys/erp-shared": "3.0.0-beta.17",
50
- "@naisys/common": "3.0.0-beta.17",
51
- "@naisys/common-node": "3.0.0-beta.17",
52
- "@naisys/hub-database": "3.0.0-beta.17",
53
- "@naisys/supervisor-database": "3.0.0-beta.17",
49
+ "@naisys/erp-shared": "3.0.0-beta.19",
50
+ "@naisys/common": "3.0.0-beta.19",
51
+ "@naisys/common-node": "3.0.0-beta.19",
52
+ "@naisys/hub-database": "3.0.0-beta.19",
53
+ "@naisys/supervisor-database": "3.0.0-beta.19",
54
54
  "@prisma/adapter-better-sqlite3": "^7.5.0",
55
55
  "@prisma/client": "^7.5.0",
56
56
  "@scalar/fastify-api-reference": "^1.48.7",