@things-factory/station 10.1.39 → 10.1.40

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@things-factory/station",
3
- "version": "10.1.39",
3
+ "version": "10.1.40",
4
4
  "main": "dist-server/index.js",
5
5
  "browser": "dist-client/index.js",
6
6
  "things-factory": true,
@@ -33,12 +33,12 @@
33
33
  "@hatiolab/things-scene": "^10.0.0",
34
34
  "@operato/i18n": "^10.0.0",
35
35
  "@operato/styles": "^10.0.0",
36
- "@things-factory/auth-base": "^10.1.39",
37
- "@things-factory/board-service": "^10.1.39",
38
- "@things-factory/ops-master": "^10.1.39",
39
- "@things-factory/shell": "^10.1.39",
40
- "@things-factory/worklist": "^10.1.39",
36
+ "@things-factory/auth-base": "^10.1.40",
37
+ "@things-factory/board-service": "^10.1.40",
38
+ "@things-factory/ops-master": "^10.1.40",
39
+ "@things-factory/shell": "^10.1.40",
40
+ "@things-factory/worklist": "^10.1.40",
41
41
  "i18next": "^24.2.1"
42
42
  },
43
- "gitHead": "fe5257ad8995fe7e79275e287f36e95b5fd32d1c"
43
+ "gitHead": "51c5d804c14ad8fcc6d4707e6ef80c9deede2766"
44
44
  }
@@ -1,4 +1,9 @@
1
1
  /** The closed set of context axis names a station screen may read. Declared once; see the .js. */
2
2
  export const STATION_AXES: readonly string[]
3
- export function isStationAxis(axis: string): boolean
4
- export function nearestAxes(said: string, howMany?: number): string[]
3
+ /** The axes any product's bench answers - the module owns them (ADR-0083 ruling ①). */
4
+ export const STATION_CORE_AXES: readonly string[]
5
+ /** operato-plant's own axes, held here until plant declares them itself. */
6
+ export const STATION_TRANSITIONAL_AXES: readonly string[]
7
+ /** `declared` is what the product added in `StationProduct.axes`. */
8
+ export function isStationAxis(axis: string, declared?: readonly string[]): boolean
9
+ export function nearestAxes(said: string, howMany?: number, declared?: readonly string[]): string[]
@@ -32,8 +32,15 @@
32
32
  * ──────────────────────────────────────────────────────────────────────────────────────────
33
33
  */
34
34
 
