@campfire-interactive/master-data-client 5.14.0 → 5.16.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,143 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TenantProgramResource = void 0;
4
+ /**
5
+ * The tenant's own programs ("Campfire Programs") at /v1/tenant-programs.
6
+ * `client.programs` is the LEGACY program and is unchanged; these take the
7
+ * plain name once legacy is gone (nextgen plan
8
+ * 2026-10-08-tenant-programs-pm-first.md).
9
+ */
10
+ class TenantProgramResource {
11
+ http;
12
+ constructor(http) {
13
+ this.http = http;
14
+ }
15
+ async list(options) {
16
+ const query = {};
17
+ if (options) {
18
+ if (options.limit !== undefined)
19
+ query.limit = String(options.limit);
20
+ if (options.cursor)
21
+ query.cursor = options.cursor;
22
+ if (options.sort)
23
+ query.sort = options.sort;
24
+ if (options.q)
25
+ query.q = options.q;
26
+ if (options.status)
27
+ query.status = options.status;
28
+ if (options.ids?.length)
29
+ query.ids = options.ids.join(',');
30
+ if (options.customerCompanyId)
31
+ query.customerCompanyId = options.customerCompanyId;
32
+ if (options.geographicScopeId)
33
+ query.geographicScopeId = options.geographicScopeId;
34
+ if (options.productScopeId)
35
+ query.productScopeId = options.productScopeId;
36
+ if (options.include?.length)
37
+ query.include = options.include.join(',');
38
+ }
39
+ return this.http.request({ method: 'GET', path: '/v1/tenant-programs', query });
40
+ }
41
+ async get(id, options) {
42
+ return this.http.request({
43
+ method: 'GET',
44
+ path: `/v1/tenant-programs/${encodeURIComponent(id)}`,
45
+ query: options?.include?.length ? { include: options.include.join(',') } : {},
46
+ });
47
+ }
48
+ /** With `id` the program takes the caller's id; with `finishedGoods` the
49
+ * lines attach in the same transaction (a refused line writes nothing). */
50
+ async create(input, idempotencyKey) {
51
+ return this.http.request({
52
+ method: 'POST',
53
+ path: '/v1/tenant-programs',
54
+ body: input,
55
+ idempotencyKey,
56
+ });
57
+ }
58
+ async update(id, input) {
59
+ return this.http.request({
60
+ method: 'PUT',
61
+ path: `/v1/tenant-programs/${encodeURIComponent(id)}`,
62
+ body: input,
63
+ });
64
+ }
65
+ /** Archive; never a hard delete. */
66
+ async archive(id) {
67
+ await this.http.request({ method: 'DELETE', path: `/v1/tenant-programs/${encodeURIComponent(id)}` });
68
+ }
69
+ async restore(id) {
70
+ return this.http.request({
71
+ method: 'POST',
72
+ path: `/v1/tenant-programs/${encodeURIComponent(id)}/restore`,
73
+ });
74
+ }
75
+ async getAudit(id) {
76
+ return this.http.request({
77
+ method: 'GET',
78
+ path: `/v1/tenant-programs/${encodeURIComponent(id)}/audit`,
79
+ });
80
+ }
81
+ // ─── finished goods ────────────────────────────────────────────────────────
82
+ async listFinishedGoods(programId) {
83
+ return this.http.request({
84
+ method: 'GET',
85
+ path: `/v1/tenant-programs/${encodeURIComponent(programId)}/finished-goods`,
86
+ });
87
+ }
88
+ /** All lines attach or none do. */
89
+ async addFinishedGoods(programId, input) {
90
+ return this.http.request({
91
+ method: 'POST',
92
+ path: `/v1/tenant-programs/${encodeURIComponent(programId)}/finished-goods`,
93
+ body: input,
94
+ });
95
+ }
96
+ async updateFinishedGood(programId, finishedGoodId, input) {
97
+ return this.http.request({
98
+ method: 'PATCH',
99
+ path: `/v1/tenant-programs/${encodeURIComponent(programId)}/finished-goods/${encodeURIComponent(finishedGoodId)}`,
100
+ body: input,
101
+ });
102
+ }
103
+ async removeFinishedGood(programId, finishedGoodId) {
104
+ await this.http.request({
105
+ method: 'DELETE',
106
+ path: `/v1/tenant-programs/${encodeURIComponent(programId)}/finished-goods/${encodeURIComponent(finishedGoodId)}`,
107
+ });
108
+ }
109
+ /** The finished goods of up to 100 programs in one read. */
110
+ async finishedGoodsByPrograms(programIds) {
111
+ return this.http.request({
112
+ method: 'GET',
113
+ path: '/v1/tenant-programs/finished-goods/by-programs',
114
+ query: { programIds: programIds.join(',') },
115
+ });
116
+ }
117
+ /** Which program holds each line of a quote, or each named line. */
118
+ async finishedGoodsByQuote(filter) {
119
+ return this.http.request({
120
+ method: 'GET',
121
+ path: '/v1/tenant-programs/finished-goods',
122
+ query: {
123
+ quoteId: filter.quoteId,
124
+ quoteLineIds: filter.quoteLineIds?.length ? filter.quoteLineIds.join(',') : undefined,
125
+ },
126
+ });
127
+ }
128
+ /** Awarded quote lines a program can take, each annotated with its holder.
129
+ * `meta.truncated` is true when more matched than `limit`. */
130
+ async availableAwardedLines(options) {
131
+ return this.http.request({
132
+ method: 'GET',
133
+ path: '/v1/tenant-programs/available-lines',
134
+ query: {
135
+ q: options?.q,
136
+ programId: options?.programId,
137
+ limit: options?.limit !== undefined ? String(options.limit) : undefined,
138
+ },
139
+ });
140
+ }
141
+ }
142
+ exports.TenantProgramResource = TenantProgramResource;
143
+ //# sourceMappingURL=tenantPrograms.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tenantPrograms.js","sourceRoot":"","sources":["../src/tenantPrograms.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -48,6 +48,10 @@ export interface Location {
48
48
  createdAt: string;
