PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.14.1
Yatra – Travel Booking & Tour Operator Software v3.0.14.1
3.0.16 3.0.15 3.0.14 3.0.14.1 3.0.14.2 3.0.12 3.0.13 3.0.11 3.0.10 3.0.9 3.0.8 3.0.7 3.0.6 3.0.5 3.0.5.1 3.0.4 3.0.3 3.0.2.9 3.0.2.7 3.0.2.8 3.0.2.6 trunk 1.0.0 2.0.0 2.0.1 All 84 releases
yatra / resources / js / api / channel-manager-api.ts

channel-manager-api.ts in Yatra – Travel Booking & Tour Operator Software 3.0.14.1, at resources/js/api/channel-manager-api.ts

362 lines 9.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { apiClient } from "../lib/api-client";
2
3 export interface ChannelTypeDef {
4 type: string;
5 name: string;
6 description: string;
7 docs_url: string;
8 signup_url: string;
9 credentials: Record<
10 string,
11 { label: string; description: string; required: boolean; docs_url?: string }
12 >;
13 capabilities: Record<string, boolean>;
14 }
15
16 export interface ChannelManagerMeta {
17 is_eligible: boolean;
18 is_module_enabled: boolean;
19 channel_types: ChannelTypeDef[];
20 upgrade_url: string;
21 docs_url: string;
22 webhook_url: string;
23 }
24
25 export interface ChannelHealth {
26 status: "green" | "amber" | "red";
27 breaker: {
28 state: "closed" | "open" | "half_open";
29 failure_count: number;
30 opened_at: number;
31 last_failure: string;
32 updated_at: number;
33 };
34 recent: { ok: number; fail: number; total: number };
35 }
36
37 export interface ChannelRow {
38 id: number;
39 channel_type: string;
40 display_name: string;
41 account_label: string;
42 is_enabled: boolean;
43 is_test_mode: boolean;
44 currency: string;
45 default_offset_percent: number;
46 commission_percent: number;
47 inventory_buffer: number;
48 last_sync_at: string | null;
49 last_sync_status: string | null;
50 last_sync_error: string | null;
51 settings: Record<string, unknown>;
52 credentials?: Record<string, { configured: boolean; hint: string }>;
53 health?: ChannelHealth;
54 }
55
56 export interface MappingRow {
57 id: number;
58 channel_id: number;
59 trip_id: number;
60 external_product_id: string;
61 external_url: string | null;
62 price_offset_percent: number;
63 is_active: boolean;
64 sync_inventory: boolean;
65 sync_pricing: boolean;
66 last_synced_at: string | null;
67 last_sync_status: string | null;
68 external_data: Record<string, unknown>;
69 }
70
71 export interface ChannelBookingRow {
72 id: number;
73 channel_id: number;
74 mapping_id: number | null;
75 trip_id: number | null;
76 yatra_booking_id: number | null;
77 external_booking_id: string;
78 external_status: string;
79 customer_name: string | null;
80 customer_email: string | null;
81 customer_phone: string | null;
82 departure_date: string | null;
83 travelers_total: number;
84 total_amount: number;
85 currency: string;
86 commission_amount: number | null;
87 net_amount: number | null;
88 processing_status: string;
89 error_message: string | null;
90 received_at: string;
91 processed_at: string | null;
92 }
93
94 export interface SyncLogRow {
95 id: number;
96 channel_id: number | null;
97 mapping_id: number | null;
98 trip_id: number | null;
99 booking_id: number | null;
100 direction: "push" | "pull";
101 operation: string;
102 status: string;
103 http_status: number | null;
104 external_id: string | null;
105 summary: string | null;
106 error_message: string | null;
107 duration_ms: number | null;
108 created_at: string;
109 }
110
111 export const channelManagerApi = {
112 getMeta: () =>
113 apiClient.get("/channel-manager/meta") as Promise<ChannelManagerMeta>,
114
115 listChannels: () =>
116 apiClient.get("/channel-manager/channels") as Promise<{
117 data: ChannelRow[];
118 }>,
119
120 createChannel: (payload: Partial<ChannelRow> & { channel_type: string }) =>
121 apiClient.post("/channel-manager/channels", payload) as Promise<{
122 data: ChannelRow;
123 message: string;
124 }>,
125
126 updateChannel: (id: number, payload: Partial<ChannelRow>) =>
127 apiClient.put(`/channel-manager/channels/${id}`, payload) as Promise<{
128 data: ChannelRow;
129 message: string;
130 }>,
131
132 deleteChannel: (id: number) =>
133 apiClient.delete(`/channel-manager/channels/${id}`) as Promise<{
134 message: string;
135 }>,
136
137 updateCredential: (id: number, field: string, value: string) =>
138 apiClient.put(`/channel-manager/channels/${id}/credential`, {
139 field,
140 value,
141 }) as Promise<{
142 credentials: Record<string, { configured: boolean; hint: string }>;
143 message: string;
144 }>,
145
146 testConnection: (id: number) =>
147 apiClient.post(
148 `/channel-manager/channels/${id}/test-connection`,
149 {},
150 ) as Promise<{
151 ok: boolean;
152 http_status: number | null;
153 error: string;
154 }>,
155
156 syncChannel: (id: number) =>
157 apiClient.post(`/channel-manager/channels/${id}/sync`, {}) as Promise<{
158 ok: boolean;
159 pushed: number;
160 failed: number;
161 message: string;
162 }>,
163
164 channelHealth: (id: number) =>
165 apiClient.get(`/channel-manager/channels/${id}/health`) as Promise<{
166 data: ChannelHealth;
167 }>,
168
169 testWebhook: (id: number) =>
170 apiClient.post(
171 `/channel-manager/channels/${id}/test-webhook`,
172 {},
173 ) as Promise<{
174 ok: boolean;
175 http_status: number;
176 response: Record<string, unknown>;
177 webhook_url: string;
178 error?: string;
179 }>,
180
181 bulkMappings: (
182 action: "sync" | "enable" | "disable" | "delete",
183 ids: number[],
184 ) =>
185 apiClient.post("/channel-manager/mappings/bulk", {
186 action,
187 ids,
188 }) as Promise<{
189 ok: boolean;
190 action: string;
191 succeeded: number;
192 failed: number;
193 results: Array<{ id: number; ok: boolean; message: string }>;
194 message: string;
195 }>,
196
197 listMappings: (channelId?: number) =>
198 apiClient.get("/channel-manager/mappings", {
199 params: channelId ? { channel_id: channelId } : {},
200 }) as Promise<{ data: MappingRow[] }>,
201
202 createMapping: (payload: Partial<MappingRow>) =>
203 apiClient.post("/channel-manager/mappings", payload) as Promise<{
204 data: MappingRow;
205 message: string;
206 }>,
207
208 updateMapping: (id: number, payload: Partial<MappingRow>) =>
209 apiClient.put(`/channel-manager/mappings/${id}`, payload) as Promise<{
210 data: MappingRow;
211 message: string;
212 }>,
213
214 deleteMapping: (id: number) =>
215 apiClient.delete(`/channel-manager/mappings/${id}`) as Promise<{
216 message: string;
217 }>,
218
219 syncMapping: (id: number) =>
220 apiClient.post(`/channel-manager/mappings/${id}/sync`, {}) as Promise<{
221 ok: boolean;
222 http_status: number | null;
223 error: string;
224 }>,
225
226 listBookings: (
227 filters: {
228 channel_id?: number;
229 processing_status?: string;
230 per_page?: number;
231 } = {},
232 ) =>
233 apiClient.get("/channel-manager/bookings", { params: filters }) as Promise<{
234 data: ChannelBookingRow[];
235 }>,
236
237 listLogs: (
238 filters: {
239 channel_id?: number;
240 operation?: string;
241 status?: string;
242 per_page?: number;
243 } = {},
244 ) =>
245 apiClient.get("/channel-manager/logs", { params: filters }) as Promise<{
246 data: SyncLogRow[];
247 }>,
248
249 /* --------------------- reconciliation report --------------------- */
250 /** Cross-channel snapshot — flags inventory staleness, pending
251 * booking promotions, sync success/fail counts, and breaker states.
252 * Suitable both for the React reconciliation tab AND for external
253 * monitoring polling. */
254 getReconciliation: () =>
255 apiClient.get("/channel-manager/reconciliation") as Promise<{
256 data: ChannelManagerReconciliation;
257 }>,
258
259 /** Per-channel + per-provider + global latency aggregation. avg /
260 * p50 / p95 / p99 of duration_ms across 24h and 7d windows. */
261 getLatency: () =>
262 apiClient.get("/channel-manager/latency") as Promise<{
263 data: ChannelManagerLatency;
264 }>,
265 };
266
267 /* -------------------------------------------------------------------------- */
268 /* Reconciliation + latency shapes */
269 /* -------------------------------------------------------------------------- */
270
271 export interface ChannelManagerReconciliation {
272 generated_at: string;
273 window: {
274 inventory_stale_seconds: number;
275 recent_24h_cutoff: string;
276 recent_7d_cutoff: string;
277 };
278 totals: {
279 channels: { total: number; enabled: number };
280 mappings_active: number;
281 inventory_stale: number;
282 bookings_pending: number;
283 bookings_failed_7d: number;
284 syncs_24h: { success: number; failed: number };
285 syncs_7d: { success: number; failed: number };
286 breakers_open: number;
287 };
288 channels: Array<{
289 channel: {
290 id: number;
291 type: string;
292 display_name: string;
293 is_enabled: boolean;
294 last_sync_at: string | null;
295 last_sync_status: string | null;
296 };
297 mappings: {
298 total: number;
299 active: number;
300 paused: number;
301 stale: number;
302 last_failed: number;
303 };
304 bookings: {
305 pending: number;
306 failed_7d: number;
307 promoted_7d: number;
308 };
309 syncs: {
310 success_24h: number;
311 failed_24h: number;
312 success_7d: number;
313 failed_7d: number;
314 };
315 breaker: {
316 state: string;
317 [k: string]: unknown;
318 };
319 latest_failure: {
320 operation: string;
321 http_status: number | null;
322 error_message: string;
323 occurred_at: string;
324 } | null;
325 needs_attention: boolean;
326 }>;
327 }
328
329 interface LatencyWindowSummary {
330 samples: number;
331 avg_ms: number | null;
332 p50_ms: number | null;
333 p95_ms: number | null;
334 p99_ms: number | null;
335 success_count: number;
336 fail_count: number;
337 }
338
339 export interface ChannelManagerLatency {
340 generated_at: string;
341 sample_cap: number;
342 global: {
343 last_24h: LatencyWindowSummary;
344 last_7d: LatencyWindowSummary;
345 };
346 per_provider: Array<{
347 provider: string;
348 last_24h: LatencyWindowSummary;
349 last_7d: LatencyWindowSummary;
350 }>;
351 per_channel: Array<{
352 channel: {
353 id: number;
354 type: string;
355 display_name: string;
356 is_enabled: boolean;
357 };
358 last_24h: LatencyWindowSummary;
359 last_7d: LatencyWindowSummary;
360 }>;
361 }
362