@campfire-interactive/master-data-client 3.1.2 → 3.5.1

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.
Files changed (51) hide show
  1. package/dist/client.d.ts +8 -2
  2. package/dist/client.d.ts.map +1 -1
  3. package/dist/client.js +12 -3
  4. package/dist/client.js.map +1 -1
  5. package/dist/equipment.d.ts +7 -7
  6. package/dist/equipment.d.ts.map +1 -1
  7. package/dist/equipment.js +5 -15
  8. package/dist/equipment.js.map +1 -1
  9. package/dist/index.d.ts +5 -2
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +9 -3
  12. package/dist/index.js.map +1 -1
  13. package/dist/partAttributes.d.ts +14 -0
  14. package/dist/partAttributes.d.ts.map +1 -0
  15. package/dist/partAttributes.js +63 -0
  16. package/dist/partAttributes.js.map +1 -0
  17. package/dist/parts.d.ts +10 -1
  18. package/dist/parts.d.ts.map +1 -1
  19. package/dist/parts.js +11 -0
  20. package/dist/parts.js.map +1 -1
  21. package/dist/plants.d.ts +2 -2
  22. package/dist/plants.d.ts.map +1 -1
  23. package/dist/plants.js +3 -19
  24. package/dist/plants.js.map +1 -1
  25. package/dist/processFamilies.d.ts +2 -1
  26. package/dist/processFamilies.d.ts.map +1 -1
  27. package/dist/processFamilies.js +4 -2
  28. package/dist/processFamilies.js.map +1 -1
  29. package/dist/rateBooks.d.ts +18 -0
  30. package/dist/rateBooks.d.ts.map +1 -0
  31. package/dist/rateBooks.js +76 -0
  32. package/dist/rateBooks.js.map +1 -0
  33. package/dist/rateCatalog.d.ts +7 -5
  34. package/dist/rateCatalog.d.ts.map +1 -1
  35. package/dist/rateCatalog.js +11 -7
  36. package/dist/rateCatalog.js.map +1 -1
  37. package/dist/rateElements.d.ts +31 -0
  38. package/dist/rateElements.d.ts.map +1 -0
  39. package/dist/rateElements.js +104 -0
  40. package/dist/rateElements.js.map +1 -0
  41. package/dist/rateTables.d.ts +32 -0
  42. package/dist/rateTables.d.ts.map +1 -0
  43. package/dist/rateTables.js +116 -0
  44. package/dist/rateTables.js.map +1 -0
  45. package/dist/rates.d.ts +2 -3
  46. package/dist/rates.d.ts.map +1 -1
  47. package/dist/rates.js +11 -12
  48. package/dist/rates.js.map +1 -1
  49. package/dist/types.d.ts +423 -245
  50. package/dist/types.d.ts.map +1 -1
  51. package/package.json +1 -1
package/dist/types.d.ts CHANGED
@@ -407,105 +407,89 @@ export interface ListMaterialsOptions {
407
407
  quality?: 'draft' | 'verified';
408
408
  category?: string;
409
409
  }
410
- export type PlantStatus = 'active' | 'archived';
411
410
  export interface Plant {
412
411
  id: string;
413
412
  tenantId: string;
414
- companyId: string | null;
415
- locationId: string | null;
416
413
  code: string;
417
414
  name: string;
418
- description: string | null;
419
- /** Denormalised; useful even when locationId is null. */
415
+ location: string | null;
416
+ /** Denormalised country. */
420
417
  country: string | null;
421
- /** Free-text in v1; may FK to Region later. */
418
+ /** Free-text region. */
422
419
  region: string | null;
423
420
  headcount: number | null;
424
- annualCapacityHours: number | null;
425
- /** Annual throughput capacity in units (distinct from annualCapacityHours). */
426
- annualCapacityUnits: number | null;
421
+ /** Annual throughput capacity (units). */
422
+ annualCapacity: number | null;
427
423
  /** 0..1. */
428
424
  currentUtilization: number | null;
425
+ /** $/hr fully-loaded labor cost. Decimal-ish; carried as number. */
426
+ laborCostPerHour: number | null;
429
427
  riskLevel: string | null;
430
- /** Plant operating currency (ISO 4217). Ergonomic default for rate entry;
431
- * rate values carry their own authoritative currency. Defaults to "USD". */
428
+ /** Plant operating currency (ISO 4217). Defaults to "USD". */
432
429
  currency: string;
433
430
  numShifts: number;
434
431
  hoursPerShift: number;
435
432
  workingDaysPerYear: number;
436
433
  /** 0..1; defaults to 0.15. */
437
434
  indirectHeadcountPct: number;
438
- status: PlantStatus;
439
- quality: 'draft' | 'verified';
440
- createdBy: string;
441
- updatedBy: string;
435
+ active: boolean;
442
436
  createdAt: string;
443
437
  updatedAt: string;
444
- company?: Company;
445
- location?: Location;
446
438
  }
