@kquika-inc/s-system 1.0.7 → 2.0.0

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/README.md CHANGED
@@ -26,6 +26,10 @@ record before acting on it.
26
26
  | `live_feed` | Observed from the live provider feed. |
27
27
  | `database` | Observed on an earlier read and persisted. |
28
28
 
29
+ Every record this API returns is an observation. `live_feed` is the current
30
+ reading from the provider; `database` is the same reading persisted from an
31
+ earlier call, so it may lag the feed. Neither is an estimate.
32
+
29
33
  Fields are left null where the source carries no value. A null
30
34
  `delay_minutes` means no time was reported.
31
35
 
@@ -35,6 +39,20 @@ Fields are left null where the source carries no value. A null
35
39
  are in the response. Flights that reported no time are excluded from that
36
40
  denominator, so other ratios can be derived from the same payload.
37
41
 
42
+ `on_time` counts departures within `on_time_threshold_minutes`, which is
43
+ returned on the response and defaults to 15. Read it rather than assuming it.
44
+
45
+ `on_time_percentage` is null when the figure cannot be measured, and
46
+ `ontime_unavailable_reason` says why. Three cases:
47
+
48
+ - Nothing was measured.
49
+ - Coverage was too thin to describe the operation.
50
+ - The sample was censored: every flight carrying a time was late, and none
51
+ departed early or on schedule. This happens when the upstream feed publishes
52
+ a delay only when there is one, so "on time" and "unknown" collapse into the
53
+ same absence. A rate over only late flights reads near zero whatever the
54
+ real punctuality is, so no rate is returned at all.
55
+
38
56
  `gate_conflicts` is keyed on airport and gate together, so gate labels are
39
57
  only compared within a single station.
40
58
 
