busroot-sdk 0.0.8-dev.2832183355 → 0.0.8-dev.2836398557

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/build/index.js CHANGED
@@ -142,8 +142,7 @@ var require_sku = __commonJS({
142
142
  allowUseInQuickSchedule: zod_1.z.boolean().nullish().describe("Allow Use In Quick Schedule: Determines if this SKU can be selected when creating ad-hoc schedules from tablets"),
143
143
  stationCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Station Codes: Array of station codes allowed to produce this SKU. If specified, only these stations can be scheduled with this SKU. Example: ['STA-01', 'STA-02']"),
144
144
  stationGroupCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Station Group Codes: Array of station group codes allowed to produce this SKU. If specified, only stations in these groups can be scheduled with this SKU. Example: ['LINE-01', 'LINE-02']"),
145
- taskCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Task Codes: Array of Task codes linked to this SKU. References Tasks defined at the account level. Example: ['TASK-001', 'QC-CHECK']"),
146
- includeTaskCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Include Task Codes: If set, only these Task codes are available for this SKU.")
145
+ taskCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Task Codes: Array of Task codes linked to this SKU. References Tasks defined at the account level. Example: ['TASK-001', 'QC-CHECK']")
147
146
  }).strict().describe("A record for an SKU (aka part or component) that is referenced when scheduling production.");
148
147
  }
149
148
  });
@@ -153,7 +152,7 @@ var require_task = __commonJS({
153
152
  "../../packages/common/build/schemas/task.js"(exports2) {
154
153
  "use strict";
155
154
  Object.defineProperty(exports2, "__esModule", { value: true });
156
- exports2.TaskSchema = exports2.TaskListSchema = exports2.TaskDescriptionSchema = exports2.TaskNameSchema = exports2.TaskCodeSchema = exports2.TaskFrequencySchema = exports2.TASK_FREQUENCY_TYPE_ALWAYS = exports2.TASK_FREQUENCY_TYPE_CRON = exports2.TASK_FREQUENCY_TYPE_SCHEDULE = void 0;
155
+ exports2.TaskSchema = exports2.TaskListMembershipsSchema = exports2.TaskListMembershipSchema = exports2.TASK_LIST_ORDER_RANGE_MESSAGE = exports2.TASK_LIST_ORDER_MAX = exports2.TaskListSchema = exports2.TaskDescriptionSchema = exports2.TaskNameSchema = exports2.TaskCodeSchema = exports2.TaskFrequencySchema = exports2.TASK_FREQUENCY_TYPE_ALWAYS = exports2.TASK_FREQUENCY_TYPE_CRON = exports2.TASK_FREQUENCY_TYPE_SCHEDULE = void 0;
157
156
  var zod_1 = require("zod");
158
157
  exports2.TASK_FREQUENCY_TYPE_SCHEDULE = "schedule";
159
158
  exports2.TASK_FREQUENCY_TYPE_CRON = "cron";
@@ -187,21 +186,41 @@ var require_task = __commonJS({
187
186
  name: zod_1.z.string().describe("Human-readable name of the Task list (e.g., 'Daily Checks')"),
188
187
  // Optional at the schema level so a list saved without one still parses. Lengths and the
189
188
  // required-ness of `name`/`code` are enforced on the write path — see `TaskCodeSchema`.
190
- description: zod_1.z.string().optional().describe("Detailed description of what this Task list groups together")
189
+ description: zod_1.z.string().optional().describe("Detailed description of what this Task list groups together"),
190
+ // Optional at the schema level so lists written before frequency moved here still parse; the
191
+ // write path requires it. A list without one behaves as per-schedule, the pre-move default.
192
+ frequency: exports2.TaskFrequencySchema.optional().describe("How often every Task in this list must be completed. Set on the list, not the Task \u2014 all Tasks in a list share it.")
191
193
  }).strict();
194
+ exports2.TASK_LIST_ORDER_MAX = 100;
195
+ exports2.TASK_LIST_ORDER_RANGE_MESSAGE = `Order must be greater than 0 and at most ${exports2.TASK_LIST_ORDER_MAX}`;
196
+ exports2.TaskListMembershipSchema = zod_1.z.object({
197
+ code: zod_1.z.string().min(1).describe("Code of the Task list this Task belongs to"),
198
+ // Optional at the schema level so memberships written before ordering existed still parse —
199
+ // those sort last, in manifest order. The write path requires it.
200
+ order: zod_1.z.number().optional().describe(`Display order of this Task within this list: greater than 0 and at most ${exports2.TASK_LIST_ORDER_MAX}. Decimals are allowed, so a Task can be inserted between two others.`)
201
+ }).strict();
202
+ exports2.TaskListMembershipsSchema = zod_1.z.preprocess((value) => Array.isArray(value) ? value.map((entry) => typeof entry === "string" ? { code: entry } : entry) : value, zod_1.z.array(exports2.TaskListMembershipSchema));
192
203
  exports2.TaskSchema = zod_1.z.object({
193
204
  code: zod_1.z.string().describe("Unique Task code used to reference this procedure (e.g., 'TASK-001', 'STARTUP-CHECK'). Must be unique within the account."),
194
205
  title: zod_1.z.string().describe("Human-readable title of the Task (e.g., 'Machine Startup Checklist', 'Quality Inspection Procedure')"),
195
206
  // Optional at the schema level so a Task saved without one still parses. Lengths and the
196
207
  // required-ness of `title`/`code` are enforced on the write path — see `TaskCodeSchema`.
197
208
  description: zod_1.z.string().optional().describe("Detailed description of the Task and its purpose"),
198
- frequency: exports2.TaskFrequencySchema.default({ type: exports2.TASK_FREQUENCY_TYPE_SCHEDULE }),
209
+ // Legacy: frequency now lives on the Task list, so every Task in a list shares it. Kept here
210
+ // so stored manifests still parse and so Task History can still label a completion whose list
211
+ // has since been deleted — nothing else reads it, and no write path sets it any more.
212
+ //
213
+ // `.optional()`, not `.default()`: a default would put a meaningless per-schedule frequency on
214
+ // every Task the code constructs, and make the field look required to every caller building a
215
+ // Task. Absent is the honest value for a Task written since the move.
216
+ frequency: exports2.TaskFrequencySchema.optional(),
199
217
  // Optional at the schema level so pre-existing Tasks (written before this field existed) still
200
218
  // parse — absent means notes are not required, the pre-feature behaviour.
201
219
  requireNotes: zod_1.z.boolean().optional().describe("When enabled, operators must enter notes before this Task can be confirmed as complete."),
202
220
  // Optional at the schema level so pre-existing Tasks (written before Task lists existed)
203
- // still parse — absent means the Task belongs to no list.
204
- taskListCodes: zod_1.z.array(zod_1.z.string()).optional().describe("Codes of the Task lists this Task belongs to. Purely organisational grouping; a Task can belong to zero or many lists.")
221
+ // still parse — absent means the Task belongs to no list and is therefore scoped to nothing.
222
+ // The write path requires at least one entry, each with an order.
223
+ taskListCodes: exports2.TaskListMembershipsSchema.optional().describe("The Task lists this Task belongs to, with its display order within each. A Task can belong to several lists and is completed independently in each.")
205
224
  }).strict();
206
225
  }
207
226
  });