447
439
  export interface CreatePlantInput {
448
440
  code: string;
449
441
  name: string;
450
- description?: string;
451
- companyId?: string | null;
452
- locationId?: string | null;
442
+ location?: string;
453
443
  country?: string;
454
444
  region?: string;
455
445
  headcount?: number;
456
- annualCapacityHours?: number;
457
- annualCapacityUnits?: number;
446
+ annualCapacity?: number;
458
447
  currentUtilization?: number;
448
+ laborCostPerHour?: number;
459
449
  riskLevel?: string;
460
450
  currency?: string;
461
451
  numShifts?: number;
462
452
  hoursPerShift?: number;
463
453
  workingDaysPerYear?: number;
464
454
  indirectHeadcountPct?: number;
465
- quality?: 'draft' | 'verified';
455
+ active?: boolean;
466
456
  }
467
457
  export interface UpdatePlantInput {
468
458
  code?: string;
469
459
  name?: string;
470
- description?: string | null;
471
- companyId?: string | null;
472
- locationId?: string | null;
460
+ location?: string | null;
473
461
  country?: string | null;
474
462
  region?: string | null;
475
463
  headcount?: number | null;
476
- annualCapacityHours?: number | null;
477
- annualCapacityUnits?: number | null;
464
+ annualCapacity?: number | null;
478
465
  currentUtilization?: number | null;
466
+ laborCostPerHour?: number | null;
479
467
  riskLevel?: string | null;
480
468
  currency?: string;
481
469
  numShifts?: number;
482
470
  hoursPerShift?: number;
483
471
  workingDaysPerYear?: number;
484
472
  indirectHeadcountPct?: number;
485
- quality?: 'draft' | 'verified';
473
+ active?: boolean;
486
474
  }
487
475
  export interface ListPlantsOptions {
488
476
  limit?: number;
489
477
  cursor?: string;
490
478
  sort?: string;
491
479
  q?: string;
492
- status?: PlantStatus | 'all';
493
- quality?: 'draft' | 'verified';
494
- companyId?: string;
495
- locationId?: string;
480
+ active?: boolean;
496
481
  country?: string;
497
482
  region?: string;
498
- include?: ('company' | 'location')[];
499
483
  }
500
484
  export interface GetPlantOptions {
501
- include?: ('company' | 'location')[];
485
+ /** Reserved for future relation expansions; currently no-op. */
486
+ include?: string[];
502
487
  }
503
488
  export type PlantMatchType = 'exact_code' | 'trgm_name';