@@ -106,15 +124,20 @@ if (error || !data?.success) {
106
124
 
107
125
  ```ts
108
126
  for (const flight of data.data) {
109
- if (flight.data_confidence === 'live_feed') schedule(flight);
127
+ // Both values are observations, so both are safe to schedule against.
128
+ // Branch on freshness only when it matters to you: `database` may lag the
129
+ // live feed by a sync interval.
130
+ if (flight.data_confidence === 'live_feed') scheduleNow(flight);
131
+ else queueForRefresh(flight);
110
132
  }
111
133
  ```
112
134
 
113
135
  `live_feed` is the current reading from the provider. `database` is the same
114
- reading persisted from an earlier call, so it may lag the feed.
136
+ reading persisted from an earlier call, so it may lag the feed by up to one
137
+ sync interval.
115
138
 
116
- TypeScript narrows that union, so a typo fails to compile instead of
117
- silently never matching.
139
+ TypeScript narrows the union, so a typo fails to compile instead of silently
140
+ never matching.
118
141
 
119
142
  ## Nulls
120
143
 
@@ -158,6 +181,13 @@ if (!heat.data?.data?.lidar_available) {
158
181
  `avg_wait_minutes` covers queueing zones only: security, check-in,
159
182
  immigration and customs. Gates and lounges are out of scope.
160
183
 
184
+ Check `data_source` on the heatmap response before acting on occupancy or wait
185
+ times. `measured` means a sensor, gate read or throughput count is behind the
186
+ figure. `modelled` means it is derived from terminal layout and time of day
187
+ with no sensor behind it, in which case two calls seconds apart can return
188
+ different values with no underlying event. Do not diff them to infer movement.
189
+
190
+
161
191
  Heatmap and congestion require Professional. Overview is Standard.
162
192
 
163
193
  ## Flight metrics and route analytics
@@ -204,16 +234,23 @@ Every schema is exported.
204
234
  ```ts
205
235
  import type {
206
236
  Flight,
207
- DisruptionPrediction,
208
- Exposure,
209
- Meta,
237
+ MetricsResponse,
238
+ HeatmapResponse,
239
+ ErrorResponse,
210
240
  } from '@kquika-inc/s-system';
211
241
 
212
- function isActionable(p: DisruptionPrediction): boolean {
213
- return p.risk_level === 'critical' || p.risk_level === 'elevated';
242
+ function isActionable(flight: Flight): boolean {
243
+ // delay_minutes must be null-checked first. `?? 0` here would treat an
244
+ // unreported flight as departing exactly on schedule.
245
+ return flight.delay_minutes !== null && flight.delay_minutes > 15;
214
246
  }
215
247
  ```
216
248
 
249
+ Disruption prediction and passenger-rights exposure are not on the public API
250
+ and have no exported types. They are delivered through the application and
251
+ through scheduled data delivery; talk to your account manager about direct
252
+ access.
253
+
217
254
  ## Support
218
255
 
219
256
  An API key, a plan change, or a capability you need that your plan does not
package/dist/sdk.gen.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { Options as ClientOptions, TDataShape, Client } from '@hey-api/client-fetch';
2
- import type { ListFlightsData, GetFlightData, GetFlightMetricsData, GetRouteAnalyticsData, SearchFlightsData, RefreshFlightsData, GetAirportOverviewData, GetAirportHeatmapData, GetAirportCongestionData } from './types.gen';
2
+ import type { ListFlightsData, GetFlightData, GetFlightMetricsData, GetRouteAnalyticsData, SearchFlightsData, RefreshFlightsData, GetAirportOverviewData, GetAirportHeatmapData, GetAirportCongestionData, GetUsageData } from './types.gen';
3
3
  export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean> = ClientOptions<TData, ThrowOnError> & {
4
4
  /**
5
5
  * You can provide a client instance returned by `createClient()` instead of
@@ -19,8 +19,9 @@ export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends
19
19
  *
20
20
  * **Requires Standard.**
21
21
  *
22
- * Each flight carries a `data_confidence` value. Confirm it before using the
23
- * flight for operational planning.
22
+ * Every record returned is an observation. Records generated to fill a gap in the live
23
+ * feed are excluded rather than labelled, so no provenance check is required before using
24
+ * a flight for operational planning. `excluded_generated` reports how many were removed.
24
25
  */
25
26
  export declare const listFlights: <ThrowOnError extends boolean = false>(options?: Options<ListFlightsData, ThrowOnError>) => import("@hey-api/client-fetch").RequestResult<import("./types.gen").FlightListResponse, import("./types.gen").ErrorResponse, ThrowOnError>;
26
27
  /**
@@ -96,3 +97,12 @@ export declare const getAirportHeatmap: <ThrowOnError extends boolean = false>(o
96
97
  * immigration and customs.
97
98
  */
98
99
  export declare const getAirportCongestion: <ThrowOnError extends boolean = false>(options: Options<GetAirportCongestionData, ThrowOnError>) => import("@hey-api/client-fetch").RequestResult<import("./types.gen").CongestionResponse, import("./types.gen").ErrorResponse, ThrowOnError>;
100
+ /**
101
+ * Usage against your allowance
102
+ * Calls made this period, the allowance, and what remains.
103
+ *
104
+ * **Requires Standard.**
105
+ *
106
+ * Every response already carries the same position in its `quota` block and in the `X-Quota-*` headers, so polling this endpoint to watch consumption wastes the allowance it reports. Call it when you want the breakdown by endpoint, which headers cannot carry.
107
+ */
108
+ export declare const getUsage: <ThrowOnError extends boolean = false>(options?: Options<GetUsageData, ThrowOnError>) => import("@hey-api/client-fetch").RequestResult<import("./types.gen").UsageResponse, import("./types.gen").ErrorResponse, ThrowOnError>;
package/dist/sdk.gen.js CHANGED
@@ -6,8 +6,9 @@ import { client as _heyApiClient } from './client.gen';
6
6
  *
7
7
  * **Requires Standard.**
8
8
  *
9
- * Each flight carries a `data_confidence` value. Confirm it before using the
10
- * flight for operational planning.
9
+ * Every record returned is an observation. Records generated to fill a gap in the live
10
+ * feed are excluded rather than labelled, so no provenance check is required before using
11
+ * a flight for operational planning. `excluded_generated` reports how many were removed.
11
12
  */
12
13
  export const listFlights = (options) => {
13
14
  return (options?.client ?? _heyApiClient).get({
@@ -182,3 +183,23 @@ export const getAirportCongestion = (options) => {
182
183
  ...options
183
184
  });
184
185
  };
186
+ /**
187
+ * Usage against your allowance
188
+ * Calls made this period, the allowance, and what remains.
189
+ *
190
+ * **Requires Standard.**
191
+ *
192
+ * Every response already carries the same position in its `quota` block and in the `X-Quota-*` headers, so polling this endpoint to watch consumption wastes the allowance it reports. Call it when you want the breakdown by endpoint, which headers cannot carry.
193
+ */
194
+ export const getUsage = (options) => {
195
+ return (options?.client ?? _heyApiClient).get({
196
+ security: [
197
+ {
198
+ name: 'X-API-Key',
199
+ type: 'apiKey'
200
+ }
201
+ ],
202
+ url: '/api/v1/usage',
203
+ ...options
204
+ });
205
+ };
@@ -16,6 +16,20 @@ export type Envelope = {
16
16
  * contract; branch on the HTTP status or on `error`.
17
17
  */
18
18
  message: string;
19
+ /**
20
+ * Your consumption after this call, on every response. A client can slow down before it is throttled rather than after: a quota you discover only by being refused is not a quota. Mirrored in the X-Quota-Remaining and X-RateLimit-Remaining headers, so a caller that does not parse the body still sees it.
21
+ */
22
+ quota?: {
23
+ /**
24
+ * Null on plans metered by rate rather than volume.
25
+ */
26
+ calls_remaining?: number | null;
27
+ percent_used?: number | null;
28
+ /**
29
+ * Requests left in the current minute.
30
+ */
31
+ rate_limit_remaining?: number | null;
32
+ };
19
33
  };
20
34
  export type Flight = {
21
35
  flight_number: string;
@@ -45,21 +59,26 @@ export type Flight = {
45
59
  */
46
60
  status?: 'scheduled' | 'active' | 'landed' | 'delayed' | 'cancelled' | 'diverted' | 'unknown';
47
61
  /**
48
- * Provenance of this record. `live_feed` and `database` are observed records.
49
- * `generated` is synthetic sample data and is not suitable for operational
50
- * planning.
62
+ * Provenance of this record. Both values are observations: `live_feed` is the current reading from the provider, `database` is the same reading persisted from an earlier call and may lag the feed by up to one sync interval.
63
+ *
64
+ * There is no value for generated data. Records produced to fill a gap in the feed are excluded from this API entirely rather than labelled, so every record you receive is an observation and no client-side check is required before acting on one.
51
65
  */
52
- data_confidence: 'live_feed' | 'database' | 'generated';
66
+ data_confidence: 'live_feed' | 'database';
53
67
  };
54
68
  export type FlightListResponse = Envelope & {
55
69
  data?: {
56
70
  flights?: Array<Flight>;
57
71
  count?: number;
58
72
  /**
59
- * Provenance of the returned records. `generated` indicates synthetic sample
60
- * data.
73
+ * Provenance of the returned records. `generated` appears only when it was requested explicitly, since the default excludes it.
74
+ */
75
+ source?: 'live_feed' | 'database' | 'mixed';
76
+ /**
77
+ * Records matching your filters that were produced to fill a gap in the live feed, and therefore excluded. Always excluded; this is the count, not a choice.
78
+ *
79
+ * A non-zero value means the feed was thin enough for the platform to generate rows, so a short result can be told apart from a short schedule. It is a signal about the feed, not about your query.
61
80
  */
62
- source?: 'live_feed' | 'database' | 'generated' | 'mixed';
81
+ excluded_generated?: number | null;
63
82
  };
64
83
  };
65
84
  export type FlightResponse = Envelope & {
@@ -76,13 +95,29 @@ export type MetricsResponse = Envelope & {
76
95
  */
77
96
  measured_flights?: number;
78
97
  /**
79
- * Departures within 15 minutes of schedule.
98
+ * Departures within `on_time_threshold_minutes` of schedule, which defaults to 15. Read the threshold from the response rather than assuming it.
80
99
  */
81
100
  on_time?: number;
82
101
  /**
83
- * `on_time` divided by `measured_flights`. Null when `measured_flights` is 0.
102
+ * `on_time` divided by `measured_flights`.
103
+ *
104
+ * Null in three cases, which `ontime_unavailable_reason` distinguishes: nothing was measured; coverage was too thin for the figure to describe the operation; or the sample was censored, meaning every flight carrying a time was late and none departed early or on schedule. The third is the one to watch, because a rate computed over only late flights reads near zero whatever the real punctuality is.
105
+ *
106
+ * Null is not zero. Treating it as zero reports perfect lateness on a day nothing was measured.
84
107
  */
85
108
  on_time_percentage?: number | null;
109
+ /**
110
+ * False when the sample cannot support an on-time rate. `on_time_percentage` is null whenever this is false.
111
+ */
112
+ ontime_measurable?: boolean;
113
+ /**
114
+ * Plain sentence naming why the rate could not be computed. Null when it could.
115
+ */
116
+ ontime_unavailable_reason?: string | null;
117
+ /**
118
+ * Minutes of delay still counted as on time. Configurable per deployment, so read it rather than assuming 15.
119
+ */
120
+ on_time_threshold_minutes?: number;
86
121
  /**
87
122
  * Mean delay across delayed departures only. The denominator excludes on time
88
123
  * departures.
@@ -138,8 +173,22 @@ export type HeatmapResponse = Envelope & {
138
173
  /**
139
174
  * Whether LiDAR coverage exists at this station. `points` is empty when false,
140
175
  * which carries no information about occupancy.
176
+ *
177
+ * **Read `data_source` before acting on any figure here.** Where it is `modelled`, occupancy and wait times are derived from terminal layout and time of day rather than measured from sensors, regardless of what this flag says.
141
178
  */
142
179
  lidar_available?: boolean;
180
+ /**
181
+ * How the figures in `points` were produced. `measured` means a sensor, gate read or throughput count. `modelled` means derived from terminal layout and time of day, with no sensor behind it. Two calls seconds apart can return different modelled values with no underlying event, so do not diff them to infer movement.
182
+ */
183
+ data_source?: 'measured' | 'modelled';
184
+ /**
185
+ * False when the figures are modelled. Present as a boolean as well as in `data_source` so a client can branch without string comparison.
186
+ */
187
+ is_measured?: boolean;
188
+ /**
189
+ * Plain sentence describing how these figures were produced, safe to display.
190
+ */
191
+ provenance_note?: string | null;
143
192
  points?: Array<{
144
193
  zone?: string;
145
194
  zone_type?: string;
@@ -179,6 +228,28 @@ export type ErrorResponse = Envelope & {
179
228
  */
180
229
  retry_after_seconds?: number | null;
181
230
  };
231
+ export type UsageResponse = Envelope & {
232
+ data?: {
233
+ period_start?: string;
234
+ period_end?: string;
235
+ plan?: 'Standard' | 'Professional' | 'Enterprise';
236
+ calls_made?: number;
237
+ /**
238
+ * Monthly allowance. Null on plans metered by rate rather than volume, which is not the same as unlimited: the per-minute limit still applies.
239
+ */
240
+ calls_included?: number | null;
241
+ calls_remaining?: number | null;
242
+ percent_used?: number | null;
243
+ /**
244
+ * Where the calls went. The reason to call this endpoint.
245
+ */
246
+ by_endpoint?: Array<{
247
+ endpoint?: string;
248
+ calls?: number;
249
+ }>;
250
+ rate_limit_per_minute?: number;
251
+ };
252
+ };
182
253
  /**
183
254
  * IATA code, three letters. Case insensitive.
184
255
  */
@@ -446,6 +517,26 @@ export type GetAirportCongestionResponses = {
446
517
  200: CongestionResponse;
447
518
  };
448
519
  export type GetAirportCongestionResponse = GetAirportCongestionResponses[keyof GetAirportCongestionResponses];
520
+ export type GetUsageData = {
521
+ body?: never;
522
+ path?: never;
523
+ query?: never;
524
+ url: '/api/v1/usage';
525
+ };
526
+ export type GetUsageErrors = {
527
+ /**
528
+ * Missing or invalid API key.
529
+ */
530
+ 401: ErrorResponse;
531
+ };
532
+ export type GetUsageError = GetUsageErrors[keyof GetUsageErrors];
533
+ export type GetUsageResponses = {
534
+ /**
535
+ * Usage for the current period.
536
+ */
537
+ 200: UsageResponse;
538
+ };
539
+ export type GetUsageResponse = GetUsageResponses[keyof GetUsageResponses];
449
540
  export type ClientOptions = {
450
541
  baseUrl: 'https://www.s-system.cloud' | (string & {});
451
542
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kquika-inc/s-system",
3
- "version": "1.0.7",
3
+ "version": "2.0.0",
4
4
  "description": "Predict flight disruption, price the passenger-rights exposure it carries, and rebook before it costs you.",
5
5
  "author": { "name": "Kquika, Inc.", "email": "support@kquika.com" },
6
6
  "homepage": "https://www.s-system.cloud/document",