@campfire-interactive/master-data-client 4.13.0 → 4.14.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.
- package/dist/attributeDefinitions.d.ts +15 -0
- package/dist/attributeDefinitions.d.ts.map +1 -0
- package/dist/attributeDefinitions.js +70 -0
- package/dist/attributeDefinitions.js.map +1 -0
- package/dist/attributeGroups.d.ts +14 -0
- package/dist/attributeGroups.d.ts.map +1 -0
- package/dist/attributeGroups.js +51 -0
- package/dist/attributeGroups.js.map +1 -0
- package/dist/attributeOptions.d.ts +18 -0
- package/dist/attributeOptions.d.ts.map +1 -0
- package/dist/attributeOptions.js +63 -0
- package/dist/attributeOptions.js.map +1 -0
- package/dist/attributeValidation.d.ts +15 -0
- package/dist/attributeValidation.d.ts.map +1 -0
- package/dist/attributeValidation.js +141 -0
- package/dist/attributeValidation.js.map +1 -0
- package/dist/client.d.ts +12 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +18 -0
- package/dist/client.js.map +1 -1
- package/dist/companies.d.ts.map +1 -1
- package/dist/companies.js +2 -0
- package/dist/companies.js.map +1 -1
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +5 -2
- package/dist/http.js.map +1 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -1
- package/dist/index.js.map +1 -1
- package/dist/ownership.d.ts +21 -0
- package/dist/ownership.d.ts.map +1 -0
- package/dist/ownership.js +36 -0
- package/dist/ownership.js.map +1 -0
- package/dist/programs.d.ts.map +1 -1
- package/dist/programs.js +2 -0
- package/dist/programs.js.map +1 -1
- package/dist/quoteAsks.d.ts +66 -0
- package/dist/quoteAsks.d.ts.map +1 -0
- package/dist/quoteAsks.js +103 -0
- package/dist/quoteAsks.js.map +1 -0
- package/dist/quoteLines.d.ts +91 -0
- package/dist/quoteLines.d.ts.map +1 -0
- package/dist/quoteLines.js +147 -0
- package/dist/quoteLines.js.map +1 -0
- package/dist/quotes.d.ts +10 -5
- package/dist/quotes.d.ts.map +1 -1
- package/dist/quotes.js +10 -5
- package/dist/quotes.js.map +1 -1
- package/dist/rateBooks.d.ts +28 -1
- package/dist/rateBooks.d.ts.map +1 -1
- package/dist/rateBooks.js +73 -0
- package/dist/rateBooks.js.map +1 -1
- package/dist/rates.d.ts +6 -1
- package/dist/rates.d.ts.map +1 -1
- package/dist/rates.js +14 -0
- package/dist/rates.js.map +1 -1
- package/dist/types.d.ts +659 -4
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -2
package/dist/types.d.ts
CHANGED
|
@@ -97,12 +97,16 @@ export interface ListProgramsOptions {
|
|
|
97
97
|
customerCompanyId?: string;
|
|
98
98
|
/** @deprecated Use customerCompanyId. Removed in the next major. */
|
|
99
99
|
oemCompanyId?: string;
|
|
100
|
+
/** Batch-get a specific set of programs by id — returns them regardless of
|
|
101
|
+
* status. Comma-joined server-side; cap ~100/call for URL length and chunk
|
|
102
|
+
* larger sets. The server bumps the page size to cover the ids. */
|
|
103
|
+
ids?: string[];
|
|
100
104
|
include?: ('customerCompany' | 'oemCompany')[];
|
|
101
105
|
}
|
|
102
106
|
export interface GetProgramOptions {
|
|
103
107
|
include?: ('customerCompany' | 'oemCompany')[];
|
|
104
108
|
}
|
|
105
|
-
export type QuoteStatus = 'draft' | 'costing_requested' | 'costing_in_progress' | 'costing_complete' | 'pricing' | 'routed_for_approval' | 'in_review' | 'approved' | 'submitted' | 'negotiating' | 'awarded' | 'lost';
|
|
109
|
+
export type QuoteStatus = 'draft' | 'costing_requested' | 'costing_in_progress' | 'costing_complete' | 'pricing' | 'routed_for_approval' | 'in_review' | 'approved' | 'submitted' | 'negotiating' | 'awarded' | 'lost' | 'not_taken';
|
|
106
110
|
/**
|
|
107
111
|
* Who is driving the transition. Required on every status update so the
|
|
108
112
|
* server can enforce role-gated transitions. `admin` is the escape hatch
|
|
@@ -133,6 +137,23 @@ export interface Quote {
|
|
|
133
137
|
name: string | null;
|
|
134
138
|
customerCompanyId: string;
|
|
135
139
|
programId: string | null;
|
|
140
|
+
/**
|
|
141
|
+
* The OEM request this quote is one competing answer to — see {@link QuoteAsk}.
|
|
142
|
+
* Null means it competes with nothing and is awardable on its own, which is a
|
|
143
|
+
* legitimate state, not missing data.
|
|
144
|
+
*/
|
|
145
|
+
askId: string | null;
|
|
146
|
+
/**
|
|
147
|
+
* @deprecated A DERIVED MIRROR of the quote's lines — read `quoteLines.list()`
|
|
148
|
+
* instead.
|
|
149
|
+
*
|
|
150
|
+
* Free text holding a part NUMBER (never a uuid), historically the quote's only
|
|
151
|
+
* part reference. A quote is multi-part now, and this reflects the FIRST line
|
|
152
|
+
* only, so it is lossy the moment a quote has more than one. Writes still work
|
|
153
|
+
* for the whole deprecation window (they transparently maintain the quote's
|
|
154
|
+
* single line), but new code should not read it as "the quote's part". Dropped
|
|
155
|
+
* in a later major. See the nextgen ADR `2026-08-05-multi-part-quotes.md`.
|
|
156
|
+
*/
|
|
136
157
|
partId: string | null;
|
|
137
158
|
/**
|
|
138
159
|
* The historical/parent quote this one was copied from. OMSF sets this when
|
|
@@ -211,6 +232,24 @@ export interface Quote {
|
|
|
211
232
|
* column stays the canonical yearly curve.
|
|
212
233
|
*/
|
|
213
234
|
effectiveVolumesByYear: EffectiveVolumeByYear[] | null;
|
|
235
|
+
/**
|
|
236
|
+
* The VEHICLE stream (added 2026-08-06) — how many vehicles the program
|
|
237
|
+
* builds, NOT how many parts we sell.
|
|
238
|
+
*
|
|
239
|
+
* This is what each {@link QuoteLine} bridges from: `vehicleAnnualVolume ×
|
|
240
|
+
* takeRate × partsPerVehicle` is that finished good's part volume. One quote
|
|
241
|
+
* covering four finished goods has ONE vehicle stream and four different part
|
|
242
|
+
* volumes, which is why the part columns above cannot serve as the input.
|
|
243
|
+
*
|
|
244
|
+
* **Null on every quote written before 2026-08-06**, and that is not a gap:
|
|
245
|
+
* those quotes' lines bridge from the part columns instead, at a 100/1 bridge
|
|
246
|
+
* that leaves the figure untouched. Read it as "does this quote calculate its
|
|
247
|
+
* line volumes, or carry them directly?" rather than as missing data.
|
|
248
|
+
*/
|
|
249
|
+
vehicleAnnualVolume: number | null;
|
|
250
|
+
/** Per-year vehicle curve, same shape as {@link effectiveVolumesByYear}.
|
|
251
|
+
* Bridged year by year onto each line. */
|
|
252
|
+
vehicleVolumesByYear: EffectiveVolumeByYear[] | null;
|
|
214
253
|
/**
|
|
215
254
|
* Customer-committed PART volume on ARBITRARY periods — the general form of
|
|
216
255
|
* {@link effectiveVolumesByYear}, for deals tracked at a granularity the year
|
|
@@ -302,6 +341,230 @@ export interface SetEffectivePriceInput {
|
|
|
302
341
|
/** Which app is writing — gated to 'omsf' | 'cpq' | 'admin' server-side. */
|
|
303
342
|
callerRole: 'omsf' | 'cpq' | 'admin';
|
|
304
343
|
}
|
|
344
|
+
export type QuoteAskStatus = 'open' | 'resolved' | 'cancelled';
|
|
345
|
+
export interface QuoteAsk {
|
|
346
|
+
id: string;
|
|
347
|
+
tenantId: string;
|
|
348
|
+
/** `ASK-YYYY-NNN`, minted server-side from an atomic per-(tenant, year) counter. */
|
|
349
|
+
askNumber: string;
|
|
350
|
+
name: string | null;
|
|
351
|
+
customerCompanyId: string;
|
|
352
|
+
/** Reporting only — NEVER used to decide competition. An opportunity spans
|
|
353
|
+
* rounds; an ask is one round. */
|
|
354
|
+
opportunityId: string | null;
|
|
355
|
+
dueDate: string | null;
|
|
356
|
+
status: QuoteAskStatus;
|
|
357
|
+
/** Which quote won. A recorded fact — closing the siblings is a later phase. */
|
|
358
|
+
resolvedByQuoteId: string | null;
|
|
359
|
+
resolvedAt: string | null;
|
|
360
|
+
createdBy: string;
|
|
361
|
+
updatedBy: string;
|
|
362
|
+
createdAt: string;
|
|
363
|
+
updatedAt: string;
|
|
364
|
+
}
|
|
365
|
+
export interface QuoteAskSummary extends QuoteAsk {
|
|
366
|
+
/** How many quotes compete in this ask. Deliberately not a value aggregate. */
|
|
367
|
+
quoteCount: number;
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* A RANGE across the ask's quotes — deliberately not a total.
|
|
371
|
+
*
|
|
372
|
+
* The quotes are ALTERNATIVES: three of four lose on every multi-scenario RFQ by
|
|
373
|
+
* construction, so adding them multiply-counts the same business.
|
|
374
|
+
*/
|
|
375
|
+
export interface QuoteAskRange {
|
|
376
|
+
quoteCount: number;
|
|
377
|
+
minValue: number | null;
|
|
378
|
+
maxValue: number | null;
|
|
379
|
+
minBlendedMarginPct: number | null;
|
|
380
|
+
maxBlendedMarginPct: number | null;
|
|
381
|
+
}
|
|
382
|
+
export interface QuoteAskCompetingQuote {
|
|
383
|
+
id: string;
|
|
384
|
+
quoteNumber: string;
|
|
385
|
+
name: string | null;
|
|
386
|
+
status: QuoteStatus;
|
|
387
|
+
lines: QuoteLine[];
|
|
388
|
+
rollUp: QuoteLineRollUp;
|
|
389
|
+
}
|
|
390
|
+
export interface QuoteAskDetail extends QuoteAsk {
|
|
391
|
+
quotes: QuoteAskCompetingQuote[];
|
|
392
|
+
range: QuoteAskRange;
|
|
393
|
+
}
|
|
394
|
+
export interface CreateQuoteAskInput {
|
|
395
|
+
customerCompanyId: string;
|
|
396
|
+
name?: string | null;
|
|
397
|
+
opportunityId?: string | null;
|
|
398
|
+
dueDate?: string | null;
|
|
399
|
+
}
|
|
400
|
+
export interface UpdateQuoteAskInput {
|
|
401
|
+
name?: string | null;
|
|
402
|
+
dueDate?: string | null;
|
|
403
|
+
opportunityId?: string | null;
|
|
404
|
+
status?: QuoteAskStatus;
|
|
405
|
+
/** Required when resolving; must be one of this ask's own quotes. */
|
|
406
|
+
resolvedByQuoteId?: string | null;
|
|
407
|
+
}
|
|
408
|
+
export interface ListQuoteAsksOptions {
|
|
409
|
+
status?: QuoteAskStatus;
|
|
410
|
+
customerCompanyId?: string;
|
|
411
|
+
opportunityId?: string;
|
|
412
|
+
}
|
|
413
|
+
/** A per-year volume point. Same shape the quote header uses. */
|
|
414
|
+
export interface QuoteLineVolumeByYear {
|
|
415
|
+
year: number;
|
|
416
|
+
effectiveVolume: number;
|
|
417
|
+
}
|
|
418
|
+
export interface QuoteLine {
|
|
419
|
+
id: string;
|
|
420
|
+
tenantId: string;
|
|
421
|
+
quoteId: string;
|
|
422
|
+
/** Document order. Also picks the line that supplies the deprecated `Quote.partId`. */
|
|
423
|
+
sortOrder: number;
|
|
424
|
+
/**
|
|
425
|
+
* The canonical master-data {@link Part}. NULL is legal — soft enforcement, so a
|
|
426
|
+
* part number not yet reconciled into the catalog can still be quoted. Denotes
|
|
427
|
+
* the BASE part per the part-identity ADR.
|
|
428
|
+
*/
|
|
429
|
+
partId: string | null;
|
|
430
|
+
/** Required, denormalised. Carries the line on its own when `partId` is null. */
|
|
431
|
+
partNumber: string;
|
|
432
|
+
/** Engineering revision this line is quoted AT, when known. Never identity. */
|
|
433
|
+
revision: string | null;
|
|
434
|
+
/**
|
|
435
|
+
* Vehicle→part bridge, unique per line. At the defaults (100 / 1) the
|
|
436
|
+
* header→line volume projection is the IDENTITY.
|
|
437
|
+
*/
|
|
438
|
+
takeRate: number | null;
|
|
439
|
+
partsPerVehicle: number | null;
|
|
440
|
+
/** Authored. Null inherits the header through the bridge. */
|
|
441
|
+
annualVolume: number | null;
|
|
442
|
+
/** Authored per-year series. Authoritative over `annualVolume` when present. */
|
|
443
|
+
effectiveVolumesByYear: QuoteLineVolumeByYear[] | null;
|
|
444
|
+
/** Authored offered price for this line. */
|
|
445
|
+
unitPrice: string | null;
|
|
446
|
+
/** Free text against an unhealthy line. Writable during review. */
|
|
447
|
+
note: string | null;
|
|
448
|
+
/** DERIVED — published only via `quoteLines.setEffectiveCost`. */
|
|
449
|
+
effectiveUnitCost: string | null;
|
|
450
|
+
effectiveCostSource: string | null;
|
|
451
|
+
effectiveCostBasis: string | null;
|
|
452
|
+
effectiveCostedAt: string | null;
|
|
453
|
+
effectiveCostedBy: string | null;
|
|
454
|
+
effectiveCostBreakdown: unknown | null;
|
|
455
|
+
/** DERIVED — published only via `quoteLines.setEffectivePrice`. */
|
|
456
|
+
effectiveUnitPrice: string | null;
|
|
457
|
+
effectivePriceSource: string | null;
|
|
458
|
+
effectivePriceBasis: string | null;
|
|
459
|
+
effectivePricedAt: string | null;
|
|
460
|
+
effectivePricedBy: string | null;
|
|
461
|
+
effectivePriceBreakdown: unknown | null;
|
|
462
|
+
createdBy: string;
|
|
463
|
+
updatedBy: string;
|
|
464
|
+
createdAt: string;
|
|
465
|
+
updatedAt: string;
|
|
466
|
+
/** Present when the line resolves to a catalog part. */
|
|
467
|
+
part?: {
|
|
468
|
+
id: string;
|
|
469
|
+
partNumber: string;
|
|
470
|
+
name: string;
|
|
471
|
+
partTypeId: string | null;
|
|
472
|
+
} | null;
|
|
473
|
+
/** Resolved figures — see {@link ResolvedQuoteLineTerms}. */
|
|
474
|
+
terms: ResolvedQuoteLineTerms;
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* A line's resolved terms. The `*Source` / `*FromLine` flags let a caller tell an
|
|
478
|
+
* authored figure from an inherited one without re-deriving the precedence.
|
|
479
|
+
*/
|
|
480
|
+
export interface ResolvedQuoteLineTerms {
|
|
481
|
+
annualVolume: number;
|
|
482
|
+
volumesByYear: QuoteLineVolumeByYear[] | null;
|
|
483
|
+
unitCost: number | null;
|
|
484
|
+
unitPrice: number | null;
|
|
485
|
+
value: number;
|
|
486
|
+
marginPct: number | null;
|
|
487
|
+
/**
|
|
488
|
+
* Which tier the volume came from: the line's own series, the line's own annual
|
|
489
|
+
* figure, or the quote header bridged through take rate × parts per vehicle.
|
|
490
|
+
*/
|
|
491
|
+
volumeSource: 'line_years' | 'line_annual' | 'header_bridged';
|
|
492
|
+
costFromLine: boolean;
|
|
493
|
+
priceFromLine: boolean;
|
|
494
|
+
}
|
|
495
|
+
/**
|
|
496
|
+
* Consolidated figures for ONE quote's lines, computed on read.
|
|
497
|
+
*
|
|
498
|
+
* `blendedMarginPct` is value-weighted over the lines whose margin is KNOWN, not
|
|
499
|
+
* over the whole quote value — a blend diluted by parts with no cost yet is a
|
|
500
|
+
* worse number that is equally false. `linesWithoutMargin` reports that gap.
|
|
501
|
+
*/
|
|
502
|
+
export interface QuoteLineRollUp {
|
|
503
|
+
lineCount: number;
|
|
504
|
+
totalAnnualVolume: number;
|
|
505
|
+
totalValue: number;
|
|
506
|
+
blendedMarginPct: number | null;
|
|
507
|
+
linesWithoutMargin: number;
|
|
508
|
+
/** Lines whose part number isn't reconciled into the catalog yet. */
|
|
509
|
+
linesWithoutCatalogPart: number;
|
|
510
|
+
}
|
|
511
|
+
export interface QuoteLinesResponse {
|
|
512
|
+
quoteId: string;
|
|
513
|
+
quoteNumber: string;
|
|
514
|
+
lines: QuoteLine[];
|
|
515
|
+
rollUp: QuoteLineRollUp;
|
|
516
|
+
}
|
|
517
|
+
export interface QuoteLinesWithApprovalFlag extends QuoteLinesResponse {
|
|
518
|
+
/**
|
|
519
|
+
* True when the published figure landed on a quote already in approval — the
|
|
520
|
+
* approver signed off on a different number. Surfaced rather than silently
|
|
521
|
+
* absorbed; the caller decides whether to void and re-route.
|
|
522
|
+
*/
|
|
523
|
+
invalidatesApproval: boolean;
|
|
524
|
+
}
|
|
525
|
+
export interface AddQuoteLineInput {
|
|
526
|
+
partNumber: string;
|
|
527
|
+
/** Omit to resolve from `partNumber`; pass `null` to pin it null. */
|
|
528
|
+
partId?: string | null;
|
|
529
|
+
revision?: string | null;
|
|
530
|
+
/** Defaults to the end of the list, so a new line can't take over the mirror. */
|
|
531
|
+
sortOrder?: number;
|
|
532
|
+
/** Percentage, 0–100. Defaults to 100. */
|
|
533
|
+
takeRate?: number;
|
|
534
|
+
/** Defaults to 1. */
|
|
535
|
+
partsPerVehicle?: number;
|
|
536
|
+
annualVolume?: number | null;
|
|
537
|
+
effectiveVolumesByYear?: QuoteLineVolumeByYear[] | null;
|
|
538
|
+
unitPrice?: number | null;
|
|
539
|
+
note?: string | null;
|
|
540
|
+
}
|
|
541
|
+
export interface UpdateQuoteLineInput {
|
|
542
|
+
partNumber?: string;
|
|
543
|
+
/** Omitted with a changed `partNumber` re-resolves the catalog link. */
|
|
544
|
+
partId?: string | null;
|
|
545
|
+
revision?: string | null;
|
|
546
|
+
sortOrder?: number;
|
|
547
|
+
takeRate?: number;
|
|
548
|
+
partsPerVehicle?: number;
|
|
549
|
+
annualVolume?: number | null;
|
|
550
|
+
effectiveVolumesByYear?: QuoteLineVolumeByYear[] | null;
|
|
551
|
+
unitPrice?: number | null;
|
|
552
|
+
note?: string | null;
|
|
553
|
+
}
|
|
554
|
+
export interface SetQuoteLineEffectiveCostInput {
|
|
555
|
+
unitCost: number;
|
|
556
|
+
/** Required — what the figure was costed against. */
|
|
557
|
+
costBasis: string;
|
|
558
|
+
/** Declared by the adapter. Defaults to 'cpq'. */
|
|
559
|
+
source?: string;
|
|
560
|
+
breakdown?: unknown;
|
|
561
|
+
}
|
|
562
|
+
export interface SetQuoteLineEffectivePriceInput {
|
|
563
|
+
unitPrice: number;
|
|
564
|
+
priceBasis: string;
|
|
565
|
+
source?: string;
|
|
566
|
+
breakdown?: unknown;
|
|
567
|
+
}
|
|
305
568
|
export interface CreateQuoteInput {
|
|
306
569
|
/**
|
|
307
570
|
* MIGRATION ESCAPE HATCH — do not set this from production code.
|
|
@@ -319,6 +582,10 @@ export interface CreateQuoteInput {
|
|
|
319
582
|
name?: string;
|
|
320
583
|
customerCompanyId: string;
|
|
321
584
|
programId?: string;
|
|
585
|
+
/** Join the quote to an OEM request ({@link QuoteAsk}). Optional — a quote with
|
|
586
|
+
* no ask competes with nothing and is awardable on its own. Validated to exist
|
|
587
|
+
* in-tenant AND to belong to the same customer as the quote. */
|
|
588
|
+
askId?: string | null;
|
|
322
589
|
partId?: string;
|
|
323
590
|
/** Historical/parent quote this one was copied from. Validated to exist
|
|
324
591
|
* in-tenant on write; no DB FK. */
|
|
@@ -338,6 +605,12 @@ export interface CreateQuoteInput {
|
|
|
338
605
|
eopPrecision?: SopEopPrecision;
|
|
339
606
|
effectiveAnnualVolume?: number;
|
|
340
607
|
effectiveVolumesByYear?: EffectiveVolumeByYear[];
|
|
608
|
+
/** The VEHICLE stream every line bridges from — vehicles the program builds,
|
|
609
|
+
* not parts sold. Each line turns it into its own part volume with its take
|
|
610
|
+
* rate and parts-per-vehicle. Omit it and the lines fall back to the part
|
|
611
|
+
* columns, which is what pre-2026-08-06 quotes do. (4.12.0) */
|
|
612
|
+
vehicleAnnualVolume?: number;
|
|
613
|
+
vehicleVolumesByYear?: EffectiveVolumeByYear[];
|
|
341
614
|
/** Arbitrary-period committed volume. Non-empty makes the two fields above
|
|
342
615
|
* derived — passing either alongside it is a 422. (4.8.0) */
|
|
343
616
|
effectiveVolumesByPeriod?: EffectiveVolumeByPeriod[];
|
|
@@ -368,6 +641,9 @@ export interface UpdateQuoteInput {
|
|
|
368
641
|
quoteNumber?: string;
|
|
369
642
|
name?: string | null;
|
|
370
643
|
programId?: string | null;
|
|
644
|
+
/** Join the quote to an OEM request ({@link QuoteAsk}), or `null` to detach it
|
|
645
|
+
* (it then competes with nothing). Validated to match the quote's customer. */
|
|
646
|
+
askId?: string | null;
|
|
371
647
|
partId?: string | null;
|
|
372
648
|
/** Set to a quote id to record provenance, or `null` to clear it. */
|
|
373
649
|
referenceQuoteId?: string | null;
|
|
@@ -385,6 +661,11 @@ export interface UpdateQuoteInput {
|
|
|
385
661
|
eopPrecision?: SopEopPrecision | null;
|
|
386
662
|
effectiveAnnualVolume?: number | null;
|
|
387
663
|
effectiveVolumesByYear?: EffectiveVolumeByYear[] | null;
|
|
664
|
+
/** The VEHICLE stream. Editing it moves EVERY line's calculated volume at
|
|
665
|
+
* once — one program build rate, many finished goods. `null` hands the lines
|
|
666
|
+
* back to the part columns. (4.12.0) */
|
|
667
|
+
vehicleAnnualVolume?: number | null;
|
|
668
|
+
vehicleVolumesByYear?: EffectiveVolumeByYear[] | null;
|
|
388
669
|
/** Full replace. Non-empty makes the yearly fields derived (writing them is a
|
|
389
670
|
* 422); `null` or `[]` clears the schedule and hands them back. The last
|
|
390
671
|
* derived values are left in place — clearing stops maintaining them, it
|
|
@@ -724,6 +1005,7 @@ export interface MergePlantsRequest {
|
|
|
724
1005
|
survivorId: string;
|
|
725
1006
|
mergedIds: string[];
|
|
726
1007
|
}
|
|
1008
|
+
export type RateBookStatus = 'draft' | 'active' | 'archived';
|
|
727
1009
|
export type RateSourcingMode = 'fixed' | 'indexed';
|
|
728
1010
|
export type RateRollForwardMode = 'carry_forward_flagged' | 'blank_force_entry';
|
|
729
1011
|
export type RateValueOrigin = 'entered' | 'escalated' | 'overridden' | 'carried_forward';
|
|
@@ -1026,6 +1308,213 @@ export interface RateLookupResult {
|
|
|
1026
1308
|
container: string | null;
|
|
1027
1309
|
};
|
|
1028
1310
|
}
|
|
1311
|
+
/**
|
|
1312
|
+
* Bulk rate set for consumer per-run caching (e.g. CPQ costing). One read
|
|
1313
|
+
* returns every book, every element + its values, the three catalogs, and the
|
|
1314
|
+
* active legacy rate tables — enough to resolve rates in-memory for a whole
|
|
1315
|
+
* calc run instead of N×M live `rates.lookup` calls. Decimals are strings.
|
|
1316
|
+
*/
|
|
1317
|
+
export interface RateSnapshot {
|
|
1318
|
+
asOf: string;
|
|
1319
|
+
books: Array<{
|
|
1320
|
+
id: string;
|
|
1321
|
+
name: string;
|
|
1322
|
+
year: number;
|
|
1323
|
+
status: string;
|
|
1324
|
+
effectiveDate: string | null;
|
|
1325
|
+
currency: string;
|
|
1326
|
+
horizonStart: number;
|
|
1327
|
+
horizonEnd: number;
|
|
1328
|
+
escalationPct: string | null;
|
|
1329
|
+
rollForwardMode: string;
|
|
1330
|
+
publishedAt: string | null;
|
|
1331
|
+
}>;
|
|
1332
|
+
elements: Array<{
|
|
1333
|
+
id: string;
|
|
1334
|
+
scope: string;
|
|
1335
|
+
plantId: string | null;
|
|
1336
|
+
rateLineId: string | null;
|
|
1337
|
+
gradeCode: string | null;
|
|
1338
|
+
equipmentCode: string | null;
|
|
1339
|
+
equipmentId: string | null;
|
|
1340
|
+
skillClass: string | null;
|
|
1341
|
+
lane: string | null;
|
|
1342
|
+
mode: string | null;
|
|
1343
|
+
container: string | null;
|
|
1344
|
+
identityKey: string;
|
|
1345
|
+
escalationPct: string | null;
|
|
1346
|
+
values: Array<{
|
|
1347
|
+
id: string;
|
|
1348
|
+
bookId: string;
|
|
1349
|
+
effectiveFrom: string | null;
|
|
1350
|
+
effectiveTo: string | null;
|
|
1351
|
+
origin: string;
|
|
1352
|
+
rate: string | null;
|
|
1353
|
+
ratePerKg: string | null;
|
|
1354
|
+
uom: string;
|
|
1355
|
+
currency: string;
|
|
1356
|
+
sourcingMode: string;
|
|
1357
|
+
}>;
|
|
1358
|
+
}>;
|
|
1359
|
+
rateLines: Array<{
|
|
1360
|
+
id: string;
|
|
1361
|
+
code: string;
|
|
1362
|
+
label: string;
|
|
1363
|
+
binding: string;
|
|
1364
|
+
allowedUoms: string[];
|
|
1365
|
+
defaultUom: string | null;
|
|
1366
|
+
escalationDefault: string | null;
|
|
1367
|
+
active: boolean;
|
|
1368
|
+
}>;
|
|
1369
|
+
rateGrades: Array<{
|
|
1370
|
+
id: string;
|
|
1371
|
+
code: string;
|
|
1372
|
+
label: string;
|
|
1373
|
+
allowedUoms: string[];
|
|
1374
|
+
defaultUom: string;
|
|
1375
|
+
density: string | null;
|
|
1376
|
+
densityUnit: string | null;
|
|
1377
|
+
active: boolean;
|
|
1378
|
+
}>;
|
|
1379
|
+
uoms: Array<{
|
|
1380
|
+
id: string;
|
|
1381
|
+
tenantId: string | null;
|
|
1382
|
+
code: string;
|
|
1383
|
+
label: string;
|
|
1384
|
+
bindings: string[];
|
|
1385
|
+
basis: string;
|
|
1386
|
+
perBaseFactor: string | null;
|
|
1387
|
+
needsDensity: boolean;
|
|
1388
|
+
active: boolean;
|
|
1389
|
+
}>;
|
|
1390
|
+
legacyRateTables: Array<{
|
|
1391
|
+
id: string;
|
|
1392
|
+
name: string;
|
|
1393
|
+
status: string;
|
|
1394
|
+
year: number;
|
|
1395
|
+
currency: string;
|
|
1396
|
+
effectiveDate: string | null;
|
|
1397
|
+
effectiveTo: string | null;
|
|
1398
|
+
version: number;
|
|
1399
|
+
entries: Array<{
|
|
1400
|
+
id: string;
|
|
1401
|
+
category: string;
|
|
1402
|
+
subcategory: string;
|
|
1403
|
+
region: string | null;
|
|
1404
|
+
rate: number;
|
|
1405
|
+
unit: string;
|
|
1406
|
+
effectiveDate: string | null;
|
|
1407
|
+
key: string | null;
|
|
1408
|
+
type: string | null;
|
|
1409
|
+
plantId: string | null;
|
|
1410
|
+
plantSubtype: string | null;
|
|
1411
|
+
skillTier: string | null;
|
|
1412
|
+
lane: string | null;
|
|
1413
|
+
mode: string | null;
|
|
1414
|
+
sourcingMode: string | null;
|
|
1415
|
+
currency: string | null;
|
|
1416
|
+
density: number | null;
|
|
1417
|
+
densityUnit: string | null;
|
|
1418
|
+
ratePerKg: number | null;
|
|
1419
|
+
}>;
|
|
1420
|
+
}>;
|
|
1421
|
+
}
|
|
1422
|
+
export type RateCategoryKind = 'material' | 'packaging' | 'freight' | 'labor';
|
|
1423
|
+
/** The active book summary (`GET /v1/rate-books/active` → `{ book }`). */
|
|
1424
|
+
export interface RateBookSummary {
|
|
1425
|
+
id: string;
|
|
1426
|
+
name: string;
|
|
1427
|
+
year: number;
|
|
1428
|
+
status: RateBookStatus;
|
|
1429
|
+
currency: string;
|
|
1430
|
+
horizonStart: number;
|
|
1431
|
+
horizonEnd: number;
|
|
1432
|
+
rollForwardMode: RateRollForwardMode;
|
|
1433
|
+
escalationPct: number;
|
|
1434
|
+
}
|
|
1435
|
+
/** A plant carrying rate elements in a book (`GET /v1/rate-books/:id/plants`). */
|
|
1436
|
+
export interface RateBookPlant {
|
|
1437
|
+
plantId: string;
|
|
1438
|
+
code: string | null;
|
|
1439
|
+
name: string | null;
|
|
1440
|
+
/** Plant-local currency; 'USD' when the opaque plantId has no local Plant row. */
|
|
1441
|
+
currency: string;
|
|
1442
|
+
elementCount: number;
|
|
1443
|
+
}
|
|
1444
|
+
/** A machine in a plant, collapsed to its base-year per-line summary. */
|
|
1445
|
+
export interface RateBookEquipment {
|
|
1446
|
+
equipmentCode: string;
|
|
1447
|
+
name: string | null;
|
|
1448
|
+
processFamily: string | null;
|
|
1449
|
+
/** Base-year value per rate line — the collapsed row's summary. */
|
|
1450
|
+
summary: Array<{
|
|
1451
|
+
lineCode: string;
|
|
1452
|
+
rate: number;
|
|
1453
|
+
uom: string;
|
|
1454
|
+
}>;
|
|
1455
|
+
}
|
|
1456
|
+
/** Cursor-paginated equipment page (`GET .../plants/:plantId/equipment`). */
|
|
1457
|
+
export interface RateBookEquipmentPage {
|
|
1458
|
+
items: RateBookEquipment[];
|
|
1459
|
+
nextCursor: string | null;
|
|
1460
|
+
total: number;
|
|
1461
|
+
}
|
|
1462
|
+
/** The rate-line × year matrix for one machine (`.../equipment/:code/rates`). */
|
|
1463
|
+
export interface MachineRateLine {
|
|
1464
|
+
elementId: string;
|
|
1465
|
+
rateLineId: string | null;
|
|
1466
|
+
rateLineCode: string | null;
|
|
1467
|
+
rateLineLabel: string | null;
|
|
1468
|
+
/** Effective escalation pct (element override → rate-line default → book). */
|
|
1469
|
+
escalationPct: number;
|
|
1470
|
+
/** True when escalationPct is a row-level override (element.escalationPct set). */
|
|
1471
|
+
escalationOverride: boolean;
|
|
1472
|
+
/** Always true from master-data — no soft-deactivation is exposed. */
|
|
1473
|
+
active: boolean;
|
|
1474
|
+
values: Array<{
|
|
1475
|
+
year: number;
|
|
1476
|
+
rate: number;
|
|
1477
|
+
uom: string;
|
|
1478
|
+
currency: string;
|
|
1479
|
+
origin: string;
|
|
1480
|
+
}>;
|
|
1481
|
+
}
|
|
1482
|
+
/** A category (material/packaging/freight/labor) rate row, global merged with
|
|
1483
|
+
* a plant's overrides (`GET /v1/rate-books/:id/rates?kind=&plantId=`). */
|
|
1484
|
+
export interface CategoryRateRow {
|
|
1485
|
+
elementId: string;
|
|
1486
|
+
scope: 'plant' | 'global';
|
|
1487
|
+
/** The global element this row overrides, when a plant row shadows a global. */
|
|
1488
|
+
globalElementId: string | null;
|
|
1489
|
+
label: string;
|
|
1490
|
+
dimKey: string;
|
|
1491
|
+
uom: string | null;
|
|
1492
|
+
currency: string | null;
|
|
1493
|
+
escalationPct: number;
|
|
1494
|
+
escalationOverride: boolean;
|
|
1495
|
+
/** Always true from master-data — no soft-deactivation is exposed. */
|
|
1496
|
+
active: boolean;
|
|
1497
|
+
values: Array<{
|
|
1498
|
+
year: number;
|
|
1499
|
+
rate: number;
|
|
1500
|
+
origin: string;
|
|
1501
|
+
}>;
|
|
1502
|
+
}
|
|
1503
|
+
/** A packaging-container option (`GET /v1/rate-containers` → `{ rows }`). */
|
|
1504
|
+
export interface RateContainer {
|
|
1505
|
+
code: string;
|
|
1506
|
+
label: string;
|
|
1507
|
+
}
|
|
1508
|
+
/** Options for the paginated equipment read. */
|
|
1509
|
+
export interface ListRateBookEquipmentOptions {
|
|
1510
|
+
q?: string;
|
|
1511
|
+
family?: string;
|
|
1512
|
+
cursor?: string;
|
|
1513
|
+
limit?: number;
|
|
1514
|
+
/** 'rated' (default) = machines with a rate in the book; 'all' = union with
|
|
1515
|
+
* the plant's live machine master (for the add-entry picker). */
|
|
1516
|
+
lens?: 'rated' | 'all';
|
|
1517
|
+
}
|
|
1029
1518
|
export interface Equipment {
|
|
1030
1519
|
id: string;
|
|
1031
1520
|
tenantId: string;
|
|
@@ -1635,8 +2124,8 @@ export interface ListPartTypesOptions {
|
|
|
1635
2124
|
/** When true, request only active types (drops archived). */
|
|
1636
2125
|
activeOnly?: boolean;
|
|
1637
2126
|
}
|
|
1638
|
-
export type AttributeDataType = 'text' | 'number' | 'boolean' | 'enum' | 'date';
|
|
1639
|
-
export type AttributeStatus = 'active' | 'archived';
|
|
2127
|
+
export type AttributeDataType = 'text' | 'number' | 'boolean' | 'enum' | 'date' | 'multi_select' | 'hierarchy';
|
|
2128
|
+
export type AttributeStatus = 'active' | 'deprecated' | 'archived';
|
|
1640
2129
|
/** Typed rules stored per definition and enforced by the server on every
|
|
1641
2130
|
* attribute write. `min`/`max` are value bounds for `number` and length bounds
|
|
1642
2131
|
* for `text`; `regex` applies to `text`; `precision` is max decimal places for
|
|
@@ -1693,6 +2182,135 @@ export interface ListPartAttributesOptions {
|
|
|
1693
2182
|
/** When true, request only active definitions (drops archived). */
|
|
1694
2183
|
activeOnly?: boolean;
|
|
1695
2184
|
}
|
|
2185
|
+
/** Per-type config + rules stored per definition (superset of AttributeValidation). */
|
|
2186
|
+
export interface AttributeValidationRules {
|
|
2187
|
+
required?: boolean;
|
|
2188
|
+
min?: number;
|
|
2189
|
+
max?: number;
|
|
2190
|
+
regex?: string;
|
|
2191
|
+
precision?: number;
|
|
2192
|
+
/** hierarchy: ordered level names, e.g. ["OEM","Platform","Program"]. */
|
|
2193
|
+
levels?: string[];
|
|
2194
|
+
minSelections?: number;
|
|
2195
|
+
maxSelections?: number;
|
|
2196
|
+
[k: string]: unknown;
|
|
2197
|
+
}
|
|
2198
|
+
export interface AttributeDefinition {
|
|
2199
|
+
id: string;
|
|
2200
|
+
tenantId: string;
|
|
2201
|
+
entityType: string;
|
|
2202
|
+
key: string;
|
|
2203
|
+
label: string;
|
|
2204
|
+
dataType: AttributeDataType;
|
|
2205
|
+
unit: string | null;
|
|
2206
|
+
/** Legacy inline enum values; prefer `attributeOptions` rows. */
|
|
2207
|
+
options: string[] | null;
|
|
2208
|
+
group: string | null;
|
|
2209
|
+
groupId: string | null;
|
|
2210
|
+
validation: AttributeValidationRules | null;
|
|
2211
|
+
filterable: boolean;
|
|
2212
|
+
analyticsVisible: boolean;
|
|
2213
|
+
status: AttributeStatus;
|
|
2214
|
+
sortOrder: number;
|
|
2215
|
+
createdBy: string;
|
|
2216
|
+
updatedBy: string;
|
|
2217
|
+
createdAt: string;
|
|
2218
|
+
updatedAt: string;
|
|
2219
|
+
/** Present when the definition is fetched with its options (select/hierarchy). */
|
|
2220
|
+
attributeOptions?: AttributeOption[];
|
|
2221
|
+
}
|
|
2222
|
+
export interface CreateAttributeDefinitionInput {
|
|
2223
|
+
entityType: string;
|
|
2224
|
+
key: string;
|
|
2225
|
+
label: string;
|
|
2226
|
+
dataType: AttributeDataType;
|
|
2227
|
+
unit?: string | null;
|
|
2228
|
+
options?: string[] | null;
|
|
2229
|
+
groupId?: string | null;
|
|
2230
|
+
validation?: AttributeValidationRules | null;
|
|
2231
|
+
filterable?: boolean;
|
|
2232
|
+
analyticsVisible?: boolean;
|
|
2233
|
+
sortOrder?: number;
|
|
2234
|
+
}
|
|
2235
|
+
export interface UpdateAttributeDefinitionInput {
|
|
2236
|
+
label?: string;
|
|
2237
|
+
dataType?: AttributeDataType;
|
|
2238
|
+
unit?: string | null;
|
|
2239
|
+
options?: string[] | null;
|
|
2240
|
+
groupId?: string | null;
|
|
2241
|
+
validation?: AttributeValidationRules | null;
|
|
2242
|
+
filterable?: boolean;
|
|
2243
|
+
analyticsVisible?: boolean;
|
|
2244
|
+
sortOrder?: number;
|
|
2245
|
+
status?: AttributeStatus;
|
|
2246
|
+
}
|
|
2247
|
+
export interface ListAttributeDefinitionsOptions {
|
|
2248
|
+
/** Required — the entity whose definitions to list ('opportunity', 'quote', …). */
|
|
2249
|
+
entityType: string;
|
|
2250
|
+
activeOnly?: boolean;
|
|
2251
|
+
groupId?: string;
|
|
2252
|
+
}
|
|
2253
|
+
export interface AttributeGroup {
|
|
2254
|
+
id: string;
|
|
2255
|
+
tenantId: string;
|
|
2256
|
+
entityType: string;
|
|
2257
|
+
name: string;
|
|
2258
|
+
sortOrder: number;
|
|
2259
|
+
createdBy: string;
|
|
2260
|
+
updatedBy: string;
|
|
2261
|
+
createdAt: string;
|
|
2262
|
+
updatedAt: string;
|
|
2263
|
+
}
|
|
2264
|
+
export interface CreateAttributeGroupInput {
|
|
2265
|
+
entityType: string;
|
|
2266
|
+
name: string;
|
|
2267
|
+
sortOrder?: number;
|
|
2268
|
+
}
|
|
2269
|
+
export interface UpdateAttributeGroupInput {
|
|
2270
|
+
name?: string;
|
|
2271
|
+
sortOrder?: number;
|
|
2272
|
+
}
|
|
2273
|
+
/** Disposition for a group's definitions when the group is deleted. */
|
|
2274
|
+
export interface DeleteAttributeGroupOptions {
|
|
2275
|
+
reassignTo?: string;
|
|
2276
|
+
archive?: boolean;
|
|
2277
|
+
}
|
|
2278
|
+
export interface AttributeOption {
|
|
2279
|
+
id: string;
|
|
2280
|
+
tenantId: string;
|
|
2281
|
+
definitionId: string;
|
|
2282
|
+
value: string;
|
|
2283
|
+
label: string;
|
|
2284
|
+
sortOrder: number;
|
|
2285
|
+
parentId: string | null;
|
|
2286
|
+
level: number;
|
|
2287
|
+
createdBy: string;
|
|
2288
|
+
updatedBy: string;
|
|
2289
|
+
createdAt: string;
|
|
2290
|
+
updatedAt: string;
|
|
2291
|
+
}
|
|
2292
|
+
export interface CreateAttributeOptionInput {
|
|
2293
|
+
value: string;
|
|
2294
|
+
label?: string;
|
|
2295
|
+
sortOrder?: number;
|
|
2296
|
+
parentId?: string | null;
|
|
2297
|
+
}
|
|
2298
|
+
export interface UpdateAttributeOptionInput {
|
|
2299
|
+
value?: string;
|
|
2300
|
+
label?: string;
|
|
2301
|
+
sortOrder?: number;
|
|
2302
|
+
}
|
|
2303
|
+
/** Result of the option Excel import (validate-preview or commit). */
|
|
2304
|
+
export interface ImportOptionsResult {
|
|
2305
|
+
summary: {
|
|
2306
|
+
rows: number;
|
|
2307
|
+
roots: number;
|
|
2308
|
+
total: number;
|
|
2309
|
+
byLevel: Record<number, number>;
|
|
2310
|
+
errors: string[];
|
|
2311
|
+
};
|
|
2312
|
+
committed: boolean;
|
|
2313
|
+
}
|
|
1696
2314
|
export interface AuditLogEntry {
|
|
1697
2315
|
id: string;
|
|
1698
2316
|
tenantId: string | null;
|
|
@@ -1786,7 +2404,7 @@ export type SourceApp = 'master-data' | 'erfq' | 'cpq' | 'bom' | 'forecast' | 'o
|
|
|
1786
2404
|
* "Empty" means SQL NULL only — a stored '', 0, false, or 0.0 counts as
|
|
1787
2405
|
* populated and will not be overwritten by fill_empty. */
|
|
1788
2406
|
export type MergePolicy = 'overwrite' | 'fill_empty';
|
|
1789
|
-
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' | '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' | 'key' | 'dataType' | 'options' | 'group' | 'required' | 'min' | 'max' | 'regex' | 'precision' | 'basis' | 'bindings' | 'perBaseFactor' | 'needsDensity' | 'binding' | 'allowedUoms' | 'defaultUom' | 'escalationDefault' | 'density' | 'densityUnit';
|
|
2407
|
+
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';
|
|
1790
2408
|
export interface ImportSession {
|
|
1791
2409
|
id: string;
|
|
1792
2410
|
tenantId: string;
|
|
@@ -2062,10 +2680,20 @@ export interface BulkArchiveResult {
|
|
|
2062
2680
|
errors: number;
|
|
2063
2681
|
};
|
|
2064
2682
|
}
|
|
2683
|
+
/** Ownership verdict carried on an *enforced* entity's read/list response
|
|
2684
|
+
* `meta` (Master Data Ownership Phase 4). Present only for enforced elements
|
|
2685
|
+
* (Plant today). `readOnly` ⇒ the element is externally owned and Campfire
|
|
2686
|
+
* edits are rejected server-side; the UI renders read-only + `editHint`. */
|
|
2687
|
+
export interface OwnershipMeta {
|
|
2688
|
+
readOnly: boolean;
|
|
2689
|
+
ownerSystem: string;
|
|
2690
|
+
editHint: string | null;
|
|
2691
|
+
}
|
|
2065
2692
|
export interface ApiMeta {
|
|
2066
2693
|
requestId: string;
|
|
2067
2694
|
timestamp: string;
|
|
2068
2695
|
resolvedFrom?: string;
|
|
2696
|
+
ownership?: OwnershipMeta;
|
|
2069
2697
|
}
|
|
2070
2698
|
export interface ListMeta extends ApiMeta {
|
|
2071
2699
|
nextCursor: string | null;
|
|
@@ -2079,6 +2707,29 @@ export interface DuplicateWarning {
|
|
|
2079
2707
|
matchName: string;
|
|
2080
2708
|
score: number;
|
|
2081
2709
|
}
|
|
2710
|
+
export type OwnerType = 'campfire' | 'external';
|
|
2711
|
+
/** One catalog element merged with its (optional) stored ownership row. The
|
|
2712
|
+
* GET response fills catalog defaults where a tenant has no row. */
|
|
2713
|
+
export interface MasterDataElementOwnership {
|
|
2714
|
+
element: string;
|
|
2715
|
+
label: string;
|
|
2716
|
+
category: string;
|
|
2717
|
+
ownerType: OwnerType;
|
|
2718
|
+
/** Owning system display name; 'Campfire' when Campfire-owned. */
|
|
2719
|
+
systemName: string;
|
|
2720
|
+
syncMethod: string | null;
|
|
2721
|
+
/** Opaque integrations Source id (external only) — traceability, not a FK. */
|
|
2722
|
+
sourceRef: string | null;
|
|
2723
|
+
updatedAt: string | null;
|
|
2724
|
+
updatedBy: string | null;
|
|
2725
|
+
}
|
|
2726
|
+
export interface SetOwnershipInput {
|
|
2727
|
+
ownerType: OwnerType;
|
|
2728
|
+
/** Required when ownerType is 'external'. */
|
|
2729
|
+
systemName?: string;
|
|
2730
|
+
syncMethod?: string;
|
|
2731
|
+
sourceRef?: string;
|
|
2732
|
+
}
|
|
2082
2733
|
export interface SingleResponse<T> {
|
|
2083
2734
|
data: T;
|
|
2084
2735
|
meta: ApiMeta;
|
|
@@ -2100,6 +2751,10 @@ export interface ListCompaniesOptions {
|
|
|
2100
2751
|
status?: 'active' | 'archived' | 'all';
|
|
2101
2752
|
quality?: 'draft' | 'verified';
|
|
2102
2753
|
role?: 'supplier' | 'customer' | 'oem';
|
|
2754
|
+
/** Batch-get a specific set of companies by id — returns them regardless of
|
|
2755
|
+
* status. Comma-joined server-side; cap ~100/call for URL length and chunk
|
|
2756
|
+
* larger sets. The server bumps the page size to cover the ids. */
|
|
2757
|
+
ids?: string[];
|
|
2103
2758
|
include?: ('contacts' | 'locations')[];
|
|
2104
2759
|
}
|
|
2105
2760
|
export interface GetCompanyOptions {
|