@brownandroot/api 0.14.0 → 1.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 +246 -21
- package/dist/businessUnits.remote.d.ts +4 -0
- package/dist/businessUnits.remote.js +7 -0
- package/dist/client.d.ts +8 -0
- package/dist/client.js +21 -0
- package/dist/costcodes.remote.d.ts +6 -0
- package/dist/costcodes.remote.js +13 -0
- package/dist/employees.remote.d.ts +10 -0
- package/dist/employees.remote.js +20 -0
- package/dist/index.d.ts +9 -6
- package/dist/index.js +20 -5
- package/dist/jobtypejobsteps.remote.d.ts +3 -0
- package/dist/jobtypejobsteps.remote.js +6 -0
- package/dist/llm.remote.d.ts +2 -0
- package/dist/llm.remote.js +17 -0
- package/dist/paytypes.remote.d.ts +4 -0
- package/dist/paytypes.remote.js +7 -0
- package/dist/rag.remote.d.ts +4 -0
- package/dist/rag.remote.js +16 -0
- package/dist/workorders.remote.d.ts +5 -0
- package/dist/workorders.remote.js +8 -0
- package/package.json +58 -6
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @brownandroot/api
|
|
2
2
|
|
|
3
|
-
TypeScript client for the Brown & Root APIHub data service. Provides
|
|
3
|
+
TypeScript client for the Brown & Root APIHub data service. Provides access to employee, business unit, cost code, pay type, work order, job type/job step, LLM chat, and document search data.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -16,57 +16,217 @@ import { ApiHubClient } from '@brownandroot/api'
|
|
|
16
16
|
const client = new ApiHubClient({
|
|
17
17
|
baseUrl: 'https://your-apihub-url.com',
|
|
18
18
|
apiKey: 'your-api-key',
|
|
19
|
+
cacheTtl: 5 * 60 * 1000, // optional, default 5 minutes (0 to disable)
|
|
19
20
|
})
|
|
20
21
|
```
|
|
21
22
|
|
|
22
|
-
|
|
23
|
+
---
|
|
23
24
|
|
|
24
|
-
|
|
25
|
+
## Employees
|
|
26
|
+
|
|
27
|
+
### Fetching
|
|
25
28
|
|
|
26
29
|
```typescript
|
|
30
|
+
// All employees
|
|
27
31
|
const employees = await client.getEmployees()
|
|
28
|
-
|
|
32
|
+
|
|
33
|
+
// Dropdown format: { value: employeeId, label: name }[]
|
|
34
|
+
const dropdown = await client.getEmployeesDropdown()
|
|
35
|
+
|
|
36
|
+
// Single employee by ID — throws if not found
|
|
29
37
|
const employee = await client.getEmployee('12345')
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Search
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
// By name (case-insensitive partial match)
|
|
30
44
|
const results = await client.searchByName('John')
|
|
45
|
+
|
|
46
|
+
// By email (case-insensitive partial match)
|
|
31
47
|
const results = await client.searchByEmail('john@example.com')
|
|
48
|
+
|
|
49
|
+
// By home business unit (case-insensitive partial match)
|
|
50
|
+
const results = await client.searchByHbu('TX01')
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Org hierarchy
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
// All employees reporting directly to a supervisor
|
|
32
57
|
const reports = await client.getBySupervisor('12345')
|
|
58
|
+
|
|
59
|
+
// Full supervisor chain above an employee (excludes the employee themselves)
|
|
33
60
|
const chain = await client.getSupervisorChain('12345')
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Email → JDE lookup
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
34
66
|
const { jde, employee } = await client.getJdeFromEmail('john@example.com')
|
|
67
|
+
// jde: string | null
|
|
68
|
+
// employee: Employee | null
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Identity verification
|
|
72
|
+
|
|
73
|
+
Verifies an employee's identity from name, date of birth, and last 4 of SSN alone — no employee ID needed. Returns the full employee record on a match.
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
const employee = await client.verifyIdentity({
|
|
77
|
+
first3FirstName: 'joh', // first 3 chars of first name, case-insensitive
|
|
78
|
+
first3LastName: 'doe', // first 3 chars of last name, case-insensitive
|
|
79
|
+
dob: '1985-03-15', // YYYY-MM-DD
|
|
80
|
+
ssn4: '4321', // last 4 digits of SSN
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
if (employee) {
|
|
84
|
+
// identity confirmed — full Employee object returned
|
|
85
|
+
} else {
|
|
86
|
+
// no employee matched these inputs
|
|
87
|
+
}
|
|
88
|
+
// Throws on 400 (missing fields) or 503 (not configured server-side)
|
|
35
89
|
```
|
|
36
90
|
|
|
37
|
-
###
|
|
91
|
+
### Employee fields
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
interface Employee {
|
|
95
|
+
// Identity
|
|
96
|
+
employeeId: string
|
|
97
|
+
name: string | null
|
|
98
|
+
email: string | null
|
|
99
|
+
badgeNumber: string | null
|
|
100
|
+
nccerNumber: string | null
|
|
101
|
+
|
|
102
|
+
// Organization
|
|
103
|
+
company: string | null // company code
|
|
104
|
+
businessUnitId: string | null
|
|
105
|
+
hbu: string | null // home business unit
|
|
106
|
+
departmentCode: string | null
|
|
107
|
+
division: string | null
|
|
108
|
+
sector: string | null
|
|
109
|
+
subsector: string | null
|
|
110
|
+
|
|
111
|
+
// Contact
|
|
112
|
+
phone: string | null
|
|
113
|
+
|
|
114
|
+
// Employment
|
|
115
|
+
employementStatus: string | null
|
|
116
|
+
employeePayStatus: string | null
|
|
117
|
+
recordType: string | null
|
|
118
|
+
|
|
119
|
+
// Job
|
|
120
|
+
jobType: string | null
|
|
121
|
+
jobStep: string | null
|
|
122
|
+
jobDescription: string | null
|
|
123
|
+
workSchedule: string | null
|
|
124
|
+
shift: string | null
|
|
125
|
+
|
|
126
|
+
// Pay & compensation
|
|
127
|
+
payClass: string | null
|
|
128
|
+
payFrequency: string | null
|
|
129
|
+
payCycleCode: string | null
|
|
130
|
+
checkRouteCode: string | null
|
|
131
|
+
hourlyRate: string | null // string — format as needed
|
|
132
|
+
annualSalary: string | null // string — format as needed
|
|
133
|
+
|
|
134
|
+
// Tax
|
|
135
|
+
residentTaxArea: string | null
|
|
136
|
+
workTaxArea: string | null
|
|
137
|
+
|
|
138
|
+
// Benefits
|
|
139
|
+
benefitGroup: string | null
|
|
140
|
+
|
|
141
|
+
// PTO
|
|
142
|
+
topFlexPtoDate: string | null // ISO timestamp
|
|
143
|
+
clientPtoDate: string | null // ISO timestamp
|
|
144
|
+
|
|
145
|
+
// Security & reporting
|
|
146
|
+
securityLevel: string | null
|
|
147
|
+
reportingLevel: string | null
|
|
148
|
+
|
|
149
|
+
// Relationships
|
|
150
|
+
supervisor: string | null // supervisor employee ID
|
|
151
|
+
mentor: string | null
|
|
152
|
+
|
|
153
|
+
// Dates
|
|
154
|
+
hireDate: string | null
|
|
155
|
+
termDate: string | null
|
|
156
|
+
adjustedServiceDate: string | null
|
|
157
|
+
|
|
158
|
+
// Metadata
|
|
159
|
+
source: string | null
|
|
160
|
+
createdAt: string | null
|
|
161
|
+
updatedAtJulian: number | null
|
|
162
|
+
updatedAt: string | null
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Business Units
|
|
38
169
|
|
|
39
170
|
```typescript
|
|
40
171
|
const units = await client.getBusinessUnits()
|
|
41
172
|
const dropdown = await client.getBusinessUnitsDropdown() // { value, label }[]
|
|
42
173
|
const unit = await client.getBusinessUnit('BU001')
|
|
174
|
+
|
|
175
|
+
// Search by description (case-insensitive partial match)
|
|
176
|
+
const results = await client.searchBusinessUnits('west')
|
|
43
177
|
```
|
|
44
178
|
|
|
45
|
-
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## Cost Codes
|
|
46
182
|
|
|
47
183
|
```typescript
|
|
48
184
|
const codes = await client.getCostcodes()
|
|
49
185
|
const dropdown = await client.getCostcodesDropdown() // { value, label }[]
|
|
50
186
|
const code = await client.getCostcode('CC001')
|
|
187
|
+
|
|
188
|
+
// Filtered by business unit
|
|
189
|
+
const buDropdown = await client.getCostcodesDropdownByBu('BU001')
|
|
190
|
+
|
|
191
|
+
// Filtered by business unit and pay type
|
|
192
|
+
const buPtDropdown = await client.getCostcodesDropdownByBuAndPayType('BU001', 'PT01')
|
|
193
|
+
|
|
194
|
+
// Search by description or JDE cost code (case-insensitive partial match)
|
|
195
|
+
const results = await client.searchCostcodes('labor')
|
|
51
196
|
```
|
|
52
197
|
|
|
53
|
-
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## Pay Types
|
|
54
201
|
|
|
55
202
|
```typescript
|
|
56
203
|
const types = await client.getPaytypes()
|
|
57
204
|
const dropdown = await client.getPaytypesDropdown() // { value, label, payClass }[]
|
|
58
205
|
const type = await client.getPaytype('PT001')
|
|
206
|
+
|
|
207
|
+
// Search by description (case-insensitive partial match)
|
|
208
|
+
const results = await client.searchPaytypes('regular')
|
|
59
209
|
```
|
|
60
210
|
|
|
61
|
-
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## Work Orders
|
|
62
214
|
|
|
63
215
|
```typescript
|
|
64
216
|
const orders = await client.getWorkorders()
|
|
65
217
|
const dropdown = await client.getWorkordersDropdown() // { value, label }[]
|
|
66
218
|
const order = await client.getWorkorder('WO001')
|
|
219
|
+
|
|
220
|
+
// Filtered by business unit
|
|
221
|
+
const buDropdown = await client.getWorkordersDropdownByBu('BU001')
|
|
222
|
+
|
|
223
|
+
// Search by description or client work order ID (case-insensitive partial match)
|
|
224
|
+
const results = await client.searchWorkorders('pipe')
|
|
67
225
|
```
|
|
68
226
|
|
|
69
|
-
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## Job Type / Job Steps
|
|
70
230
|
|
|
71
231
|
```typescript
|
|
72
232
|
const items = await client.getJobtypejobsteps()
|
|
@@ -74,26 +234,83 @@ const dropdown = await client.getJobtypejobstepsDropdown() // { value, label }[]
|
|
|
74
234
|
const item = await client.getJobtypejobstep('JTJS001')
|
|
75
235
|
```
|
|
76
236
|
|
|
77
|
-
|
|
237
|
+
---
|
|
78
238
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
239
|
+
## LLM
|
|
240
|
+
|
|
241
|
+
### Chat completion
|
|
82
242
|
|
|
83
|
-
|
|
243
|
+
```typescript
|
|
84
244
|
const result = await client.chat({
|
|
85
245
|
messages: [{ role: 'user', content: 'Summarize this document...' }],
|
|
86
|
-
source: 'my-app',
|
|
87
|
-
user: 'jane.doe',
|
|
88
|
-
function: 'summarize',
|
|
246
|
+
source: 'my-app', // your application name
|
|
247
|
+
user: 'jane.doe', // user identifier for logging
|
|
248
|
+
function: 'summarize', // optional label for logging
|
|
249
|
+
temperature: 0.7, // optional, default 0.7
|
|
250
|
+
maxTokens: 1000, // optional
|
|
89
251
|
})
|
|
252
|
+
|
|
90
253
|
console.log(result.message.content)
|
|
91
254
|
console.log(result.usage) // { tokensIn, tokensOut, totalTokens }
|
|
92
255
|
```
|
|
93
256
|
|
|
94
|
-
|
|
257
|
+
### Streaming chat
|
|
95
258
|
|
|
96
|
-
|
|
259
|
+
Returns a raw SSE `Response` for you to proxy or consume directly.
|
|
260
|
+
|
|
261
|
+
```typescript
|
|
262
|
+
const response = await client.chatStream({
|
|
263
|
+
messages: [{ role: 'user', content: 'Hello' }],
|
|
264
|
+
userContext: { name: 'Jane Doe', department: 'Engineering', roles: ['admin'] },
|
|
265
|
+
useRag: true, // optional, search document knowledge base
|
|
266
|
+
tools: ['...'], // optional
|
|
267
|
+
source: 'my-app',
|
|
268
|
+
})
|
|
269
|
+
|
|
270
|
+
// Proxy to the browser, or read the SSE stream directly
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### LLM logs
|
|
274
|
+
|
|
275
|
+
```typescript
|
|
276
|
+
const logs = await client.getLlmLogs() // newest first
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
## Documents (RAG)
|
|
282
|
+
|
|
283
|
+
Upload and search documents in the knowledge base.
|
|
284
|
+
|
|
285
|
+
```typescript
|
|
286
|
+
// Upload a document (PDF or CSV)
|
|
287
|
+
const doc = await client.uploadDocument('report.pdf', base64Content, 'jane.doe')
|
|
288
|
+
|
|
289
|
+
// List all documents
|
|
290
|
+
const docs = await client.listDocuments()
|
|
291
|
+
|
|
292
|
+
// Search with a natural language query
|
|
293
|
+
const results = await client.searchDocuments('overtime policy', 5)
|
|
294
|
+
// results: { chunkId, content, fileName, documentType, score }[]
|
|
295
|
+
|
|
296
|
+
// Delete a document and all its chunks
|
|
297
|
+
await client.deleteDocument(doc.id)
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
---
|
|
301
|
+
|
|
302
|
+
## Cache management
|
|
303
|
+
|
|
304
|
+
All GET methods cache responses client-side for `cacheTtl` milliseconds (default 5 minutes). To invalidate:
|
|
305
|
+
|
|
306
|
+
```typescript
|
|
307
|
+
client.clearCache() // clear everything
|
|
308
|
+
client.clearCache('/employees') // clear a specific path
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
---
|
|
312
|
+
|
|
313
|
+
## Types
|
|
97
314
|
|
|
98
315
|
```typescript
|
|
99
316
|
import type {
|
|
@@ -107,15 +324,21 @@ import type {
|
|
|
107
324
|
ChatMessage,
|
|
108
325
|
ChatRequest,
|
|
109
326
|
ChatResponse,
|
|
327
|
+
StreamChatRequest,
|
|
328
|
+
StreamChatUserContext,
|
|
329
|
+
DocumentRecord,
|
|
330
|
+
SearchResult,
|
|
110
331
|
ApiHubClientOptions,
|
|
111
332
|
DropdownOption,
|
|
112
333
|
PaytypeDropdownOption,
|
|
113
334
|
} from '@brownandroot/api'
|
|
114
335
|
```
|
|
115
336
|
|
|
116
|
-
|
|
337
|
+
---
|
|
117
338
|
|
|
118
|
-
|
|
339
|
+
## Error handling
|
|
340
|
+
|
|
341
|
+
All methods throw an `Error` when the API returns a non-OK response. The error message contains the server's detail or the HTTP status.
|
|
119
342
|
|
|
120
343
|
```typescript
|
|
121
344
|
try {
|
|
@@ -124,3 +347,5 @@ try {
|
|
|
124
347
|
console.error(err.message) // "Employee not found"
|
|
125
348
|
}
|
|
126
349
|
```
|
|
350
|
+
|
|
351
|
+
`verifyIdentity` is the exception — it returns `null` when no employee matches the inputs, and only throws for request errors (400, 503, network failure).
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { query } from '$app/server';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { getClient } from './client.js';
|
|
4
|
+
export const getBusinessUnits = query(async () => getClient().getBusinessUnits());
|
|
5
|
+
export const getBusinessUnitsDropdown = query(async () => getClient().getBusinessUnitsDropdown());
|
|
6
|
+
export const getBusinessUnit = query(z.string(), async (id) => getClient().getBusinessUnit(id));
|
|
7
|
+
export const searchBusinessUnits = query(z.string(), async (q) => getClient().searchBusinessUnits(q));
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ApiHubClient } from './index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Returns a singleton ApiHubClient configured from the consuming app's
|
|
4
|
+
* APIHUB_URL and APIHUB_API_KEY environment variables.
|
|
5
|
+
*
|
|
6
|
+
* Must only be called inside remote function bodies (server-side only).
|
|
7
|
+
*/
|
|
8
|
+
export declare function getClient(): ApiHubClient;
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { env } from '$env/dynamic/private';
|
|
2
|
+
import { ApiHubClient } from './index.js';
|
|
3
|
+
let _client = null;
|
|
4
|
+
/**
|
|
5
|
+
* Returns a singleton ApiHubClient configured from the consuming app's
|
|
6
|
+
* APIHUB_URL and APIHUB_API_KEY environment variables.
|
|
7
|
+
*
|
|
8
|
+
* Must only be called inside remote function bodies (server-side only).
|
|
9
|
+
*/
|
|
10
|
+
export function getClient() {
|
|
11
|
+
if (!_client) {
|
|
12
|
+
const baseUrl = env.APIHUB_URL;
|
|
13
|
+
const apiKey = env.APIHUB_API_KEY;
|
|
14
|
+
if (!baseUrl)
|
|
15
|
+
throw new Error('APIHUB_URL environment variable is not set');
|
|
16
|
+
if (!apiKey)
|
|
17
|
+
throw new Error('APIHUB_API_KEY environment variable is not set');
|
|
18
|
+
_client = new ApiHubClient({ baseUrl, apiKey });
|
|
19
|
+
}
|
|
20
|
+
return _client;
|
|
21
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const getCostcodes: any;
|
|
2
|
+
export declare const getCostcodesDropdown: any;
|
|
3
|
+
export declare const getCostcode: any;
|
|
4
|
+
export declare const getCostcodesDropdownByBu: any;
|
|
5
|
+
export declare const getCostcodesDropdownByBuAndPayType: any;
|
|
6
|
+
export declare const searchCostcodes: any;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { query } from '$app/server';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { getClient } from './client.js';
|
|
4
|
+
const buPayTypeSchema = z.object({
|
|
5
|
+
businessUnitId: z.string(),
|
|
6
|
+
payTypeCode: z.string(),
|
|
7
|
+
});
|
|
8
|
+
export const getCostcodes = query(async () => getClient().getCostcodes());
|
|
9
|
+
export const getCostcodesDropdown = query(async () => getClient().getCostcodesDropdown());
|
|
10
|
+
export const getCostcode = query(z.string(), async (id) => getClient().getCostcode(id));
|
|
11
|
+
export const getCostcodesDropdownByBu = query(z.string(), async (businessUnitId) => getClient().getCostcodesDropdownByBu(businessUnitId));
|
|
12
|
+
export const getCostcodesDropdownByBuAndPayType = query(buPayTypeSchema, async ({ businessUnitId, payTypeCode }) => getClient().getCostcodesDropdownByBuAndPayType(businessUnitId, payTypeCode));
|
|
13
|
+
export const searchCostcodes = query(z.string(), async (q) => getClient().searchCostcodes(q));
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const getEmployees: any;
|
|
2
|
+
export declare const getEmployeesDropdown: any;
|
|
3
|
+
export declare const getEmployee: any;
|
|
4
|
+
export declare const searchByName: any;
|
|
5
|
+
export declare const getBySupervisor: any;
|
|
6
|
+
export declare const searchByEmail: any;
|
|
7
|
+
export declare const getSupervisorChain: any;
|
|
8
|
+
export declare const getJdeFromEmail: any;
|
|
9
|
+
export declare const searchByHbu: any;
|
|
10
|
+
export declare const verifyIdentity: any;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { query, command } from '$app/server';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { getClient } from './client.js';
|
|
4
|
+
const employeeIdSchema = z.string().min(1);
|
|
5
|
+
const verifyIdentitySchema = z.object({
|
|
6
|
+
first3FirstName: z.string(),
|
|
7
|
+
first3LastName: z.string(),
|
|
8
|
+
dob: z.string(),
|
|
9
|
+
ssn4: z.string(),
|
|
10
|
+
});
|
|
11
|
+
export const getEmployees = query(async () => getClient().getEmployees());
|
|
12
|
+
export const getEmployeesDropdown = query(async () => getClient().getEmployeesDropdown());
|
|
13
|
+
export const getEmployee = query(employeeIdSchema, async (employeeId) => getClient().getEmployee(employeeId));
|
|
14
|
+
export const searchByName = query(z.string(), async (name) => getClient().searchByName(name));
|
|
15
|
+
export const getBySupervisor = query(employeeIdSchema, async (supervisorId) => getClient().getBySupervisor(supervisorId));
|
|
16
|
+
export const searchByEmail = query(z.string(), async (email) => getClient().searchByEmail(email));
|
|
17
|
+
export const getSupervisorChain = query(employeeIdSchema, async (employeeId) => getClient().getSupervisorChain(employeeId));
|
|
18
|
+
export const getJdeFromEmail = query(z.string(), async (email) => getClient().getJdeFromEmail(email));
|
|
19
|
+
export const searchByHbu = query(z.string(), async (hbu) => getClient().searchByHbu(hbu));
|
|
20
|
+
export const verifyIdentity = command(verifyIdentitySchema, async (inputs) => getClient().verifyIdentity(inputs));
|
package/dist/index.d.ts
CHANGED
|
@@ -231,17 +231,16 @@ export declare class ApiHubClient {
|
|
|
231
231
|
/** Search employees by home business unit (case-insensitive partial match) */
|
|
232
232
|
searchByHbu(hbu: string): Promise<Employee[]>;
|
|
233
233
|
/**
|
|
234
|
-
* Verify an employee's identity
|
|
235
|
-
*
|
|
234
|
+
* Verify an employee's identity from name/dob/SSN inputs alone — no employee ID needed.
|
|
235
|
+
* Returns the Employee on a match, or null if no employee matches the inputs.
|
|
236
|
+
* Throws on 400 (missing fields) or 503 (not configured server-side).
|
|
236
237
|
*/
|
|
237
|
-
verifyIdentity(
|
|
238
|
+
verifyIdentity(inputs: {
|
|
238
239
|
first3FirstName: string;
|
|
239
240
|
first3LastName: string;
|
|
240
241
|
dob: string;
|
|
241
242
|
ssn4: string;
|
|
242
|
-
}): Promise<
|
|
243
|
-
verified: boolean;
|
|
244
|
-
}>;
|
|
243
|
+
}): Promise<Employee | null>;
|
|
245
244
|
/** List all LLM log entries (newest first) */
|
|
246
245
|
getLlmLogs(): Promise<LlmLog[]>;
|
|
247
246
|
/** Send a chat completion request to the LLM */
|
|
@@ -259,6 +258,7 @@ export declare class ApiHubClient {
|
|
|
259
258
|
getBusinessUnits(): Promise<BusinessUnit[]>;
|
|
260
259
|
getBusinessUnitsDropdown(): Promise<DropdownOption[]>;
|
|
261
260
|
getBusinessUnit(id: string): Promise<BusinessUnit>;
|
|
261
|
+
searchBusinessUnits(q: string): Promise<BusinessUnit[]>;
|
|
262
262
|
getCostcodes(): Promise<Costcode[]>;
|
|
263
263
|
getCostcodesDropdown(): Promise<DropdownOption[]>;
|
|
264
264
|
getCostcode(id: string): Promise<Costcode>;
|
|
@@ -266,14 +266,17 @@ export declare class ApiHubClient {
|
|
|
266
266
|
getCostcodesDropdownByBu(businessUnitId: string): Promise<DropdownOption[]>;
|
|
267
267
|
/** Get cost codes for a specific business unit and pay type, formatted for dropdown controls */
|
|
268
268
|
getCostcodesDropdownByBuAndPayType(businessUnitId: string, payTypeCode: string): Promise<DropdownOption[]>;
|
|
269
|
+
searchCostcodes(q: string): Promise<Costcode[]>;
|
|
269
270
|
getPaytypes(): Promise<Paytype[]>;
|
|
270
271
|
getPaytypesDropdown(): Promise<PaytypeDropdownOption[]>;
|
|
271
272
|
getPaytype(id: string): Promise<Paytype>;
|
|
273
|
+
searchPaytypes(q: string): Promise<Paytype[]>;
|
|
272
274
|
getWorkorders(): Promise<Workorder[]>;
|
|
273
275
|
getWorkordersDropdown(): Promise<DropdownOption[]>;
|
|
274
276
|
/** Get work orders for a specific business unit, formatted for dropdown controls */
|
|
275
277
|
getWorkordersDropdownByBu(businessUnitId: string): Promise<DropdownOption[]>;
|
|
276
278
|
getWorkorder(id: string): Promise<Workorder>;
|
|
279
|
+
searchWorkorders(q: string): Promise<Workorder[]>;
|
|
277
280
|
getJobtypejobsteps(): Promise<Jobtypejobstep[]>;
|
|
278
281
|
getJobtypejobstepsDropdown(): Promise<DropdownOption[]>;
|
|
279
282
|
getJobtypejobstep(id: string): Promise<Jobtypejobstep>;
|
package/dist/index.js
CHANGED
|
@@ -86,21 +86,24 @@ export class ApiHubClient {
|
|
|
86
86
|
return this.request(`/employees/search?hbu=${encodeURIComponent(hbu)}`);
|
|
87
87
|
}
|
|
88
88
|
/**
|
|
89
|
-
* Verify an employee's identity
|
|
90
|
-
*
|
|
89
|
+
* Verify an employee's identity from name/dob/SSN inputs alone — no employee ID needed.
|
|
90
|
+
* Returns the Employee on a match, or null if no employee matches the inputs.
|
|
91
|
+
* Throws on 400 (missing fields) or 503 (not configured server-side).
|
|
91
92
|
*/
|
|
92
|
-
async verifyIdentity(
|
|
93
|
+
async verifyIdentity(inputs) {
|
|
93
94
|
let res;
|
|
94
95
|
try {
|
|
95
|
-
res = await fetch(`${this.baseUrl}/employees
|
|
96
|
+
res = await fetch(`${this.baseUrl}/employees/verify-identity`, {
|
|
96
97
|
method: 'POST',
|
|
97
98
|
headers: { 'x-api-key': this.apiKey, 'Content-Type': 'application/json' },
|
|
98
99
|
body: JSON.stringify(inputs),
|
|
99
100
|
});
|
|
100
101
|
}
|
|
101
102
|
catch {
|
|
102
|
-
throw new Error(`APIHub unavailable: ${this.baseUrl}/employees
|
|
103
|
+
throw new Error(`APIHub unavailable: ${this.baseUrl}/employees/verify-identity`);
|
|
103
104
|
}
|
|
105
|
+
if (res.status === 401)
|
|
106
|
+
return null;
|
|
104
107
|
if (!res.ok) {
|
|
105
108
|
const body = await res.json().catch(() => null);
|
|
106
109
|
const message = (body && typeof body === 'object' && 'error' in body && typeof body.error === 'string' ? body.error : null) ??
|
|
@@ -253,6 +256,9 @@ export class ApiHubClient {
|
|
|
253
256
|
async getBusinessUnit(id) {
|
|
254
257
|
return this.request(`/business-units/${encodeURIComponent(id)}`);
|
|
255
258
|
}
|
|
259
|
+
async searchBusinessUnits(q) {
|
|
260
|
+
return this.request(`/business-units/search?q=${encodeURIComponent(q)}`);
|
|
261
|
+
}
|
|
256
262
|
// -----------------------------------------------------------------------
|
|
257
263
|
// Cost Codes
|
|
258
264
|
// -----------------------------------------------------------------------
|
|
@@ -273,6 +279,9 @@ export class ApiHubClient {
|
|
|
273
279
|
async getCostcodesDropdownByBuAndPayType(businessUnitId, payTypeCode) {
|
|
274
280
|
return this.cachedRequest(`/costcodes/by-bu/${encodeURIComponent(businessUnitId)}/by-paytype/${encodeURIComponent(payTypeCode)}/dropdown`);
|
|
275
281
|
}
|
|
282
|
+
async searchCostcodes(q) {
|
|
283
|
+
return this.request(`/costcodes/search?q=${encodeURIComponent(q)}`);
|
|
284
|
+
}
|
|
276
285
|
// -----------------------------------------------------------------------
|
|
277
286
|
// Pay Types
|
|
278
287
|
// -----------------------------------------------------------------------
|
|
@@ -285,6 +294,9 @@ export class ApiHubClient {
|
|
|
285
294
|
async getPaytype(id) {
|
|
286
295
|
return this.request(`/paytypes/${encodeURIComponent(id)}`);
|
|
287
296
|
}
|
|
297
|
+
async searchPaytypes(q) {
|
|
298
|
+
return this.request(`/paytypes/search?q=${encodeURIComponent(q)}`);
|
|
299
|
+
}
|
|
288
300
|
// -----------------------------------------------------------------------
|
|
289
301
|
// Work Orders
|
|
290
302
|
// -----------------------------------------------------------------------
|
|
@@ -301,6 +313,9 @@ export class ApiHubClient {
|
|
|
301
313
|
async getWorkorder(id) {
|
|
302
314
|
return this.request(`/workorders/${encodeURIComponent(id)}`);
|
|
303
315
|
}
|
|
316
|
+
async searchWorkorders(q) {
|
|
317
|
+
return this.request(`/workorders/search?q=${encodeURIComponent(q)}`);
|
|
318
|
+
}
|
|
304
319
|
// -----------------------------------------------------------------------
|
|
305
320
|
// Job Type / Job Steps
|
|
306
321
|
// -----------------------------------------------------------------------
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { query } from '$app/server';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { getClient } from './client.js';
|
|
4
|
+
export const getJobtypejobsteps = query(async () => getClient().getJobtypejobsteps());
|
|
5
|
+
export const getJobtypejobstepsDropdown = query(async () => getClient().getJobtypejobstepsDropdown());
|
|
6
|
+
export const getJobtypejobstep = query(z.string(), async (id) => getClient().getJobtypejobstep(id));
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { query, command } from '$app/server';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { getClient } from './client.js';
|
|
4
|
+
const chatMessageSchema = z.object({
|
|
5
|
+
role: z.enum(['system', 'user', 'assistant']),
|
|
6
|
+
content: z.string(),
|
|
7
|
+
});
|
|
8
|
+
const chatRequestSchema = z.object({
|
|
9
|
+
messages: z.array(chatMessageSchema),
|
|
10
|
+
source: z.string(),
|
|
11
|
+
user: z.string(),
|
|
12
|
+
function: z.string().optional(),
|
|
13
|
+
temperature: z.number().min(0).max(2).optional(),
|
|
14
|
+
maxTokens: z.number().int().positive().optional(),
|
|
15
|
+
});
|
|
16
|
+
export const getLlmLogs = query(async () => getClient().getLlmLogs());
|
|
17
|
+
export const chat = command(chatRequestSchema, async (request) => getClient().chat(request));
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { query } from '$app/server';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { getClient } from './client.js';
|
|
4
|
+
export const getPaytypes = query(async () => getClient().getPaytypes());
|
|
5
|
+
export const getPaytypesDropdown = query(async () => getClient().getPaytypesDropdown());
|
|
6
|
+
export const getPaytype = query(z.string(), async (id) => getClient().getPaytype(id));
|
|
7
|
+
export const searchPaytypes = query(z.string(), async (q) => getClient().searchPaytypes(q));
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { query, command } from '$app/server';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { getClient } from './client.js';
|
|
4
|
+
const uploadDocumentSchema = z.object({
|
|
5
|
+
fileName: z.string().min(1),
|
|
6
|
+
base64Content: z.string().min(1),
|
|
7
|
+
uploadedBy: z.string().min(1),
|
|
8
|
+
});
|
|
9
|
+
const searchDocumentsSchema = z.object({
|
|
10
|
+
query: z.string().min(1),
|
|
11
|
+
topK: z.number().int().positive().optional(),
|
|
12
|
+
});
|
|
13
|
+
export const listDocuments = query(async () => getClient().listDocuments());
|
|
14
|
+
export const uploadDocument = command(uploadDocumentSchema, async ({ fileName, base64Content, uploadedBy }) => getClient().uploadDocument(fileName, base64Content, uploadedBy));
|
|
15
|
+
export const deleteDocument = command(z.number().int().positive(), async (id) => getClient().deleteDocument(id));
|
|
16
|
+
export const searchDocuments = command(searchDocumentsSchema, async ({ query: q, topK }) => getClient().searchDocuments(q, topK));
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { query } from '$app/server';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { getClient } from './client.js';
|
|
4
|
+
export const getWorkorders = query(async () => getClient().getWorkorders());
|
|
5
|
+
export const getWorkordersDropdown = query(async () => getClient().getWorkordersDropdown());
|
|
6
|
+
export const getWorkordersDropdownByBu = query(z.string(), async (businessUnitId) => getClient().getWorkordersDropdownByBu(businessUnitId));
|
|
7
|
+
export const getWorkorder = query(z.string(), async (id) => getClient().getWorkorder(id));
|
|
8
|
+
export const searchWorkorders = query(z.string(), async (q) => getClient().searchWorkorders(q));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brownandroot/api",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -11,19 +11,71 @@
|
|
|
11
11
|
"types": "./dist/index.d.ts",
|
|
12
12
|
"exports": {
|
|
13
13
|
".": {
|
|
14
|
-
"
|
|
15
|
-
"
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"default": "./dist/index.js"
|
|
16
|
+
},
|
|
17
|
+
"./employees": {
|
|
18
|
+
"types": "./dist/employees.remote.d.ts",
|
|
19
|
+
"default": "./dist/employees.remote.js"
|
|
20
|
+
},
|
|
21
|
+
"./businessUnits": {
|
|
22
|
+
"types": "./dist/businessUnits.remote.d.ts",
|
|
23
|
+
"default": "./dist/businessUnits.remote.js"
|
|
24
|
+
},
|
|
25
|
+
"./costcodes": {
|
|
26
|
+
"types": "./dist/costcodes.remote.d.ts",
|
|
27
|
+
"default": "./dist/costcodes.remote.js"
|
|
28
|
+
},
|
|
29
|
+
"./paytypes": {
|
|
30
|
+
"types": "./dist/paytypes.remote.d.ts",
|
|
31
|
+
"default": "./dist/paytypes.remote.js"
|
|
32
|
+
},
|
|
33
|
+
"./workorders": {
|
|
34
|
+
"types": "./dist/workorders.remote.d.ts",
|
|
35
|
+
"default": "./dist/workorders.remote.js"
|
|
36
|
+
},
|
|
37
|
+
"./jobtypejobsteps": {
|
|
38
|
+
"types": "./dist/jobtypejobsteps.remote.d.ts",
|
|
39
|
+
"default": "./dist/jobtypejobsteps.remote.js"
|
|
40
|
+
},
|
|
41
|
+
"./llm": {
|
|
42
|
+
"types": "./dist/llm.remote.d.ts",
|
|
43
|
+
"default": "./dist/llm.remote.js"
|
|
44
|
+
},
|
|
45
|
+
"./rag": {
|
|
46
|
+
"types": "./dist/rag.remote.d.ts",
|
|
47
|
+
"default": "./dist/rag.remote.js"
|
|
16
48
|
}
|
|
17
49
|
},
|
|
18
50
|
"files": [
|
|
19
51
|
"dist"
|
|
20
52
|
],
|
|
21
53
|
"scripts": {
|
|
22
|
-
"
|
|
23
|
-
"
|
|
54
|
+
"prepare": "bun svelte-kit sync || echo ''",
|
|
55
|
+
"build": "bun svelte-kit sync && bun svelte-package",
|
|
56
|
+
"prepublishOnly": "bun run build",
|
|
24
57
|
"publish:manual": "npm publish --access public"
|
|
25
58
|
},
|
|
59
|
+
"peerDependencies": {
|
|
60
|
+
"@sveltejs/kit": "^2.0.0",
|
|
61
|
+
"svelte": "^5.0.0"
|
|
62
|
+
},
|
|
63
|
+
"peerDependenciesMeta": {
|
|
64
|
+
"@sveltejs/kit": {
|
|
65
|
+
"optional": true
|
|
66
|
+
},
|
|
67
|
+
"svelte": {
|
|
68
|
+
"optional": true
|
|
69
|
+
}
|
|
70
|
+
},
|
|
26
71
|
"devDependencies": {
|
|
27
|
-
"
|
|
72
|
+
"@sveltejs/adapter-node": "^5.0.0",
|
|
73
|
+
"@sveltejs/kit": "^2.0.0",
|
|
74
|
+
"@sveltejs/package": "^2.0.0",
|
|
75
|
+
"@sveltejs/vite-plugin-svelte": "^6.0.0",
|
|
76
|
+
"svelte": "^5.0.0",
|
|
77
|
+
"typescript": "^5.0.0",
|
|
78
|
+
"vite": "^6.0.0",
|
|
79
|
+
"zod": "^3.0.0"
|
|
28
80
|
}
|
|
29
81
|
}
|