504
489
  export interface PlantMatch {
505
490
  id: string;
506
491
  name: string;
507
492
  code: string;
508
- companyId: string | null;
509
493
  country: string | null;
510
494
  region: string | null;
511
495
  /** 1.0 for exact-code match; pg_trgm similarity in (threshold..1] otherwise. */
@@ -514,8 +498,6 @@ export interface PlantMatch {
514
498
  }
515
499
  export interface PlantMatchQuery {
516
500
  name: string;
517
- /** When set, restricts both exact and fuzzy matches to plants of this company. */
518
- companyId?: string;
519
501
  /** When present, an exact match on (tenantId, code) is unioned at score=1.0. */
520
502
  code?: string;
521
503
  }
@@ -542,233 +524,309 @@ export interface MergePlantsRequest {
542
524
  survivorId: string;
543
525
  mergedIds: string[];
544
526
  }
545
- export type RateLibraryStatus = 'draft' | 'active' | 'archived';
546
- export type RateEntryKind = 'labor' | 'machine' | 'overhead' | 'material' | 'freight';
547
527
  export type RateSourcingMode = 'fixed' | 'indexed';
548
528
  export type RateRollForwardMode = 'carry_forward_flagged' | 'blank_force_entry';
549
529
  export type RateValueOrigin = 'entered' | 'escalated' | 'overridden' | 'carried_forward';
550
- export interface RateLibrary {
530
+ /** Legacy alias retained for the v0 rate-table entries + the lookup `kind` param. */
531
+ export type RateEntryKind = 'labor' | 'machine' | 'overhead' | 'material' | 'freight';
532
+ export interface RateBook {
551
533
  id: string;
552
534
  tenantId: string;
553
535
  name: string;
554
- code: string;
555
- description: string | null;
556
- currency: string;
536
+ year: number;
537
+ status: string;
557
538
  effectiveDate: string;
558
- effectiveTo: string | null;
559
- /** Multi-year projection horizon (calendar years) + book-level escalation
560
- * and roll-forward policy. Carried over from CPQ's RateBook. Null horizon
561
- * = single-window library. Added in the 2026-07-02 rate superset. */
562
- horizonStart: number | null;
563
- horizonEnd: number | null;
539
+ currency: string;
540
+ horizonStart: number;
541
+ horizonEnd: number;
564
542
  escalationPct: number;
565
543
  rollForwardMode: RateRollForwardMode;
566
- status: RateLibraryStatus;
567
- quality: 'draft' | 'verified';
568
- version: number;
569
544
  publishedAt: string | null;
570
- publishedBy: string | null;
571
- archivedAt: string | null;
572
- archivedBy: string | null;
573
- createdBy: string;
574
- updatedBy: string;
575
545
  createdAt: string;
576
546
  updatedAt: string;
577
- entries?: RateEntry[];
578
- /** Which app most-recently wrote any field on this row. Derived from
579
- * `FieldProvenance` server-side. Defaults to `'master-data'` for rows
580
- * without provenance entries. Added in 2.15.0. */
581
- lastEditedBy?: SourceApp;
582
547
  }
583
- export interface RateEntry {
548
+ export interface CreateRateBookInput {
549
+ name: string;
550
+ year: number;
551
+ effectiveDate: string;
552
+ currency?: string;
553
+ horizonStart?: number;
554
+ horizonEnd?: number;
555
+ escalationPct?: number;
556
+ rollForwardMode?: RateRollForwardMode;
557
+ }
558
+ export interface UpdateRateBookInput {
559
+ name?: string;
560
+ year?: number;
561
+ effectiveDate?: string;
562
+ currency?: string;
563
+ horizonStart?: number;
564
+ horizonEnd?: number;
565
+ escalationPct?: number;
566
+ rollForwardMode?: RateRollForwardMode;
567
+ }
568
+ export interface ListRateBooksOptions {
569
+ limit?: number;
570
+ cursor?: string;
571
+ sort?: string;
572
+ q?: string;
573
+ status?: string;
574
+ year?: number;
575
+ currency?: string;
576
+ }
577
+ export interface RateElement {
584
578
  id: string;
585
579
  tenantId: string;
586
- rateLibraryId: string;
587
- kind: RateEntryKind;
580
+ scope: string;
588
581
  plantId: string | null;
589
- /** Equipment scope for machine-burden rates (superset). */
590
- equipmentId: string | null;
591
- equipmentCode: string | null;
592
- skillTier: string | null;
593
- materialId: string | null;
594
- /** Material grade code — resolves to a RateGrade for density. */
582
+ rateLineId: string | null;
595
583
  gradeCode: string | null;
596
- regionId: string | null;
584
+ equipmentCode: string | null;
585
+ equipmentId: string | null;
586
+ skillClass: string | null;
597
587
  lane: string | null;
598
- /** Freight mode + packaging container qualifiers. */
599
588
  mode: string | null;
600
589
  container: string | null;
590
+ /** Computed server-side from the element's dimensions. */
591
+ identityKey: string;
592
+ escalationPct: number | null;
593
+ externalRef: string | null;
594
+ sourceSystem: string | null;
595
+ createdAt: string;
596
+ updatedAt: string;
597
+ values?: RateValue[];
598
+ }
599
+ export interface CreateRateElementInput {
600
+ scope: string;
601
+ plantId?: string | null;
602
+ rateLineId?: string | null;
603
+ gradeCode?: string | null;
604
+ equipmentCode?: string | null;
605
+ equipmentId?: string | null;
606
+ skillClass?: string | null;
607
+ lane?: string | null;
608
+ mode?: string | null;
609
+ container?: string | null;
610
+ escalationPct?: number | null;
611
+ externalRef?: string | null;
612
+ sourceSystem?: string | null;
613
+ }
614
+ export interface ListRateElementsOptions {
615
+ limit?: number;
616
+ cursor?: string;
617
+ sort?: string;
618
+ scope?: string;
619
+ plantId?: string;
620
+ rateLineId?: string;
621
+ equipmentCode?: string;
622
+ equipmentId?: string;
623
+ gradeCode?: string;
624
+ }
625
+ export interface RateValue {
626
+ id: string;
627
+ tenantId: string;
628
+ elementId: string;
629
+ effectiveFrom: string;
630
+ effectiveTo: string | null;
631
+ origin: RateValueOrigin;
601
632
  /** Decimal serialized as string to preserve precision across the wire. */
602
633
  rate: string;
603
- /** Canonical mass-basis cost (Decimal string), derived for material rates. */
604
- ratePerKg: string | null;
605
- unit: string;
606
634
  currency: string;
607
- /** Per-year projection window (null = inherits the library window). */
608
- effectiveFrom: string | null;
609
- effectiveTo: string | null;
610
- /** Per-row escalation override (null = inherit the library default). */
611
- escalationPct: number | null;
612
- origin: RateValueOrigin;
635
+ uom: string;
636
+ ratePerKg: string | null;
613
637
  sourcingMode: RateSourcingMode;
614
- indexRef: string | null;
615
- lastSyncedAt: string | null;
616
638
  sourceSystem: string | null;
617
- externalRef: string | null;
618
- notes: string | null;
619
- createdBy: string;
620
- updatedBy: string;
639
+ priceIndexId: string | null;
640
+ indexRefLegacy: string | null;
641
+ bookId: string;
621
642
  createdAt: string;
622
643
  updatedAt: string;
623
644
  }
624
- export interface CreateRateLibraryInput {
625
- name: string;
626
- code: string;
627
- description?: string;
645
+ export interface CreateRateValueInput {
646
+ effectiveFrom: string;
647
+ effectiveTo?: string | null;
648
+ origin?: RateValueOrigin;
649
+ /** Number accepted; string preferred for precision. */
650
+ rate: number | string;
628
651
  currency?: string;
652
+ uom: string;
653
+ ratePerKg?: number | string | null;
654
+ sourcingMode?: RateSourcingMode;
655
+ sourceSystem?: string | null;
656
+ priceIndexId?: string | null;
657
+ indexRefLegacy?: string | null;
658
+ bookId: string;
659
+ }
660
+ export interface ListRateValuesOptions {
661
+ bookId?: string;
662
+ asOf?: string;
663
+ }
664
+ export interface RateTable {
665
+ id: string;
666
+ tenantId: string;
667
+ name: string;
668
+ effectiveDate: string;
669
+ effectiveTo: string | null;
670
+ status: string;
671
+ year: number;
672
+ currency: string;
673
+ version: number;
674
+ publishedAt: string | null;
675
+ publishedById: string | null;
676
+ archivedAt: string | null;
677
+ archivedById: string | null;
678
+ createdAt: string;
679
+ updatedAt: string;
680
+ entries?: RateEntry[];
681
+ }
682
+ export interface CreateRateTableInput {
683
+ name: string;
629
684
  effectiveDate: string;
630
685
  effectiveTo?: string | null;
631
- horizonStart?: number | null;
632
- horizonEnd?: number | null;
633
- escalationPct?: number;
634
- rollForwardMode?: RateRollForwardMode;
686
+ year: number;
687
+ currency?: string;
635
688
  }
636
- export interface UpdateRateLibraryInput {
689
+ export interface UpdateRateTableInput {
637
690
  name?: string;
638
- description?: string | null;
639
- currency?: string;
640
691
  effectiveDate?: string;
641
692
  effectiveTo?: string | null;
642
- quality?: 'draft' | 'verified';
643
- horizonStart?: number | null;
644
- horizonEnd?: number | null;
645
- escalationPct?: number;
646
- rollForwardMode?: RateRollForwardMode;
647
- }
648
- export interface RollForwardResult {
649
- libraryId: string;
650
- horizonStart: number;
651
- horizonEnd: number;
652
- mode: RateRollForwardMode;
653
- seedsProjected: number;
654
- rowsCreated: number;
655
- rowsReplaced: number;
693
+ year?: number;
694
+ currency?: string;
656
695
  }
657
- export interface ListRateLibrariesOptions {
696
+ export interface ListRateTablesOptions {
658
697
  limit?: number;
659
698
  cursor?: string;
660
699
  sort?: string;
661
700
  q?: string;
662
- status?: RateLibraryStatus | 'all';
663
- /** Filter to libraries effective on this date (effectiveDate <= asOf, effectiveTo null or > asOf). */
664
- asOf?: string;
665
- code?: string;
701
+ status?: string;
702
+ year?: number;
666
703
  currency?: string;
667
704
  }
668
- export interface GetRateLibraryOptions {
669
- include?: 'entries'[];
705
+ export interface RateEntry {
706
+ id: string;
707
+ tenantId: string;
708
+ rateTableId: string;
709
+ category: string;
710
+ subcategory: string;
711
+ region: string | null;
712
+ /** Decimal serialized as string to preserve precision across the wire. */
713
+ rate: string;
714
+ unit: string;
715
+ effectiveDate: string;
716
+ notes: string | null;
717
+ key: string | null;
718
+ alias: string | null;
719
+ type: string | null;
720
+ plantId: string | null;
721
+ plantSubtype: string | null;
722
+ skillTier: string | null;
723
+ lane: string | null;
724
+ mode: string | null;
725
+ sourcingMode: string | null;
726
+ indexRef: string | null;
727
+ source: string | null;
728
+ lastSyncedAt: string | null;
729
+ syncStatus: string | null;
730
+ confidence: number | null;
731
+ entryVersion: number;
732
+ currency: string | null;
733
+ density: number | null;
734
+ densityUnit: string | null;
735
+ ratePerKg: string | null;
736
+ createdAt: string;
737
+ updatedAt: string;
670
738
  }
671
739
  export interface CreateRateEntryInput {
672
- kind: RateEntryKind;
673
- plantId?: string | null;
674
- equipmentId?: string | null;
675
- equipmentCode?: string | null;
676
- skillTier?: string | null;
677
- materialId?: string | null;
678
- gradeCode?: string | null;
679
- regionId?: string | null;
680
- lane?: string | null;
681
- mode?: string | null;
682
- container?: string | null;
740
+ category: string;
741
+ subcategory: string;
742
+ region?: string | null;
683
743
  /** Number accepted; string preferred for precision. */
684
744
  rate: number | string;
685
- ratePerKg?: number | string | null;
686
745
  unit: string;
687
- currency?: string;
688
- effectiveFrom?: string | null;
689
- effectiveTo?: string | null;
690
- escalationPct?: number | null;
691
- origin?: RateValueOrigin;
692
- sourcingMode?: RateSourcingMode;
693
- indexRef?: string | null;
694
- sourceSystem?: string | null;
695
- externalRef?: string | null;
746
+ effectiveDate: string;
696
747
  notes?: string | null;
697
- }
698
- export interface UpdateRateEntryInput {
748
+ key?: string | null;
749
+ alias?: string | null;
750
+ type?: string | null;
699
751
  plantId?: string | null;
700
- equipmentId?: string | null;
701
- equipmentCode?: string | null;
752
+ plantSubtype?: string | null;
702
753
  skillTier?: string | null;
703
- materialId?: string | null;
704
- gradeCode?: string | null;
705
- regionId?: string | null;
706
754
  lane?: string | null;
707
755
  mode?: string | null;
708
- container?: string | null;
709
- rate?: number | string;
756
+ sourcingMode?: string | null;
757
+ indexRef?: string | null;
758
+ source?: string | null;
759
+ currency?: string | null;
760
+ density?: number | null;
761
+ densityUnit?: string | null;
710
762
  ratePerKg?: number | string | null;
763
+ }
764
+ export interface UpdateRateEntryInput {
765
+ category?: string;
766
+ subcategory?: string;
767
+ region?: string | null;
768
+ rate?: number | string;
711
769
  unit?: string;
712
- currency?: string;
713
- effectiveFrom?: string | null;
714
- effectiveTo?: string | null;
715
- escalationPct?: number | null;
716
- origin?: RateValueOrigin;
717
- sourcingMode?: RateSourcingMode;
718
- indexRef?: string | null;
719
- sourceSystem?: string | null;
720
- externalRef?: string | null;
770
+ effectiveDate?: string;
721
771
  notes?: string | null;
722
- }
723
- export interface ListRateEntriesOptions {
724
- kind?: RateEntryKind;
725
- }
726
- export interface RateLookupInput {
727
- kind: RateEntryKind;
772
+ key?: string | null;
773
+ alias?: string | null;
774
+ type?: string | null;
728
775
  plantId?: string | null;
729
- equipmentId?: string | null;
730
- equipmentCode?: string | null;
776
+ plantSubtype?: string | null;
731
777
  skillTier?: string | null;
732
- materialId?: string | null;
733
- gradeCode?: string | null;
734
- regionId?: string | null;
735
778
  lane?: string | null;
736
779
  mode?: string | null;
737
- container?: string | null;
780
+ sourcingMode?: string | null;
781
+ indexRef?: string | null;
782
+ source?: string | null;
783
+ currency?: string | null;
784
+ density?: number | null;
785
+ densityUnit?: string | null;
786
+ ratePerKg?: number | string | null;
787
+ }
788
+ export interface RateLookupInput {
789
+ rateLineId?: string;
790
+ /** Legacy alias for rateLineId; accepted server-side for back-compat. */
791
+ kind?: string;
792
+ plantId?: string;
793
+ equipmentCode?: string;
794
+ equipmentId?: string;
795
+ skillClass?: string;
796
+ gradeCode?: string;
797
+ lane?: string;
798
+ mode?: string;
799
+ container?: string;
738
800
  /** ISO date (YYYY-MM-DD). Defaults to today. */
739
801
  asOf?: string;
740
802
  }
741
803
  export interface RateLookupResult {
742
- libraryId: string;
743
- libraryCode: string;
744
- libraryVersion: number;
745
- entryId: string;
746
- kind: RateEntryKind;
804
+ elementId: string;
805
+ bookId: string;
806
+ identityKey: string;
747
807
  /** Decimal serialized as string. */
748
808
  rate: string;
749
809
  /** Decimal serialized as string; null when not a mass-basis material rate. */
750
810
  ratePerKg: string | null;
751
- unit: string;
811
+ uom: string;
752
812
  currency: string;
753
813
  sourcingMode: RateSourcingMode;
754
- indexRef: string | null;
755
814
  /** Echoes the asOf the server resolved against (YYYY-MM-DD). */
756
815
  asOf: string;
757
- /** Echoes the dimensions on the matched entry — handy for consumer audit logging. */
816
+ /** Echoes the dimensions on the matched element — handy for consumer audit logging. */
758
817
  resolvedFrom: {
818
+ rateLineId: string | null;
759
819
  plantId: string | null;
760
- equipmentId: string | null;
761
820
  equipmentCode: string | null;
762
- skillTier: string | null;
763
- materialId: string | null;
821
+ equipmentId: string | null;
822
+ skillClass: string | null;
764
823
  gradeCode: string | null;
765
- regionId: string | null;
766
824
  lane: string | null;
767
825
  mode: string | null;
768
826
  container: string | null;
769
827
  };
770
828
  }
771
- export interface PlantEquipment {
829
+ export interface Equipment {
772
830
  id: string;
773
831
  tenantId: string;
774
832
  plantId: string;
@@ -786,13 +844,9 @@ export interface PlantEquipment {
786
844
  defaultAutomationPct: number;
787
845
  defaultMachinesPerOperator: number;
788
846
  defaultSetupCrew: number;
789
- status: PlantStatus;
790
- quality: 'draft' | 'verified';
791
- createdBy: string;
792
- updatedBy: string;
847
+ active: boolean;
793
848
  createdAt: string;
794
849
  updatedAt: string;
795
- plant?: Plant;
796
850
  }
797
851
  export interface CreateEquipmentInput {
798
852
  plantId: string;
@@ -807,7 +861,7 @@ export interface CreateEquipmentInput {
807
861
  defaultAutomationPct?: number;
808
862
  defaultMachinesPerOperator?: number;
809
863
  defaultSetupCrew?: number;
810
- quality?: 'draft' | 'verified';
864
+ active?: boolean;
811
865
  }
812
866
  export interface UpdateEquipmentInput {
813
867
  code?: string;
@@ -821,122 +875,133 @@ export interface UpdateEquipmentInput {
821
875
  defaultAutomationPct?: number;
822
876
  defaultMachinesPerOperator?: number;
823
877
  defaultSetupCrew?: number;
824
- quality?: 'draft' | 'verified';
878
+ active?: boolean;
825
879
  }
826
880
  export interface ListEquipmentOptions {
827
881
  limit?: number;
828
882
  cursor?: string;
829
883
  sort?: string;
830
884
  q?: string;
831
- status?: PlantStatus | 'all';
832
- quality?: 'draft' | 'verified';
833
885
  plantId?: string;
834
886
  processFamily?: string;
835
- include?: 'plant'[];
836
- }
837
- export interface GetEquipmentOptions {
838
- include?: 'plant'[];
887
+ active?: boolean;
839
888
  }
840
889
  export interface ProcessFamily {
841
890
  id: string;
842
- tenantId: string;
891
+ tenantId: string | null;
843
892
  code: string;
844
- name: string;
845
- description: string | null;
893
+ label: string;
894
+ category: string;
846
895
  sortOrder: number;
847
- status: PlantStatus;
848
- createdBy: string;
849
- updatedBy: string;
896
+ active: boolean;
897
+ isDefault: boolean;
850
898
  createdAt: string;
851
899
  updatedAt: string;
852
900
  }
853
901
  export interface CreateProcessFamilyInput {
854
902
  code: string;
855
- name: string;
856
- description?: string;
903
+ label: string;
904
+ category: string;
857
905
  sortOrder?: number;
906
+ active?: boolean;
907
+ isDefault?: boolean;
858
908
  }
859
909
  export interface UpdateProcessFamilyInput {
860
- name?: string;
861
- description?: string | null;
910
+ label?: string;
911
+ category?: string;
862
912
  sortOrder?: number;
863
- status?: 'active' | 'archived';
913
+ active?: boolean;
914
+ isDefault?: boolean;
864
915
  }
865
916
  export interface Uom {
866
917
  id: string;
867
- tenantId: string;
918
+ tenantId: string | null;
868
919
  code: string;
869
- name: string;
870
- dimension: string | null;
871
- createdBy: string;
872
- updatedBy: string;
920
+ label: string;
921
+ bindings: string[];
922
+ basis: string;
923
+ perBaseFactor: number | null;
924
+ needsDensity: boolean;
925
+ active: boolean;
873
926
  createdAt: string;
874
927
  updatedAt: string;
875
928
  }
876
929
  export interface CreateUomInput {
877
930
  code: string;
878
- name: string;
879
- dimension?: string;
931
+ label: string;
932
+ bindings?: string[];
933
+ basis: string;
934
+ perBaseFactor?: number | null;
935
+ needsDensity?: boolean;
936
+ active?: boolean;
880
937
  }
881
938
  export interface UpdateUomInput {
882
- name?: string;
883
- dimension?: string | null;
939
+ label?: string;
940
+ bindings?: string[];
941
+ basis?: string;
942
+ perBaseFactor?: number | null;
943
+ needsDensity?: boolean;
944
+ active?: boolean;
884
945
  }
885
946
  export interface RateLine {
886
947
  id: string;
887
948
  tenantId: string;
888
949
  code: string;
889
- name: string;
890
- kind: RateEntryKind;
950
+ label: string;
951
+ binding: string;
891
952
  allowedUoms: string[];
892
- description: string | null;
893
- sortOrder: number;
894
- status: PlantStatus;
895
- createdBy: string;
896
- updatedBy: string;
953
+ defaultUom: string | null;
954
+ escalationDefault: number | null;
955
+ active: boolean;
897
956
  createdAt: string;
898
957
  updatedAt: string;
899
958
  }
900
959
  export interface CreateRateLineInput {
901
960
  code: string;
902
- name: string;
903
- kind: RateEntryKind;
961
+ label: string;
962
+ binding: string;
904
963
  allowedUoms?: string[];
905
- description?: string;
906
- sortOrder?: number;
964
+ defaultUom?: string | null;
965
+ escalationDefault?: number | null;
966
+ active?: boolean;
907
967
  }
908
968
  export interface UpdateRateLineInput {
909
- name?: string;
910
- kind?: RateEntryKind;
969
+ label?: string;
970
+ binding?: string;
911
971
  allowedUoms?: string[];
912
- description?: string | null;
913
- sortOrder?: number;
914
- status?: 'active' | 'archived';
972
+ defaultUom?: string | null;
973
+ escalationDefault?: number | null;
974
+ active?: boolean;
915
975
  }
916
976
  export interface RateGrade {
917
977
  id: string;
918
978
  tenantId: string;
919
979
  code: string;
920
- name: string;
921
- materialId: string | null;
980
+ label: string;
981
+ allowedUoms: string[];
982
+ defaultUom: string;
922
983
  density: number | null;
923
- status: PlantStatus;
924
- createdBy: string;
925
- updatedBy: string;
984
+ densityUnit: string | null;
985
+ active: boolean;
926
986
  createdAt: string;
927
987
  updatedAt: string;
928
988
  }
929
989
  export interface CreateRateGradeInput {
930
990
  code: string;
931
- name: string;
932
- materialId?: string | null;
991
+ label: string;
992
+ allowedUoms?: string[];
993
+ defaultUom: string;
933
994
  density?: number | null;
995
+ densityUnit?: string | null;
996
+ active?: boolean;
934
997
  }
935
998
  export interface UpdateRateGradeInput {
936
- name?: string;
937
- materialId?: string | null;
999
+ label?: string;
1000
+ allowedUoms?: string[];
1001
+ defaultUom?: string;
938
1002
  density?: number | null;
939
- status?: 'active' | 'archived';
1003
+ densityUnit?: string | null;
1004
+ active?: boolean;
940
1005
  }
941
1006
  export type ExchangeRateStatus = 'draft' | 'active' | 'archived';
942
1007
  export type ExchangeRateScope = 'tenant' | 'global';
@@ -1039,8 +1104,15 @@ export interface Part {
1039
1104
  partNumber: string;
1040
1105
  /** Supplier's own number; nullable for customer-numbered parts. */
1041
1106
  manufacturingPartNumber: string | null;
1107
+ /** Customer's own cross-reference number for this part. Additive alias only —
1108
+ * never an identity key; canonical key stays partNumber (Decision C). */
1109
+ customerPartNumber: string | null;
1042
1110
  name: string;
1043
1111
  description: string | null;
1112
+ /** Part-level (rev-invariant) attribute bag, governed by the tenant's
1113
+ * part-level attribute dictionary (Decision G). Rev-specific values are on
1114
+ * PartRevision.attributes. */
1115
+ attributes: Record<string, unknown> | null;
1044
1116
  /** @deprecated free-text; use partTypeId (governed PartType catalog). */
1045
1117
  partType: string | null;
1046
1118
  /** The per-tenant PartType this part is classified as. */
@@ -1080,15 +1152,38 @@ export interface PartRevision {
1080
1152
  releaseStatus: string | null;
1081
1153
  leadTime: number | null;
1082
1154
  attributes: Record<string, unknown> | null;
1155
+ /** Latest costed price per unit (string-serialized Decimal). */
1156
+ latestUnitCost: string | null;
1157
+ /** ISO 4217 currency of latestUnitCost. */
1158
+ latestCostCurrency: string | null;
1159
+ /** Opaque ref to the source CPQ quote (cross-app; not FK-validated). */
1160
+ latestCostSourceQuoteId: string | null;
1161
+ latestCostedAt: string | null;
1162
+ latestCostContext: Record<string, unknown> | null;
1083
1163
  status: PartStatus;
1084
1164
  createdBy: string;
1085
1165
  updatedBy: string;
1086
1166
  createdAt: string;
1087
1167
  updatedAt: string;
1088
1168
  }
1169
+ /** Input for `parts.setLatestCost` — the cost-owner-only snapshot write path
1170
+ * (Decision F). Mirrors the server's SetLatestCostInput. */
1171
+ export interface SetLatestCostInput {
1172
+ /** Costed price per unit. Required, must be >= 0. */
1173
+ unitCost: number;
1174
+ /** ISO 4217 currency of unitCost (e.g. "USD"). */
1175
+ currency?: string | null;
1176
+ /** Opaque ref to the source CPQ quote (cross-app; not FK-validated). */
1177
+ sourceQuoteId?: string | null;
1178
+ /** When the cost was struck (ISO string). Defaults to now server-side. */
1179
+ costedAt?: string | null;
1180
+ /** Lossless extras about the costing (quote line id, volume band, etc.). */
1181
+ context?: Record<string, unknown> | null;
1182
+ }
1089
1183
  export interface CreatePartInput {
1090
1184
  partNumber: string;
1091
1185
  manufacturingPartNumber?: string | null;
1186
+ customerPartNumber?: string | null;
1092
1187
  name: string;
1093
1188
  description?: string | null;
1094
1189
  /** @deprecated free-text; use partTypeId. */
@@ -1097,10 +1192,14 @@ export interface CreatePartInput {
1097
1192
  partCategoryId?: string | null;
1098
1193
  manufacturer?: string | null;
1099
1194
  quality?: 'draft' | 'verified';
1195
+ /** Part-level attribute bag; validated against the tenant's part-level
1196
+ * attribute dictionary (Decision G). */
1197
+ attributes?: Record<string, unknown> | null;
1100
1198
  }
1101
1199
  export interface UpdatePartInput {
1102
1200
  partNumber?: string;
1103
1201
  manufacturingPartNumber?: string | null;
1202
+ customerPartNumber?: string | null;
1104
1203
  name?: string;
1105
1204
  description?: string | null;
1106
1205
  /** @deprecated free-text; use partTypeId. */
@@ -1109,6 +1208,9 @@ export interface UpdatePartInput {
1109
1208
  partCategoryId?: string | null;
1110
1209
  manufacturer?: string | null;
1111
1210
  quality?: 'draft' | 'verified';
1211
+ /** Part-level attribute bag; merged key-level (overwrite) into the existing
1212
+ * bag and validated against the tenant's part-level dictionary (Decision G). */
1213
+ attributes?: Record<string, unknown> | null;
1112
1214
  }
1113
1215
  export interface CreatePartRevisionInput {
1114
1216
  revision: string;
@@ -1147,6 +1249,7 @@ export interface BatchUpsertPartInput {
1147
1249
  partNumber: string;
1148
1250
  name?: string;
1149
1251
  manufacturingPartNumber?: string | null;
1252
+ customerPartNumber?: string | null;
1150
1253
  description?: string | null;
1151
1254
  partType?: string | null;
1152
1255
  partCategoryId?: string | null;
@@ -1162,7 +1265,12 @@ export interface BatchUpsertPartInput {
1162
1265
  pcfPerUnit?: number | null;
1163
1266
  releaseStatus?: string | null;
1164
1267
  leadTime?: number | null;
1268
+ /** Revision-level (rev-specific) attribute bag; key-merged into the revision. */
1165
1269
  attributes?: Record<string, unknown> | null;
1270
+ /** Part-level (rev-invariant) attribute bag; key-merged into Part.attributes.
1271
+ * Both bags are validated against the tenant's attribute dictionary by level
1272
+ * (Decision G) — a no-op while the dictionary is empty. */
1273
+ partAttributes?: Record<string, unknown> | null;
1166
1274
  }
1167
1275
  export interface BatchUpsertPartsOptions {
1168
1276
  /** Which app is pushing these parts; recorded in FieldProvenance. Defaults to
@@ -1176,7 +1284,10 @@ export interface BatchUpsertPartsOptions {
1176
1284
  }
1177
1285
  /** Per-row outcome from a parts batch upsert. 'mergedFields' / 'untouched' only
1178
1286
  * occur under mergePolicy='fill_empty'. `revisionCreated` is true when the row
1179
- * carried a `revision` that didn't already exist on the part. */
1287
+ * carried a `revision` that didn't already exist on the part. `filledFields`
1288
+ * are Part-header columns filled/overwritten; `mergedAttributeKeys` are
1289
+ * top-level `PartRevision.attributes` keys merged on an EXISTING revision
1290
+ * (Decision D — key-level attributes merge). */
1180
1291
  export interface BatchPartItemResult {
1181
1292
  index: number;
1182
1293
  status: 'created' | 'mergedFields' | 'untouched' | 'error';
@@ -1185,6 +1296,9 @@ export interface BatchPartItemResult {
1185
1296
  code?: string;
1186
1297
  filledFields?: string[];
1187
1298
  revisionCreated?: boolean;
1299
+ /** Top-level attribute keys merged on an existing part/revision bag (Decision D
1300
+ * rev-level + Decision G part-level). Part-level keys are prefixed `part:`. */
1301
+ mergedAttributeKeys?: string[];
1188
1302
  }
1189
1303
  export interface BatchUpsertPartsResult {
1190
1304
  results: BatchPartItemResult[];
@@ -1294,6 +1408,70 @@ export interface ListPartTypesOptions {
1294
1408
  /** When true, request only active types (drops archived). */
1295
1409
  activeOnly?: boolean;
1296
1410
  }
1411
+ export type AttributeDataType = 'text' | 'number' | 'boolean' | 'enum' | 'date';
1412
+ export type AttributeLevel = 'part' | 'revision';
1413
+ export type AttributeStatus = 'active' | 'archived';
1414
+ /** Typed rules stored per definition and enforced by the server on every
1415
+ * attribute write. `min`/`max` are value bounds for `number` and length bounds
1416
+ * for `text`; `regex` applies to `text`; `precision` is max decimal places for
1417
+ * `number`. `required` (v1) means "non-empty if present". */
1418
+ export interface AttributeValidation {
1419
+ required?: boolean;
1420
+ min?: number;
1421
+ max?: number;
1422
+ regex?: string;
1423
+ precision?: number;
1424
+ }
1425
+ export interface PartAttributeDefinition {
1426
+ id: string;
1427
+ tenantId: string;
1428
+ /** Stable machine key; joins to a JSON key in the value bag. Immutable. */
1429
+ key: string;
1430
+ label: string;
1431
+ dataType: AttributeDataType;
1432
+ level: AttributeLevel;
1433
+ unit: string | null;
1434
+ /** Allowed values when `dataType='enum'`; null otherwise. */
1435
+ options: string[] | null;
1436
+ group: string | null;
1437
+ validation: AttributeValidation | null;
1438
+ status: AttributeStatus;
1439
+ sortOrder: number;
1440
+ createdBy: string;
1441
+ updatedBy: string;
1442
+ createdAt: string;
1443
+ updatedAt: string;
1444
+ }
1445
+ export interface CreatePartAttributeInput {
1446
+ key: string;
1447
+ label: string;
1448
+ dataType: AttributeDataType;
1449
+ level: AttributeLevel;
1450
+ unit?: string | null;
1451
+ options?: string[] | null;
1452
+ group?: string | null;
1453
+ validation?: AttributeValidation | null;
1454
+ sortOrder?: number;
1455
+ }
1456
+ /** `key` is intentionally omitted — it's immutable once created. dataType/level
1457
+ * may be changed but only govern future writes (existing values aren't migrated). */
1458
+ export interface UpdatePartAttributeInput {
1459
+ label?: string;
1460
+ dataType?: AttributeDataType;
1461
+ level?: AttributeLevel;
1462
+ unit?: string | null;
1463
+ options?: string[] | null;
1464
+ group?: string | null;
1465
+ validation?: AttributeValidation | null;
1466
+ sortOrder?: number;
1467
+ status?: AttributeStatus;
1468
+ }
1469
+ export interface ListPartAttributesOptions {
1470
+ /** When true, request only active definitions (drops archived). */
1471
+ activeOnly?: boolean;
1472
+ /** Filter to one level (part | revision). */
1473
+ level?: AttributeLevel;
1474
+ }
1297
1475
  export interface AuditLogEntry {
1298
1476
  id: string;
1299
1477
  tenantId: string | null;