@@ -411,8 +430,12 @@ var require_base_station_group = __commonJS({
411
430
  // tri-state `enable*` fields, added below via flagSchemaFieldsForLevel("stationGroup").
412
431
  includeReasonCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Include Reason Codes: If set, only these reason codes are available at this level. Applied before excludeReasonCodes."),
413
432
  excludeReasonCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Exclude Reason Codes: These reason codes are removed at this level. Applied after includeReasonCodes."),
414
- includeTaskCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Include Task Codes: If set, only these Task codes are available at this level. Applied before excludeTaskCodes."),
415
- excludeTaskCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Exclude Task Codes: These Task codes are removed at this level. Applied after includeTaskCodes."),
433
+ // Legacy: scoping moved from individual Tasks to Task lists. Kept so stored manifests still
434
+ // parse; nothing reads them and no write path sets them. Use the Task list fields below.
435
+ includeTaskCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Include Task Codes: Legacy, no longer applied. Superseded by includeTaskListCodes."),
436
+ excludeTaskCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Exclude Task Codes: Legacy, no longer applied. Superseded by excludeTaskListCodes."),
437
+ includeTaskListCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Include Task List Codes: The Task lists available at this level. Unlike reasons, no level setting this means no Task lists are available \u2014 lists must be included explicitly before their Tasks appear on a station."),
438
+ excludeTaskListCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Exclude Task List Codes: These Task list codes are removed at this level. Applied after includeTaskListCodes."),
416
439
  totalEnergyStationCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Total Energy Station Codes: When set, this group's energy (kWh, cost, CO2) is the sum of these stations' energy instead of the additive sum over member stations."),
417
440
  createdAt: zod_1.z.string().nullish().describe("Group creation timestamp (ISO 8601, system managed)"),
418
441
  updatedAt: zod_1.z.string().nullish().describe("Last update timestamp (ISO 8601, system managed)"),
@@ -791,8 +814,12 @@ var require_base_station = __commonJS({
791
814
  lineSpeedTarget: zod_1.z.number().gt(0).lte(99999).nullish().describe("Line Speed Target: Target operating speed for the station. Example: 100, 120, 50"),
792
815
  includeReasonCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Include Reason Codes: If set, only these reason codes are available at this level. Applied before excludeReasonCodes."),
793
816
  excludeReasonCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Exclude Reason Codes: These reason codes are removed at this level. Applied after includeReasonCodes."),
794
- includeTaskCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Include Task Codes: If set, only these Task codes are available at this level. Applied before excludeTaskCodes."),
795
- excludeTaskCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Exclude Task Codes: These Task codes are removed at this level. Applied after includeTaskCodes."),
817
+ // Legacy: scoping moved from individual Tasks to Task lists. Kept so stored manifests still
818
+ // parse; nothing reads them and no write path sets them. Use the Task list fields below.
819
+ includeTaskCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Include Task Codes: Legacy, no longer applied. Superseded by includeTaskListCodes."),
820
+ excludeTaskCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Exclude Task Codes: Legacy, no longer applied. Superseded by excludeTaskListCodes."),
821
+ includeTaskListCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Include Task List Codes: The Task lists available at this level. Unlike reasons, no level setting this means no Task lists are available \u2014 lists must be included explicitly before their Tasks appear on a station."),
822
+ excludeTaskListCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Exclude Task List Codes: These Task list codes are removed at this level. Applied after includeTaskListCodes."),
796
823
  alertMessage: zod_1.z.string().nullish().describe("Alert Message: Current alert message for the station (system managed)"),
797
824
  alertExpiresAt: zod_1.z.string().nullish().describe("Alert Expires At: Timestamp when alert expires (ISO 8601, system managed)"),
798
825
  // System info
@@ -824,8 +851,12 @@ var require_plant = __commonJS({
824
851
  weekStartDay: zod_1.z.number().int().gte(0).lte(6).default(0).describe("Day the production week starts. 0 = Monday (default, ISO standard), 1 = Tuesday, 2 = Wednesday, 3 = Thursday, 4 = Friday, 5 = Saturday, 6 = Sunday"),
825
852
  includeReasonCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Include Reason Codes: If set, only these reason codes are available at this level. Applied before excludeReasonCodes."),
826
853
  excludeReasonCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Exclude Reason Codes: These reason codes are removed at this level. Applied after includeReasonCodes."),
827
- includeTaskCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Include Task Codes: If set, only these Task codes are available at this level. Applied before excludeTaskCodes."),
828
- excludeTaskCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Exclude Task Codes: These Task codes are removed at this level. Applied after includeTaskCodes."),
854
+ // Legacy: scoping moved from individual Tasks to Task lists. Kept so stored manifests still
855
+ // parse; nothing reads them and no write path sets them. Use the Task list fields below.
856
+ includeTaskCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Include Task Codes: Legacy, no longer applied. Superseded by includeTaskListCodes."),
857
+ excludeTaskCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Exclude Task Codes: Legacy, no longer applied. Superseded by excludeTaskListCodes."),
858
+ includeTaskListCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Include Task List Codes: The Task lists available at this level. Unlike reasons, no level setting this means no Task lists are available \u2014 lists must be included explicitly before their Tasks appear on a station."),
859
+ excludeTaskListCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Exclude Task List Codes: These Task list codes are removed at this level. Applied after includeTaskListCodes."),
829
860
  totalEnergyStationCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Total Energy Station Codes: When set, this plant's energy (kWh, cost, CO2) is the sum of these stations' energy instead of the additive sum over member stations."),
830
861
  stationGroups: zod_1.z.array(base_station_group_1.BaseStationGroupSchema.extend({
831
862
  stations: zod_1.z.array(base_station_1.BaseStationSchema).describe("Array of stations within this group (minimum 1)")
@@ -1889,8 +1920,12 @@ var require_base_account = __commonJS({
1889
1920
  appUrls: zod_1.z.string().nullish().describe("Custom application URLs (system managed)"),
1890
1921
  includeReasonCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Include Reason Codes: If set, only these reason codes are available at this level. Applied before excludeReasonCodes."),
1891
1922
  excludeReasonCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Exclude Reason Codes: These reason codes are removed at this level. Applied after includeReasonCodes."),
1892
- includeTaskCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Include Task Codes: If set, only these Task codes are available at this level. Applied before excludeTaskCodes."),
1893
- excludeTaskCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Exclude Task Codes: These Task codes are removed at this level. Applied after includeTaskCodes."),
1923
+ // Legacy: scoping moved from individual Tasks to Task lists. Kept so stored manifests still
1924
+ // parse; nothing reads them and no write path sets them. Use the Task list fields below.
1925
+ includeTaskCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Include Task Codes: Legacy, no longer applied. Superseded by includeTaskListCodes."),
1926
+ excludeTaskCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Exclude Task Codes: Legacy, no longer applied. Superseded by excludeTaskListCodes."),
1927
+ includeTaskListCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Include Task List Codes: The Task lists available at this level. Unlike reasons, no level setting this means no Task lists are available \u2014 lists must be included explicitly before their Tasks appear on a station."),
1928
+ excludeTaskListCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Exclude Task List Codes: These Task list codes are removed at this level. Applied after includeTaskListCodes."),
1894
1929
  createdAt: zod_1.z.string().nullish().describe("Account creation timestamp (ISO 8601, system managed)"),
1895
1930
  updatedAt: zod_1.z.string().nullish().describe("Last update timestamp (ISO 8601, system managed)"),
1896
1931
  archivedAt: zod_1.z.string().nullish().describe("Archive timestamp (ISO 8601, system managed). When set, the account is archived and hidden from active lists."),
@@ -2244,6 +2279,7 @@ var require_manifest = __commonJS({
2244
2279
  };
2245
2280
  const validReasonCodes = new Set(flattenReasonCodes(data.account.reasons ?? []));
2246
2281
  const validTaskCodes = new Set((data.account.tasks ?? []).map((s) => s.code));
2282
+ const validTaskListCodes = new Set((data.account.taskLists ?? []).map((l) => l.code));
2247
2283
  const validShiftPatternCodes = new Set((data.account.shiftPatterns ?? []).map((sp) => sp.code));
2248
2284
  const validateShiftPatternCode = (code, path) => {
2249
2285
  if (code && !validShiftPatternCodes.has(code)) {
@@ -2254,6 +2290,11 @@ var require_manifest = __commonJS({
2254
2290
  });
2255
2291
  }
2256
2292
  };
2293
+ const SOURCE_BY_LABEL = {
2294
+ "Reason code": "reasons",
2295
+ "Task code": "tasks",
2296
+ "Task list code": "taskLists"
2297
+ };
2257
2298
  const validateCodes = (codes, validSet, label, path) => {
2258
2299
  if (!codes) {
2259
2300
  return;
@@ -2262,7 +2303,7 @@ var require_manifest = __commonJS({
2262
2303
  if (!validSet.has(code)) {
2263
2304
  ctx.addIssue({
2264
2305
  code: zod_1.z.ZodIssueCode.custom,
2265
- message: `${label} '${code}' is not defined in manifest.account.${label.startsWith("Reason") ? "reasons" : "tasks"}`,
2306
+ message: `${label} '${code}' is not defined in manifest.account.${SOURCE_BY_LABEL[label] ?? "tasks"}`,
2266
2307
  path
2267
2308
  });
2268
2309
  }
@@ -2284,10 +2325,10 @@ var require_manifest = __commonJS({
2284
2325
  const validateLevel = (level, basePath) => {
2285
2326
  validateCodes(level.includeReasonCodes, validReasonCodes, "Reason code", [...basePath, "includeReasonCodes"]);
2286
2327
  validateCodes(level.excludeReasonCodes, validReasonCodes, "Reason code", [...basePath, "excludeReasonCodes"]);
2287
- validateCodes(level.includeTaskCodes, validTaskCodes, "Task code", [...basePath, "includeTaskCodes"]);
2288
- validateCodes(level.excludeTaskCodes, validTaskCodes, "Task code", [...basePath, "excludeTaskCodes"]);
2328
+ validateCodes(level.includeTaskListCodes, validTaskListCodes, "Task list code", [...basePath, "includeTaskListCodes"]);
2329
+ validateCodes(level.excludeTaskListCodes, validTaskListCodes, "Task list code", [...basePath, "excludeTaskListCodes"]);
2289
2330
  validateNoOverlap(level.includeReasonCodes, level.excludeReasonCodes, "Reason code", [...basePath, "includeReasonCodes"], [...basePath, "excludeReasonCodes"]);
2290
- validateNoOverlap(level.includeTaskCodes, level.excludeTaskCodes, "Task code", [...basePath, "includeTaskCodes"], [...basePath, "excludeTaskCodes"]);
2331
+ validateNoOverlap(level.includeTaskListCodes, level.excludeTaskListCodes, "Task list code", [...basePath, "includeTaskListCodes"], [...basePath, "excludeTaskListCodes"]);
2291
2332
  };
2292
2333
  validateLevel(data.account, ["account"]);
2293
2334
  const validateTotalEnergyStationCodes = (codes, activeStationCodesLower, scopeLabel, path) => {
@@ -2340,7 +2381,6 @@ var require_manifest = __commonJS({
2340
2381
  for (const [ki, sku] of (data.account.skus ?? []).entries()) {
2341
2382
  const skuPath = ["account", "skus", ki];
2342
2383
  validateCodes(sku.taskCodes, validTaskCodes, "Task code", [...skuPath, "taskCodes"]);
2343
- validateCodes(sku.includeTaskCodes, validTaskCodes, "Task code", [...skuPath, "includeTaskCodes"]);
2344
2384
  }
2345
2385
  });
2346
2386
  exports2.StrictManifestSchema = exports2.ManifestSchema.superRefine((data, ctx) => {
@@ -2583,6 +2623,11 @@ var require_task_completion = __commonJS({
2583
2623
  accountId: zod_1.z.string(),
2584
2624
  stationCode: zod_1.z.string(),
2585
2625
  taskCode: zod_1.z.string(),
2626
+ // The list this completion belongs to. Completion is per (Task, list, station): a Task in two
2627
+ // lists is completed separately in each, so this is part of the row's identity, not a label.
2628
+ // Nullish only because rows written before Task lists became the unit of operation kept their
2629
+ // NULL — see migration 20260909143000. Every write path sets it.
2630
+ taskListCode: zod_1.z.string().nullish(),
2586
2631
  scheduleId: zod_1.z.number().nullish(),
2587
2632
  periodStartAt: zod_1.z.string().nullish(),
2588
2633
  periodEndAt: zod_1.z.string().nullish(),
@@ -2796,8 +2841,8 @@ var require_plant2 = __commonJS({
2796
2841
  // Without these the flag values posted by the admin form are stripped by `.parse()` before
2797
2842
  // `PlantService.applyPlantFlags` ever sees them.
2798
2843
  ...(0, feature_flags_1.flagSchemaFieldsForLevel)("plant"),
2799
- includeTaskCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Include Task Codes: Only these Task codes are available at this level."),
2800
- excludeTaskCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Exclude Task Codes: These Task codes are removed at this level."),
2844
+ includeTaskListCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Include Task List Codes: The Task lists available at this level. No level setting this means no Task lists are available."),
2845
+ excludeTaskListCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Exclude Task List Codes: These Task list codes are removed at this level."),
2801
2846
  includeReasonCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Include Reason Codes: If set, only these reason codes are available at this level. Applied before excludeReasonCodes."),
2802
2847
  excludeReasonCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Exclude Reason Codes: These reason codes are removed at this level. Applied after includeReasonCodes."),
2803
2848
  totalEnergyStationCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Total Energy Station Codes: When set, this plant's energy (kWh, cost, CO2) is the sum of these stations' energy instead of the additive sum over member stations.")
@@ -2990,8 +3035,8 @@ var require_station_group2 = __commonJS({
2990
3035
  shiftPatternCode: schemas_1.shiftPatternCodeSchema.describe("Shift Pattern: Select which Shift Pattern the group will follow."),
2991
3036
  // Group-level feature-flag config fields (tri-state on/off/inherit), generated from the registry.
2992
3037
  ...(0, feature_flags_1.flagSchemaFieldsForLevel)("stationGroup"),
2993
- includeTaskCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Include Task Codes: Only these Task codes are available at this level."),
2994
- excludeTaskCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Exclude Task Codes: These Task codes are removed at this level."),
3038
+ includeTaskListCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Include Task List Codes: The Task lists available at this level. No level setting this means no Task lists are available."),
3039
+ excludeTaskListCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Exclude Task List Codes: These Task list codes are removed at this level."),
2995
3040
  includeReasonCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Include Reason Codes: If set, only these reason codes are available at this level. Applied before excludeReasonCodes."),
2996
3041
  excludeReasonCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Exclude Reason Codes: These reason codes are removed at this level. Applied after includeReasonCodes."),
2997
3042
  totalEnergyStationCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Total Energy Station Codes: When set, this group's energy (kWh, cost, CO2) is the sum of these stations' energy instead of the additive sum over member stations.")
@@ -5931,8 +5976,8 @@ var require_account2 = __commonJS({
5931
5976
  durationFormat: zod_1.z.enum(times_1.SUPPORTED_DURATION).default("months").describe("Duration Format: Select the format to display durations, for example a downtime period or length of a schedule."),
5932
5977
  includeReasonCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Include Reason Codes: If set, only these reason codes are available at this level. Applied before excludeReasonCodes."),
5933
5978
  excludeReasonCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Exclude Reason Codes: These reason codes are removed at this level. Applied after includeReasonCodes."),
5934
- includeTaskCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Include Task Codes: If set, only these Task codes are available at this level. Applied before excludeTaskCodes."),
5935
- excludeTaskCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Exclude Task Codes: These Task codes are removed at this level. Applied after includeTaskCodes.")
5979
+ includeTaskListCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Include Task List Codes: The Task lists available at this level. No level setting this means no Task lists are available."),
5980
+ excludeTaskListCodes: zod_1.z.array(zod_1.z.string()).nullish().describe("Exclude Task List Codes: These Task list codes are removed at this level. Applied after includeTaskListCodes.")
5936
5981
  });
5937
5982
  }
5938
5983
  });
@@ -6585,10 +6630,23 @@ var require_task2 = __commonJS({
6585
6630
  exports2.TaskDeleteRequest = exports2.TaskPostRequest = void 0;
6586
6631
  var zod_1 = require("zod");
6587
6632
  var task_1 = require_task();
6588
- exports2.TaskPostRequest = task_1.TaskSchema.extend({
6633
+ exports2.TaskPostRequest = task_1.TaskSchema.omit({ frequency: true }).extend({
6589
6634
  code: task_1.TaskCodeSchema.describe("Unique Task code used to reference this procedure (e.g., 'TASK-001', 'STARTUP-CHECK'). Must be unique within the account."),
6590
6635
  title: task_1.TaskNameSchema.describe("Human-readable title of the Task (e.g., 'Machine Startup Checklist', 'Quality Inspection Procedure')"),
6591
- description: task_1.TaskDescriptionSchema.describe("Detailed description of the Task and its purpose")
6636
+ description: task_1.TaskDescriptionSchema.describe("Detailed description of the Task and its purpose"),
6637
+ // Membership is what scopes a Task to a station and what gives it a frequency, so a Task with no
6638
+ // list would be invisible everywhere — rejected here rather than saved into limbo. The manifest
6639
+ // schema stays permissive so pre-existing listless Tasks keep parsing; only new writes conform.
6640
+ //
6641
+ // `order` is required per entry for the same reason it is optional in the manifest: the display
6642
+ // order has to exist for new Tasks, but back-filling it onto stored ones would be a migration.
6643
+ // It is bounded here and nowhere in the manifest schema, so a stored order outside the bounds
6644
+ // keeps loading and only has to conform when the Task is next saved.
6645
+ // `TaskService.save` fills in the next whole number when a caller omits the whole membership
6646
+ // list entry, which is what makes the SDK path workable.
6647
+ taskListCodes: zod_1.z.array(task_1.TaskListMembershipSchema.required({ order: true }).extend({
6648
+ order: zod_1.z.number().gt(0, task_1.TASK_LIST_ORDER_RANGE_MESSAGE).max(task_1.TASK_LIST_ORDER_MAX, task_1.TASK_LIST_ORDER_RANGE_MESSAGE)
6649
+ })).min(1, "A Task must belong to at least one Task list").describe("The Task lists this Task belongs to, with its display order within each. At least one is required.")
6592
6650
  });
6593
6651
  exports2.TaskDeleteRequest = zod_1.z.object({
6594
6652
  code: zod_1.z.string()
@@ -6607,7 +6665,11 @@ var require_task_list = __commonJS({
6607
6665
  exports2.TaskListPostRequest = task_1.TaskListSchema.extend({
6608
6666
  code: task_1.TaskCodeSchema.describe("Unique Task list code used to reference this list (e.g., 'DAILY-CHECKS'). Must be unique within the account."),
6609
6667
  name: task_1.TaskNameSchema.describe("Human-readable name of the Task list (e.g., 'Daily Checks')"),
6610
- description: task_1.TaskDescriptionSchema.describe("Detailed description of what this Task list groups together")
6668
+ description: task_1.TaskDescriptionSchema.describe("Detailed description of what this Task list groups together"),
6669
+ // Required here, optional on the manifest schema: every Task in the list follows this, so a list
6670
+ // without one would leave its Tasks with no defined timing. Lists stored before frequency moved
6671
+ // here keep parsing and fall back to per-schedule (see `taskListUtils.taskListFrequency`).
6672
+ frequency: task_1.TaskFrequencySchema.describe("How often every Task in this list must be completed.")
6611
6673
  });
6612
6674
  exports2.TaskListDeleteRequest = zod_1.z.object({
6613
6675
  code: zod_1.z.string()
@@ -7187,7 +7249,7 @@ var require_station_allowed_list = __commonJS({
7187
7249
  "../../packages/common/build/utils/station-allowed-list.js"(exports2) {
7188
7250
  "use strict";
7189
7251
  Object.defineProperty(exports2, "__esModule", { value: true });
7190
- exports2.getValidSkus = exports2.getValidReasons = exports2.requiredTaskCodes = exports2.resolveTaskCodes = exports2.resolveReasonCodes = exports2.flattenReasonCodes = void 0;
7252
+ exports2.getValidSkus = exports2.getValidReasons = exports2.requiredTaskRefs = exports2.requiredTaskListCodes = exports2.resolveTaskListCodes = exports2.resolveReasonCodes = exports2.flattenReasonCodes = void 0;
7191
7253
  var flattenReasonCodes = (reasons) => {
7192
7254
  const codes = [];
7193
7255
  for (const reason of reasons) {
@@ -7224,16 +7286,15 @@ var require_station_allowed_list = __commonJS({
7224
7286
  return codes;
7225
7287
  };
7226
7288
  exports2.resolveReasonCodes = resolveReasonCodes;
7227
- var resolveTaskCodes = (allCodes, ...levels) => {
7228
- const hasAnyInclude = levels.some((level) => level?.includeTaskCodes?.length);
7289
+ var resolveTaskListCodes = (allCodes, ...levels) => {
7229
7290
  const allCodesSet = new Set(allCodes);
7230
- let codes = hasAnyInclude ? [] : [...allCodes];
7291
+ let codes = [];
7231
7292
  for (const level of levels) {
7232
7293
  if (!level) {
7233
7294
  continue;
7234
7295
  }
7235
- if (level.includeTaskCodes?.length) {
7236
- const toAdd = level.includeTaskCodes.filter((code) => allCodesSet.has(code));
7296
+ if (level.includeTaskListCodes?.length) {
7297
+ const toAdd = level.includeTaskListCodes.filter((code) => allCodesSet.has(code));
7237
7298
  const existing = new Set(codes);
7238
7299
  for (const code of toAdd) {
7239
7300
  if (!existing.has(code)) {
@@ -7241,16 +7302,16 @@ var require_station_allowed_list = __commonJS({
7241
7302
  }
7242
7303
  }
7243
7304
  }
7244
- if (level.excludeTaskCodes?.length) {
7245
- const excludeSet = new Set(level.excludeTaskCodes);
7305
+ if (level.excludeTaskListCodes?.length) {
7306
+ const excludeSet = new Set(level.excludeTaskListCodes);
7246
7307
  codes = codes.filter((code) => !excludeSet.has(code));
7247
7308
  }
7248
7309
  }
7249
7310
  return codes;
7250
7311
  };
7251
- exports2.resolveTaskCodes = resolveTaskCodes;
7252
- var requiredTaskCodes = (manifest, stationCode, schedule) => {
7253
- const allTaskCodes = (manifest.account.tasks ?? []).map((s) => s.code);
7312
+ exports2.resolveTaskListCodes = resolveTaskListCodes;
7313
+ var requiredTaskListCodes = (manifest, stationCode) => {
7314
+ const allListCodes = (manifest.account.taskLists ?? []).map((list) => list.code);
7254
7315
  let plant;
7255
7316
  let group;
7256
7317
  let station;
@@ -7269,21 +7330,40 @@ var require_station_allowed_list = __commonJS({
7269
7330
  if (!station) {
7270
7331
  return [];
7271
7332
  }
7272
- const baseCodes = (0, exports2.resolveTaskCodes)(allTaskCodes, manifest.account, plant, group, station);
7273
- if (schedule?.skuCode) {
7274
- const sku = manifest.account.skus?.find((s) => s.code === schedule.skuCode);
7275
- if (sku?.includeTaskCodes?.length) {
7276
- const existing = new Set(baseCodes);
7277
- for (const code of sku.includeTaskCodes) {
7278
- if (!existing.has(code)) {
7279
- baseCodes.push(code);
7280
- }
7333
+ return (0, exports2.resolveTaskListCodes)(allListCodes, manifest.account, plant, group, station);
7334
+ };
7335
+ exports2.requiredTaskListCodes = requiredTaskListCodes;
7336
+ var requiredTaskRefs = (manifest, stationCode) => {
7337
+ const listCodes = (0, exports2.requiredTaskListCodes)(manifest, stationCode);
7338
+ if (listCodes.length === 0) {
7339
+ return [];
7340
+ }
7341
+ const tasks = manifest.account.tasks ?? [];
7342
+ const refs = [];
7343
+ for (const listCode of listCodes) {
7344
+ const members = tasks.flatMap((task, position) => {
7345
+ const membership = (task.taskListCodes ?? []).find((entry) => entry.code.toLowerCase() === listCode.toLowerCase());
7346
+ return membership ? [{ taskCode: task.code, order: membership.order, position }] : [];
7347
+ });
7348
+ members.sort((a, b) => {
7349
+ if (a.order == null && b.order == null) {
7350
+ return a.position - b.position;
7281
7351
  }
7352
+ if (a.order == null) {
7353
+ return 1;
7354
+ }
7355
+ if (b.order == null) {
7356
+ return -1;
7357
+ }
7358
+ return a.order - b.order;
7359
+ });
7360
+ for (const member of members) {
7361
+ refs.push({ taskCode: member.taskCode, taskListCode: listCode });
7282
7362
  }
7283
7363
  }
7284
- return baseCodes;
7364
+ return refs;
7285
7365
  };
7286
- exports2.requiredTaskCodes = requiredTaskCodes;
7366
+ exports2.requiredTaskRefs = requiredTaskRefs;
7287
7367
  var getValidReasons = (reasons, allowedReasonCodes) => {
7288
7368
  if (!allowedReasonCodes) {
7289
7369
  return reasons;
@@ -7359,6 +7439,48 @@ var require_feature_flags3 = __commonJS({
7359
7439
  }
7360
7440
  });
7361
7441
 
7442
+ // ../../packages/common/build/utils/task-list.js
7443
+ var require_task_list2 = __commonJS({
7444
+ "../../packages/common/build/utils/task-list.js"(exports2) {
7445
+ "use strict";
7446
+ Object.defineProperty(exports2, "__esModule", { value: true });
7447
+ exports2.taskListsFromManifest = taskListsFromManifest;
7448
+ exports2.taskListByCode = taskListByCode;
7449
+ exports2.taskListFrequency = taskListFrequency;
7450
+ exports2.taskListCodesOf = taskListCodesOf;
7451
+ exports2.taskListOrderOf = taskListOrderOf;
7452
+ exports2.isInTaskList = isInTaskList;
7453
+ exports2.nextTaskListOrder = nextTaskListOrder;
7454
+ var task_1 = require_task();
7455
+ function taskListsFromManifest(manifest) {
7456
+ return manifest.account.taskLists ?? [];
7457
+ }
7458
+ function taskListByCode(manifest, code) {
7459
+ return taskListsFromManifest(manifest).find((t) => t.code.toLowerCase() === code.toLowerCase());
7460
+ }
7461
+ function taskListFrequency(manifest, code) {
7462
+ return taskListByCode(manifest, code)?.frequency ?? { type: task_1.TASK_FREQUENCY_TYPE_SCHEDULE };
7463
+ }
7464
+ function taskListCodesOf(task) {
7465
+ return (task.taskListCodes ?? []).map((entry) => entry.code);
7466
+ }
7467
+ function taskListOrderOf(task, listCode) {
7468
+ return (task.taskListCodes ?? []).find((entry) => entry.code.toLowerCase() === listCode.toLowerCase())?.order;
7469
+ }
7470
+ function isInTaskList(task, listCode) {
7471
+ return (task.taskListCodes ?? []).some((entry) => entry.code.toLowerCase() === listCode.toLowerCase());
7472
+ }
7473
+ function nextTaskListOrder(tasks, listCode) {
7474
+ const orders = tasks.flatMap((task) => {
7475
+ const order = taskListOrderOf(task, listCode);
7476
+ return order == null ? [] : [order];
7477
+ });
7478
+ const next = orders.length === 0 ? 1 : Math.floor(Math.max(...orders)) + 1;
7479
+ return Math.min(Math.max(next, 1), task_1.TASK_LIST_ORDER_MAX);
7480
+ }
7481
+ }
7482
+ });
7483
+
7362
7484
  // ../../packages/common/build/utils/station.js
7363
7485
  var require_station3 = __commonJS({
7364
7486
  "../../packages/common/build/utils/station.js"(exports2) {
@@ -7371,6 +7493,8 @@ var require_station3 = __commonJS({
7371
7493
  var shift_1 = require_shift3();
7372
7494
  var station_allowed_list_1 = require_station_allowed_list();
7373
7495
  var feature_flags_1 = require_feature_flags3();
7496
+ var task_list_1 = require_task_list2();
7497
+ var task_1 = require_task();
7374
7498
  function stationsFromManifest(manifest, options) {
7375
7499
  if (!manifest) {
7376
7500
  return [];
@@ -7409,10 +7533,24 @@ var require_station3 = __commonJS({
7409
7533
  }
7410
7534
  const allReasonCodes = manifest.account.reasons ? (0, station_allowed_list_1.flattenReasonCodes)(manifest.account.reasons) : [];
7411
7535
  const stationResolvedReasonCodes = (0, station_allowed_list_1.resolveReasonCodes)(allReasonCodes, manifest.account, plant, group, station);
7412
- const allTaskCodes = manifest.account.tasks?.map((task) => task.code) ?? [];
7413
- const resolvedTaskCodes = (0, station_allowed_list_1.resolveTaskCodes)(allTaskCodes, manifest.account, plant, group, station);
7414
- const resolvedTaskCodeSet = new Set(resolvedTaskCodes);
7415
- const requiredTasks = (0, feature_flags_1.resolveFlag)(manifest, "enableTasks") ? manifest.account.tasks?.filter((task) => resolvedTaskCodeSet.has(task.code)) ?? [] : [];
7536
+ const tasksByCode = new Map((manifest.account.tasks ?? []).map((task) => [task.code, task]));
7537
+ const requiredTasks = (0, feature_flags_1.resolveFlag)(manifest, "enableTasks") ? (0, station_allowed_list_1.requiredTaskRefs)(manifest, station.code).flatMap((ref) => {
7538
+ const task = tasksByCode.get(ref.taskCode);
7539
+ if (!task) {
7540
+ return [];
7541
+ }
7542
+ const list = (0, task_list_1.taskListByCode)(manifest, ref.taskListCode);
7543
+ return [
7544
+ {
7545
+ ...task,
7546
+ taskListCode: ref.taskListCode,
7547
+ taskListName: list?.name ?? ref.taskListCode,
7548
+ // Frequency comes from the list, never from the Task's own legacy field.
7549
+ frequency: list?.frequency ?? { type: task_1.TASK_FREQUENCY_TYPE_SCHEDULE },
7550
+ order: (0, task_list_1.taskListOrderOf)(task, ref.taskListCode) ?? null
7551
+ }
7552
+ ];
7553
+ }) : [];
7416
7554
  const stationResult = {
7417
7555
  accountId: manifest.account.id,
7418
7556
  code: station.code,
@@ -8166,6 +8304,8 @@ var require_production3 = __commonJS({
8166
8304
  exports2.productionCap = productionCap;
8167
8305
  exports2.isAtProductionCap = isAtProductionCap;
8168
8306
  exports2.exceedsProductionCap = exceedsProductionCap;
8307
+ exports2.historicalCorrectionAnchor = historicalCorrectionAnchor;
8308
+ exports2.isHistoricalCorrectionRow = isHistoricalCorrectionRow;
8169
8309
  exports2.formatScheduleProductionCount = formatScheduleProductionCount;
8170
8310
  exports2.processProduction = processProduction;
8171
8311
  exports2.filterBySkuType = filterBySkuType;
@@ -8194,6 +8334,15 @@ var require_production3 = __commonJS({
8194
8334
  }
8195
8335
  return (quantityTotal ?? 0) + delta > cap;
8196
8336
  }
8337
+ function historicalCorrectionAnchor(actualEndAtTimestamp) {
8338
+ return actualEndAtTimestamp - time_1.TimeIntervals["1s"].ms;
8339
+ }
8340
+ function isHistoricalCorrectionRow(production, schedule) {
8341
+ if (schedule.actualEndAtTimestamp == null || production.type !== enums_1.PRODUCTION_TYPE.CORRECTION) {
8342
+ return false;
8343
+ }
8344
+ return production.lastUnitAtTimestamp === historicalCorrectionAnchor(schedule.actualEndAtTimestamp);
8345
+ }
8197
8346
  function formatScheduleProductionCount(manifest, quantityTotal) {
8198
8347
  const formatted = (0, _1.roundTo)(quantityTotal ?? 0, 2).toLocaleString("en-us");
8199
8348
  return isAtProductionCap(manifest, quantityTotal) ? `${formatted} (limit)` : formatted;
@@ -10282,8 +10431,8 @@ var require_station4 = __commonJS({
10282
10431
  exports2.StationViewModel = schemas_1.StationSchema.omit({
10283
10432
  includeReasonCodes: true,
10284
10433
  excludeReasonCodes: true,
10285
- includeTaskCodes: true,
10286
- excludeTaskCodes: true,
10434
+ includeTaskListCodes: true,
10435
+ excludeTaskListCodes: true,
10287
10436
  createdAt: true,
10288
10437
  updatedAt: true,
10289
10438
  archivedAt: true,
@@ -10319,6 +10468,11 @@ var require_station4 = __commonJS({
10319
10468
  notes: zod_1.z.array(note_1.NoteViewModel).optional().describe("Active notes attached to this station."),
10320
10469
  allowedReasonCodes: zod_1.z.array(zod_1.z.string()).optional().describe("The reason codes available for this station after include/exclude filtering."),
10321
10470
  requiredTasks: zod_1.z.array(task_1.TaskSchema.extend({
10471
+ taskListCode: zod_1.z.string().describe("The Task list this entry is being viewed through. A Task in two lists assigned to this station appears twice, once per list, each with that list's frequency and its own completion state."),
10472
+ taskListName: zod_1.z.string().nullish().describe("Name of the Task list this entry belongs to, falling back to the code."),
10473
+ taskListDescription: zod_1.z.string().nullish().describe("Description of the Task list this entry belongs to, shown as the subtitle on its tablet button."),
10474
+ frequency: task_1.TaskFrequencySchema.describe("The frequency of the Task list this entry belongs to \u2014 not the Task's own legacy field."),
10475
+ order: zod_1.z.number().nullish().describe("Display order of the Task within this list."),
10322
10476
  completedAt: zod_1.z.string().nullish(),
10323
10477
  lastCompletedAt: zod_1.z.string().nullish().describe("ISO timestamp of the most recent completion ('always'-frequency Tasks only). Such a Task is available again the instant it is completed, so it is never 'completed' \u2014 this records when it was last done."),
10324
10478
  completedOperatorInitials: zod_1.z.string().nullish(),
@@ -10367,8 +10521,8 @@ var require_station_group3 = __commonJS({
10367
10521
  exports2.StationGroupViewModel = schemas_1.StationGroupSchema.omit({
10368
10522
  includeReasonCodes: true,
10369
10523
  excludeReasonCodes: true,
10370
- includeTaskCodes: true,
10371
- excludeTaskCodes: true,
10524
+ includeTaskListCodes: true,
10525
+ excludeTaskListCodes: true,
10372
10526
  createdAt: true,
10373
10527
  updatedAt: true,
10374
10528
  // Feature-flag config fields are not exposed on the VM — consumers resolve a flag's effective value
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "busroot-sdk",
3
- "version": "0.0.8-dev.2832183355",
3
+ "version": "0.0.8-dev.2836398557",
4
4
  "description": "An SDK for accessing Busroot from output.industries",
5
5
  "homepage": "https://www.output.industries",
6
6
  "main": "./build/index.js",