@naisys/erp 3.0.0-beta.51 → 3.0.0-beta.53

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.
@@ -48,7 +48,8 @@ var ScheduleEntrySchema = object({
48
48
  name: string().min(1, "Name is required").regex(URL_SAFE_KEY_REGEX, URL_SAFE_KEY_MESSAGE).describe("Unique identifier for this schedule within the agent"),
49
49
  cron: string().min(1, "Cron expression is required").refine((expr) => validateCron(expr).ok, { message: "Invalid cron expression" }).describe("Standard 5-field cron expression in the hub's local timezone"),
50
50
  enabled: boolean().optional().describe("When false, the schedule is paused but kept for editing"),
51
- prompt: string().max(2e3, "Prompt must be at most 2000 characters").optional().describe("Chat message sent to the agent when the schedule fires. Falls back to the schedule name when empty")
51
+ prompt: string().max(2e3, "Prompt must be at most 2000 characters").optional().describe("Chat message sent to the agent when the schedule fires. Falls back to the schedule name when empty"),
52
+ initiator: string().regex(URL_SAFE_KEY_REGEX, URL_SAFE_KEY_MESSAGE).optional().describe("Username the fire message is sent from. The agent reports back to this user when done, letting that agent run its own post-processing. When unset, defaults to the agent's lead, or admin if it has no lead")
52
53
  });