35
- const STATION_AXES = [
36
- /* Where the operator is standing, and when. */
35
+ /*
36
+ * ── The core, and what a product adds (ADR-0083 ruling ①, 2026-09-24) ─────────────────────────
37
+ * The core is what any product's bench answers: where the station stands and when, who scanned in,
38
+ * where it is, the task in hand, how many this window, and the order at its plainest. The module
39
+ * owns it. Anything else is a product's word and the product declares it (`StationProduct.axes`);
40
+ * the closed set a screen is checked against is the core, the transitional list below, and that
41
+ * declaration.
42
+ */
43
+ const STATION_CORE_AXES = [
37
44
  'station.equipment',
38
45
  'station.operation',
39
46
  'station.shift',
@@ -44,31 +51,37 @@ const STATION_AXES = [
44
51
  'station.problem',
45
52
  'station.readAt',
46
53
  'station.live',
47
-
48
54
  'location.name',
49
55
  'location.type',
50
56
  'location.level',
51
- 'productionLine.name',
52
-
53
- /* Who scanned in. Until this is filled nothing else is attributable. */
54
57
  'operator.name',
55
58
  'operator.personnelClassIds',
56
59
  'operator.scannedAt',
57
-
58
- /* What is being made. */
59
60
  'order.name',
60
- 'order.material',
61
61
  'order.quantity',
62
62
  'order.uom',
63
63
  'order.status',
64
+ 'task.name',
65
+ 'task.since',
66
+ 'window.tasks'
67
+ ]
68
+
69
+ /*
70
+ * ── Transitional: operato-plant's own words, still held here ─────────────────────────────────
71
+ * These are a factory's - its line, its directives and routes, good and scrap, its equipment state.
72
+ * They stay in the module until plant declares them in its own `axes` (ruling ①: taking them out
73
+ * first would break plant's screens). Until then a second product's authoring tool offers them too,
74
+ * which the ruling accepts as noise. When plant has moved them this list is empty and goes.
75
+ */
76
+ const STATION_TRANSITIONAL_AXES = [
77
+ 'productionLine.name',
78
+ 'order.material',
64
79
  'order.directive',
65
80
  'order.directiveVersion',
66
81
  'order.route',
67
82
  'materialDefinition.name',
68
83
  'materialDefinition.description',
69
84
  'materialDefinition.materialClassIds',
70
-
71
- /* How it is made. */
72
85
  'route.key',
73
86
  'route.steps',
74
87
  'route.stepNumber',
@@ -82,34 +95,26 @@ const STATION_AXES = [
82
95
  'operation.name',
83
96
  'operation.description',
84
97
  'operation.duration',
85
-
86
- /* What is happening right now. */
87
- 'task.name',
88
- 'task.since',
89
98
  'paused.at',
90
99
  'paused.reason',
91
100
  'paused.detail',
92
-
93
- /* How much, this window. */
94
101
  'window.good',
95
102
  'window.scrap',
96
- 'window.tasks',
97
-
98
- /* The equipment's own state. */
99
103
  'state.status',
100
104
  'state.knownUntil',
101
105
  'state.reason',
102
-
103
- /* Counts of things waiting. */
104
106
  'staged.count',
105
107
  'candidates.count',
106
108
  'maintenance.count'
107
109
  ]
108
110
 
111
+ const STATION_AXES = [...STATION_CORE_AXES, ...STATION_TRANSITIONAL_AXES]
112
+
109
113
  const KNOWN = new Set(STATION_AXES)
110
114
 
111
- function isStationAxis(axis) {
112
- return KNOWN.has(axis)
115
+ /** Is this a name a screen may read — the machine's own, or one the product declared. */
116
+ function isStationAxis(axis, declared = []) {
117
+ return KNOWN.has(axis) || declared.includes(axis)
113
118
  }
114
119
 
115
120
  /*
@@ -119,14 +124,15 @@ function isStationAxis(axis) {
119
124
  * them what is right, and with fifty-five names that is most of the work left undone. One
120
125
  * character out is the common case, so it is the case worth answering.
121
126
  */
122
- function nearestAxes(said, howMany = 3) {
127
+ function nearestAxes(said, howMany = 3, declared = []) {
123
128
  const asked = String(said ?? '').trim().toLowerCase()
124
129
 
125
130
  if (!asked) {
126
131
  return []
127
132
  }
128
133
 
129
- return STATION_AXES.map(axis => ({ axis, far: distance(asked, axis.toLowerCase()) }))
134
+ /* A product's own axes are the likeliest thing its author meant, so they are in the running. */
135
+ return [...STATION_AXES, ...declared].map(axis => ({ axis, far: distance(asked, axis.toLowerCase()) }))
130
136
  .sort((a, b) => a.far - b.far)
131
137
  .slice(0, howMany)
132
138
  .filter(one => one.far <= Math.max(3, Math.floor(asked.length / 3)))
@@ -151,5 +157,7 @@ function distance(a, b) {
151
157
  }
152
158
 
153
159
  exports.STATION_AXES = STATION_AXES
160
+ exports.STATION_CORE_AXES = STATION_CORE_AXES
161
+ exports.STATION_TRANSITIONAL_AXES = STATION_TRANSITIONAL_AXES
154
162
  exports.isStationAxis = isStationAxis
155
163
  exports.nearestAxes = nearestAxes