49
49
  updatedAt: string;
50
50
  }
51
+ /** LEGACY: the old program (master-data table `programs_legacy`), in practice
52
+ * an OEM's vehicle program scoped to one customer. Unchanged on the wire for
53
+ * the apps still on it; the tenant's own program is {@link TenantProgram}
54
+ * (`client.tenantPrograms`). */
51
55
  export interface Program {
52
56
  id: string;
53
57
  tenantId: string;
@@ -124,6 +128,153 @@ export interface ListProgramsOptions {
124
128
  export interface GetProgramOptions {
125
129
  include?: ('customerCompany' | 'oemCompany')[];
126
130
  }
131
+ export interface TenantProgram {
132
+ id: string;
133
+ tenantId: string;
134
+ code: string;
135
+ name: string;
136
+ description: string | null;
137
+ status: 'active' | 'archived';
138
+ geographicScopeId: string | null;
139
+ productScopeId: string | null;
140
+ /** Custom attribute values (entity type 'program'). */
141
+ attributes: Record<string, unknown>;
142
+ /** Distinct customers of the finished goods' quotes, in attach order. */
143
+ customerCompanyIds: string[];
144
+ /** With include=customerCompanies. */
145
+ customerCompanies?: unknown[];
146
+ finishedGoodCount: number;
147
+ /** With include=finishedGoods (get), and on a create that attached some. */
148
+ finishedGoods?: TenantProgramFinishedGood[];
149
+ createdBy: string;
150
+ updatedBy: string;
151
+ createdAt: string;
152
+ updatedAt: string;
153
+ }
154
+ export interface ListTenantProgramsOptions {
155
+ limit?: number;
156
+ cursor?: string;
157
+ /** name | code | createdAt | updatedAt, '-' prefix for descending. */
158
+ sort?: string;
159
+ q?: string;
160
+ status?: 'active' | 'archived' | 'all';
161
+ /** Any status, at most 200. */
162
+ ids?: string[];
163
+ /** Programs with a finished good for this customer. */
164
+ customerCompanyId?: string;
165
+ geographicScopeId?: string;
166
+ productScopeId?: string;
167
+ include?: 'customerCompanies'[];
168
+ }
169
+ export interface GetTenantProgramOptions {
170
+ include?: ('finishedGoods' | 'customerCompanies')[];
171
+ }
172
+ export interface CreateTenantProgramInput {
173
+ /** Caller-chosen id (a UUID); pm keeps its lifecycle rows under it. */
174
+ id?: string;
175
+ name: string;
176
+ /** Unique in the tenant. */
177
+ code: string;
178
+ description?: string | null;
179
+ geographicScopeId?: string | null;
180
+ productScopeId?: string | null;
181
+ attributes?: Record<string, unknown>;
182
+ /** Attached in the same transaction; a refused line writes nothing. */
183
+ finishedGoods?: AddTenantProgramFinishedGoodsInput;
184
+ }
185
+ export interface UpdateTenantProgramInput {
186
+ name?: string;
187
+ code?: string;
188
+ description?: string | null;
189
+ geographicScopeId?: string | null;
190
+ productScopeId?: string | null;
191
+ }
192
+ /** One awarded quote line on a tenant program. A line sits on at most one
193
+ * program. Lifecycle (status, gates) is pm's. Decimals are strings. */
194
+ export interface TenantProgramFinishedGood {
195
+ id: string;
196
+ tenantId: string;
197
+ programId: string;
198
+ /** Null once the quote or line is wiped; the snapshot below survives. */
199
+ quoteId: string | null;
200
+ quoteLineId: string | null;
201
+ partId: string | null;
202
+ partNumber: string;
203
+ /** The catalog part's name, when the line is cataloged. */
204
+ partName: string | null;
205
+ plantId: string | null;
206
+ sopDate: string | null;
207
+ eopDate: string | null;
208
+ awardedUnitPrice: string | null;
209
+ awardedAnnualVolume: string | null;
210
+ awardedLifetimeRevenue: string | null;
211
+ awardedMarginPct: string | null;
212
+ awardedCurrency: string | null;
213
+ quote: {
214
+ id: string;
215
+ quoteNumber: string;
216
+ name: string | null;
217
+ customerCompanyId: string;
218
+ } | null;
219
+ createdBy: string;
220
+ updatedBy: string;
221
+ createdAt: string;
222
+ updatedAt: string;
223
+ }
224
+ export interface AddTenantProgramFinishedGoodsInput {
225
+ /** Lines of awarded quotes, at most 200; all attach or none do. */
226
+ quoteLineIds: string[];
227
+ /** One plant for every line in this call. */
228
+ plantId?: string | null;
229
+ /** Override the quote's SOP/EOP for every line in this call. */
230
+ sopDate?: string | null;
231
+ eopDate?: string | null;
232
+ /** The id each new finished good takes, keyed by quote line id; a line
233
+ * without one gets a generated id. A taken id is a 409. */
234
+ idsByQuoteLineId?: Record<string, string>;
235
+ }
236
+ export interface UpdateTenantProgramFinishedGoodInput {
237
+ plantId?: string | null;
238
+ sopDate?: string | null;
239
+ eopDate?: string | null;
240
+ }
241
+ /** A finished good with the program holding it, from the by-quote lookup. */
242
+ export interface TenantProgramFinishedGoodHolder extends Omit<TenantProgramFinishedGood, 'partName' | 'quote'> {
243
+ program: {
244
+ id: string;
245
+ name: string;
246
+ code: string;
247
+ status: 'active' | 'archived';
248
+ };
249
+ }
250
+ /** An awarded quote line, annotated with the program already holding it. */
251
+ export interface AvailableAwardedLine {
252
+ quoteLineId: string;
253
+ partId: string | null;
254
+ partNumber: string;
255
+ partName: string | null;
256
+ unitPrice: string | null;
257
+ annualVolume: string | null;
258
+ quoteId: string;
259
+ quoteNumber: string;
260
+ quoteName: string | null;
261
+ customerCompanyId: string;
262
+ sopDate: string | null;
263
+ eopDate: string | null;
264
+ currency: string;
265
+ takenByProgramId: string | null;
266
+ takenByProgramCode: string | null;
267
+ /** True when held by the programId passed to the query. */
268
+ onThisProgram: boolean;
269
+ }
270
+ export interface ListAvailableAwardedLinesOptions {
271
+ /** Part number, part name, quote number or quote name; omitted = newest. */
272
+ q?: string;
273
+ /** Marks lines already on this program (onThisProgram). */
274
+ programId?: string;
275
+ /** 1-200, default 50. */
276
+ limit?: number;
277
+ }
127
278
  export type QuoteStatus = 'draft' | 'costing_requested' | 'costing_in_progress' | 'costing_complete' | 'pricing' | 'routed_for_approval' | 'in_review' | 'approved' | 'submitted' | 'negotiating' | 'awarded' | 'lost' | 'not_taken';
128
279
  /**
129
280
  * Who is driving the transition. Required on every status update so the
@@ -3764,6 +3915,22 @@ export interface MasterDataClientConfig {
3764
3915
  timeout?: number;
3765
3916
  /** When set, sends X-Target-Tenant header on every request (platform tenant override). */
3766
3917
  targetTenantId?: string;
3918
+ /**
3919
+ * Retry on 429 Too Many Requests and 503 Service Unavailable — the hub's (and
3920
+ * its API gateway's) answers for load. On by default; `false` turns it off.
3921
+ * Exponential backoff with full jitter, honoring a `Retry-After` header when
3922
+ * one is sent. A write is retried with the SAME Idempotency-Key, which the
3923
+ * hub honors, so a retry can never apply a mutation twice. Timeouts and
3924
+ * network errors are NOT retried: the server's state is unknown there.
3925
+ */
3926
+ retry?: false | {
3927
+ /** Retries after the first attempt. Default 4. */
3928
+ maxRetries?: number;
3929
+ /** First backoff ceiling in ms; doubles each retry. Default 250. */
3930
+ baseDelayMs?: number;
3931
+ /** Largest single wait in ms, Retry-After included. Default 8000. */
3932
+ maxDelayMs?: number;
3933
+ };
3767
3934
  }
3768
3935
  export type QuoteDocumentStage = 'feasibility' | 'award';
3769
3936
  /** Quote-level (one document for the quote) or one per finished good. The