@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.
@@ -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,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -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;