@campfire-interactive/master-data-client 5.10.1 → 5.11.0

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.
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CLOSED_QUOTE_STATUSES = exports.OPEN_QUOTE_STATUSES = void 0;
4
+ exports.quoteStatusBucket = quoteStatusBucket;
5
+ exports.isOpenQuoteStatus = isOpenQuoteStatus;
6
+ /**
7
+ * The one table. `Record<QuoteStatus, …>` is what makes it exhaustive: adding
8
+ * a status to {@link QuoteStatus} without bucketing it here fails to compile,
9
+ * which is the only way to keep this from drifting behind the state machine.
10
+ *
11
+ * `lost` and `not_taken` share a bucket here and stay distinct everywhere else
12
+ * — see {@link QuoteStatus} on why collapsing them miscounts a won deal as a
13
+ * defeat. This bucket answers only "should the row be in the working list?",
14
+ * and that answer is the same for both.
15
+ */
16
+ const BUCKET_BY_STATUS = {
17
+ draft: 'open',
18
+ costing_requested: 'open',
19
+ costing_in_progress: 'open',
20
+ costing_complete: 'open',
21
+ pricing: 'open',
22
+ routed_for_approval: 'open',
23
+ in_review: 'open',
24
+ approved: 'open',
25
+ submitted: 'open',
26
+ negotiating: 'open',
27
+ awarded: 'awarded',
28
+ lost: 'closed',
29
+ not_taken: 'closed',
30
+ };
31
+ const statusesIn = (bucket) => Object.keys(BUCKET_BY_STATUS).filter((s) => BUCKET_BY_STATUS[s] === bucket);
32
+ /**
33
+ * Still work: draft through negotiating. Mirrors the server's `OPEN_STATUSES`
34
+ * and is the set behind `GET /v1/quotes?status=open`.
35
+ */
36
+ exports.OPEN_QUOTE_STATUSES = statusesIn('open');
37
+ /** Closed and not won: `lost`, `not_taken`. */
38
+ exports.CLOSED_QUOTE_STATUSES = statusesIn('closed');
39
+ /**
40
+ * Which bucket a status falls in. An unrecognized value is reported as `open`:
41
+ * a status this build hasn't heard of is far likelier to be a newly added
42
+ * working state than a new terminal one, and the failure that matters is
43
+ * hiding live work, not listing one row too many.
44
+ */
45
+ function quoteStatusBucket(status) {
46
+ if (status == null)
47
+ return 'open';
48
+ return BUCKET_BY_STATUS[status] ?? 'open';
49
+ }
50
+ /** True for every status in {@link OPEN_QUOTE_STATUSES}. */
51
+ function isOpenQuoteStatus(status) {
52
+ return quoteStatusBucket(status) === 'open';
53
+ }
54
+ //# sourceMappingURL=quoteStatus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quoteStatus.js","sourceRoot":"","sources":["../src/quoteStatus.ts"],"names":[],"mappings":";;;AAoEA,8CAKC;AAGD,8CAEC;AAxDD;;;;;;;;;GASG;AACH,MAAM,gBAAgB,GAAG;IACvB,KAAK,EAAE,MAAM;IACb,iBAAiB,EAAE,MAAM;IACzB,mBAAmB,EAAE,MAAM;IAC3B,gBAAgB,EAAE,MAAM;IACxB,OAAO,EAAE,MAAM;IACf,mBAAmB,EAAE,MAAM;IAC3B,SAAS,EAAE,MAAM;IACjB,QAAQ,EAAE,MAAM;IAChB,SAAS,EAAE,MAAM;IACjB,WAAW,EAAE,MAAM;IACnB,OAAO,EAAE,SAAS;IAClB,IAAI,EAAE,QAAQ;IACd,SAAS,EAAE,QAAQ;CACsC,CAAC;AAE5D,MAAM,UAAU,GAAG,CAAC,MAAyB,EAA0B,EAAE,CACtE,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAmB,CAAC,MAAM,CACrD,CAAC,CAAC,EAAE,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC,KAAK,MAAM,CACtC,CAAC;AAEJ;;;GAGG;AACU,QAAA,mBAAmB,GAA2B,UAAU,CAAC,MAAM,CAAC,CAAC;AAE9E,+CAA+C;AAClC,QAAA,qBAAqB,GAA2B,UAAU,CAAC,QAAQ,CAAC,CAAC;AAElF;;;;;GAKG;AACH,SAAgB,iBAAiB,CAC/B,MAA+C;IAE/C,IAAI,MAAM,IAAI,IAAI;QAAE,OAAO,MAAM,CAAC;IAClC,OAAO,gBAAgB,CAAC,MAAqB,CAAC,IAAI,MAAM,CAAC;AAC3D,CAAC;AAED,4DAA4D;AAC5D,SAAgB,iBAAiB,CAAC,MAA+C;IAC/E,OAAO,iBAAiB,CAAC,MAAM,CAAC,KAAK,MAAM,CAAC;AAC9C,CAAC"}
package/dist/types.d.ts CHANGED
@@ -875,10 +875,16 @@ export interface ListQuotesOptions {
875
875
  sort?: string;
876
876
  q?: string;
877
877
  /**
878
- * `all` returns every status. Omitting defaults to "not lost" — the
879
- * common active-deals feed. Pass `lost` (or `all`) to include them.
878
+ * `all` returns every status. `open` returns only the statuses still in
879
+ * play — `OPEN_QUOTE_STATUSES`, i.e. everything but `awarded`, `lost` and
880
+ * `not_taken`. (5.10.2)
881
+ *
882
+ * Omitting defaults to "not closed": `lost` and `not_taken` are excluded,
883
+ * `awarded` is not. That default is deliberately unchanged — it is what
884
+ * every existing consumer is built on — so a caller that wants awarded
885
+ * quotes out of its list asks for `open` explicitly.
880
886
  */
881
- status?: QuoteStatus | 'all';
887
+ status?: QuoteStatus | 'all' | 'open';
882
888
  quality?: 'draft' | 'verified';
883
889
  customerCompanyId?: string;
884
890
  programId?: string;
@@ -2212,20 +2218,116 @@ export interface ExchangeRate {
2212
2218
  createdAt: string;
2213
2219
  updatedAt: string;
2214
2220
  }
2215
- export interface CreateExchangeRateInput {
2221
+ /**
2222
+ * The rate half of a create/update. Supply EXACTLY ONE of `perUsd` (the stored
2223
+ * unit) or `perBase` (units per 1 `base`, converted to per-USD on write).
2224
+ * Supplying both is a 422 rather than a silent preference.
2225
+ *
2226
+ * Base-relative entry exists because a tenant whose base is EUR holds a
2227
+ * EUR-relative feed. The conversion is server-side, `perBase × perUsd(base)`
2228
+ * resolved as of the row's own `effectiveFrom`, so the figure that lands is the
2229
+ * one costing would have derived for that date. **Storage is unchanged** —
2230
+ * `ExchangeRate.perUsd` and `FxTable.base: 'USD'` are exactly as before.
2231
+ */
2232
+ export interface ExchangeRateEntryInput {
2233
+ /** Units of `currency` per 1 USD — the stored unit. */
2234
+ perUsd?: number | string;
2235
+ /** Units of `currency` per 1 `base`. */
2236
+ perBase?: number | string;
2237
+ /**
2238
+ * The unit `perBase` is expressed in. Defaults to the tenant's configured
2239
+ * base currency (see `exchangeRates.settings()`).
2240
+ *
2241
+ * Two rules to know when this is not USD:
2242
+ * - `currency === base` is rejected; a currency is 1 per 1 of itself.
2243
+ * - `currency === 'USD'` is **the anchor**: `perBase(USD)` is `1/perUsd(base)`,
2244
+ * so it restates the base↔USD rate and writes a row for **`base`**, not for
2245
+ * USD. The returned `ExchangeRate` reports the row actually written, so read
2246
+ * `.currency` off the response rather than assuming what you sent.
2247
+ */
2248
+ base?: string;
2249
+ }
2250
+ export interface CreateExchangeRateInput extends ExchangeRateEntryInput {
2216
2251
  currency: string;
2217
- perUsd: number | string;
2218
2252
  /** YYYY-MM-DD. */
2219
2253
  effectiveFrom: string;
2220
2254
  effectiveTo?: string | null;
2221
2255
  notes?: string | null;
2222
2256
  }
2223
- export interface UpdateExchangeRateInput {
2224
- perUsd?: number | string;
2257
+ export interface UpdateExchangeRateInput extends ExchangeRateEntryInput {
2225
2258
  effectiveFrom?: string;
2226
2259
  effectiveTo?: string | null;
2227
2260
  notes?: string | null;
2228
2261
  }
2262
+ /**
2263
+ * A tenant's FX settings. `baseCurrency` is the unit this tenant's people READ
2264
+ * and TYPE rates in — NOT a storage pivot. `/v1/fx/table` still reports
2265
+ * `base: 'USD'` to every consumer regardless of what this says, and no stored
2266
+ * rate changes when it is flipped.
2267
+ */
2268
+ export interface TenantFxSettings {
2269
+ /** ISO-4217 code. `'USD'` when the tenant has never set one. */
2270
+ baseCurrency: string;
2271
+ /** False when no row exists yet and this is the platform default. */
2272
+ customized: boolean;
2273
+ }
2274
+ export interface UpdateTenantFxSettingsInput {
2275
+ /** Must be a currency that is enabled in the tenant's catalog. */
2276
+ baseCurrency?: string;
2277
+ }
2278
+ export type CurrencyScope = 'global' | 'tenant';
2279
+ /**
2280
+ * One entry in a tenant's effective currency catalog.
2281
+ *
2282
+ * Mixed tenancy, the same shape as ExchangeRate: the platform seeds the active
2283
+ * ISO-4217 set as shared rows, and a tenant row for the same code shadows one
2284
+ * to rename or hide it for that tenant alone. A tenant row for a code the seed
2285
+ * does not carry is a custom currency.
2286
+ *
2287
+ * `active` is CURATION, not deletion. 155 codes is a useless picker, so a
2288
+ * tenant turns off what it does not trade in. It never invalidates history:
2289
+ * membership is enforced only on NEW writes, so rates already written against
2290
+ * a code keep resolving.
2291
+ */
2292
+ export interface Currency {
2293
+ /** ISO-4217 code, uppercase. */
2294
+ code: string;
2295
+ name: string;
2296
+ symbol: string | null;
2297
+ /** ISO-4217 exponent. Drives money FORMATTING only — rates are 6-dp decimals. */
2298
+ minorUnits: number;
2299
+ active: boolean;
2300
+ /** Which row won: `tenant` when this tenant authored or overrode it. */
2301
+ scope: CurrencyScope;
2302
+ /** True when a tenant row shadows a seeded global of the same code. */
2303
+ overridesGlobal: boolean;
2304
+ /** True when only this tenant has it — not part of the seeded ISO set. */
2305
+ custom: boolean;
2306
+ }
2307
+ export interface ListCurrenciesOptions {
2308
+ /** Default true. Pass false for just the enabled ones — what a picker wants. */
2309
+ includeInactive?: boolean;
2310
+ /** Case-insensitive substring match on code or name. */
2311
+ q?: string;
2312
+ }
2313
+ export interface CreateCurrencyInput {
2314
+ code: string;
2315
+ name: string;
2316
+ symbol?: string | null;
2317
+ /** 0-4. Defaults to 2. */
2318
+ minorUnits?: number;
2319
+ active?: boolean;
2320
+ }
2321
+ export interface UpdateCurrencyInput {
2322
+ name?: string;
2323
+ symbol?: string | null;
2324
+ minorUnits?: number;
2325
+ /**
2326
+ * Enable or hide for this tenant. USD can never be turned off (every rate is
2327
+ * stored against it), and neither can the tenant's own base currency.
2328
+ */
2329
+ active?: boolean;
2330
+ }
2229
2331
  export interface ListExchangeRatesOptions {
2230
2332
  limit?: number;
2231
2333
  cursor?: string;
@@ -2815,7 +2917,7 @@ export interface CreateAttributeDefinitionInput {
2815
2917
  * for `hierarchy`, a `Parent > Child > Grandchild` path per entry, which the
2816
2918
  * server turns into an option tree (shared prefixes dedupe).
2817
2919
  *
2818
- * **Required for `enum`, `multi_select` and `hierarchy`** (since 5.10.0) — a
2920
+ * **Required for `enum`, `multi_select` and `hierarchy`** (since 5.10.1) — a
2819
2921
  * select with no values renders as an empty picker, and marked required it
2820
2922
  * is a dead end. Legacy inline `options` satisfies the same rule. */
2821
2923
  optionValues?: string[] | null;
@@ -3080,7 +3182,7 @@ export type SourceApp = 'master-data' | 'erfq' | 'cpq' | 'bom' | 'forecast' | 'o
3080
3182
  * "Empty" means SQL NULL only — a stored '', 0, false, or 0.0 counts as
3081
3183
  * populated and will not be overwritten by fill_empty. */
3082
3184
  export type MergePolicy = 'overwrite' | 'fill_empty';
3083
- export type ImportTargetField = 'name' | 'legalName' | 'code' | 'taxId' | 'dunsNumber' | 'website' | 'logoUrl' | 'roles' | 'email' | 'phone' | 'role' | 'type' | 'description' | 'street' | 'city' | 'stateProvince' | 'postalCode' | 'country' | 'category' | 'parent_company_ref' | 'companyCode' | 'companyName' | 'locationCode' | 'region' | 'headcount' | 'annualCapacityHours' | 'currentUtilization' | 'riskLevel' | 'numShifts' | 'hoursPerShift' | 'workingDaysPerYear' | 'indirectHeadcountPct' | 'currency' | 'effectiveDate' | 'effectiveTo' | 'libraryCode' | 'kind' | 'plantCode' | 'skillTier' | 'materialCode' | 'regionCode' | 'lane' | 'rate' | 'unit' | 'sourcingMode' | 'indexRef' | 'notes' | 'partNumber' | 'manufacturingPartNumber' | 'customerPartNumber' | 'partType' | 'manufacturer' | 'partCategoryCode' | 'quality' | 'revision' | 'uom' | 'weightPerUnit' | 'recycledPct' | 'pcfPerUnit' | 'releaseStatus' | 'leadTime' | 'customerCompanyCode' | 'customerCompanyName' | 'sopDate' | 'eopDate' | 'displayOrder' | 'label' | 'sortOrder' | 'processFamily' | 'capacityHoursPerYear' | 'cavities' | 'availabilityPct' | 'performancePct' | 'defaultHeadcount' | 'defaultAutomationPct' | 'defaultMachinesPerOperator' | 'defaultSetupCrew' | 'perUsd' | 'effectiveFrom' | 'quoteNumber' | 'programCode' | 'partId' | 'regionName' | 'annualVolume' | 'apw' | 'mpw' | 'targetPrice' | 'dueDate' | 'status' | 'key' | 'dataType' | 'options' | 'group' | 'required' | 'min' | 'max' | 'regex' | 'precision' | 'basis' | 'bindings' | 'perBaseFactor' | 'needsDensity' | 'binding' | 'allowedUoms' | 'defaultUom' | 'escalationDefault' | 'density' | 'densityUnit' | `attr:${string}`;
3185
+ export type ImportTargetField = 'name' | 'legalName' | 'code' | 'taxId' | 'dunsNumber' | 'website' | 'logoUrl' | 'roles' | 'email' | 'phone' | 'role' | 'type' | 'description' | 'street' | 'city' | 'stateProvince' | 'postalCode' | 'country' | 'category' | 'parent_company_ref' | 'companyCode' | 'companyName' | 'locationCode' | 'region' | 'headcount' | 'annualCapacityHours' | 'currentUtilization' | 'riskLevel' | 'numShifts' | 'hoursPerShift' | 'workingDaysPerYear' | 'indirectHeadcountPct' | 'currency' | 'effectiveDate' | 'effectiveTo' | 'libraryCode' | 'kind' | 'plantCode' | 'skillTier' | 'materialCode' | 'regionCode' | 'lane' | 'rate' | 'unit' | 'sourcingMode' | 'indexRef' | 'notes' | 'partNumber' | 'manufacturingPartNumber' | 'customerPartNumber' | 'partType' | 'manufacturer' | 'partCategoryCode' | 'quality' | 'revision' | 'uom' | 'weightPerUnit' | 'recycledPct' | 'pcfPerUnit' | 'releaseStatus' | 'leadTime' | 'customerCompanyCode' | 'customerCompanyName' | 'sopDate' | 'eopDate' | 'displayOrder' | 'label' | 'sortOrder' | 'processFamily' | 'capacityHoursPerYear' | 'cavities' | 'availabilityPct' | 'performancePct' | 'defaultHeadcount' | 'defaultAutomationPct' | 'defaultMachinesPerOperator' | 'defaultSetupCrew' | 'perUsd' | 'base' | 'effectiveFrom' | 'quoteNumber' | 'programCode' | 'partId' | 'regionName' | 'annualVolume' | 'apw' | 'mpw' | 'targetPrice' | 'dueDate' | 'status' | 'key' | 'dataType' | 'options' | 'group' | 'required' | 'min' | 'max' | 'regex' | 'precision' | 'basis' | 'bindings' | 'perBaseFactor' | 'needsDensity' | 'binding' | 'allowedUoms' | 'defaultUom' | 'escalationDefault' | 'density' | 'densityUnit' | `attr:${string}`;
3084
3186
  export interface ImportSession {
3085
3187
  id: string;
3086
3188
  tenantId: string;
@@ -3848,4 +3950,211 @@ export interface AiLlmConfigRows {
3848
3950
  valid_providers: string[];
3849
3951
  suggested_models: Record<string, string[]>;
3850
3952
  }
3953
+ export type KnownWorkStepSubjectKind = 'quote' | 'vehicle_program' | 'launch_program';
3954
+ /** OPEN union: a new kind is an additive change, so do not switch exhaustively. */
3955
+ export type WorkStepSubjectKind = KnownWorkStepSubjectKind | (string & {});
3956
+ /** Stored state. `at_risk` and `past_due` are derived at read time (see WorkStepDisplayState). */
3957
+ export type WorkStepState = 'not_started' | 'open' | 'done';
3958
+ export type KnownWorkStepDisplayState = WorkStepState | 'at_risk' | 'past_due';
3959
+ export type WorkStepDisplayState = KnownWorkStepDisplayState | (string & {});
3960
+ /**
3961
+ * How the timing was obtained. `late` is only claimable for `measured` and
3962
+ * `signed_off`; everything else is a record, not a measurement.
3963
+ */
3964
+ export type KnownWorkStepCertainty = 'measured' | 'signed_off' | 'observed' | 'recorded' | 'untracked';
3965
+ export type WorkStepCertainty = KnownWorkStepCertainty | (string & {});
3966
+ /** The role a write is made on behalf of. The server checks it against the subject kind. */
3967
+ export type WorkStepCallerRole = 'omsf' | 'cpq' | 'pm' | 'admin';
3968
+ export type WorkStepStandardUnit = 'hours' | 'days';
3969
+ export type WorkStepSlaBasis = 'internal' | 'elapsed';
3970
+ export type WorkStepAnchor = 'award' | 'sop' | 'eop' | 'gap_fraction' | 'custom';
3971
+ export interface WorkStepDefinition {
3972
+ /** null when this is the platform default and the tenant has no row. */
3973
+ id: string | null;
3974
+ stepCode: string;
3975
+ subjectKind: WorkStepSubjectKind;
3976
+ variant: string;
3977
+ grain: 'subject' | 'child';
3978
+ plannedBasis: 'duration' | 'anchored_date' | 'fixed_date';
3979
+ label: string;
3980
+ milestone: string | null;
3981
+ sortOrder: number;
3982
+ parentCode: string | null;
3983
+ standardQty: number | null;
3984
+ standardUnit: WorkStepStandardUnit;
3985
+ slaBasis: WorkStepSlaBasis;
3986
+ anchor: WorkStepAnchor | null;
3987
+ anchorFraction: number | null;
3988
+ ownerRole: string | null;
3989
+ ownerScope: 'tenant' | 'child_team';
3990
+ measurementSource: string;
3991
+ active: boolean;
3992
+ /** true when a tenant row exists; false when this is the platform default. */
3993
+ customized: boolean;
3994
+ }
3995
+ export interface ListWorkStepDefinitionsOptions {
3996
+ /** Omit for every kind. */
3997
+ subjectKind?: WorkStepSubjectKind;
3998
+ /** 'default' or 'eco' (quote steps only). */
3999
+ variant?: string;
4000
+ includeInactive?: boolean;
4001
+ }
4002
+ export interface WorkStepDefinitionRowInput {
4003
+ stepCode: string;
4004
+ /** Program kinds only; the quote graph is fixed. */
4005
+ label?: string;
4006
+ milestone?: string | null;
4007
+ sortOrder?: number;
4008
+ standardQty?: number | null;
4009
+ standardUnit?: WorkStepStandardUnit;
4010
+ slaBasis?: WorkStepSlaBasis;
4011
+ anchor?: WorkStepAnchor | null;
4012
+ anchorFraction?: number | null;
4013
+ ownerRole?: string | null;
4014
+ active?: boolean;
4015
+ /** Custom (non-catalog) program steps only. */
4016
+ plannedBasis?: 'anchored_date' | 'fixed_date';
4017
+ }
4018
+ export interface SaveWorkStepDefinitionsInput {
4019
+ subjectKind: WorkStepSubjectKind;
4020
+ variant?: string;
4021
+ rows: WorkStepDefinitionRowInput[];
4022
+ /** Deactivate this kind's custom steps absent from `rows`. */
4023
+ archiveMissing?: boolean;
4024
+ }
4025
+ /** One execution of a step. Dates are ISO-8601 strings on the wire. */
4026
+ export interface WorkStepEpisode {
4027
+ id: string;
4028
+ subjectType: WorkStepSubjectKind;
4029
+ subjectId: string;
4030
+ /** '' for a subject-grain step. */
4031
+ childId: string;
4032
+ childLabel: string | null;
4033
+ stepCode: string;
4034
+ iteration: number;
4035
+ plannedStart: string | null;
4036
+ plannedEnd: string | null;
4037
+ actualStart: string | null;
4038
+ actualEnd: string | null;
4039
+ state: WorkStepState;
4040
+ certainty: WorkStepCertainty;
4041
+ openedBy: string | null;
4042
+ closedBy: string | null;
4043
+ reopenReason: string | null;
4044
+ createdAt: string;
4045
+ updatedAt: string;
4046
+ }
4047
+ export interface WorkStepSeriesEntry {
4048
+ subjectType: WorkStepSubjectKind;
4049
+ subjectId: string;
4050
+ childId: string;
4051
+ childLabel: string | null;
4052
+ stepCode: string;
4053
+ /** The latest iteration wins. */
4054
+ latest: WorkStepEpisode;
4055
+ iterations: number;
4056
+ reopenCount: number;
4057
+ derived: {
4058
+ displayState: WorkStepDisplayState;
4059
+ /** null when it cannot be claimed. */
4060
+ late: boolean | null;
4061
+ };
4062
+ }
4063
+ export interface WorkStepKeyInput {
4064
+ subjectType: WorkStepSubjectKind;
4065
+ subjectId: string;
4066
+ /** Required for per-child steps. */
4067
+ childId?: string;
4068
+ stepCode: string;
4069
+ callerRole: WorkStepCallerRole;
4070
+ }
4071
+ export interface OpenWorkStepInput extends WorkStepKeyInput {
4072
+ childLabel?: string | null;
4073
+ variant?: string;
4074
+ /** Plant whose calendar governs an internal-days standard. */
4075
+ calendarSourceId?: string | null;
4076
+ actualStart?: string | null;
4077
+ plannedStart?: string | null;
4078
+ plannedEnd?: string | null;
4079
+ openedBy?: string | null;
4080
+ }
4081
+ export interface CloseWorkStepInput extends WorkStepKeyInput {
4082
+ variant?: string;
4083
+ actualEnd?: string | null;
4084
+ closedBy?: string | null;
4085
+ childLabel?: string | null;
4086
+ }
4087
+ export interface ReopenWorkStepInput extends WorkStepKeyInput {
4088
+ variant?: string;
4089
+ calendarSourceId?: string | null;
4090
+ reopenReason: string;
4091
+ openedBy?: string | null;
4092
+ }
4093
+ export interface BatchWorkStepEpisodeRow {
4094
+ subjectType: WorkStepSubjectKind;
4095
+ subjectId: string;
4096
+ childId?: string;
4097
+ stepCode: string;
4098
+ /** The caller supplies the iteration here (default 1); open/reopen assign it server-side. */
4099
+ iteration?: number;
4100
+ childLabel?: string | null;
4101
+ plannedStart?: string | null;
4102
+ plannedEnd?: string | null;
4103
+ actualStart?: string | null;
4104
+ actualEnd?: string | null;
4105
+ state?: WorkStepState;
4106
+ certainty?: WorkStepCertainty;
4107
+ openedBy?: string | null;
4108
+ closedBy?: string | null;
4109
+ reopenReason?: string | null;
4110
+ }
4111
+ export interface BatchWorkStepEpisodesInput {
4112
+ callerRole: WorkStepCallerRole;
4113
+ /** 1 to 500. Duplicate keys within one batch are a 422. */
4114
+ episodes: BatchWorkStepEpisodeRow[];
4115
+ }
4116
+ export interface BatchWorkStepEpisodesResult {
4117
+ created: number;
4118
+ updated: number;
4119
+ unchanged: number;
4120
+ /** A done row is never regressed by a stale replay. */
4121
+ skipped: number;
4122
+ }
4123
+ export interface ListWorkStepEpisodesOptions {
4124
+ /** ISO-8601; the analytics feed's watermark. */
4125
+ updatedSince?: string;
4126
+ subjectType?: WorkStepSubjectKind;
4127
+ stepCode?: string;
4128
+ /** 1 to 1000. */
4129
+ limit?: number;
4130
+ cursor?: string;
4131
+ }
4132
+ export interface WorkingCalendarException {
4133
+ id: string;
4134
+ date: string;
4135
+ working: boolean;
4136
+ reason: string;
4137
+ }
4138
+ export interface WorkingCalendar {
4139
+ id: string;
4140
+ /** master-data Plant id. */
4141
+ productionSourceId: string;
4142
+ sourceLabel: string | null;
4143
+ /** UTC weekday numbers that are working days, 0 = Sunday. Never empty. */
4144
+ workingDays: number[];
4145
+ timeZone: string | null;
4146
+ exceptions?: WorkingCalendarException[];
4147
+ }
4148
+ export interface UpsertWorkingCalendarInput {
4149
+ sourceLabel?: string | null;
4150
+ workingDays?: number[];
4151
+ timeZone?: string | null;
4152
+ }
4153
+ export interface PutWorkingCalendarExceptionInput {
4154
+ /** YYYY-MM-DD */
4155
+ date: string;
4156
+ /** Default false (a non-working day); true is a make-up working day. */
4157
+ working?: boolean;
4158
+ reason: string;
4159
+ }
3851
4160
  //# sourceMappingURL=types.d.ts.map