@mothership/rebill-model-api 0.2.1
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/.env.example +4 -0
- package/.husky/pre-commit +6 -0
- package/.tool-versions +2 -0
- package/README.md +182 -0
- package/biome.json +112 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/__tests__/queries.unit.test.d.ts +2 -0
- package/dist/__tests__/queries.unit.test.d.ts.map +1 -0
- package/dist/__tests__/queries.unit.test.js +183 -0
- package/dist/__tests__/queries.unit.test.js.map +1 -0
- package/dist/__tests__/schema.unit.test.d.ts +2 -0
- package/dist/__tests__/schema.unit.test.d.ts.map +1 -0
- package/dist/__tests__/schema.unit.test.js +184 -0
- package/dist/__tests__/schema.unit.test.js.map +1 -0
- package/dist/__tests__/types.unit.test.d.ts +2 -0
- package/dist/__tests__/types.unit.test.d.ts.map +1 -0
- package/dist/__tests__/types.unit.test.js +88 -0
- package/dist/__tests__/types.unit.test.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/rebill-model.client.d.ts +111 -0
- package/dist/rebill-model.client.d.ts.map +1 -0
- package/dist/rebill-model.client.js +348 -0
- package/dist/rebill-model.client.js.map +1 -0
- package/dist/types.d.ts +59 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +38 -0
- package/dist/types.js.map +1 -0
- package/example.ts +91 -0
- package/package.json +53 -0
- package/pnpm-workspace.yaml +4 -0
- package/vitest.config.mts +42 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rebill Model Client
|
|
3
|
+
*
|
|
4
|
+
* TypeScript client for querying rebill predictions from Databricks.
|
|
5
|
+
*/
|
|
6
|
+
import { QueryOptions, RebillPrediction } from './types';
|
|
7
|
+
/**
|
|
8
|
+
* Configuration for RebillModelClient
|
|
9
|
+
*/
|
|
10
|
+
export interface RebillModelClientConfig {
|
|
11
|
+
workspaceUrl: string;
|
|
12
|
+
clientId: string;
|
|
13
|
+
clientSecret: string;
|
|
14
|
+
warehouseId: string;
|
|
15
|
+
}
|
|
16
|
+
export declare class RebillModelClient {
|
|
17
|
+
private _client;
|
|
18
|
+
private _session;
|
|
19
|
+
private _connectionPromise;
|
|
20
|
+
private readonly _workspaceUrl;
|
|
21
|
+
private readonly _clientId;
|
|
22
|
+
private readonly _clientSecret;
|
|
23
|
+
private readonly _warehouseId;
|
|
24
|
+
constructor(config: RebillModelClientConfig);
|
|
25
|
+
private _validate;
|
|
26
|
+
/**
|
|
27
|
+
* Close the connection to Databricks
|
|
28
|
+
* Call this when you're done using the client to release resources
|
|
29
|
+
*/
|
|
30
|
+
close(): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Ensure connection is established (lazy connection)
|
|
33
|
+
* Called automatically before queries
|
|
34
|
+
*/
|
|
35
|
+
private _ensureConnected;
|
|
36
|
+
/**
|
|
37
|
+
* Initialize the connection to Databricks
|
|
38
|
+
*/
|
|
39
|
+
private _connect;
|
|
40
|
+
/**
|
|
41
|
+
* Close the connection to Databricks
|
|
42
|
+
*/
|
|
43
|
+
private _close;
|
|
44
|
+
/**
|
|
45
|
+
* Wrap a promise with a client-side timeout
|
|
46
|
+
* This ensures reliable timeout behavior regardless of API/server behavior
|
|
47
|
+
*/
|
|
48
|
+
private _withTimeout;
|
|
49
|
+
/**
|
|
50
|
+
* Execute a raw SQL query (private method for internal use)
|
|
51
|
+
*
|
|
52
|
+
* @param query SQL query string
|
|
53
|
+
* @param parameters Query parameters (ordinal/positional parameters)
|
|
54
|
+
* @param timeoutMs Timeout in milliseconds
|
|
55
|
+
* @returns Query results
|
|
56
|
+
*/
|
|
57
|
+
private _executeQuery;
|
|
58
|
+
/**
|
|
59
|
+
* Get predictions by EDI invoice inbound IDs
|
|
60
|
+
* Makes a single batched query to Databricks for optimal performance
|
|
61
|
+
*
|
|
62
|
+
* @param ediInboundIds Array of EDI invoice inbound IDs
|
|
63
|
+
* @param options Query options
|
|
64
|
+
* @returns Array of predictions in the same order as input IDs (missing IDs excluded)
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```typescript
|
|
68
|
+
* const ids = ['12345', '67890', '11111'];
|
|
69
|
+
* const predictions = await rebillModelClient.getByEdiInboundIds(ids);
|
|
70
|
+
* console.log(`Found ${predictions.length} predictions`);
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
getByEdiInboundIds(ediInboundIds: string[], options?: QueryOptions): Promise<RebillPrediction[]>;
|
|
74
|
+
/**
|
|
75
|
+
* Get the latest prediction for each EDI invoice inbound ID
|
|
76
|
+
* Returns only the most recent prediction per EDI ID (using window function)
|
|
77
|
+
*
|
|
78
|
+
* @param ediInboundIds Array of EDI invoice inbound IDs
|
|
79
|
+
* @param options Query options
|
|
80
|
+
* @returns Array of predictions (latest per EDI ID) in the same order as input IDs (missing IDs excluded)
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```typescript
|
|
84
|
+
* const ids = ['12345', '67890', '11111'];
|
|
85
|
+
* const predictions = await rebillModelClient.getLatestByEdiInboundIds(ids);
|
|
86
|
+
* console.log(`Found ${predictions.length} latest predictions`);
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
getLatestByEdiInboundIds(ediInboundIds: string[], options?: QueryOptions): Promise<RebillPrediction[]>;
|
|
90
|
+
/**
|
|
91
|
+
* Get predictions by inference IDs
|
|
92
|
+
* Makes a single batched query to Databricks for optimal performance
|
|
93
|
+
*
|
|
94
|
+
* @param inferenceIds Array of inference IDs
|
|
95
|
+
* @param options Query options
|
|
96
|
+
* @returns Array of predictions in the same order as input IDs (missing IDs excluded)
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* ```typescript
|
|
100
|
+
* const ids = ['inf-12345', 'inf-67890', 'inf-11111'];
|
|
101
|
+
* const predictions = await rebillModelClient.getByInferenceIds(ids);
|
|
102
|
+
* console.log(`Found ${predictions.length} predictions`);
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
getByInferenceIds(inferenceIds: string[], options?: QueryOptions): Promise<RebillPrediction[]>;
|
|
106
|
+
/**
|
|
107
|
+
* Parse a database row into a RebillPrediction object
|
|
108
|
+
*/
|
|
109
|
+
private _parseRow;
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=rebill-model.client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rebill-model.client.d.ts","sourceRoot":"","sources":["../src/rebill-model.client.ts"],"names":[],"mappings":"AACA;;;;GAIG;AAIH,OAAO,EAAE,YAAY,EAAoD,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAoB1G;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,YAAY,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,QAAQ,CAA6B;IAC7C,OAAO,CAAC,kBAAkB,CAA6B;IACvD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAQ;IACtC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAQ;IAClC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAQ;IACtC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAQ;gBAEzB,MAAM,EAAE,uBAAuB;IAO3C,OAAO,CAAC,SAAS;IAWjB;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B;;;OAGG;YACW,gBAAgB;IAY9B;;OAEG;YACW,QAAQ;IA8DtB;;OAEG;YACW,MAAM;IAgBpB;;;OAGG;IACH,OAAO,CAAC,YAAY;IAkBpB;;;;;;;OAOG;YACW,aAAa;IAoC3B;;;;;;;;;;;;;;OAcG;IACG,kBAAkB,CAAC,aAAa,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAwC1G;;;;;;;;;;;;;;OAcG;IACG,wBAAwB,CAAC,aAAa,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAgDhH;;;;;;;;;;;;;;OAcG;IACG,iBAAiB,CAAC,YAAY,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAuCxG;;OAEG;IACH,OAAO,CAAC,SAAS;CAkBlB"}
|
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* istanbul ignore file */
|
|
3
|
+
/**
|
|
4
|
+
* Rebill Model Client
|
|
5
|
+
*
|
|
6
|
+
* TypeScript client for querying rebill predictions from Databricks.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.RebillModelClient = void 0;
|
|
10
|
+
const sql_1 = require("@databricks/sql");
|
|
11
|
+
const types_1 = require("./types");
|
|
12
|
+
class RebillModelClient {
|
|
13
|
+
constructor(config) {
|
|
14
|
+
this._client = null;
|
|
15
|
+
this._session = null;
|
|
16
|
+
this._connectionPromise = null;
|
|
17
|
+
this._workspaceUrl = this._validate(config.workspaceUrl, 'workspaceUrl');
|
|
18
|
+
this._clientId = this._validate(config.clientId, 'clientId');
|
|
19
|
+
this._clientSecret = this._validate(config.clientSecret, 'clientSecret');
|
|
20
|
+
this._warehouseId = this._validate(config.warehouseId, 'warehouseId');
|
|
21
|
+
}
|
|
22
|
+
_validate(value, name) {
|
|
23
|
+
if (!value) {
|
|
24
|
+
throw new Error(`Missing required config: ${name}`);
|
|
25
|
+
}
|
|
26
|
+
const trimmed = value.trim();
|
|
27
|
+
if (!trimmed) {
|
|
28
|
+
throw new Error(`Config ${name} is empty or whitespace`);
|
|
29
|
+
}
|
|
30
|
+
return trimmed;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Close the connection to Databricks
|
|
34
|
+
* Call this when you're done using the client to release resources
|
|
35
|
+
*/
|
|
36
|
+
async close() {
|
|
37
|
+
await this._close();
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Ensure connection is established (lazy connection)
|
|
41
|
+
* Called automatically before queries
|
|
42
|
+
*/
|
|
43
|
+
async _ensureConnected() {
|
|
44
|
+
if (this._session) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (this._connectionPromise) {
|
|
48
|
+
await this._connectionPromise;
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
this._connectionPromise = this._connect();
|
|
52
|
+
await this._connectionPromise;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Initialize the connection to Databricks
|
|
56
|
+
*/
|
|
57
|
+
async _connect() {
|
|
58
|
+
if (this._client && this._session) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
this._client = new sql_1.DBSQLClient();
|
|
63
|
+
// Normalize the workspace URL: remove protocol, trailing slashes, and any path
|
|
64
|
+
let host = this._workspaceUrl.trim();
|
|
65
|
+
// Remove protocol
|
|
66
|
+
host = host.replace(/^https?:\/\//, '');
|
|
67
|
+
// Remove trailing slash
|
|
68
|
+
host = host.replace(/\/$/, '');
|
|
69
|
+
// Remove any path component (everything after the first /)
|
|
70
|
+
const pathIndex = host.indexOf('/');
|
|
71
|
+
if (pathIndex !== -1) {
|
|
72
|
+
host = host.substring(0, pathIndex);
|
|
73
|
+
}
|
|
74
|
+
// Normalize warehouse ID: remove any leading/trailing slashes and path prefixes
|
|
75
|
+
let warehouseId = this._warehouseId.trim();
|
|
76
|
+
// Remove leading slash
|
|
77
|
+
warehouseId = warehouseId.replace(/^\//, '');
|
|
78
|
+
// Remove path prefix if present (e.g., "/sql/1.0/warehouses/")
|
|
79
|
+
warehouseId = warehouseId.replace(/^sql\/1\.0\/warehouses\//, '');
|
|
80
|
+
// Remove any remaining path components
|
|
81
|
+
const warehouseIdIndex = warehouseId.indexOf('/');
|
|
82
|
+
if (warehouseIdIndex !== -1) {
|
|
83
|
+
warehouseId = warehouseId.substring(0, warehouseIdIndex);
|
|
84
|
+
}
|
|
85
|
+
const connectionOptions = {
|
|
86
|
+
authType: 'databricks-oauth',
|
|
87
|
+
host,
|
|
88
|
+
oauthClientId: this._clientId,
|
|
89
|
+
oauthClientSecret: this._clientSecret,
|
|
90
|
+
path: `/sql/1.0/warehouses/${warehouseId}`,
|
|
91
|
+
};
|
|
92
|
+
await this._client.connect(connectionOptions);
|
|
93
|
+
this._session = await this._client.openSession();
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
// Convert error to Error instance if it's not already
|
|
97
|
+
const errorInstance = error instanceof Error ? error : new Error(String(error));
|
|
98
|
+
// Extract more detailed error information if available
|
|
99
|
+
let errorMessage = 'Failed to connect to Databricks';
|
|
100
|
+
if (errorInstance.message) {
|
|
101
|
+
errorMessage += `: ${errorInstance.message}`;
|
|
102
|
+
}
|
|
103
|
+
// Check if it's a known error type with additional info
|
|
104
|
+
if (error && typeof error === 'object' && 'statusCode' in error) {
|
|
105
|
+
const statusCode = error.statusCode;
|
|
106
|
+
errorMessage += ` (HTTP ${statusCode})`;
|
|
107
|
+
}
|
|
108
|
+
throw new types_1.RebillException(errorMessage, types_1.RebillErrorCode.DATABRICKS_CONNECTION_FAILED, errorInstance);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Close the connection to Databricks
|
|
113
|
+
*/
|
|
114
|
+
async _close() {
|
|
115
|
+
try {
|
|
116
|
+
if (this._session) {
|
|
117
|
+
await this._session.close();
|
|
118
|
+
this._session = null;
|
|
119
|
+
}
|
|
120
|
+
if (this._client) {
|
|
121
|
+
await this._client.close();
|
|
122
|
+
this._client = null;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
// Silently ignore close errors - these are cleanup operations
|
|
127
|
+
// and not actionable by API consumers
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Wrap a promise with a client-side timeout
|
|
132
|
+
* This ensures reliable timeout behavior regardless of API/server behavior
|
|
133
|
+
*/
|
|
134
|
+
_withTimeout(promise, timeoutMs) {
|
|
135
|
+
return new Promise((resolve, reject) => {
|
|
136
|
+
const timer = setTimeout(() => {
|
|
137
|
+
reject(new types_1.RebillException(`Query timed out after ${timeoutMs}ms`, types_1.RebillErrorCode.QUERY_TIMEOUT));
|
|
138
|
+
}, timeoutMs);
|
|
139
|
+
promise
|
|
140
|
+
.then((result) => {
|
|
141
|
+
clearTimeout(timer);
|
|
142
|
+
resolve(result);
|
|
143
|
+
})
|
|
144
|
+
.catch((error) => {
|
|
145
|
+
clearTimeout(timer);
|
|
146
|
+
reject(error);
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Execute a raw SQL query (private method for internal use)
|
|
152
|
+
*
|
|
153
|
+
* @param query SQL query string
|
|
154
|
+
* @param parameters Query parameters (ordinal/positional parameters)
|
|
155
|
+
* @param timeoutMs Timeout in milliseconds
|
|
156
|
+
* @returns Query results
|
|
157
|
+
*/
|
|
158
|
+
async _executeQuery(query, parameters = [], timeoutMs = 30000) {
|
|
159
|
+
await this._ensureConnected();
|
|
160
|
+
const session = this._session;
|
|
161
|
+
if (!session) {
|
|
162
|
+
throw new types_1.RebillException('Client not connected. Call connect() first.', types_1.RebillErrorCode.SESSION_NOT_INITIALIZED);
|
|
163
|
+
}
|
|
164
|
+
try {
|
|
165
|
+
const queryPromise = (async () => {
|
|
166
|
+
const queryOperation = await session.executeStatement(query, {
|
|
167
|
+
ordinalParameters: parameters,
|
|
168
|
+
queryTimeout: timeoutMs, // Still pass to server as a hint
|
|
169
|
+
});
|
|
170
|
+
const result = await queryOperation.fetchAll();
|
|
171
|
+
await queryOperation.close();
|
|
172
|
+
return result;
|
|
173
|
+
})();
|
|
174
|
+
return await this._withTimeout(queryPromise, timeoutMs);
|
|
175
|
+
}
|
|
176
|
+
catch (error) {
|
|
177
|
+
if (error instanceof types_1.RebillException) {
|
|
178
|
+
throw error; // Re-throw timeout or other RebillExceptions
|
|
179
|
+
}
|
|
180
|
+
throw new types_1.RebillException(`Failed to execute query: ${error.message}`, types_1.RebillErrorCode.QUERY_EXECUTION_FAILED, error);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Get predictions by EDI invoice inbound IDs
|
|
185
|
+
* Makes a single batched query to Databricks for optimal performance
|
|
186
|
+
*
|
|
187
|
+
* @param ediInboundIds Array of EDI invoice inbound IDs
|
|
188
|
+
* @param options Query options
|
|
189
|
+
* @returns Array of predictions in the same order as input IDs (missing IDs excluded)
|
|
190
|
+
*
|
|
191
|
+
* @example
|
|
192
|
+
* ```typescript
|
|
193
|
+
* const ids = ['12345', '67890', '11111'];
|
|
194
|
+
* const predictions = await rebillModelClient.getByEdiInboundIds(ids);
|
|
195
|
+
* console.log(`Found ${predictions.length} predictions`);
|
|
196
|
+
* ```
|
|
197
|
+
*/
|
|
198
|
+
async getByEdiInboundIds(ediInboundIds, options = {}) {
|
|
199
|
+
if (ediInboundIds.length === 0) {
|
|
200
|
+
return [];
|
|
201
|
+
}
|
|
202
|
+
const { timeoutMs = 30000 } = options;
|
|
203
|
+
try {
|
|
204
|
+
const placeholders = ediInboundIds.map(() => '?').join(', ');
|
|
205
|
+
const query = `
|
|
206
|
+
SELECT
|
|
207
|
+
inference_id,
|
|
208
|
+
edi_invoice_inbound_id,
|
|
209
|
+
prediction_json,
|
|
210
|
+
processed_at
|
|
211
|
+
FROM rebill_model.v1.predictions
|
|
212
|
+
WHERE edi_invoice_inbound_id IN (${placeholders})
|
|
213
|
+
ORDER BY processed_at DESC
|
|
214
|
+
`;
|
|
215
|
+
const results = await this._executeQuery(query, ediInboundIds, timeoutMs);
|
|
216
|
+
const predictions = results.map((row) => this._parseRow(row));
|
|
217
|
+
// Create map for O(1) lookup and preserve input order
|
|
218
|
+
const resultMap = new Map(predictions.map((p) => [p.edi_invoice_inbound_id, p]));
|
|
219
|
+
// Return results in the same order as input IDs, filtering out missing
|
|
220
|
+
return ediInboundIds.map((id) => resultMap.get(id)).filter((p) => p !== undefined);
|
|
221
|
+
}
|
|
222
|
+
catch (error) {
|
|
223
|
+
if (error instanceof types_1.RebillException) {
|
|
224
|
+
throw error;
|
|
225
|
+
}
|
|
226
|
+
throw new types_1.RebillException(`Failed to query records: ${error.message}`, types_1.RebillErrorCode.QUERY_EXECUTION_FAILED, error);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Get the latest prediction for each EDI invoice inbound ID
|
|
231
|
+
* Returns only the most recent prediction per EDI ID (using window function)
|
|
232
|
+
*
|
|
233
|
+
* @param ediInboundIds Array of EDI invoice inbound IDs
|
|
234
|
+
* @param options Query options
|
|
235
|
+
* @returns Array of predictions (latest per EDI ID) in the same order as input IDs (missing IDs excluded)
|
|
236
|
+
*
|
|
237
|
+
* @example
|
|
238
|
+
* ```typescript
|
|
239
|
+
* const ids = ['12345', '67890', '11111'];
|
|
240
|
+
* const predictions = await rebillModelClient.getLatestByEdiInboundIds(ids);
|
|
241
|
+
* console.log(`Found ${predictions.length} latest predictions`);
|
|
242
|
+
* ```
|
|
243
|
+
*/
|
|
244
|
+
async getLatestByEdiInboundIds(ediInboundIds, options = {}) {
|
|
245
|
+
if (ediInboundIds.length === 0) {
|
|
246
|
+
return [];
|
|
247
|
+
}
|
|
248
|
+
const { timeoutMs = 30000 } = options;
|
|
249
|
+
try {
|
|
250
|
+
const placeholders = ediInboundIds.map(() => '?').join(', ');
|
|
251
|
+
const query = `
|
|
252
|
+
SELECT
|
|
253
|
+
inference_id,
|
|
254
|
+
edi_invoice_inbound_id,
|
|
255
|
+
prediction_json,
|
|
256
|
+
processed_at
|
|
257
|
+
FROM (
|
|
258
|
+
SELECT
|
|
259
|
+
inference_id,
|
|
260
|
+
edi_invoice_inbound_id,
|
|
261
|
+
prediction_json,
|
|
262
|
+
processed_at,
|
|
263
|
+
ROW_NUMBER() OVER (PARTITION BY edi_invoice_inbound_id ORDER BY processed_at DESC) as rn
|
|
264
|
+
FROM rebill_model.v1.predictions
|
|
265
|
+
WHERE edi_invoice_inbound_id IN (${placeholders})
|
|
266
|
+
)
|
|
267
|
+
WHERE rn = 1
|
|
268
|
+
`;
|
|
269
|
+
const results = await this._executeQuery(query, ediInboundIds, timeoutMs);
|
|
270
|
+
const predictions = results.map((row) => this._parseRow(row));
|
|
271
|
+
// Create map for O(1) lookup and preserve input order
|
|
272
|
+
const resultMap = new Map(predictions.map((p) => [p.edi_invoice_inbound_id, p]));
|
|
273
|
+
// Return results in the same order as input IDs, filtering out missing
|
|
274
|
+
return ediInboundIds.map((id) => resultMap.get(id)).filter((p) => p !== undefined);
|
|
275
|
+
}
|
|
276
|
+
catch (error) {
|
|
277
|
+
if (error instanceof types_1.RebillException) {
|
|
278
|
+
throw error;
|
|
279
|
+
}
|
|
280
|
+
throw new types_1.RebillException(`Failed to query records: ${error.message}`, types_1.RebillErrorCode.QUERY_EXECUTION_FAILED, error);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Get predictions by inference IDs
|
|
285
|
+
* Makes a single batched query to Databricks for optimal performance
|
|
286
|
+
*
|
|
287
|
+
* @param inferenceIds Array of inference IDs
|
|
288
|
+
* @param options Query options
|
|
289
|
+
* @returns Array of predictions in the same order as input IDs (missing IDs excluded)
|
|
290
|
+
*
|
|
291
|
+
* @example
|
|
292
|
+
* ```typescript
|
|
293
|
+
* const ids = ['inf-12345', 'inf-67890', 'inf-11111'];
|
|
294
|
+
* const predictions = await rebillModelClient.getByInferenceIds(ids);
|
|
295
|
+
* console.log(`Found ${predictions.length} predictions`);
|
|
296
|
+
* ```
|
|
297
|
+
*/
|
|
298
|
+
async getByInferenceIds(inferenceIds, options = {}) {
|
|
299
|
+
if (inferenceIds.length === 0) {
|
|
300
|
+
return [];
|
|
301
|
+
}
|
|
302
|
+
const { timeoutMs = 30000 } = options;
|
|
303
|
+
try {
|
|
304
|
+
const placeholders = inferenceIds.map(() => '?').join(', ');
|
|
305
|
+
const query = `
|
|
306
|
+
SELECT
|
|
307
|
+
inference_id,
|
|
308
|
+
edi_invoice_inbound_id,
|
|
309
|
+
prediction_json,
|
|
310
|
+
processed_at
|
|
311
|
+
FROM rebill_model.v1.predictions
|
|
312
|
+
WHERE inference_id IN (${placeholders})
|
|
313
|
+
`;
|
|
314
|
+
const results = await this._executeQuery(query, inferenceIds, timeoutMs);
|
|
315
|
+
const predictions = results.map((row) => this._parseRow(row));
|
|
316
|
+
// Create map for O(1) lookup and preserve input order
|
|
317
|
+
const resultMap = new Map(predictions.map((p) => [p.inference_id, p]));
|
|
318
|
+
// Return results in the same order as input IDs, filtering out missing
|
|
319
|
+
return inferenceIds.map((id) => resultMap.get(id)).filter((p) => p !== undefined);
|
|
320
|
+
}
|
|
321
|
+
catch (error) {
|
|
322
|
+
if (error instanceof types_1.RebillException) {
|
|
323
|
+
throw error;
|
|
324
|
+
}
|
|
325
|
+
throw new types_1.RebillException(`Failed to query records: ${error.message}`, types_1.RebillErrorCode.QUERY_EXECUTION_FAILED, error);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Parse a database row into a RebillPrediction object
|
|
330
|
+
*/
|
|
331
|
+
_parseRow(row) {
|
|
332
|
+
try {
|
|
333
|
+
const parsed = JSON.parse(row.prediction_json);
|
|
334
|
+
return {
|
|
335
|
+
customer_summary: parsed.customer_summary,
|
|
336
|
+
edi_invoice_inbound_id: row.edi_invoice_inbound_id,
|
|
337
|
+
inference_id: row.inference_id,
|
|
338
|
+
processed_at: new Date(row.processed_at),
|
|
339
|
+
rebill_line_items: parsed.rebill_line_items,
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
catch (error) {
|
|
343
|
+
throw new types_1.RebillException('Failed to parse prediction JSON', types_1.RebillErrorCode.RESPONSE_PARSE_FAILED, error);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
exports.RebillModelClient = RebillModelClient;
|
|
348
|
+
//# sourceMappingURL=rebill-model.client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rebill-model.client.js","sourceRoot":"","sources":["../src/rebill-model.client.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript type definitions for Rebill Model API
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Error codes for Rebill Model API exceptions
|
|
6
|
+
*/
|
|
7
|
+
export declare enum RebillErrorCode {
|
|
8
|
+
DATABRICKS_CONNECTION_FAILED = "DATABRICKS_CONNECTION_FAILED",
|
|
9
|
+
SESSION_NOT_INITIALIZED = "SESSION_NOT_INITIALIZED",
|
|
10
|
+
QUERY_EXECUTION_FAILED = "QUERY_EXECUTION_FAILED",
|
|
11
|
+
QUERY_TIMEOUT = "QUERY_TIMEOUT",
|
|
12
|
+
RESPONSE_PARSE_FAILED = "RESPONSE_PARSE_FAILED"
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* A single rebill line item with detailed information
|
|
16
|
+
*/
|
|
17
|
+
export interface RebillLineItem {
|
|
18
|
+
/** The rebill type (e.g., "INCORRECT_WEIGHT", "LIFT_GATE_AT_DELIVERY") */
|
|
19
|
+
type: string;
|
|
20
|
+
/** The amount for this line item */
|
|
21
|
+
amount: number;
|
|
22
|
+
/** Description of the line item from the initial rate and/or invoice */
|
|
23
|
+
line_item_description: string;
|
|
24
|
+
/** Root cause(s) of the difference between initial rate and invoice */
|
|
25
|
+
root_cause: string;
|
|
26
|
+
/** Documentation or information that supports the root cause */
|
|
27
|
+
supporting_documentation: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* A rebill prediction record from the model
|
|
31
|
+
*/
|
|
32
|
+
export interface RebillPrediction {
|
|
33
|
+
/** Unique identifier for this inference run */
|
|
34
|
+
inference_id: string;
|
|
35
|
+
/** EDI invoice inbound ID (primary key for querying) */
|
|
36
|
+
edi_invoice_inbound_id: string;
|
|
37
|
+
/** Timestamp when prediction was processed */
|
|
38
|
+
processed_at: Date;
|
|
39
|
+
/** Array of rebill line items with detailed information */
|
|
40
|
+
rebill_line_items: RebillLineItem[];
|
|
41
|
+
/** Customer-facing summary of the rebill */
|
|
42
|
+
customer_summary: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Query options for fetching records
|
|
46
|
+
*/
|
|
47
|
+
export interface QueryOptions {
|
|
48
|
+
/** Timeout in milliseconds (default: 30000) */
|
|
49
|
+
timeoutMs?: number;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Exception thrown by the API
|
|
53
|
+
*/
|
|
54
|
+
export declare class RebillException extends Error {
|
|
55
|
+
readonly code: RebillErrorCode;
|
|
56
|
+
readonly originalError?: Error;
|
|
57
|
+
constructor(message: string, code: RebillErrorCode, originalError?: Error);
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,oBAAY,eAAe;IAEzB,4BAA4B,iCAAiC;IAG7D,uBAAuB,4BAA4B;IAGnD,sBAAsB,2BAA2B;IACjD,aAAa,kBAAkB;IAG/B,qBAAqB,0BAA0B;CAChD;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAA;IACZ,oCAAoC;IACpC,MAAM,EAAE,MAAM,CAAA;IACd,wEAAwE;IACxE,qBAAqB,EAAE,MAAM,CAAA;IAC7B,uEAAuE;IACvE,UAAU,EAAE,MAAM,CAAA;IAClB,gEAAgE;IAChE,wBAAwB,EAAE,MAAM,CAAA;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,+CAA+C;IAC/C,YAAY,EAAE,MAAM,CAAA;IACpB,wDAAwD;IACxD,sBAAsB,EAAE,MAAM,CAAA;IAC9B,8CAA8C;IAC9C,YAAY,EAAE,IAAI,CAAA;IAClB,2DAA2D;IAC3D,iBAAiB,EAAE,cAAc,EAAE,CAAA;IACnC,4CAA4C;IAC5C,gBAAgB,EAAE,MAAM,CAAA;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;GAEG;AACH,qBAAa,eAAgB,SAAQ,KAAK;IACxC,SAAgB,IAAI,EAAE,eAAe,CAAA;IACrC,SAAgB,aAAa,CAAC,EAAE,KAAK,CAAA;gBAEzB,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,EAAE,aAAa,CAAC,EAAE,KAAK;CAW1E"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* TypeScript type definitions for Rebill Model API
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.RebillException = exports.RebillErrorCode = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* Error codes for Rebill Model API exceptions
|
|
9
|
+
*/
|
|
10
|
+
var RebillErrorCode;
|
|
11
|
+
(function (RebillErrorCode) {
|
|
12
|
+
// Connection Errors
|
|
13
|
+
RebillErrorCode["DATABRICKS_CONNECTION_FAILED"] = "DATABRICKS_CONNECTION_FAILED";
|
|
14
|
+
// Session Errors
|
|
15
|
+
RebillErrorCode["SESSION_NOT_INITIALIZED"] = "SESSION_NOT_INITIALIZED";
|
|
16
|
+
// Query Errors
|
|
17
|
+
RebillErrorCode["QUERY_EXECUTION_FAILED"] = "QUERY_EXECUTION_FAILED";
|
|
18
|
+
RebillErrorCode["QUERY_TIMEOUT"] = "QUERY_TIMEOUT";
|
|
19
|
+
// Response Errors
|
|
20
|
+
RebillErrorCode["RESPONSE_PARSE_FAILED"] = "RESPONSE_PARSE_FAILED";
|
|
21
|
+
})(RebillErrorCode || (exports.RebillErrorCode = RebillErrorCode = {}));
|
|
22
|
+
/**
|
|
23
|
+
* Exception thrown by the API
|
|
24
|
+
*/
|
|
25
|
+
class RebillException extends Error {
|
|
26
|
+
constructor(message, code, originalError) {
|
|
27
|
+
super(message);
|
|
28
|
+
this.name = 'RebillException';
|
|
29
|
+
this.code = code;
|
|
30
|
+
this.originalError = originalError;
|
|
31
|
+
// Maintains proper stack trace for where error was thrown (V8 engines)
|
|
32
|
+
if (Error.captureStackTrace) {
|
|
33
|
+
Error.captureStackTrace(this, RebillException);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
exports.RebillException = RebillException;
|
|
38
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH;;GAEG;AACH,IAAY,eAaX;AAbD,WAAY,eAAe;IACzB,oBAAoB;IACpB,gFAA6D,CAAA;IAE7D,iBAAiB;IACjB,sEAAmD,CAAA;IAEnD,eAAe;IACf,oEAAiD,CAAA;IACjD,kDAA+B,CAAA;IAE/B,kBAAkB;IAClB,kEAA+C,CAAA;AACjD,CAAC,EAbW,eAAe,+BAAf,eAAe,QAa1B;AA0CD;;GAEG;AACH,MAAa,eAAgB,SAAQ,KAAK;IAIxC,YAAY,OAAe,EAAE,IAAqB,EAAE,aAAqB;QACvE,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAA;QAC7B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,aAAa,GAAG,aAAa,CAAA;QAElC,uEAAuE;QACvE,IAAI,KAAK,CAAC,iBAAiB,EAAE,CAAC;YAC5B,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,eAAe,CAAC,CAAA;QAChD,CAAC;IACH,CAAC;CACF;AAfD,0CAeC"}
|
package/example.ts
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example: Using the Rebill Model API
|
|
3
|
+
*
|
|
4
|
+
* Demonstrates all available query methods.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* 1. Copy .env.example to .env and fill in your credentials
|
|
8
|
+
* 2. Run: pnpm tsx example.ts
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import 'dotenv/config'
|
|
12
|
+
import { RebillErrorCode, RebillException, RebillModelClient } from './src'
|
|
13
|
+
|
|
14
|
+
async function main() {
|
|
15
|
+
// Initialize client with configuration from environment
|
|
16
|
+
const client = new RebillModelClient({
|
|
17
|
+
clientId: process.env.DATABRICKS_CLIENT_ID!,
|
|
18
|
+
clientSecret: process.env.DATABRICKS_CLIENT_SECRET!,
|
|
19
|
+
warehouseId: process.env.DATABRICKS_WAREHOUSE_ID!,
|
|
20
|
+
workspaceUrl: process.env.DATABRICKS_WORKSPACE_URL!,
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
// Example EDI IDs to query (replace with real IDs)
|
|
25
|
+
const ediIds = ['12345', '67890']
|
|
26
|
+
|
|
27
|
+
console.log('--- Get Latest Predictions by EDI IDs ---')
|
|
28
|
+
const latest = await client.getLatestByEdiInboundIds(ediIds)
|
|
29
|
+
console.log(`Found ${latest.length} predictions`)
|
|
30
|
+
|
|
31
|
+
for (const prediction of latest) {
|
|
32
|
+
console.log(`\n EDI ID: ${prediction.edi_invoice_inbound_id}`)
|
|
33
|
+
console.log(` Inference ID: ${prediction.inference_id}`)
|
|
34
|
+
console.log(` Processed At: ${prediction.processed_at.toISOString()}`)
|
|
35
|
+
console.log(` Line Items: ${prediction.rebill_line_items.length}`)
|
|
36
|
+
console.log(` Summary: ${prediction.customer_summary}`)
|
|
37
|
+
|
|
38
|
+
// Calculate total rebill amount
|
|
39
|
+
const total = prediction.rebill_line_items.reduce((sum, item) => sum + item.amount, 0)
|
|
40
|
+
console.log(` Total Amount: $${total.toFixed(2)}`)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
console.log('\n--- Get All Predictions by EDI IDs (including history) ---')
|
|
44
|
+
const all = await client.getByEdiInboundIds(ediIds)
|
|
45
|
+
console.log(`Found ${all.length} total predictions`)
|
|
46
|
+
|
|
47
|
+
console.log('\n--- Get Predictions by Inference IDs ---')
|
|
48
|
+
if (latest.length > 0) {
|
|
49
|
+
const inferenceIds = latest.map((p) => p.inference_id)
|
|
50
|
+
const byInference = await client.getByInferenceIds(inferenceIds)
|
|
51
|
+
console.log(`Found ${byInference.length} predictions by inference ID`)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
console.log('\n--- Query with Custom Timeout ---')
|
|
55
|
+
const withTimeout = await client.getLatestByEdiInboundIds(ediIds, {
|
|
56
|
+
timeoutMs: 60000, // 60 seconds
|
|
57
|
+
})
|
|
58
|
+
console.log(`Found ${withTimeout.length} predictions (60s timeout)`)
|
|
59
|
+
|
|
60
|
+
console.log('\n✅ All examples completed successfully')
|
|
61
|
+
} catch (error) {
|
|
62
|
+
if (error instanceof RebillException) {
|
|
63
|
+
console.error('\n❌ RebillException:', error.code)
|
|
64
|
+
console.error(' Message:', error.message)
|
|
65
|
+
|
|
66
|
+
// Handle specific error codes
|
|
67
|
+
switch (error.code) {
|
|
68
|
+
case RebillErrorCode.DATABRICKS_CONNECTION_FAILED:
|
|
69
|
+
console.error(' → Check your credentials and network connection')
|
|
70
|
+
break
|
|
71
|
+
case RebillErrorCode.QUERY_TIMEOUT:
|
|
72
|
+
console.error(' → Try increasing the timeout or reducing the query size')
|
|
73
|
+
break
|
|
74
|
+
case RebillErrorCode.QUERY_EXECUTION_FAILED:
|
|
75
|
+
console.error(' → Check your query parameters')
|
|
76
|
+
break
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (error.originalError) {
|
|
80
|
+
console.error(' Original:', error.originalError.message)
|
|
81
|
+
}
|
|
82
|
+
} else {
|
|
83
|
+
console.error('Unexpected error:', error)
|
|
84
|
+
}
|
|
85
|
+
} finally {
|
|
86
|
+
// Always clean up connection
|
|
87
|
+
await client.close()
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
main().catch(console.error)
|