@d19n/youfibre-odin-sdk 2.0.103-beta.5 → 2.0.103-beta.7
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 +33 -0
- package/dist/wholesale-provider/index.js +59 -0
- package/dist/wholesale-provider/interface.d.ts +112 -0
- package/dist/wholesale-provider/interface.js +2 -0
- package/dist/wholesale-provider/providers/netomnia-provider.d.ts +110 -0
- package/dist/wholesale-provider/providers/netomnia-provider.js +124 -0
- package/dist/wholesale-provider/test/netomnia-provider.spec.d.ts +1 -0
- package/dist/wholesale-provider/test/netomnia-provider.spec.js +352 -0
- package/dist/wholesale-provider/types/fibrecafe.d.ts +512 -0
- package/dist/wholesale-provider/types/fibrecafe.js +21 -0
- package/dist/wholesale-provider/types/vmo2.d.ts +390 -0
- package/dist/wholesale-provider/types/vmo2.js +2 -0
- package/dist/wholesale-provider/types/wholesale.d.ts +51 -0
- package/dist/wholesale-provider/types/wholesale.js +9 -0
- package/package.json +16 -3
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wholesale provider — subpath barrel.
|
|
3
|
+
*
|
|
4
|
+
* Consumers import from `@d19n/youfibre-odin-sdk/dist/wholesale-provider`:
|
|
5
|
+
*
|
|
6
|
+
* ```ts
|
|
7
|
+
* import {
|
|
8
|
+
* WholesaleProvider,
|
|
9
|
+
* NetomniaProvider,
|
|
10
|
+
* NetomniaProviderDeps,
|
|
11
|
+
* } from '@d19n/youfibre-odin-sdk/dist/wholesale-provider';
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* **Architecture (Path B / pass-through delegation):**
|
|
15
|
+
* - `WholesaleProvider` is a strategy-dispatchable interface. Method names
|
|
16
|
+
* align with VMO2 spec where it makes sense; args match existing NET
|
|
17
|
+
* module method signatures.
|
|
18
|
+
* - `NetomniaProvider implements WholesaleProvider` — pass-through to deps
|
|
19
|
+
* wired by modules to their existing NestJS-injected NET methods. Zero
|
|
20
|
+
* transformation at the boundary.
|
|
21
|
+
* - VMO2-shaped types (`./types/vmo2`) and FibreCafe-shaped types
|
|
22
|
+
* (`./types/fibrecafe`) are exported as **reference types** for future
|
|
23
|
+
* use (Vmo2Provider implementation, module DTO consolidation). They are
|
|
24
|
+
* NOT on the WholesaleProvider public surface in Phase 0.
|
|
25
|
+
*
|
|
26
|
+
* Linked: T-20260508-009 / T-20260508-010
|
|
27
|
+
*/
|
|
28
|
+
export type { WholesaleProvider, CreateOrderOptions, CancellationReasonCode, ReserveAppointmentArgs, ListAppointmentsArgs, ScheduleServiceWorkOrderArgs, RescheduleServiceWorkOrderArgs, AmendAppointmentArgs, SyncWorkOrderToSupplierArgs, UpdateOrderExternalRefArgs, } from './interface';
|
|
29
|
+
export type { WholesaleResult, WholesaleSyncResponse, WholesaleRejectionResponse, WholesaleRejectionMessage, WholesaleBUS, WholesaleSYS, ISO8601DateTime, ISODate, TransactionId, UPRN, UUID, SwitchOrderReference, } from './types/wholesale';
|
|
30
|
+
export { NetomniaProvider, AggregateNotificationError } from './providers/netomnia-provider';
|
|
31
|
+
export type { NetomniaProviderDeps } from './providers/netomnia-provider';
|
|
32
|
+
export type { VMO2OrderId, VMO2RequestId, VMO2AppointmentKey, VMO2PremiseId, VMO2OrderNotificationType, VMO2SMRNotificationType, VMO2NotificationEnvelope, VMO2OrderNotification, VMO2SMRNotification, VMO2InboundNotification, } from './types/vmo2';
|
|
33
|
+
export * from './types/fibrecafe';
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Wholesale provider — subpath barrel.
|
|
4
|
+
*
|
|
5
|
+
* Consumers import from `@d19n/youfibre-odin-sdk/dist/wholesale-provider`:
|
|
6
|
+
*
|
|
7
|
+
* ```ts
|
|
8
|
+
* import {
|
|
9
|
+
* WholesaleProvider,
|
|
10
|
+
* NetomniaProvider,
|
|
11
|
+
* NetomniaProviderDeps,
|
|
12
|
+
* } from '@d19n/youfibre-odin-sdk/dist/wholesale-provider';
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* **Architecture (Path B / pass-through delegation):**
|
|
16
|
+
* - `WholesaleProvider` is a strategy-dispatchable interface. Method names
|
|
17
|
+
* align with VMO2 spec where it makes sense; args match existing NET
|
|
18
|
+
* module method signatures.
|
|
19
|
+
* - `NetomniaProvider implements WholesaleProvider` — pass-through to deps
|
|
20
|
+
* wired by modules to their existing NestJS-injected NET methods. Zero
|
|
21
|
+
* transformation at the boundary.
|
|
22
|
+
* - VMO2-shaped types (`./types/vmo2`) and FibreCafe-shaped types
|
|
23
|
+
* (`./types/fibrecafe`) are exported as **reference types** for future
|
|
24
|
+
* use (Vmo2Provider implementation, module DTO consolidation). They are
|
|
25
|
+
* NOT on the WholesaleProvider public surface in Phase 0.
|
|
26
|
+
*
|
|
27
|
+
* Linked: T-20260508-009 / T-20260508-010
|
|
28
|
+
*/
|
|
29
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
30
|
+
if (k2 === undefined) k2 = k;
|
|
31
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
32
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
33
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
34
|
+
}
|
|
35
|
+
Object.defineProperty(o, k2, desc);
|
|
36
|
+
}) : (function(o, m, k, k2) {
|
|
37
|
+
if (k2 === undefined) k2 = k;
|
|
38
|
+
o[k2] = m[k];
|
|
39
|
+
}));
|
|
40
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
41
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
42
|
+
};
|
|
43
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
|
+
exports.AggregateNotificationError = exports.NetomniaProvider = void 0;
|
|
45
|
+
// ── Provider implementation ───────────────────────────────────────────
|
|
46
|
+
var netomnia_provider_1 = require("./providers/netomnia-provider");
|
|
47
|
+
Object.defineProperty(exports, "NetomniaProvider", { enumerable: true, get: function () { return netomnia_provider_1.NetomniaProvider; } });
|
|
48
|
+
Object.defineProperty(exports, "AggregateNotificationError", { enumerable: true, get: function () { return netomnia_provider_1.AggregateNotificationError; } });
|
|
49
|
+
// ── Reference types (re-exported — not on WholesaleProvider surface) ──
|
|
50
|
+
//
|
|
51
|
+
// FibreCafe wire-format types — useful for module-level DTO consolidation
|
|
52
|
+
// or building the VMO2 wire request inside a future Vmo2Provider. These
|
|
53
|
+
// are NOT used by NetomniaProviderDeps in Path B; the deps shape is YF-
|
|
54
|
+
// context-shaped.
|
|
55
|
+
//
|
|
56
|
+
// Re-exported with `export *` because TS 4.8 doesn't support `export type *`.
|
|
57
|
+
// All declarations in fibrecafe.ts are types/interfaces with no runtime
|
|
58
|
+
// exports, so `export *` re-exports them as types only (no JS code emit).
|
|
59
|
+
__exportStar(require("./types/fibrecafe"), exports);
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import type { VMO2OrderNotification, VMO2SMRNotification } from './types/vmo2';
|
|
2
|
+
/**
|
|
3
|
+
* Reasons a cancellation request can be made (NET wire-level enum value
|
|
4
|
+
* passed through to the FibreCafe gateway).
|
|
5
|
+
*/
|
|
6
|
+
export declare type CancellationReasonCode = string;
|
|
7
|
+
export interface CreateOrderOptions {
|
|
8
|
+
doNotCreateServiceAppointment?: boolean;
|
|
9
|
+
externalRefBrskFno?: string;
|
|
10
|
+
externalRefBrskIsp?: string;
|
|
11
|
+
/** Provider-specific extras — populated as needed per provider. */
|
|
12
|
+
[extra: string]: unknown;
|
|
13
|
+
}
|
|
14
|
+
export interface ReserveAppointmentArgs {
|
|
15
|
+
yfAppointmentId: string;
|
|
16
|
+
uprn: number;
|
|
17
|
+
startDateTime: string;
|
|
18
|
+
endDateTime: string;
|
|
19
|
+
/** 'PROVIDE' / 'REPAIR' / 'MODIFY' or supplier-specific. */
|
|
20
|
+
purpose: string;
|
|
21
|
+
yfOrderId: string;
|
|
22
|
+
woProperties: {
|
|
23
|
+
ServiceCallReason?: string;
|
|
24
|
+
WorkOrderExternalReference?: string;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
export interface ListAppointmentsArgs {
|
|
28
|
+
uprn: number;
|
|
29
|
+
/** ISO date the appointment search starts from. */
|
|
30
|
+
start: string;
|
|
31
|
+
appointmentPurpose: 'PROVIDE' | 'REPAIR';
|
|
32
|
+
}
|
|
33
|
+
export interface ScheduleServiceWorkOrderArgs {
|
|
34
|
+
yfWorkOrderId: string;
|
|
35
|
+
uprn: number;
|
|
36
|
+
startDateTime: string;
|
|
37
|
+
endDateTime: string;
|
|
38
|
+
yfOrderId: string;
|
|
39
|
+
properties: {
|
|
40
|
+
ServiceCallReason?: string;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export interface RescheduleServiceWorkOrderArgs {
|
|
44
|
+
yfWorkOrderId: string;
|
|
45
|
+
uprn: number;
|
|
46
|
+
startDateTime: string;
|
|
47
|
+
endDateTime: string;
|
|
48
|
+
yfOrderId: string;
|
|
49
|
+
}
|
|
50
|
+
export interface AmendAppointmentArgs {
|
|
51
|
+
yfOrderId: string;
|
|
52
|
+
yfWorkOrderId: string;
|
|
53
|
+
supplierAppointmentReference: string;
|
|
54
|
+
}
|
|
55
|
+
export interface SyncWorkOrderToSupplierArgs {
|
|
56
|
+
principal: unknown;
|
|
57
|
+
yfOrderId: string;
|
|
58
|
+
yfWorkOrderId: string;
|
|
59
|
+
yfChangeReason: {
|
|
60
|
+
id?: string;
|
|
61
|
+
externalId: string;
|
|
62
|
+
entity: string;
|
|
63
|
+
type: unknown;
|
|
64
|
+
properties: unknown;
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
export interface UpdateOrderExternalRefArgs {
|
|
68
|
+
oldYfId: string;
|
|
69
|
+
newYfId: string;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Capability-shaped interface to a wholesale supplier. Method NAMES align
|
|
73
|
+
* with VMO2 spec where it makes sense; ARGS match existing NET module
|
|
74
|
+
* method signatures. Each provider implementation translates these args
|
|
75
|
+
* into its supplier wire format internally.
|
|
76
|
+
*
|
|
77
|
+
* Returns are typed loosely — modules know the return shape via the dep
|
|
78
|
+
* function they wire in.
|
|
79
|
+
*/
|
|
80
|
+
export interface WholesaleProvider {
|
|
81
|
+
searchAddress(uprn: number): Promise<unknown>;
|
|
82
|
+
listAppointments(args: ListAppointmentsArgs): Promise<unknown>;
|
|
83
|
+
reserveAppointment(args: ReserveAppointmentArgs): Promise<unknown>;
|
|
84
|
+
scheduleServiceWorkOrder(args: ScheduleServiceWorkOrderArgs): Promise<unknown>;
|
|
85
|
+
rescheduleServiceWorkOrder(args: RescheduleServiceWorkOrderArgs): Promise<unknown>;
|
|
86
|
+
amendAppointment(args: AmendAppointmentArgs): Promise<unknown>;
|
|
87
|
+
createOrder(principal: unknown, orderId: string, options?: CreateOrderOptions): Promise<unknown>;
|
|
88
|
+
/** Tier-change CoS — wraps `createModifyOrderForYfOrder` style args. */
|
|
89
|
+
amendOrder(principal: unknown, yfOrderId: string): Promise<unknown>;
|
|
90
|
+
/** Pre-install cancel of an in-flight provide order. */
|
|
91
|
+
cancelOrder(yfOrderId: string, reasonCode: CancellationReasonCode): Promise<unknown>;
|
|
92
|
+
/** Active-customer cease (post-Active churn / OTS-losing). */
|
|
93
|
+
ceaseOrder(yfOrderId: string, serviceId: string): Promise<unknown>;
|
|
94
|
+
/** Inbound supplier KCI / notification handler. */
|
|
95
|
+
receiveKci(principal: unknown, dto: unknown): Promise<void>;
|
|
96
|
+
/** Outbound YF→supplier WO sync (cancel propagation, etc.). */
|
|
97
|
+
syncWorkOrderToSupplier(args: SyncWorkOrderToSupplierArgs): Promise<unknown>;
|
|
98
|
+
/** Inbound supplier→YF WO change application (post-receiveKci). */
|
|
99
|
+
syncWorkOrderFromSupplier(order: unknown, dto: unknown): Promise<unknown>;
|
|
100
|
+
retrieveServiceIdByUprn(uprn: number): Promise<string | null>;
|
|
101
|
+
updateOrderExternalRef(args: UpdateOrderExternalRefArgs): Promise<void>;
|
|
102
|
+
/**
|
|
103
|
+
* Register a typed handler for fanout of supplier order notifications.
|
|
104
|
+
* The webhook controller invokes `dispatchOrderNotification` on the
|
|
105
|
+
* provider after envelope-mapping; registered handlers are called in
|
|
106
|
+
* order with the normalized `VMO2OrderNotification` envelope (the
|
|
107
|
+
* SDK uses VMO2 envelope types as the cross-supplier normalization
|
|
108
|
+
* shape — easier to reason about + matches the upcoming VMO2 wire).
|
|
109
|
+
*/
|
|
110
|
+
onOrderNotification(handler: (n: VMO2OrderNotification) => Promise<void>): void;
|
|
111
|
+
onSMRNotification(handler: (n: VMO2SMRNotification) => Promise<void>): void;
|
|
112
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NetomniaProvider — concrete `WholesaleProvider` for the Netomnia
|
|
3
|
+
* wholesale platform (which exposes its tenant API via the FibreCafe
|
|
4
|
+
* gateway). Same instance handles all three Netomnia-routed `OrderProvider`
|
|
5
|
+
* values (NETOMNIA / NETOMNIA_LEGACY / BRSK).
|
|
6
|
+
*
|
|
7
|
+
* **Architecture (T-20260508-009/010 — Path B):**
|
|
8
|
+
*
|
|
9
|
+
* NetomniaProvider is a **strategy-dispatch pass-through**. Its public
|
|
10
|
+
* methods take YF-context args (matching existing NET module method
|
|
11
|
+
* signatures) and delegate 1:1 to deps. The deps are wired to the
|
|
12
|
+
* existing module-level `NetomniaProvider` / `NetomniaService` methods
|
|
13
|
+
* — zero behaviour change at the call site.
|
|
14
|
+
*
|
|
15
|
+
* Why a thin pass-through is enough:
|
|
16
|
+
* - The "abstraction value" provided is strategy dispatch — call sites
|
|
17
|
+
* do `factory.get(provider).createOrder(...)` instead of
|
|
18
|
+
* `if (isNetomnia) netomniaProvider.createNetomniaOrder(...)`.
|
|
19
|
+
* - DTO-building / HTTP / PE-log emit semantics already live in the
|
|
20
|
+
* existing NET module methods. Lifting them into the SDK (via deps
|
|
21
|
+
* that take FibreCafe DTOs and a built-in HTTP transport) was
|
|
22
|
+
* considered (Path A/C) but rejected for Phase 0 — that's a follow-up
|
|
23
|
+
* standardization step we can take if/when VMO2 alignment requires it.
|
|
24
|
+
*
|
|
25
|
+
* Inbound notification handling: provider stores registered handlers
|
|
26
|
+
* in-memory. The wholesale webhook controller (T-20260508-010 Step 1d)
|
|
27
|
+
* invokes `dispatchOrderNotification` / `dispatchSMRNotification` after
|
|
28
|
+
* envelope-mapping; registered handlers are fanned out.
|
|
29
|
+
*/
|
|
30
|
+
import type { WholesaleProvider, CreateOrderOptions, CancellationReasonCode, ReserveAppointmentArgs, ListAppointmentsArgs, ScheduleServiceWorkOrderArgs, RescheduleServiceWorkOrderArgs, AmendAppointmentArgs, SyncWorkOrderToSupplierArgs, UpdateOrderExternalRefArgs } from '../interface';
|
|
31
|
+
import type { VMO2OrderNotification, VMO2SMRNotification } from '../types/vmo2';
|
|
32
|
+
/**
|
|
33
|
+
* Function-bag of dependencies the NetomniaProvider delegates to.
|
|
34
|
+
*
|
|
35
|
+
* **Deps shape mirrors the WholesaleProvider interface 1:1.** Modules wire
|
|
36
|
+
* each property to their existing NestJS-injected NET service/provider
|
|
37
|
+
* method that already takes the equivalent YF-context args. The adapter
|
|
38
|
+
* boundary is intentionally narrow: zero transformation between dep input
|
|
39
|
+
* and the existing module method's input.
|
|
40
|
+
*
|
|
41
|
+
* Example (in a module's WholesaleModule.useFactory):
|
|
42
|
+
* ```typescript
|
|
43
|
+
* {
|
|
44
|
+
* createOrder: (p, id, opts) => existingNetomniaProvider.createNetomniaOrder(p, id, opts),
|
|
45
|
+
* cancelOrder: (id, reason) => existingNetomniaProvider.cancelProvideOrder(id, reason),
|
|
46
|
+
* amendOrder: (p, id) => existingNetomniaService.createModifyOrderForYfOrder(p, id),
|
|
47
|
+
* ...
|
|
48
|
+
* }
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export interface NetomniaProviderDeps {
|
|
52
|
+
searchAddress: (uprn: number) => Promise<unknown>;
|
|
53
|
+
listAppointments: (args: ListAppointmentsArgs) => Promise<unknown>;
|
|
54
|
+
reserveAppointment: (args: ReserveAppointmentArgs) => Promise<unknown>;
|
|
55
|
+
scheduleServiceWorkOrder: (args: ScheduleServiceWorkOrderArgs) => Promise<unknown>;
|
|
56
|
+
rescheduleServiceWorkOrder: (args: RescheduleServiceWorkOrderArgs) => Promise<unknown>;
|
|
57
|
+
amendAppointment: (args: AmendAppointmentArgs) => Promise<unknown>;
|
|
58
|
+
createOrder: (principal: unknown, orderId: string, options?: CreateOrderOptions) => Promise<unknown>;
|
|
59
|
+
amendOrder: (principal: unknown, yfOrderId: string) => Promise<unknown>;
|
|
60
|
+
cancelOrder: (yfOrderId: string, reasonCode: CancellationReasonCode) => Promise<unknown>;
|
|
61
|
+
ceaseOrder: (yfOrderId: string, serviceId: string) => Promise<unknown>;
|
|
62
|
+
receiveKci: (principal: unknown, dto: unknown) => Promise<void>;
|
|
63
|
+
syncWorkOrderToSupplier: (args: SyncWorkOrderToSupplierArgs) => Promise<unknown>;
|
|
64
|
+
syncWorkOrderFromSupplier: (order: unknown, dto: unknown) => Promise<unknown>;
|
|
65
|
+
retrieveServiceIdByUprn: (uprn: number) => Promise<string | null>;
|
|
66
|
+
updateOrderExternalRef: (args: UpdateOrderExternalRefArgs) => Promise<void>;
|
|
67
|
+
}
|
|
68
|
+
declare type OrderNotificationHandler = (n: VMO2OrderNotification) => Promise<void>;
|
|
69
|
+
declare type SMRNotificationHandler = (n: VMO2SMRNotification) => Promise<void>;
|
|
70
|
+
export declare class NetomniaProvider implements WholesaleProvider {
|
|
71
|
+
private readonly deps;
|
|
72
|
+
private readonly orderHandlers;
|
|
73
|
+
private readonly smrHandlers;
|
|
74
|
+
constructor(deps: NetomniaProviderDeps);
|
|
75
|
+
searchAddress(uprn: number): Promise<unknown>;
|
|
76
|
+
listAppointments(args: ListAppointmentsArgs): Promise<unknown>;
|
|
77
|
+
reserveAppointment(args: ReserveAppointmentArgs): Promise<unknown>;
|
|
78
|
+
scheduleServiceWorkOrder(args: ScheduleServiceWorkOrderArgs): Promise<unknown>;
|
|
79
|
+
rescheduleServiceWorkOrder(args: RescheduleServiceWorkOrderArgs): Promise<unknown>;
|
|
80
|
+
amendAppointment(args: AmendAppointmentArgs): Promise<unknown>;
|
|
81
|
+
createOrder(principal: unknown, orderId: string, options?: CreateOrderOptions): Promise<unknown>;
|
|
82
|
+
amendOrder(principal: unknown, yfOrderId: string): Promise<unknown>;
|
|
83
|
+
cancelOrder(yfOrderId: string, reasonCode: CancellationReasonCode): Promise<unknown>;
|
|
84
|
+
ceaseOrder(yfOrderId: string, serviceId: string): Promise<unknown>;
|
|
85
|
+
receiveKci(principal: unknown, dto: unknown): Promise<void>;
|
|
86
|
+
syncWorkOrderToSupplier(args: SyncWorkOrderToSupplierArgs): Promise<unknown>;
|
|
87
|
+
syncWorkOrderFromSupplier(order: unknown, dto: unknown): Promise<unknown>;
|
|
88
|
+
retrieveServiceIdByUprn(uprn: number): Promise<string>;
|
|
89
|
+
updateOrderExternalRef(args: UpdateOrderExternalRefArgs): Promise<void>;
|
|
90
|
+
onOrderNotification(handler: OrderNotificationHandler): void;
|
|
91
|
+
onSMRNotification(handler: SMRNotificationHandler): void;
|
|
92
|
+
/**
|
|
93
|
+
* Internal dispatch — invoked by the wholesale webhook controller after
|
|
94
|
+
* mapping a supplier KCI to a normalized `VMO2OrderNotification` envelope.
|
|
95
|
+
* Fans out to every registered handler in registration order. Handler
|
|
96
|
+
* errors are aggregated and re-thrown after all handlers complete.
|
|
97
|
+
*/
|
|
98
|
+
dispatchOrderNotification(n: VMO2OrderNotification): Promise<void>;
|
|
99
|
+
dispatchSMRNotification(n: VMO2SMRNotification): Promise<void>;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Aggregates errors thrown by handlers during notification dispatch so the
|
|
103
|
+
* webhook controller can surface every failure rather than masking later
|
|
104
|
+
* handlers with the first throw.
|
|
105
|
+
*/
|
|
106
|
+
export declare class AggregateNotificationError extends Error {
|
|
107
|
+
readonly errors: unknown[];
|
|
108
|
+
constructor(errors: unknown[]);
|
|
109
|
+
}
|
|
110
|
+
export {};
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.AggregateNotificationError = exports.NetomniaProvider = void 0;
|
|
13
|
+
class NetomniaProvider {
|
|
14
|
+
constructor(deps) {
|
|
15
|
+
this.deps = deps;
|
|
16
|
+
this.orderHandlers = [];
|
|
17
|
+
this.smrHandlers = [];
|
|
18
|
+
}
|
|
19
|
+
// ── Pass-through delegation ────────────────────────────────────────
|
|
20
|
+
searchAddress(uprn) {
|
|
21
|
+
return this.deps.searchAddress(uprn);
|
|
22
|
+
}
|
|
23
|
+
listAppointments(args) {
|
|
24
|
+
return this.deps.listAppointments(args);
|
|
25
|
+
}
|
|
26
|
+
reserveAppointment(args) {
|
|
27
|
+
return this.deps.reserveAppointment(args);
|
|
28
|
+
}
|
|
29
|
+
scheduleServiceWorkOrder(args) {
|
|
30
|
+
return this.deps.scheduleServiceWorkOrder(args);
|
|
31
|
+
}
|
|
32
|
+
rescheduleServiceWorkOrder(args) {
|
|
33
|
+
return this.deps.rescheduleServiceWorkOrder(args);
|
|
34
|
+
}
|
|
35
|
+
amendAppointment(args) {
|
|
36
|
+
return this.deps.amendAppointment(args);
|
|
37
|
+
}
|
|
38
|
+
createOrder(principal, orderId, options) {
|
|
39
|
+
return this.deps.createOrder(principal, orderId, options);
|
|
40
|
+
}
|
|
41
|
+
amendOrder(principal, yfOrderId) {
|
|
42
|
+
return this.deps.amendOrder(principal, yfOrderId);
|
|
43
|
+
}
|
|
44
|
+
cancelOrder(yfOrderId, reasonCode) {
|
|
45
|
+
return this.deps.cancelOrder(yfOrderId, reasonCode);
|
|
46
|
+
}
|
|
47
|
+
ceaseOrder(yfOrderId, serviceId) {
|
|
48
|
+
return this.deps.ceaseOrder(yfOrderId, serviceId);
|
|
49
|
+
}
|
|
50
|
+
receiveKci(principal, dto) {
|
|
51
|
+
return this.deps.receiveKci(principal, dto);
|
|
52
|
+
}
|
|
53
|
+
syncWorkOrderToSupplier(args) {
|
|
54
|
+
return this.deps.syncWorkOrderToSupplier(args);
|
|
55
|
+
}
|
|
56
|
+
syncWorkOrderFromSupplier(order, dto) {
|
|
57
|
+
return this.deps.syncWorkOrderFromSupplier(order, dto);
|
|
58
|
+
}
|
|
59
|
+
retrieveServiceIdByUprn(uprn) {
|
|
60
|
+
return this.deps.retrieveServiceIdByUprn(uprn);
|
|
61
|
+
}
|
|
62
|
+
updateOrderExternalRef(args) {
|
|
63
|
+
return this.deps.updateOrderExternalRef(args);
|
|
64
|
+
}
|
|
65
|
+
// ── Inbound notification subscription ─────────────────────────────
|
|
66
|
+
onOrderNotification(handler) {
|
|
67
|
+
this.orderHandlers.push(handler);
|
|
68
|
+
}
|
|
69
|
+
onSMRNotification(handler) {
|
|
70
|
+
this.smrHandlers.push(handler);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Internal dispatch — invoked by the wholesale webhook controller after
|
|
74
|
+
* mapping a supplier KCI to a normalized `VMO2OrderNotification` envelope.
|
|
75
|
+
* Fans out to every registered handler in registration order. Handler
|
|
76
|
+
* errors are aggregated and re-thrown after all handlers complete.
|
|
77
|
+
*/
|
|
78
|
+
dispatchOrderNotification(n) {
|
|
79
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
80
|
+
const errors = [];
|
|
81
|
+
for (const h of this.orderHandlers) {
|
|
82
|
+
try {
|
|
83
|
+
yield h(n);
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
errors.push(err);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (errors.length > 0) {
|
|
90
|
+
throw new AggregateNotificationError(errors);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
dispatchSMRNotification(n) {
|
|
95
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
96
|
+
const errors = [];
|
|
97
|
+
for (const h of this.smrHandlers) {
|
|
98
|
+
try {
|
|
99
|
+
yield h(n);
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
errors.push(err);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (errors.length > 0) {
|
|
106
|
+
throw new AggregateNotificationError(errors);
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
exports.NetomniaProvider = NetomniaProvider;
|
|
112
|
+
/**
|
|
113
|
+
* Aggregates errors thrown by handlers during notification dispatch so the
|
|
114
|
+
* webhook controller can surface every failure rather than masking later
|
|
115
|
+
* handlers with the first throw.
|
|
116
|
+
*/
|
|
117
|
+
class AggregateNotificationError extends Error {
|
|
118
|
+
constructor(errors) {
|
|
119
|
+
super(`${errors.length} handler error(s) during notification dispatch`);
|
|
120
|
+
this.errors = errors;
|
|
121
|
+
this.name = 'AggregateNotificationError';
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
exports.AggregateNotificationError = AggregateNotificationError;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|