@d19n/youfibre-odin-sdk 2.0.103-beta.5 → 2.0.103-beta.6
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 +26 -0
- package/dist/wholesale-provider/index.js +28 -0
- package/dist/wholesale-provider/interface.d.ts +65 -0
- package/dist/wholesale-provider/interface.js +2 -0
- package/dist/wholesale-provider/providers/netomnia-provider.d.ts +166 -0
- package/dist/wholesale-provider/providers/netomnia-provider.js +197 -0
- package/dist/wholesale-provider/test/netomnia-provider.spec.d.ts +1 -0
- package/dist/wholesale-provider/test/netomnia-provider.spec.js +249 -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,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wholesale provider — subpath barrel.
|
|
3
|
+
*
|
|
4
|
+
* Consumers import from `@d19n/youfibre-odin-sdk/wholesale-provider`:
|
|
5
|
+
*
|
|
6
|
+
* ```ts
|
|
7
|
+
* import {
|
|
8
|
+
* WholesaleProvider,
|
|
9
|
+
* NetomniaProvider,
|
|
10
|
+
* NetomniaProviderDeps,
|
|
11
|
+
* } from '@d19n/youfibre-odin-sdk/wholesale-provider';
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* This subpath exists so the wholesale provider abstraction does not collide
|
|
15
|
+
* with the auto-generated SDK surface (entities-v2 / accessors-v2 / etc.)
|
|
16
|
+
* that gets regenerated by `make regen`. Per `runner.ts:163-181`, the regen
|
|
17
|
+
* does NOT touch this directory.
|
|
18
|
+
*
|
|
19
|
+
* Linked: T-20260508-009
|
|
20
|
+
*/
|
|
21
|
+
export type { WholesaleProvider } from './interface';
|
|
22
|
+
export type { WholesaleResult, WholesaleSyncResponse, WholesaleRejectionResponse, WholesaleRejectionMessage, WholesaleBUS, WholesaleSYS, ISO8601DateTime, ISODate, TransactionId, UPRN, UUID, SwitchOrderReference, } from './types/wholesale';
|
|
23
|
+
export type { VMO2OrderId, VMO2RequestId, VMO2AppointmentKey, VMO2PremiseId, VMO2ParentServiceId, VMO2ChildServiceId, VMO2TechnicalProductId, VMO2InvoiceAccountNumber, VMO2NetworkType, VMO2DeploymentMethod, VMO2OrderIntent, VMO2OrderAction, VMO2OrderStatus, VMO2RequestType, VMO2RequestStatus, VMO2VisitType, VMO2AppointmentStatus, VMO2InstallFieldVisitRequired, VMO2SelfInstallAvailable, VMO2OrderServiceLevel, VMO2RequestServiceLevel, VMO2AdditionalWorkCode, VMO2SpecialRequestCode, VMO2CancellationReasonCode, VMO2IncidentReasonCode, VMO2ClosureCode, VMO2DelayCode, VMO2AddressFields, VMO2EndCustomerDetails, VMO2AddressLookupQuery, VMO2AddressLookupRequest, VMO2AddressLookupResult, VMO2DeploymentDetail, VMO2TechnicalProduct, VMO2NetworkCapability, VMO2PremiseRecord, VMO2JourneyType, VMO2AppointmentScope, VMO2AppointmentVisitFilter, VMO2ListAppointmentRequest, VMO2AvailableSlot, VMO2ListAppointmentResult, VMO2ReserveAppointmentRequest, VMO2ReservedSlot, VMO2ReserveAppointmentResult, VMO2AppointmentDetails, VMO2AmendAppointmentPatch, VMO2ConfirmAppointmentRequest, VMO2CreateOrderRequest, VMO2CreateOrderResult, VMO2AmendOrderPatch, VMO2OrderDetails, VMO2CreateIncidentRequest, VMO2CreateIncidentResult, VMO2AmendIncidentPatch, VMO2IncidentDetails, VMO2OrderNotificationType, VMO2SMRNotificationType, VMO2NotificationEnvelope, VMO2OrderNotification, VMO2SMRNotification, VMO2InboundNotification, } from './types/vmo2';
|
|
24
|
+
export type { FibreCafeAddressType, FibreCafeAppointmentPurpose, FibreCafeAvailabilityConstraintCode, FibreCafeInstallationType, FibreCafePortStatus, FibreCafeUnavailabilityReasonCode, FibreCafeTimeslotClassification, FibreCafeServiceCharacteristic, FibreCafeServiceProblemCharacteristic, FibreCafeEngineerTask, FibreCafeProvideOrderType, FibreCafeCeaseOrderType, FibreCafeModifyOrderType, FibreCafeUnsolicitedCeaseOrderType, FibreCafeOrderStatus, FibreCafeUnsolicitedCeaseOrderStatus, FibreCafeUnsolicitedCeaseReason, FibreCafeKciReasonCode, FibreCafeKciProblemCode, FibreCafeResolutionCode, FibreCafeGatewayErrorCode, FibreCafeAddressIdentifier, FibreCafeAddressIdentifierWithAdditional, FibreCafeSubAddress, FibreCafeAddress, FibreCafeAddressAttribute, FibreCafeAddressTenant, FibreCafeContact, FibreCafeTimeslot, FibreCafeReserveTimeslot, FibreCafeServiceCharacteristicObject, FibreCafeServiceProblemCharacteristicObject, FibreCafeServiceCharacteristicAvailability, FibreCafeServiceSpecification, FibreCafeServiceSpecificationAvailability, FibreCafeServiceOrderItem, FibreCafeSupplierNote, FibreCafeResolutionDetails, FibreCafeGatewayError, FibreCafeAvailabilityConstraint, FibreCafeUnavailabilityReason, FibreCafeLineCharacteristic, FibreCafeOntPort, FibreCafeOnt, FibreCafeExistingLine, FibreCafeSiteInformation, FibreCafeServiceAvailabilityQuery, FibreCafeServiceAvailability200, FibreCafeAddressLookupQuery, FibreCafeAddressLookup200, FibreCafeAvailableAppointmentsQuery, FibreCafeAvailableAppointments200, FibreCafeReserveAppointmentDto, FibreCafeReserveAppointment201, FibreCafeServiceWorkOrderAddress, FibreCafeServiceWorkOrderTimeslot, FibreCafeScheduleServiceWorkOrderDto, FibreCafeRescheduleServiceWorkOrderDto, FibreCafeScheduleServiceWorkOrder201, FibreCafeRescheduleServiceWorkOrder200, FibreCafeProvideServiceOrderDto, FibreCafeCeaseServiceOrderDto, FibreCafeModifyServiceOrderDto, FibreCafeOrderCreateDto, FibreCafeOrderCreate202, FibreCafeServiceOrderCancellationDto, FibreCafeProvideServiceOrderAmendmentDto, FibreCafeOrderAmendAccept202, FibreCafeProvideServiceOrder, FibreCafeCeaseServiceOrder, FibreCafeModifyServiceOrder, FibreCafeUnsolicitedCeaseServiceOrder, FibreCafeKciDto, FibreCafeServiceProblemCreateDto, FibreCafeServiceProblemCreate202, FibreCafeServiceProblemAmendmentDto, FibreCafeServiceProblemCancellationDto, FibreCafeServiceProblemDetails, } from './types/fibrecafe';
|
|
25
|
+
export { NetomniaProvider, AggregateNotificationError, NotImplementedError, } from './providers/netomnia-provider';
|
|
26
|
+
export type { NetomniaProviderDeps } from './providers/netomnia-provider';
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Wholesale provider — subpath barrel.
|
|
4
|
+
*
|
|
5
|
+
* Consumers import from `@d19n/youfibre-odin-sdk/wholesale-provider`:
|
|
6
|
+
*
|
|
7
|
+
* ```ts
|
|
8
|
+
* import {
|
|
9
|
+
* WholesaleProvider,
|
|
10
|
+
* NetomniaProvider,
|
|
11
|
+
* NetomniaProviderDeps,
|
|
12
|
+
* } from '@d19n/youfibre-odin-sdk/wholesale-provider';
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* This subpath exists so the wholesale provider abstraction does not collide
|
|
16
|
+
* with the auto-generated SDK surface (entities-v2 / accessors-v2 / etc.)
|
|
17
|
+
* that gets regenerated by `make regen`. Per `runner.ts:163-181`, the regen
|
|
18
|
+
* does NOT touch this directory.
|
|
19
|
+
*
|
|
20
|
+
* Linked: T-20260508-009
|
|
21
|
+
*/
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.NotImplementedError = exports.AggregateNotificationError = exports.NetomniaProvider = void 0;
|
|
24
|
+
// Provider implementations
|
|
25
|
+
var netomnia_provider_1 = require("./providers/netomnia-provider");
|
|
26
|
+
Object.defineProperty(exports, "NetomniaProvider", { enumerable: true, get: function () { return netomnia_provider_1.NetomniaProvider; } });
|
|
27
|
+
Object.defineProperty(exports, "AggregateNotificationError", { enumerable: true, get: function () { return netomnia_provider_1.AggregateNotificationError; } });
|
|
28
|
+
Object.defineProperty(exports, "NotImplementedError", { enumerable: true, get: function () { return netomnia_provider_1.NotImplementedError; } });
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WholesaleProvider — the typed contract YouFibre code uses to consume any
|
|
3
|
+
* wholesale gateway (FibreCafe-fronted suppliers like Netomnia / Brsk /
|
|
4
|
+
* Trooli today, VMO2 / Nutmeg from July 2026, others in future).
|
|
5
|
+
*
|
|
6
|
+
* Capability-shaped, not surface-shaped — callers ask "reserve an
|
|
7
|
+
* appointment", not "POST /ge/v1/appointments/reservations". Implementations
|
|
8
|
+
* map capability calls onto the per-supplier wire format.
|
|
9
|
+
*
|
|
10
|
+
* Lifted under T-20260508-009 from
|
|
11
|
+
* agent-os/knowledge/integrations/vmo2-nutmeg/vm-provider-interface.ts
|
|
12
|
+
*
|
|
13
|
+
* Every method returns a `WholesaleResult<T>` discriminated by `status`.
|
|
14
|
+
* Errors (4xx/5xx) materialise as `WholesaleRejectionResponse`. Transport /
|
|
15
|
+
* OAuth / idempotency / retry / rate-limiting are encapsulated by the
|
|
16
|
+
* implementation.
|
|
17
|
+
*
|
|
18
|
+
* Method names are supplier-agnostic. Argument/result types are currently
|
|
19
|
+
* VMO2-shaped (since VMO2 is the first concrete shape modelled). Per-supplier
|
|
20
|
+
* implementations adapt their wire format to/from these shapes — see
|
|
21
|
+
* `comparison-fibrecafe-vs-vmo2.md` for the field-level mapping.
|
|
22
|
+
*/
|
|
23
|
+
import type { WholesaleResult } from './types/wholesale';
|
|
24
|
+
import type { VMO2AddressLookupRequest, VMO2AddressLookupResult, VMO2ListAppointmentRequest, VMO2ListAppointmentResult, VMO2ReserveAppointmentRequest, VMO2ReserveAppointmentResult, VMO2ConfirmAppointmentRequest, VMO2AppointmentDetails, VMO2AppointmentKey, VMO2AmendAppointmentPatch, VMO2CreateOrderRequest, VMO2CreateOrderResult, VMO2AmendOrderPatch, VMO2OrderDetails, VMO2OrderId, VMO2CancellationReasonCode, VMO2PremiseId, VMO2CreateIncidentRequest, VMO2CreateIncidentResult, VMO2AmendIncidentPatch, VMO2IncidentDetails, VMO2RequestId, VMO2OrderNotification, VMO2SMRNotification } from './types/vmo2';
|
|
25
|
+
import type { ISODate, SwitchOrderReference } from './types/wholesale';
|
|
26
|
+
export interface WholesaleProvider {
|
|
27
|
+
searchAddress(req: VMO2AddressLookupRequest): Promise<WholesaleResult<VMO2AddressLookupResult>>;
|
|
28
|
+
listAppointments(req: VMO2ListAppointmentRequest): Promise<WholesaleResult<VMO2ListAppointmentResult>>;
|
|
29
|
+
reserveAppointment(req: VMO2ReserveAppointmentRequest): Promise<WholesaleResult<VMO2ReserveAppointmentResult>>;
|
|
30
|
+
confirmAppointment(req: VMO2ConfirmAppointmentRequest): Promise<WholesaleResult<{
|
|
31
|
+
appointmentKey: VMO2AppointmentKey;
|
|
32
|
+
}>>;
|
|
33
|
+
getAppointment(key: VMO2AppointmentKey): Promise<WholesaleResult<VMO2AppointmentDetails>>;
|
|
34
|
+
amendAppointment(key: VMO2AppointmentKey, patch: VMO2AmendAppointmentPatch): Promise<WholesaleResult<{
|
|
35
|
+
appointmentKey: VMO2AppointmentKey;
|
|
36
|
+
}>>;
|
|
37
|
+
cancelAppointment(key: VMO2AppointmentKey): Promise<WholesaleResult<{
|
|
38
|
+
appointmentKey: VMO2AppointmentKey;
|
|
39
|
+
}>>;
|
|
40
|
+
createOrder(req: VMO2CreateOrderRequest): Promise<WholesaleResult<VMO2CreateOrderResult>>;
|
|
41
|
+
amendOrder(orderId: VMO2OrderId, patch: VMO2AmendOrderPatch): Promise<WholesaleResult<{
|
|
42
|
+
orderId: VMO2OrderId;
|
|
43
|
+
}>>;
|
|
44
|
+
cancelOrder(orderId: VMO2OrderId, reason?: VMO2CancellationReasonCode): Promise<WholesaleResult<{
|
|
45
|
+
orderId: VMO2OrderId;
|
|
46
|
+
}>>;
|
|
47
|
+
getOrder(orderId: VMO2OrderId, opts?: {
|
|
48
|
+
displaySummary?: boolean;
|
|
49
|
+
}): Promise<WholesaleResult<VMO2OrderDetails>>;
|
|
50
|
+
unsolicitedCease(req: {
|
|
51
|
+
premiseId: VMO2PremiseId;
|
|
52
|
+
switchOrderReference?: SwitchOrderReference;
|
|
53
|
+
requestedOrderCompletionDate: ISODate;
|
|
54
|
+
}): Promise<WholesaleResult<VMO2CreateOrderResult>>;
|
|
55
|
+
createIncident(req: VMO2CreateIncidentRequest): Promise<WholesaleResult<VMO2CreateIncidentResult>>;
|
|
56
|
+
amendIncident(requestId: VMO2RequestId, patch: VMO2AmendIncidentPatch): Promise<WholesaleResult<{
|
|
57
|
+
requestId: VMO2RequestId;
|
|
58
|
+
}>>;
|
|
59
|
+
cancelIncident(requestId: VMO2RequestId): Promise<WholesaleResult<{
|
|
60
|
+
requestId: VMO2RequestId;
|
|
61
|
+
}>>;
|
|
62
|
+
getIncident(requestId: VMO2RequestId): Promise<WholesaleResult<VMO2IncidentDetails>>;
|
|
63
|
+
onOrderNotification(handler: (n: VMO2OrderNotification) => Promise<void>): void;
|
|
64
|
+
onSMRNotification(handler: (n: VMO2SMRNotification) => Promise<void>): void;
|
|
65
|
+
}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NetomniaProvider — concrete `WholesaleProvider` implementation that
|
|
3
|
+
* routes capability calls to the Netomnia wholesale platform. Netomnia
|
|
4
|
+
* exposes its tenant API via the FibreCafe gateway, so this provider's
|
|
5
|
+
* dependency function-bag is **FibreCafe-shaped** (matches the wire +
|
|
6
|
+
* existing NET module function signatures).
|
|
7
|
+
*
|
|
8
|
+
* **Architecture (T-20260508-009 — confirmed with Frank 2026-05-08):**
|
|
9
|
+
*
|
|
10
|
+
* 1. `WholesaleProvider` interface is **VMO2-shaped**. It's the single
|
|
11
|
+
* abstraction call sites speak — same vocabulary regardless of supplier.
|
|
12
|
+
* 2. `NetomniaProvider` implements that interface. Its **public methods
|
|
13
|
+
* accept VMO2-shaped requests** (per the abstraction contract).
|
|
14
|
+
* 3. `NetomniaProviderDeps` is **FibreCafe-shaped**. Modules wire their
|
|
15
|
+
* existing NestJS-injected NET clients in directly — zero
|
|
16
|
+
* transformation at the dep boundary.
|
|
17
|
+
* 4. **Mapping VMO2 ↔ FibreCafe happens INSIDE each NetomniaProvider
|
|
18
|
+
* method.** VMO2 in → map to FibreCafe → call dep → FibreCafe response
|
|
19
|
+
* → map to VMO2 → return. The single place supplier shape differences
|
|
20
|
+
* are reconciled.
|
|
21
|
+
*
|
|
22
|
+
* Phase 0 scope: mapping bodies are **stubs** (throw NotImplementedError
|
|
23
|
+
* for non-trivial mappings). T-20260508-010 will fill in the real mapping
|
|
24
|
+
* logic alongside the call-site refactor — at that point the call sites
|
|
25
|
+
* actually exercise these methods, so mapping correctness can be
|
|
26
|
+
* validated with live behavior.
|
|
27
|
+
*
|
|
28
|
+
* The same instance handles all three Netomnia-routed `OrderProvider`
|
|
29
|
+
* values (NETOMNIA / NETOMNIA_LEGACY / BRSK) — they share the same NET
|
|
30
|
+
* wholesale platform.
|
|
31
|
+
*
|
|
32
|
+
* Inbound notification handling: provider stores registered handlers
|
|
33
|
+
* in-memory. A future webhook controller (T-20260508-010) invokes
|
|
34
|
+
* `dispatchOrderNotification` / `dispatchSMRNotification` to fan out.
|
|
35
|
+
*/
|
|
36
|
+
import type { WholesaleProvider } from '../interface';
|
|
37
|
+
import type { WholesaleResult } from '../types/wholesale';
|
|
38
|
+
import type { ISODate, SwitchOrderReference } from '../types/wholesale';
|
|
39
|
+
import type { VMO2AddressLookupRequest, VMO2AddressLookupResult, VMO2ListAppointmentRequest, VMO2ListAppointmentResult, VMO2ReserveAppointmentRequest, VMO2ReserveAppointmentResult, VMO2ConfirmAppointmentRequest, VMO2AppointmentDetails, VMO2AppointmentKey, VMO2AmendAppointmentPatch, VMO2CreateOrderRequest, VMO2CreateOrderResult, VMO2AmendOrderPatch, VMO2OrderDetails, VMO2OrderId, VMO2CancellationReasonCode, VMO2PremiseId, VMO2CreateIncidentRequest, VMO2CreateIncidentResult, VMO2AmendIncidentPatch, VMO2IncidentDetails, VMO2RequestId, VMO2OrderNotification, VMO2SMRNotification } from '../types/vmo2';
|
|
40
|
+
import type { FibreCafeServiceAvailabilityQuery, FibreCafeServiceAvailability200, FibreCafeAvailableAppointmentsQuery, FibreCafeAvailableAppointments200, FibreCafeReserveAppointmentDto, FibreCafeReserveAppointment201, FibreCafeOrderCreateDto, FibreCafeOrderCreate202, FibreCafeProvideServiceOrderAmendmentDto, FibreCafeOrderAmendAccept202, FibreCafeServiceOrderCancellationDto, FibreCafeServiceProblemCreateDto, FibreCafeServiceProblemCreate202, FibreCafeServiceProblemAmendmentDto, FibreCafeServiceProblemCancellationDto, FibreCafeServiceProblemDetails, FibreCafeProvideServiceOrder } from '../types/fibrecafe';
|
|
41
|
+
/**
|
|
42
|
+
* Function-bag of FibreCafe-shaped dependencies that NetomniaProvider
|
|
43
|
+
* delegates to. Modules wire each property to their existing typed NET
|
|
44
|
+
* client method — typically these come from NestJS-injected services
|
|
45
|
+
* (`netomniaProvider.getServiceAvailability` / `.createProvideOrder` /
|
|
46
|
+
* etc.). The adapter boundary is intentionally narrow so refactoring to
|
|
47
|
+
* use NetomniaProvider doesn't change runtime behavior or PE-log emit
|
|
48
|
+
* semantics — those still live in the wrapped function bodies.
|
|
49
|
+
*
|
|
50
|
+
* Where a FibreCafe endpoint has no current YF caller (e.g. service-problems),
|
|
51
|
+
* the dep is still typed; the wired function may be a NotImplementedError
|
|
52
|
+
* thrower until that endpoint is built out.
|
|
53
|
+
*/
|
|
54
|
+
export interface NetomniaProviderDeps {
|
|
55
|
+
getServiceAvailability: (query: FibreCafeServiceAvailabilityQuery) => Promise<WholesaleResult<FibreCafeServiceAvailability200>>;
|
|
56
|
+
getAvailableAppointments: (query: FibreCafeAvailableAppointmentsQuery) => Promise<WholesaleResult<FibreCafeAvailableAppointments200>>;
|
|
57
|
+
reserveAppointment: (dto: FibreCafeReserveAppointmentDto) => Promise<WholesaleResult<FibreCafeReserveAppointment201>>;
|
|
58
|
+
/**
|
|
59
|
+
* FibreCafe doesn't expose a separate confirm endpoint — confirmation is
|
|
60
|
+
* implicit at order placement. NetomniaProvider's confirmAppointment is a
|
|
61
|
+
* no-op pass-through; this dep is provided for symmetry and future use.
|
|
62
|
+
*/
|
|
63
|
+
confirmAppointment?: (appointmentId: string) => Promise<WholesaleResult<{
|
|
64
|
+
appointmentId: string;
|
|
65
|
+
}>>;
|
|
66
|
+
/**
|
|
67
|
+
* FibreCafe retrieves appointment via the parent order — this dep wraps
|
|
68
|
+
* the existing module logic that reconstructs appointment state from the
|
|
69
|
+
* locally-cached NET WorkOrder mirror.
|
|
70
|
+
*/
|
|
71
|
+
getAppointment?: (appointmentId: string) => Promise<WholesaleResult<FibreCafeReserveAppointment201>>;
|
|
72
|
+
/** Reappoint flow — same endpoint as reserve with rescheduleType discriminator. */
|
|
73
|
+
amendAppointment?: (dto: FibreCafeReserveAppointmentDto) => Promise<WholesaleResult<FibreCafeReserveAppointment201>>;
|
|
74
|
+
/** WO-level cancellation propagating to NET-side appointment. */
|
|
75
|
+
cancelAppointment?: (appointmentId: string, reasonCode?: string) => Promise<WholesaleResult<{
|
|
76
|
+
appointmentId: string;
|
|
77
|
+
}>>;
|
|
78
|
+
createOrder: (dto: FibreCafeOrderCreateDto) => Promise<WholesaleResult<FibreCafeOrderCreate202>>;
|
|
79
|
+
amendOrder: (dto: FibreCafeProvideServiceOrderAmendmentDto) => Promise<WholesaleResult<FibreCafeOrderAmendAccept202>>;
|
|
80
|
+
cancelOrder: (dto: FibreCafeServiceOrderCancellationDto) => Promise<WholesaleResult<{
|
|
81
|
+
cancellationRequestId: string;
|
|
82
|
+
}>>;
|
|
83
|
+
getOrder: (orderId: string) => Promise<WholesaleResult<FibreCafeProvideServiceOrder>>;
|
|
84
|
+
createIncident?: (dto: FibreCafeServiceProblemCreateDto) => Promise<WholesaleResult<FibreCafeServiceProblemCreate202>>;
|
|
85
|
+
amendIncident?: (dto: FibreCafeServiceProblemAmendmentDto) => Promise<WholesaleResult<{
|
|
86
|
+
amendmentId: string;
|
|
87
|
+
}>>;
|
|
88
|
+
cancelIncident?: (dto: FibreCafeServiceProblemCancellationDto) => Promise<WholesaleResult<{
|
|
89
|
+
cancellationId: string;
|
|
90
|
+
}>>;
|
|
91
|
+
getIncident?: (serviceProblemId: string) => Promise<WholesaleResult<FibreCafeServiceProblemDetails>>;
|
|
92
|
+
}
|
|
93
|
+
declare type OrderNotificationHandler = (n: VMO2OrderNotification) => Promise<void>;
|
|
94
|
+
declare type SMRNotificationHandler = (n: VMO2SMRNotification) => Promise<void>;
|
|
95
|
+
/**
|
|
96
|
+
* Sentinel error surfaced by Phase 0 stub mapping bodies. T-20260508-010
|
|
97
|
+
* fills in real bodies; until then any call to these methods at runtime
|
|
98
|
+
* throws this. Tests verify the *delegation* path works for methods whose
|
|
99
|
+
* mapping is trivial enough to ship in Phase 0.
|
|
100
|
+
*/
|
|
101
|
+
export declare class NotImplementedError extends Error {
|
|
102
|
+
readonly method: string;
|
|
103
|
+
constructor(method: string);
|
|
104
|
+
}
|
|
105
|
+
export declare class NetomniaProvider implements WholesaleProvider {
|
|
106
|
+
private readonly deps;
|
|
107
|
+
private readonly orderHandlers;
|
|
108
|
+
private readonly smrHandlers;
|
|
109
|
+
constructor(deps: NetomniaProviderDeps);
|
|
110
|
+
searchAddress(_req: VMO2AddressLookupRequest): Promise<WholesaleResult<VMO2AddressLookupResult>>;
|
|
111
|
+
listAppointments(_req: VMO2ListAppointmentRequest): Promise<WholesaleResult<VMO2ListAppointmentResult>>;
|
|
112
|
+
reserveAppointment(_req: VMO2ReserveAppointmentRequest): Promise<WholesaleResult<VMO2ReserveAppointmentResult>>;
|
|
113
|
+
confirmAppointment(_req: VMO2ConfirmAppointmentRequest): Promise<WholesaleResult<{
|
|
114
|
+
appointmentKey: VMO2AppointmentKey;
|
|
115
|
+
}>>;
|
|
116
|
+
getAppointment(_key: VMO2AppointmentKey): Promise<WholesaleResult<VMO2AppointmentDetails>>;
|
|
117
|
+
amendAppointment(_key: VMO2AppointmentKey, _patch: VMO2AmendAppointmentPatch): Promise<WholesaleResult<{
|
|
118
|
+
appointmentKey: VMO2AppointmentKey;
|
|
119
|
+
}>>;
|
|
120
|
+
cancelAppointment(_key: VMO2AppointmentKey): Promise<WholesaleResult<{
|
|
121
|
+
appointmentKey: VMO2AppointmentKey;
|
|
122
|
+
}>>;
|
|
123
|
+
createOrder(_req: VMO2CreateOrderRequest): Promise<WholesaleResult<VMO2CreateOrderResult>>;
|
|
124
|
+
amendOrder(_orderId: VMO2OrderId, _patch: VMO2AmendOrderPatch): Promise<WholesaleResult<{
|
|
125
|
+
orderId: VMO2OrderId;
|
|
126
|
+
}>>;
|
|
127
|
+
cancelOrder(_orderId: VMO2OrderId, _reason?: VMO2CancellationReasonCode): Promise<WholesaleResult<{
|
|
128
|
+
orderId: VMO2OrderId;
|
|
129
|
+
}>>;
|
|
130
|
+
getOrder(_orderId: VMO2OrderId, _opts?: {
|
|
131
|
+
displaySummary?: boolean;
|
|
132
|
+
}): Promise<WholesaleResult<VMO2OrderDetails>>;
|
|
133
|
+
unsolicitedCease(_req: {
|
|
134
|
+
premiseId: VMO2PremiseId;
|
|
135
|
+
switchOrderReference?: SwitchOrderReference;
|
|
136
|
+
requestedOrderCompletionDate: ISODate;
|
|
137
|
+
}): Promise<WholesaleResult<VMO2CreateOrderResult>>;
|
|
138
|
+
createIncident(_req: VMO2CreateIncidentRequest): Promise<WholesaleResult<VMO2CreateIncidentResult>>;
|
|
139
|
+
amendIncident(_requestId: VMO2RequestId, _patch: VMO2AmendIncidentPatch): Promise<WholesaleResult<{
|
|
140
|
+
requestId: VMO2RequestId;
|
|
141
|
+
}>>;
|
|
142
|
+
cancelIncident(_requestId: VMO2RequestId): Promise<WholesaleResult<{
|
|
143
|
+
requestId: VMO2RequestId;
|
|
144
|
+
}>>;
|
|
145
|
+
getIncident(_requestId: VMO2RequestId): Promise<WholesaleResult<VMO2IncidentDetails>>;
|
|
146
|
+
onOrderNotification(handler: OrderNotificationHandler): void;
|
|
147
|
+
onSMRNotification(handler: SMRNotificationHandler): void;
|
|
148
|
+
/**
|
|
149
|
+
* Internal dispatch — invoked by the webhook controller (T-20260508-010)
|
|
150
|
+
* after mapping a FibreCafe KCI to a VMO2OrderNotification envelope. Fans
|
|
151
|
+
* out to every registered handler in registration order. Handler errors
|
|
152
|
+
* are aggregated and re-thrown after all handlers complete.
|
|
153
|
+
*/
|
|
154
|
+
dispatchOrderNotification(n: VMO2OrderNotification): Promise<void>;
|
|
155
|
+
dispatchSMRNotification(n: VMO2SMRNotification): Promise<void>;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Aggregates errors thrown by handlers during notification dispatch so the
|
|
159
|
+
* webhook controller can surface every failure rather than masking later
|
|
160
|
+
* handlers with the first throw.
|
|
161
|
+
*/
|
|
162
|
+
export declare class AggregateNotificationError extends Error {
|
|
163
|
+
readonly errors: unknown[];
|
|
164
|
+
constructor(errors: unknown[]);
|
|
165
|
+
}
|
|
166
|
+
export {};
|
|
@@ -0,0 +1,197 @@
|
|
|
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 = exports.NotImplementedError = void 0;
|
|
13
|
+
/**
|
|
14
|
+
* Sentinel error surfaced by Phase 0 stub mapping bodies. T-20260508-010
|
|
15
|
+
* fills in real bodies; until then any call to these methods at runtime
|
|
16
|
+
* throws this. Tests verify the *delegation* path works for methods whose
|
|
17
|
+
* mapping is trivial enough to ship in Phase 0.
|
|
18
|
+
*/
|
|
19
|
+
class NotImplementedError extends Error {
|
|
20
|
+
constructor(method) {
|
|
21
|
+
super(`NetomniaProvider.${method} mapping not yet implemented (Phase 0 stub) — ` +
|
|
22
|
+
`lands in T-20260508-010 alongside call-site refactor.`);
|
|
23
|
+
this.method = method;
|
|
24
|
+
this.name = 'NotImplementedError';
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.NotImplementedError = NotImplementedError;
|
|
28
|
+
class NetomniaProvider {
|
|
29
|
+
constructor(deps) {
|
|
30
|
+
this.deps = deps;
|
|
31
|
+
this.orderHandlers = [];
|
|
32
|
+
this.smrHandlers = [];
|
|
33
|
+
}
|
|
34
|
+
// ──────────────────────────────────────────────────────────────────
|
|
35
|
+
// Address / availability
|
|
36
|
+
// ──────────────────────────────────────────────────────────────────
|
|
37
|
+
searchAddress(_req) {
|
|
38
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
39
|
+
// Phase 0 stub: the VMO2→FibreCafe mapping for searchAddress is
|
|
40
|
+
// non-trivial (VMO2 returns premise + capability detail; FibreCafe
|
|
41
|
+
// returns address + service-spec). Real mapping lands in T-010 when
|
|
42
|
+
// call sites convert. Until then this throws to surface accidental
|
|
43
|
+
// call-site exercise.
|
|
44
|
+
throw new NotImplementedError('searchAddress');
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
// ──────────────────────────────────────────────────────────────────
|
|
48
|
+
// Appointments
|
|
49
|
+
// ──────────────────────────────────────────────────────────────────
|
|
50
|
+
listAppointments(_req) {
|
|
51
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
52
|
+
throw new NotImplementedError('listAppointments');
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
reserveAppointment(_req) {
|
|
56
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
57
|
+
throw new NotImplementedError('reserveAppointment');
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
confirmAppointment(_req) {
|
|
61
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
62
|
+
// FibreCafe has no separate confirm step — would be a no-op for NET
|
|
63
|
+
// path. Stubbed until T-010 validates the assumption end-to-end.
|
|
64
|
+
throw new NotImplementedError('confirmAppointment');
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
getAppointment(_key) {
|
|
68
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
69
|
+
throw new NotImplementedError('getAppointment');
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
amendAppointment(_key, _patch) {
|
|
73
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
74
|
+
throw new NotImplementedError('amendAppointment');
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
cancelAppointment(_key) {
|
|
78
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
79
|
+
throw new NotImplementedError('cancelAppointment');
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
// ──────────────────────────────────────────────────────────────────
|
|
83
|
+
// Orders
|
|
84
|
+
// ──────────────────────────────────────────────────────────────────
|
|
85
|
+
createOrder(_req) {
|
|
86
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
87
|
+
throw new NotImplementedError('createOrder');
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
amendOrder(_orderId, _patch) {
|
|
91
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
92
|
+
throw new NotImplementedError('amendOrder');
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
cancelOrder(_orderId, _reason) {
|
|
96
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
97
|
+
throw new NotImplementedError('cancelOrder');
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
getOrder(_orderId, _opts) {
|
|
101
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
102
|
+
throw new NotImplementedError('getOrder');
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
unsolicitedCease(_req) {
|
|
106
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
107
|
+
// FibreCafe doesn't have an outbound "unsolicited cease" — it's an
|
|
108
|
+
// inbound-only KCI on the Netomnia side. NetomniaProvider exposes the
|
|
109
|
+
// method for interface symmetry; calling it always throws.
|
|
110
|
+
throw new NotImplementedError('unsolicitedCease');
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
// ──────────────────────────────────────────────────────────────────
|
|
114
|
+
// Service Management
|
|
115
|
+
// ──────────────────────────────────────────────────────────────────
|
|
116
|
+
createIncident(_req) {
|
|
117
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
118
|
+
throw new NotImplementedError('createIncident');
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
amendIncident(_requestId, _patch) {
|
|
122
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
123
|
+
throw new NotImplementedError('amendIncident');
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
cancelIncident(_requestId) {
|
|
127
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
128
|
+
throw new NotImplementedError('cancelIncident');
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
getIncident(_requestId) {
|
|
132
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
133
|
+
throw new NotImplementedError('getIncident');
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
// ──────────────────────────────────────────────────────────────────
|
|
137
|
+
// Inbound notification subscription
|
|
138
|
+
// ──────────────────────────────────────────────────────────────────
|
|
139
|
+
onOrderNotification(handler) {
|
|
140
|
+
this.orderHandlers.push(handler);
|
|
141
|
+
}
|
|
142
|
+
onSMRNotification(handler) {
|
|
143
|
+
this.smrHandlers.push(handler);
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Internal dispatch — invoked by the webhook controller (T-20260508-010)
|
|
147
|
+
* after mapping a FibreCafe KCI to a VMO2OrderNotification envelope. Fans
|
|
148
|
+
* out to every registered handler in registration order. Handler errors
|
|
149
|
+
* are aggregated and re-thrown after all handlers complete.
|
|
150
|
+
*/
|
|
151
|
+
dispatchOrderNotification(n) {
|
|
152
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
153
|
+
const errors = [];
|
|
154
|
+
for (const h of this.orderHandlers) {
|
|
155
|
+
try {
|
|
156
|
+
yield h(n);
|
|
157
|
+
}
|
|
158
|
+
catch (err) {
|
|
159
|
+
errors.push(err);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
if (errors.length > 0) {
|
|
163
|
+
throw new AggregateNotificationError(errors);
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
dispatchSMRNotification(n) {
|
|
168
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
169
|
+
const errors = [];
|
|
170
|
+
for (const h of this.smrHandlers) {
|
|
171
|
+
try {
|
|
172
|
+
yield h(n);
|
|
173
|
+
}
|
|
174
|
+
catch (err) {
|
|
175
|
+
errors.push(err);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
if (errors.length > 0) {
|
|
179
|
+
throw new AggregateNotificationError(errors);
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
exports.NetomniaProvider = NetomniaProvider;
|
|
185
|
+
/**
|
|
186
|
+
* Aggregates errors thrown by handlers during notification dispatch so the
|
|
187
|
+
* webhook controller can surface every failure rather than masking later
|
|
188
|
+
* handlers with the first throw.
|
|
189
|
+
*/
|
|
190
|
+
class AggregateNotificationError extends Error {
|
|
191
|
+
constructor(errors) {
|
|
192
|
+
super(`${errors.length} handler error(s) during notification dispatch`);
|
|
193
|
+
this.errors = errors;
|
|
194
|
+
this.name = 'AggregateNotificationError';
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
exports.AggregateNotificationError = AggregateNotificationError;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|