@d19n/youfibre-odin-sdk 2.0.151 → 2.0.156
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/wholesale-provider/index.d.ts +1 -1
- package/dist/wholesale-provider/interface.d.ts +42 -1
- package/dist/wholesale-provider/kci-effect-bridge.d.ts +19 -1
- package/dist/wholesale-provider/kci-effect-bridge.js +42 -8
- package/dist/wholesale-provider/providers/netomnia-provider.d.ts +3 -1
- package/dist/wholesale-provider/providers/netomnia-provider.js +3 -0
- package/dist/wholesale-provider/test/netomnia-provider.spec.js +5 -0
- package/dist/wholesale-provider/types/fibrecafe.d.ts +15 -0
- package/package.json +1 -1
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
*
|
|
26
26
|
* Linked: T-20260508-009 / T-20260508-010
|
|
27
27
|
*/
|
|
28
|
-
export type { WholesaleProvider, CreateOrderOptions, CancellationReasonCode, ReserveAppointmentArgs, ListAppointmentsArgs, ScheduleServiceWorkOrderArgs, RescheduleServiceWorkOrderArgs, AmendAppointmentArgs, SyncWorkOrderToSupplierArgs, UpdateOrderExternalRefArgs, } from './interface';
|
|
28
|
+
export type { WholesaleProvider, CreateOrderOptions, CancellationReasonCode, CancelServiceWorkOrderArgs, ReserveAppointmentArgs, ListAppointmentsArgs, ScheduleServiceWorkOrderArgs, RescheduleServiceWorkOrderArgs, AmendAppointmentArgs, SyncWorkOrderToSupplierArgs, UpdateOrderExternalRefArgs, } from './interface';
|
|
29
29
|
export type { WholesaleResult, WholesaleSyncResponse, WholesaleRejectionResponse, WholesaleRejectionMessage, WholesaleBUS, WholesaleSYS, ISO8601DateTime, ISODate, TransactionId, UPRN, UUID, SwitchOrderReference, } from './types/wholesale';
|
|
30
30
|
export { NetomniaProvider, AggregateNotificationError } from './providers/netomnia-provider';
|
|
31
31
|
export type { NetomniaProviderDeps } from './providers/netomnia-provider';
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
* full types are available).
|
|
31
31
|
*/
|
|
32
32
|
import type { VMO2OrderNotification, VMO2SMRNotification } from './types/vmo2';
|
|
33
|
-
import type { FibreCafeServiceAvailability200, FibreCafeAvailableAppointments200, FibreCafeReserveAppointment201, FibreCafeScheduleServiceWorkOrder201, FibreCafeRescheduleServiceWorkOrder200, FibreCafeOrderCreate202, FibreCafeOrderAmendAccept202, FibreCafeKciDto } from './types/fibrecafe';
|
|
33
|
+
import type { FibreCafeServiceAvailability200, FibreCafeAvailableAppointments200, FibreCafeReserveAppointment201, FibreCafeScheduleServiceWorkOrder201, FibreCafeRescheduleServiceWorkOrder200, FibreCafeOrderCreate202, FibreCafeOrderAmendAccept202, FibreCafeKciDto, FibreCafeServiceProblemCancellationReasonCode } from './types/fibrecafe';
|
|
34
34
|
/**
|
|
35
35
|
* Reasons a cancellation request can be made (NET wire-level enum value
|
|
36
36
|
* passed through to the FibreCafe gateway).
|
|
@@ -107,6 +107,33 @@ export interface UpdateOrderExternalRefArgs {
|
|
|
107
107
|
oldYfId: string;
|
|
108
108
|
newYfId: string;
|
|
109
109
|
}
|
|
110
|
+
/**
|
|
111
|
+
* Args for the tenant-initiated cancellation of an inflight SERVICE WO
|
|
112
|
+
* (REPAIR). Structurally identical to `RescheduleServiceWorkOrderArgs` —
|
|
113
|
+
* cancel is the same action shape as reschedule, just a terminal
|
|
114
|
+
* transition instead of a slot move. Same flat primitive fields; only
|
|
115
|
+
* delta is `reasonCode` in place of the timeslot fields (mirrors how
|
|
116
|
+
* `cancelOrder` carries a `reasonCode` while `createOrder` doesn't).
|
|
117
|
+
*
|
|
118
|
+
* The provider impl posts to
|
|
119
|
+
* `POST /WholesaleGateway/v1.0/gateway/service-work-orders/cancel`. NET
|
|
120
|
+
* looks up its SERVICE WO by `externalId = yfWorkOrderId` (NET stamps
|
|
121
|
+
* the YF WO uuid as externalId at create time per
|
|
122
|
+
* `scheduleServiceWorkOrder`), then drives the NET WO to Cancelled via
|
|
123
|
+
* NET field-service `/cancel-action-apply` with a tenant-originated
|
|
124
|
+
* ChangeReason. The existing SERVICE WO stage-update handler emits the
|
|
125
|
+
* UPDATE+`NETOMNIA_SERVICE_WORK_ORDER_CANCELLED` KCI back to YF.
|
|
126
|
+
*
|
|
127
|
+
* YF only commits its own SERVICE WO → Cancelled transition after this
|
|
128
|
+
* call resolves successfully (NET-first semantics — see
|
|
129
|
+
* `CancelServiceWorkOrderTenantService` in field-service module).
|
|
130
|
+
*/
|
|
131
|
+
export interface CancelServiceWorkOrderArgs {
|
|
132
|
+
yfWorkOrderId: string;
|
|
133
|
+
uprn: number;
|
|
134
|
+
yfOrderId: string;
|
|
135
|
+
reasonCode: FibreCafeServiceProblemCancellationReasonCode;
|
|
136
|
+
}
|
|
110
137
|
/**
|
|
111
138
|
* Capability-shaped interface to a wholesale supplier. Method NAMES align
|
|
112
139
|
* with VMO2 spec where it makes sense; ARGS match existing NET module
|
|
@@ -154,6 +181,20 @@ export interface WholesaleProvider<TPrincipal = unknown> {
|
|
|
154
181
|
cancelOrder(yfOrderId: string, reasonCode: CancellationReasonCode): Promise<FibreCafeOrderCreate202>;
|
|
155
182
|
/** Active-customer cease (post-Active churn / OTS-losing). */
|
|
156
183
|
ceaseOrder(yfOrderId: string, serviceId: string): Promise<FibreCafeOrderCreate202>;
|
|
184
|
+
/**
|
|
185
|
+
* Tenant-initiated cancel of an inflight SERVICE WO. Structurally
|
|
186
|
+
* parallel to `rescheduleServiceWorkOrder` — same flat-primitive args,
|
|
187
|
+
* same response envelope shape, just a terminal transition instead of
|
|
188
|
+
* a slot move.
|
|
189
|
+
*
|
|
190
|
+
* **YF must NOT transition its SERVICE WO to Cancelled until this call
|
|
191
|
+
* resolves successfully** — the call site (`CancelServiceWorkOrderTenant
|
|
192
|
+
* Service` in field-service module) is responsible for gating the YF
|
|
193
|
+
* stage change on the response. The inbound UPDATE+CANCELLED KCI from
|
|
194
|
+
* NET (walker row `repair-update-service-cancelled`) is the secondary
|
|
195
|
+
* cure when YF didn't already advance.
|
|
196
|
+
*/
|
|
197
|
+
cancelServiceWorkOrder(args: CancelServiceWorkOrderArgs): Promise<FibreCafeRescheduleServiceWorkOrder200>;
|
|
157
198
|
/**
|
|
158
199
|
* Inbound supplier KCI handler — the ONE inbound channel from supplier
|
|
159
200
|
* to YF. KCIs drive (a) OrderKci persistence and (b) WO state changes
|
|
@@ -24,7 +24,25 @@
|
|
|
24
24
|
* Linked: T-20260508-010 Step 3 followup (receiveKci 100% typed + handled).
|
|
25
25
|
*/
|
|
26
26
|
import type { FibreCafeKciDto, FibreCafeKciReasonCode } from './types/fibrecafe';
|
|
27
|
-
|
|
27
|
+
/**
|
|
28
|
+
* Discriminator for the BUSINESS KIND of a KCI — not the wire envelope shape.
|
|
29
|
+
*
|
|
30
|
+
* PROVIDE / CEASE / MODIFY / UNSOLICITED_CEASE — typed by the populated
|
|
31
|
+
* sub-body field on the FibreCafe envelope (`provideServiceOrder` etc.).
|
|
32
|
+
*
|
|
33
|
+
* REPAIR — SERVICE WorkOrder state changes. NET emits these on the parent
|
|
34
|
+
* PROVIDE envelope (the SERVICE WO is a child of the PROVIDE order in
|
|
35
|
+
* the data model) but the semantic kind is REPAIR, discriminated by a
|
|
36
|
+
* `NETOMNIA_SERVICE_WORK_ORDER_*` value in `supplierCodes[]`. The
|
|
37
|
+
* envelope wire shape is a data-model artifact; the BP vocabulary is
|
|
38
|
+
* what consumers reason about (SERVICE WO = repair / service visit).
|
|
39
|
+
*
|
|
40
|
+
* `detectKciKind()` returns REPAIR when ANY supplier code matches the
|
|
41
|
+
* `NETOMNIA_SERVICE_WORK_ORDER_*` prefix, taking precedence over the
|
|
42
|
+
* envelope-field-based PROVIDE detection so service-WO KCIs route to the
|
|
43
|
+
* REPAIR-marked bridge rows.
|
|
44
|
+
*/
|
|
45
|
+
export declare type KciServiceOrderKind = 'PROVIDE' | 'CEASE' | 'MODIFY' | 'UNSOLICITED_CEASE' | 'REPAIR';
|
|
28
46
|
export declare type YfKciEffectKind = 'LOG_KCI_ONLY' | 'WO_FLOW_ACTION' | 'WO_SCHEDULE_APPOINTMENT' | 'PROPERTY_WRITE' | 'NO_OP_DOCUMENTED';
|
|
29
47
|
export declare type YfKciTargetEntity = 'OrderModule:Order' | 'CrmModule:Address' | 'FieldServiceModule:WorkOrder';
|
|
30
48
|
/**
|
|
@@ -321,11 +321,19 @@ exports.KCI_EFFECT_ROWS = [
|
|
|
321
321
|
},
|
|
322
322
|
logAgainstOrder: true,
|
|
323
323
|
},
|
|
324
|
-
//
|
|
325
|
-
|
|
326
|
-
|
|
324
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
325
|
+
// REPAIR — SERVICE WO state changes (post-install fault / service visit)
|
|
326
|
+
//
|
|
327
|
+
// NET emits these on the parent PROVIDE envelope (data-model artifact:
|
|
328
|
+
// SERVICE WO is a child of the PROVIDE order). The semantic kind is
|
|
329
|
+
// REPAIR — discriminated by a `NETOMNIA_SERVICE_WORK_ORDER_*` value in
|
|
330
|
+
// `supplierCodes[]`. `detectKciKind()` recognises that prefix and
|
|
331
|
+
// returns REPAIR ahead of the envelope-field-based PROVIDE detection.
|
|
332
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
333
|
+
{
|
|
334
|
+
id: 'repair-update-service-scheduled',
|
|
327
335
|
reasonCode: 'UPDATE',
|
|
328
|
-
serviceOrderKind: '
|
|
336
|
+
serviceOrderKind: 'REPAIR',
|
|
329
337
|
supplierCodes: ['NETOMNIA_SERVICE_WORK_ORDER_SCHEDULED'],
|
|
330
338
|
yfEffect: {
|
|
331
339
|
kind: 'LOG_KCI_ONLY',
|
|
@@ -334,9 +342,9 @@ exports.KCI_EFFECT_ROWS = [
|
|
|
334
342
|
logAgainstOrder: true,
|
|
335
343
|
},
|
|
336
344
|
{
|
|
337
|
-
id: '
|
|
345
|
+
id: 'repair-update-service-en-route',
|
|
338
346
|
reasonCode: 'UPDATE',
|
|
339
|
-
serviceOrderKind: '
|
|
347
|
+
serviceOrderKind: 'REPAIR',
|
|
340
348
|
supplierCodes: ['NETOMNIA_SERVICE_WORK_ORDER_EN_ROUTE'],
|
|
341
349
|
yfEffect: {
|
|
342
350
|
kind: 'WO_FLOW_ACTION',
|
|
@@ -346,9 +354,9 @@ exports.KCI_EFFECT_ROWS = [
|
|
|
346
354
|
logAgainstOrder: true,
|
|
347
355
|
},
|
|
348
356
|
{
|
|
349
|
-
id: '
|
|
357
|
+
id: 'repair-update-service-in-progress',
|
|
350
358
|
reasonCode: 'UPDATE',
|
|
351
|
-
serviceOrderKind: '
|
|
359
|
+
serviceOrderKind: 'REPAIR',
|
|
352
360
|
supplierCodes: ['NETOMNIA_SERVICE_WORK_ORDER_IN_PROGRESS'],
|
|
353
361
|
yfEffect: {
|
|
354
362
|
kind: 'WO_FLOW_ACTION',
|
|
@@ -448,12 +456,38 @@ exports.KCI_EFFECT_ROWS = [
|
|
|
448
456
|
},
|
|
449
457
|
logAgainstOrder: true,
|
|
450
458
|
},
|
|
459
|
+
// SERVICE-WO cancel — same REPAIR-kind UPDATE-with-supplierCode pattern
|
|
460
|
+
// as the scheduled / en-route / in-progress rows above. NET enum value:
|
|
461
|
+
// NETOMNIA_SERVICE_WORK_ORDER_CANCELLED (netomnia-supplier-code.enum.ts).
|
|
462
|
+
// Dispatcher resolves the cancel semanticOp per WO.type —
|
|
463
|
+
// SERVICE → CancelServiceWorkOrderFlowSupplier.
|
|
464
|
+
{
|
|
465
|
+
id: 'repair-update-service-cancelled',
|
|
466
|
+
reasonCode: 'UPDATE',
|
|
467
|
+
serviceOrderKind: 'REPAIR',
|
|
468
|
+
supplierCodes: ['NETOMNIA_SERVICE_WORK_ORDER_CANCELLED'],
|
|
469
|
+
yfEffect: {
|
|
470
|
+
kind: 'WO_FLOW_ACTION',
|
|
471
|
+
semanticOp: 'cancel',
|
|
472
|
+
notes: 'SERVICE WO cancelled by supplier — advance YF SERVICE WO Accepted/Scheduled/EnRoute/InProgress → Cancelled via CancelServiceWorkOrderFlowSupplier. Also the inbound confirmation when YF tenant-initiated the cancel via /service-problem-cancellations; YF WO usually already at Cancelled, action is idempotent on the WO stage.',
|
|
473
|
+
},
|
|
474
|
+
logAgainstOrder: true,
|
|
475
|
+
},
|
|
451
476
|
];
|
|
452
477
|
/**
|
|
453
478
|
* Determine which serviceOrder kind the KCI is about by inspecting which
|
|
454
479
|
* sub-body field is populated.
|
|
455
480
|
*/
|
|
456
481
|
function detectKciKind(dto) {
|
|
482
|
+
var _a;
|
|
483
|
+
// REPAIR check first — SERVICE WO state changes use the NETOMNIA_SERVICE_
|
|
484
|
+
// WORK_ORDER_* supplier-code discriminator, regardless of which sub-body
|
|
485
|
+
// field is populated (it's typically `provideServiceOrder` because the
|
|
486
|
+
// SERVICE WO is a child of a PROVIDE order in the data model).
|
|
487
|
+
const codes = (_a = dto.supplierCodes) !== null && _a !== void 0 ? _a : [];
|
|
488
|
+
if (codes.some((c) => c.startsWith('NETOMNIA_SERVICE_WORK_ORDER_'))) {
|
|
489
|
+
return 'REPAIR';
|
|
490
|
+
}
|
|
457
491
|
if (dto.provideServiceOrder)
|
|
458
492
|
return 'PROVIDE';
|
|
459
493
|
if (dto.ceaseServiceOrder)
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
* invokes `dispatchOrderNotification` / `dispatchSMRNotification` after
|
|
28
28
|
* envelope-mapping; registered handlers are fanned out.
|
|
29
29
|
*/
|
|
30
|
-
import type { WholesaleProvider, CreateOrderOptions, CancellationReasonCode, ReserveAppointmentArgs, ListAppointmentsArgs, ScheduleServiceWorkOrderArgs, RescheduleServiceWorkOrderArgs, AmendAppointmentArgs, SyncWorkOrderToSupplierArgs, UpdateOrderExternalRefArgs } from '../interface';
|
|
30
|
+
import type { WholesaleProvider, CreateOrderOptions, CancellationReasonCode, CancelServiceWorkOrderArgs, ReserveAppointmentArgs, ListAppointmentsArgs, ScheduleServiceWorkOrderArgs, RescheduleServiceWorkOrderArgs, AmendAppointmentArgs, SyncWorkOrderToSupplierArgs, UpdateOrderExternalRefArgs } from '../interface';
|
|
31
31
|
import type { VMO2OrderNotification, VMO2SMRNotification } from '../types/vmo2';
|
|
32
32
|
import type { FibreCafeServiceAvailability200, FibreCafeAvailableAppointments200, FibreCafeReserveAppointment201, FibreCafeScheduleServiceWorkOrder201, FibreCafeRescheduleServiceWorkOrder200, FibreCafeOrderCreate202, FibreCafeOrderAmendAccept202, FibreCafeKciDto } from '../types/fibrecafe';
|
|
33
33
|
/**
|
|
@@ -60,6 +60,7 @@ export interface NetomniaProviderDeps<TPrincipal = unknown, TKci = FibreCafeKciD
|
|
|
60
60
|
amendOrder: (principal: TPrincipal, yfOrderId: string) => Promise<FibreCafeOrderCreate202 | null>;
|
|
61
61
|
cancelOrder: (yfOrderId: string, reasonCode: CancellationReasonCode) => Promise<FibreCafeOrderCreate202>;
|
|
62
62
|
ceaseOrder: (yfOrderId: string, serviceId: string) => Promise<FibreCafeOrderCreate202>;
|
|
63
|
+
cancelServiceWorkOrder: (args: CancelServiceWorkOrderArgs) => Promise<FibreCafeRescheduleServiceWorkOrder200>;
|
|
63
64
|
receiveKci: (principal: TPrincipal, dto: FibreCafeKciDto) => Promise<void>;
|
|
64
65
|
syncWorkOrderToSupplier: (args: SyncWorkOrderToSupplierArgs<TPrincipal>) => Promise<void>;
|
|
65
66
|
retrieveServiceIdByUprn: (uprn: number) => Promise<string | null>;
|
|
@@ -82,6 +83,7 @@ export declare class NetomniaProvider<TPrincipal = unknown> implements Wholesale
|
|
|
82
83
|
amendOrder(principal: TPrincipal, yfOrderId: string): Promise<FibreCafeOrderCreate202>;
|
|
83
84
|
cancelOrder(yfOrderId: string, reasonCode: CancellationReasonCode): Promise<FibreCafeOrderCreate202>;
|
|
84
85
|
ceaseOrder(yfOrderId: string, serviceId: string): Promise<FibreCafeOrderCreate202>;
|
|
86
|
+
cancelServiceWorkOrder(args: CancelServiceWorkOrderArgs): Promise<FibreCafeRescheduleServiceWorkOrder200>;
|
|
85
87
|
receiveKci(principal: TPrincipal, dto: FibreCafeKciDto): Promise<void>;
|
|
86
88
|
syncWorkOrderToSupplier(args: SyncWorkOrderToSupplierArgs<TPrincipal>): Promise<void>;
|
|
87
89
|
retrieveServiceIdByUprn(uprn: number): Promise<string>;
|
|
@@ -47,6 +47,9 @@ class NetomniaProvider {
|
|
|
47
47
|
ceaseOrder(yfOrderId, serviceId) {
|
|
48
48
|
return this.deps.ceaseOrder(yfOrderId, serviceId);
|
|
49
49
|
}
|
|
50
|
+
cancelServiceWorkOrder(args) {
|
|
51
|
+
return this.deps.cancelServiceWorkOrder(args);
|
|
52
|
+
}
|
|
50
53
|
receiveKci(principal, dto) {
|
|
51
54
|
return this.deps.receiveKci(principal, dto);
|
|
52
55
|
}
|
|
@@ -71,6 +71,7 @@ function buildDeps() {
|
|
|
71
71
|
amendOrder: {},
|
|
72
72
|
cancelOrder: {},
|
|
73
73
|
ceaseOrder: {},
|
|
74
|
+
cancelServiceWorkOrder: { workOrderId: 'WO-CANC-1', appointmentId: '' },
|
|
74
75
|
};
|
|
75
76
|
const deps = {
|
|
76
77
|
searchAddress: (uprn) => {
|
|
@@ -113,6 +114,10 @@ function buildDeps() {
|
|
|
113
114
|
log.push({ method: 'ceaseOrder', args: [yfOrderId, serviceId] });
|
|
114
115
|
return Promise.resolve(stubs.ceaseOrder);
|
|
115
116
|
},
|
|
117
|
+
cancelServiceWorkOrder: (args) => {
|
|
118
|
+
log.push({ method: 'cancelServiceWorkOrder', args: [args] });
|
|
119
|
+
return Promise.resolve(stubs.cancelServiceWorkOrder);
|
|
120
|
+
},
|
|
116
121
|
receiveKci: (principal, dto) => {
|
|
117
122
|
log.push({ method: 'receiveKci', args: [principal, dto] });
|
|
118
123
|
return Promise.resolve();
|
|
@@ -430,6 +430,21 @@ export interface FibreCafeModifyServiceOrder {
|
|
|
430
430
|
serviceOrderCancellationId?: string | number;
|
|
431
431
|
serviceOrderCancellationReference?: string;
|
|
432
432
|
}
|
|
433
|
+
/**
|
|
434
|
+
* Codes representing the reason for cancelling an inflight service problem
|
|
435
|
+
* (FibreCafe `POST /service-problem-cancellations` request body). Used on
|
|
436
|
+
* the OUTBOUND (YF → NET) side for the tenant-initiated SERVICE WO cancel.
|
|
437
|
+
*
|
|
438
|
+
* The corresponding INBOUND state-change (NET → YF) confirming the
|
|
439
|
+
* cancellation is emitted by NET as an `UPDATE` KCI with
|
|
440
|
+
* `supplierCodes: [NETOMNIA_SERVICE_WORK_ORDER_CANCELLED]` — see the
|
|
441
|
+
* `provide-update-service-cancelled` row in kci-effect-bridge.ts.
|
|
442
|
+
*
|
|
443
|
+
* Mirrors NET's `ServiceProblemCancellationReasonCode` enum verbatim.
|
|
444
|
+
*
|
|
445
|
+
* @see {@link https://docs.thefibrecafe.net/openapi/supplier/operation/handleCancelProblem/#!path=reasonCode&t=request | FibreCafe ServiceProblemCancellationReasonCode}
|
|
446
|
+
*/
|
|
447
|
+
export declare type FibreCafeServiceProblemCancellationReasonCode = 'ISSUE_RESOLVED' | 'CUSTOMER_NETWORK_ISSUE' | 'NO_LONGER_REQUIRED' | 'OTHER';
|
|
433
448
|
/** Unsolicited cease — supplier-initiated, surfaced via KCI. */
|
|
434
449
|
export interface FibreCafeUnsolicitedCeaseServiceOrder {
|
|
435
450
|
orderType?: FibreCafeCeaseOrderType;
|