53
54
  function validateCron(expression) {
54
55
  const fields = expression.trim().split(/\s+/).filter(Boolean);
@@ -45,7 +45,7 @@
45
45
  <meta name="format-detection" content="telephone=no" />
46
46
 
47
47
  <title>NAISYS ERP</title>
48
- <script type="module" crossorigin src="/erp/assets/index-CO2ivEdE.js"></script>
48
+ <script type="module" crossorigin src="/erp/assets/index-D6lSIioV.js"></script>
49
49
  <link rel="modulepreload" crossorigin href="/erp/assets/rolldown-runtime-CvHMtSRF.js">
50
50
  <link rel="modulepreload" crossorigin href="/erp/assets/vendor-CJ0ET9hP.js">
51
51
  <link rel="stylesheet" crossorigin href="/erp/assets/vendor-CLUPjUnv.css">
@@ -5,16 +5,25 @@ import { API_PREFIX, selfLink } from "../../hateoas.js";
5
5
  import { hasPermission, requirePermission, } from "../../middleware/auth-middleware.js";
6
6
  import { checkOrderRunStarted, checkWorkCenterAccess, childItemLinks, formatAuditFields, formatDate, resolveActions, resolveOpRun, resolveOrderRun, useFullSerializer, wantsFullResponse, } from "../../route-helpers.js";
7
7
  import { checkStepsComplete, getOpRun, getOpRunFieldRefSummary, getOpRunStepSummary, listOpRuns, updateOpRun, validateStatusFor, } from "../../services/operations/operation-run-service.js";
8
+ import { isUserClockedIn } from "../../services/production/labor-ticket-service.js";
8
9
  function opRunResource(orderKey, runNo) {
9
10
  return `orders/${orderKey}/runs/${runNo}/ops`;
10
11
  }
11
12
  async function opRunItemActions(orderKey, runNo, seqNo, opRunId, operationId, status, user) {
12
13
  const href = `${API_PREFIX}/${opRunResource(orderKey, runNo)}/${seqNo}`;
13
14
  const isExecutor = hasPermission(user, "order_executor");
14
- const stepsErr = isExecutor && status === OperationRunStatus.in_progress
15
- ? await checkStepsComplete(opRunId)
16
- : null;
15
+ const isInProgress = status === OperationRunStatus.in_progress;
16
+ const stepsErr = isExecutor && isInProgress ? await checkStepsComplete(opRunId) : null;
17
17
  const wcErr = user ? await checkWorkCenterAccess(operationId, user) : null;
18
+ // Completing an op requires the caller to be clocked in (enforced by the
19
+ // /complete transition). Surface clock-in and the requirement here so an
20
+ // agent inspecting the op run finds it without following the `labor` link.
21
+ const userClockedIn = isExecutor && isInProgress && user
22
+ ? await isUserClockedIn(opRunId, user.id)
23
+ : false;
24
+ const notClockedInErr = isExecutor && isInProgress && !userClockedIn
25
+ ? "You must be clocked in to complete an operation"
26
+ : null;
18
27
  return resolveActions([
19
28
  {
20
29
  rel: "assign",
@@ -50,6 +59,18 @@ async function opRunItemActions(orderKey, runNo, seqNo, opRunId, operationId, st
50
59
  ? "Operation is blocked by incomplete predecessors"
51
60
  : null),
52
61
  },
62
+ {
63
+ rel: "clock-in",
64
+ path: "/labor/clock-in",
65
+ method: "POST",
66
+ title: "Clock In",
67
+ permission: "order_executor",
68
+ statuses: [OperationRunStatus.in_progress],
69
+ disabledWhen: () => wcErr ??
70
+ (userClockedIn
71
+ ? "You are already clocked in to this operation"
72
+ : null),
73
+ },
53
74
  {
54
75
  rel: "update",
55
76
  method: "PUT",
@@ -68,7 +89,7 @@ async function opRunItemActions(orderKey, runNo, seqNo, opRunId, operationId, st
68
89
  body: { note: "" },
69
90
  permission: "order_executor",
70
91
  statuses: [OperationRunStatus.in_progress],
71
- disabledWhen: () => wcErr ?? stepsErr,
92
+ disabledWhen: () => wcErr ?? notClockedInErr ?? stepsErr,
72
93
  },
73
94
  {
74
95
  rel: "skip",
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@naisys/erp",
3
- "version": "3.0.0-beta.51",
3
+ "version": "3.0.0-beta.53",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@naisys/erp",
9
- "version": "3.0.0-beta.51",
9
+ "version": "3.0.0-beta.53",
10
10
  "dependencies": {
11
11
  "@fastify/cookie": "^11.0.2",
12
12
  "@fastify/cors": "^11.2.0",
@@ -14,11 +14,11 @@
14
14
  "@fastify/rate-limit": "^10.3.0",
15
15
  "@fastify/static": "^9.0.0",
16
16
  "@fastify/swagger": "^9.7.0",
17
- "@naisys/common": "3.0.0-beta.51",
18
- "@naisys/common-node": "3.0.0-beta.51",
19
- "@naisys/erp-shared": "3.0.0-beta.51",
20
- "@naisys/hub-database": "3.0.0-beta.51",
21
- "@naisys/supervisor-database": "3.0.0-beta.51",
17
+ "@naisys/common": "3.0.0-beta.53",
18
+ "@naisys/common-node": "3.0.0-beta.53",
19
+ "@naisys/erp-shared": "3.0.0-beta.53",
20
+ "@naisys/hub-database": "3.0.0-beta.53",
21
+ "@naisys/supervisor-database": "3.0.0-beta.53",
22
22
  "@prisma/adapter-better-sqlite3": "^7.5.0",
23
23
  "@prisma/client": "^7.5.0",
24
24
  "@scalar/fastify-api-reference": "^1.48.7",
@@ -394,9 +394,9 @@
394
394
  }
395
395
  },
396
396
  "node_modules/@naisys/common": {
397
- "version": "3.0.0-beta.51",
398
- "resolved": "https://registry.npmjs.org/@naisys/common/-/common-3.0.0-beta.51.tgz",
399
- "integrity": "sha512-CTv2SNKRMnR0N1rbHM5xeqVOVAQpc16dcnATCwerJS41Uha9kakMaBITlBhoQA8O2PhO/Cc6VbzBYRnSKBsWag==",
397
+ "version": "3.0.0-beta.53",
398
+ "resolved": "https://registry.npmjs.org/@naisys/common/-/common-3.0.0-beta.53.tgz",
399
+ "integrity": "sha512-afW5vMOtPsyFkddbeaAS3c1rIZd/byvpoN9gAxI/Pa3fPj2SPKtvenFxcV2avrxlbXaslg+qSHrezIoFn7pTQA==",
400
400
  "dependencies": {
401
401
  "cron-parser": "^5.5.0",
402
402
  "semver": "^7.7.4",
@@ -404,32 +404,32 @@
404
404
  }
405
405
  },
406
406
  "node_modules/@naisys/common-node": {
407
- "version": "3.0.0-beta.51",
408
- "resolved": "https://registry.npmjs.org/@naisys/common-node/-/common-node-3.0.0-beta.51.tgz",
409
- "integrity": "sha512-0G3uDNTKpCu6ZMO5NL/vQOn/0iK4B1HOQbW3U1d8eFIZbbS2YBlLhxL8ee2p4uDlnPiwA7V3nUTXrFRcHpwGJg==",
407
+ "version": "3.0.0-beta.53",
408
+ "resolved": "https://registry.npmjs.org/@naisys/common-node/-/common-node-3.0.0-beta.53.tgz",
409
+ "integrity": "sha512-rpP4GeP0qmew5t2roluX7D5UylCYbBvmPMxczlgEr14/xE3sxZoUMe5FQ8hZIwJfgqpJULexbSr5YYoRCEdezQ==",
410
410
  "dependencies": {
411
- "@naisys/common": "3.0.0-beta.51",
411
+ "@naisys/common": "3.0.0-beta.53",
412
412
  "better-sqlite3": "^12.6.2",
413
413
  "js-yaml": "^4.1.1",
414
414
  "pino": "^10.3.1"
415
415
  }
416
416
  },
417
417
  "node_modules/@naisys/erp-shared": {
418
- "version": "3.0.0-beta.51",
419
- "resolved": "https://registry.npmjs.org/@naisys/erp-shared/-/erp-shared-3.0.0-beta.51.tgz",
420
- "integrity": "sha512-6I3ohn19tHpcYwJDFcoNpI70IUPT9Em+xpkRIG11j0G/gxOszGHIlOELsEeOtL/+qDK9MfFfsth6aoFewm11Uw==",
418
+ "version": "3.0.0-beta.53",
419
+ "resolved": "https://registry.npmjs.org/@naisys/erp-shared/-/erp-shared-3.0.0-beta.53.tgz",
420
+ "integrity": "sha512-MabLBCbpkqbVtJyhfRX0i9tSbugiRz4Z5hhGzXJyb8usRvjL/cJrOnak0rm0LNLz5RvsMNWyXMX/2dO4Md2Rqw==",
421
421
  "dependencies": {
422
- "@naisys/common": "3.0.0-beta.51",
422
+ "@naisys/common": "3.0.0-beta.53",
423
423
  "zod": "^4.3.6"
424
424
  }
425
425
  },
426
426
  "node_modules/@naisys/hub-database": {
427
- "version": "3.0.0-beta.51",
428
- "resolved": "https://registry.npmjs.org/@naisys/hub-database/-/hub-database-3.0.0-beta.51.tgz",
429
- "integrity": "sha512-TG2lOubOjl+guafQ4vKk9Vetw4Z7Vc43geRlYLYJjDBgN1twuwEBlFncRDbGdjD3Ohu81BUxhONOC5LSZiU/0A==",
427
+ "version": "3.0.0-beta.53",
428
+ "resolved": "https://registry.npmjs.org/@naisys/hub-database/-/hub-database-3.0.0-beta.53.tgz",
429
+ "integrity": "sha512-IGpCowJ26ShLjjMidYoauKc7rII4zkcbFoexvtf7x+fr+Aze6QqLe0UPyK7dUgFgV+XSvdYn4IV5DmoL1hxkoQ==",
430
430
  "dependencies": {
431
- "@naisys/common": "3.0.0-beta.51",
432
- "@naisys/common-node": "3.0.0-beta.51",
431
+ "@naisys/common": "3.0.0-beta.53",
432
+ "@naisys/common-node": "3.0.0-beta.53",
433
433
  "@prisma/adapter-better-sqlite3": "^7.5.0",
434
434
  "@prisma/client": "^7.5.0",
435
435
  "better-sqlite3": "^12.6.2",
@@ -437,12 +437,12 @@
437
437
  }
438
438
  },
439
439
  "node_modules/@naisys/supervisor-database": {
440
- "version": "3.0.0-beta.51",
441
- "resolved": "https://registry.npmjs.org/@naisys/supervisor-database/-/supervisor-database-3.0.0-beta.51.tgz",
442
- "integrity": "sha512-cSIjScSiSloqgtU1AdkgvXeBIiDy5K4eXYTc4lAsokbx3EJWuRx7tibuu/kLnPrAZfzfC2uii/wPeTv5ryTR3g==",
440
+ "version": "3.0.0-beta.53",
441
+ "resolved": "https://registry.npmjs.org/@naisys/supervisor-database/-/supervisor-database-3.0.0-beta.53.tgz",
442
+ "integrity": "sha512-dLM7mkXzkizkqcXrF+CBj9DZce2IqgGhlZCkXswhyHqb8IXY5wBzc3AEzi4MURElJNC9WvMSUCS6QPZnrBZoig==",
443
443
  "dependencies": {
444
- "@naisys/common": "3.0.0-beta.51",
445
- "@naisys/common-node": "3.0.0-beta.51",
444
+ "@naisys/common": "3.0.0-beta.53",
445
+ "@naisys/common-node": "3.0.0-beta.53",
446
446
  "@prisma/adapter-better-sqlite3": "^7.5.0",
447
447
  "@prisma/client": "^7.5.0",
448
448
  "bcryptjs": "^3.0.2",
@@ -925,9 +925,9 @@
925
925
  "license": "MIT"
926
926
  },
927
927
  "node_modules/@types/react": {
928
- "version": "19.2.14",
929
- "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz",
930
- "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==",
928
+ "version": "19.2.15",
929
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.15.tgz",
930
+ "integrity": "sha512-eRwcGNHve+E8qtEQSSRl6urh+rFop4v8gm6O8rGv25CodbvFdLjA1vVQ1KkiFE0w0UPOnb8tDiFKL5lp0rtY5Q==",
931
931
  "license": "MIT",
932
932
  "peer": true,
933
933
  "dependencies": {
@@ -1854,9 +1854,9 @@
1854
1854
  "license": "ISC"
1855
1855
  },
1856
1856
  "node_modules/jiti": {
1857
- "version": "2.6.1",
1858
- "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz",
1859
- "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==",
1857
+ "version": "2.7.0",
1858
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz",
1859
+ "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==",
1860
1860
  "license": "MIT",
1861
1861
  "bin": {
1862
1862
  "jiti": "lib/jiti-cli.mjs"
@@ -1981,9 +1981,9 @@
1981
1981
  "license": "Apache-2.0"
1982
1982
  },
1983
1983
  "node_modules/lru-cache": {
1984
- "version": "11.3.5",
1985
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.5.tgz",
1986
- "integrity": "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==",
1984
+ "version": "11.5.0",
1985
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.0.tgz",
1986
+ "integrity": "sha512-5YgH9UJd7wVb9hIouI2adWpgqrrICkt070Dnj8EUY1+B4B2P9eRLPAkAAo6NICA7CEhOIeBHl46u9zSNpNu7zA==",
1987
1987
  "license": "BlueOak-1.0.0",
1988
1988
  "engines": {
1989
1989
  "node": "20 || >=22"
@@ -2115,9 +2115,9 @@
2115
2115
  }
2116
2116
  },
2117
2117
  "node_modules/nanoid": {
2118
- "version": "5.1.9",
2119
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.9.tgz",
2120
- "integrity": "sha512-ZUvP7KeBLe3OZ1ypw6dI/TzYJuvHP77IM4Ry73waSQTLn8/g8rpdjfyVAh7t1/+FjBtG4lCP42MEbDxOsRpBMw==",
2118
+ "version": "5.1.11",
2119
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.11.tgz",
2120
+ "integrity": "sha512-v+KEsUv2ps74PaSKv0gHTxTCgMXOIfBEbaqa6w6ISIGC7ZsvHN4N9oJ8d4cmf0n5oTzQz2SLmThbQWhjd/8eKg==",
2121
2121
  "funding": [
2122
2122
  {
2123
2123
  "type": "github",
@@ -2458,9 +2458,9 @@
2458
2458
  }
2459
2459
  },
2460
2460
  "node_modules/react": {
2461
- "version": "19.2.5",
2462
- "resolved": "https://registry.npmjs.org/react/-/react-19.2.5.tgz",
2463
- "integrity": "sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA==",
2461
+ "version": "19.2.6",
2462
+ "resolved": "https://registry.npmjs.org/react/-/react-19.2.6.tgz",
2463
+ "integrity": "sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==",
2464
2464
  "license": "MIT",
2465
2465
  "peer": true,
2466
2466
  "engines": {
@@ -2468,16 +2468,16 @@
2468
2468
  }
2469
2469
  },
2470
2470
  "node_modules/react-dom": {
2471
- "version": "19.2.5",
2472
- "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.5.tgz",
2473
- "integrity": "sha512-J5bAZz+DXMMwW/wV3xzKke59Af6CHY7G4uYLN1OvBcKEsWOs4pQExj86BBKamxl/Ik5bx9whOrvBlSDfWzgSag==",
2471
+ "version": "19.2.6",
2472
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.6.tgz",
2473
+ "integrity": "sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g==",
2474
2474
  "license": "MIT",
2475
2475
  "peer": true,
2476
2476
  "dependencies": {
2477
2477
  "scheduler": "^0.27.0"
2478
2478
  },
2479
2479
  "peerDependencies": {
2480
- "react": "^19.2.5"
2480
+ "react": "^19.2.6"
2481
2481
  }
2482
2482
  },
2483
2483
  "node_modules/readable-stream": {
@@ -2649,9 +2649,9 @@
2649
2649
  "license": "BSD-3-Clause"
2650
2650
  },
2651
2651
  "node_modules/semver": {
2652
- "version": "7.7.4",
2653
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
2654
- "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
2652
+ "version": "7.8.0",
2653
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz",
2654
+ "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==",
2655
2655
  "license": "ISC",
2656
2656
  "bin": {
2657
2657
  "semver": "bin/semver.js"
@@ -2963,9 +2963,9 @@
2963
2963
  "license": "ISC"
2964
2964
  },
2965
2965
  "node_modules/yaml": {
2966
- "version": "2.8.3",
2967
- "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.3.tgz",
2968
- "integrity": "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==",
2966
+ "version": "2.9.0",
2967
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz",
2968
+ "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==",
2969
2969
  "license": "ISC",
2970
2970
  "bin": {
2971
2971
  "yaml": "bin.mjs"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@naisys/erp",
3
- "version": "3.0.0-beta.51",
3
+ "version": "3.0.0-beta.53",
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/common": "3.0.0-beta.51",
50
- "@naisys/common-node": "3.0.0-beta.51",
51
- "@naisys/erp-shared": "3.0.0-beta.51",
52
- "@naisys/hub-database": "3.0.0-beta.51",
53
- "@naisys/supervisor-database": "3.0.0-beta.51",
49
+ "@naisys/common": "3.0.0-beta.53",
50
+ "@naisys/common-node": "3.0.0-beta.53",
51
+ "@naisys/erp-shared": "3.0.0-beta.53",
52
+ "@naisys/hub-database": "3.0.0-beta.53",
53
+ "@naisys/supervisor-database": "3.0.0-beta.53",
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",