@brownandroot/api 1.2.1 → 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 +90 -471
- package/dist/businessUnits.remote.d.ts +5 -3
- package/dist/businessUnits.remote.js +23 -3
- package/dist/cache.d.ts +51 -28
- package/dist/cache.js +202 -48
- package/dist/costcodes.remote.d.ts +5 -3
- package/dist/costcodes.remote.js +23 -3
- package/dist/employees.remote.d.ts +17 -15
- package/dist/employees.remote.js +31 -7
- package/dist/index.d.ts +34 -0
- package/dist/index.js +110 -12
- package/dist/jobtypejobsteps.remote.d.ts +5 -3
- package/dist/jobtypejobsteps.remote.js +23 -3
- package/dist/llm.remote.d.ts +14 -12
- package/dist/llm.remote.js +6 -2
- package/dist/paytypes.remote.d.ts +5 -3
- package/dist/paytypes.remote.js +23 -3
- package/dist/rag.remote.d.ts +13 -11
- package/dist/rag.remote.js +10 -4
- package/dist/workorders.remote.d.ts +5 -3
- package/dist/workorders.remote.js +23 -3
- package/package.json +1 -37
package/README.md
CHANGED
|
@@ -1,31 +1,33 @@
|
|
|
1
1
|
# @brownandroot/api
|
|
2
2
|
|
|
3
|
-
TypeScript
|
|
3
|
+
Unified TypeScript API for Brown & Root APIHub data.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
|
|
8
|
+
bun add @brownandroot/api
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
## One Import Path
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Use only:
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
```ts
|
|
16
|
+
import { employees, workorders, clearCache } from '@brownandroot/api'
|
|
17
|
+
```
|
|
16
18
|
|
|
17
|
-
|
|
19
|
+
No domain subpath imports are required.
|
|
18
20
|
|
|
19
|
-
|
|
21
|
+
## Setup
|
|
20
22
|
|
|
21
|
-
Add to your app
|
|
23
|
+
Add to your app `.env`:
|
|
22
24
|
|
|
23
|
-
```
|
|
25
|
+
```bash
|
|
24
26
|
APIHUB_URL=https://your-apihub-url.com
|
|
25
27
|
APIHUB_API_KEY=your-api-key
|
|
26
28
|
```
|
|
27
29
|
|
|
28
|
-
Enable remote functions
|
|
30
|
+
Enable SvelteKit remote functions if needed:
|
|
29
31
|
|
|
30
32
|
```js
|
|
31
33
|
kit: {
|
|
@@ -35,511 +37,128 @@ kit: {
|
|
|
35
37
|
}
|
|
36
38
|
```
|
|
37
39
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
```svelte
|
|
41
|
-
<script lang="ts">
|
|
42
|
-
import { getWorkordersDropdown, getEmployees, clearCache } from '@brownandroot/api/cache'
|
|
43
|
-
|
|
44
|
-
// First page load: fetches from server and caches in IndexedDB.
|
|
45
|
-
// Subsequent loads: returns from IndexedDB instantly, refreshes in background.
|
|
46
|
-
const workorders = $derived(await getWorkordersDropdown({ businessUnitId: 'BU001' }))
|
|
47
|
-
|
|
48
|
-
// Multiple filters compose freely
|
|
49
|
-
const employees = $derived(await getEmployees({
|
|
50
|
-
hbu: 'TX01',
|
|
51
|
-
payClass: 'H',
|
|
52
|
-
q: 'john',
|
|
53
|
-
}))
|
|
54
|
-
|
|
55
|
-
// After a mutation, clear the affected entity so the next read re-fetches
|
|
56
|
-
async function onCreate() {
|
|
57
|
-
await createWorkorder(formData)
|
|
58
|
-
clearCache('workorders')
|
|
59
|
-
}
|
|
60
|
-
</script>
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
### Filter reference
|
|
64
|
-
|
|
65
|
-
All filter fields are optional. Omit the filter object entirely to return all records.
|
|
66
|
-
|
|
67
|
-
#### Workorders
|
|
68
|
-
|
|
69
|
-
```typescript
|
|
70
|
-
import { getWorkorders, getWorkordersDropdown } from '@brownandroot/api/cache'
|
|
71
|
-
|
|
72
|
-
interface WorkorderFilters {
|
|
73
|
-
businessUnitId?: string // exact match
|
|
74
|
-
costCodeId?: string // exact match
|
|
75
|
-
isActive?: boolean // exact match
|
|
76
|
-
completed?: boolean // exact match
|
|
77
|
-
area?: string // exact match
|
|
78
|
-
parentWorkOrder?: string // exact match
|
|
79
|
-
q?: string // partial match on description or clientWorkOrderId
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// Returns Workorder[]
|
|
83
|
-
const all = await getWorkorders()
|
|
84
|
-
const active = await getWorkorders({ isActive: true })
|
|
85
|
-
const byBu = await getWorkorders({ businessUnitId: 'BU001', isActive: true })
|
|
86
|
-
const search = await getWorkorders({ q: 'pipe' })
|
|
87
|
-
|
|
88
|
-
// Returns { value, label }[] — always applies isActive: true by default
|
|
89
|
-
const dropdown = await getWorkordersDropdown({ businessUnitId: 'BU001' })
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
#### Employees
|
|
93
|
-
|
|
94
|
-
```typescript
|
|
95
|
-
import { getEmployees, getEmployeesDropdown } from '@brownandroot/api/cache'
|
|
96
|
-
|
|
97
|
-
interface EmployeeFilters {
|
|
98
|
-
businessUnitId?: string // exact match
|
|
99
|
-
hbu?: string // exact match on home business unit
|
|
100
|
-
supervisor?: string // exact match on supervisor employee ID
|
|
101
|
-
payClass?: string // exact match
|
|
102
|
-
jobType?: string // exact match
|
|
103
|
-
jobStep?: string // exact match
|
|
104
|
-
sector?: string // exact match
|
|
105
|
-
division?: string // exact match
|
|
106
|
-
q?: string // partial match on name or email
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
const byHbu = await getEmployees({ hbu: 'TX01' })
|
|
110
|
-
const byName = await getEmployees({ q: 'john' })
|
|
111
|
-
const dropdown = await getEmployeesDropdown({ businessUnitId: 'BU001' })
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
#### Cost Codes
|
|
115
|
-
|
|
116
|
-
```typescript
|
|
117
|
-
import { getCostcodes, getCostcodesDropdown } from '@brownandroot/api/cache'
|
|
118
|
-
|
|
119
|
-
interface CostcodeFilters {
|
|
120
|
-
businessUnitId?: string // exact match
|
|
121
|
-
isActive?: boolean // exact match
|
|
122
|
-
entryFlag?: boolean // exact match
|
|
123
|
-
payTypeCode?: string // resolves pay type → objectAccount, filters by match
|
|
124
|
-
q?: string // partial match on description or jdeCostCode
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
const byBu = await getCostcodes({ businessUnitId: 'BU001' })
|
|
128
|
-
const search = await getCostcodes({ q: 'labor' })
|
|
129
|
-
|
|
130
|
-
// Dropdown applies isActive: true and entryFlag: true by default,
|
|
131
|
-
// and also excludes expired cost codes
|
|
132
|
-
const dropdown = await getCostcodesDropdown({ businessUnitId: 'BU001' })
|
|
133
|
-
const dropdownByPayType = await getCostcodesDropdown({
|
|
134
|
-
businessUnitId: 'BU001',
|
|
135
|
-
payTypeCode: 'PT01',
|
|
136
|
-
})
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
> **payTypeCode cross-reference:** When `payTypeCode` is set, the filter looks up that pay type's `objectAccount` from the (also cached) pay types list and only returns cost codes whose `objectAccount` matches. If the pay type has no `objectAccount`, all cost codes pass this filter.
|
|
140
|
-
|
|
141
|
-
#### Pay Types
|
|
142
|
-
|
|
143
|
-
```typescript
|
|
144
|
-
import { getPaytypes, getPaytypesDropdown } from '@brownandroot/api/cache'
|
|
145
|
-
|
|
146
|
-
interface PaytypeFilters {
|
|
147
|
-
payClass?: string // exact match
|
|
148
|
-
category?: string // exact match
|
|
149
|
-
type?: string // exact match
|
|
150
|
-
isActive?: boolean // exact match
|
|
151
|
-
perDiemPayType?: boolean // exact match
|
|
152
|
-
q?: string // partial match on description
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
const hourly = await getPaytypes({ payClass: 'H' })
|
|
156
|
-
const dropdown = await getPaytypesDropdown({ isActive: true })
|
|
157
|
-
// Dropdown returns { value, label, payClass }[]
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
#### Business Units
|
|
161
|
-
|
|
162
|
-
```typescript
|
|
163
|
-
import { getBusinessUnits, getBusinessUnitsDropdown } from '@brownandroot/api/cache'
|
|
164
|
-
|
|
165
|
-
interface BusinessUnitFilters {
|
|
166
|
-
subsector?: string // exact match
|
|
167
|
-
isActive?: boolean // exact match
|
|
168
|
-
clientId?: string // exact match
|
|
169
|
-
q?: string // partial match on description or clientDescription
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
const active = await getBusinessUnits({ isActive: true })
|
|
173
|
-
const dropdown = await getBusinessUnitsDropdown({ subsector: 'Gulf Coast' })
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
#### Job Type / Job Steps
|
|
177
|
-
|
|
178
|
-
```typescript
|
|
179
|
-
import { getJobtypejobsteps, getJobtypejobstepsDropdown } from '@brownandroot/api/cache'
|
|
180
|
-
|
|
181
|
-
interface JobtypejobstepFilters {
|
|
182
|
-
jobType?: string // exact match
|
|
183
|
-
payclass?: string // exact match
|
|
184
|
-
isActive?: boolean // exact match
|
|
185
|
-
grp?: string // exact match
|
|
186
|
-
q?: string // partial match on description, jobType, or jobStep
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
const welders = await getJobtypejobsteps({ jobType: 'WE' })
|
|
190
|
-
const dropdown = await getJobtypejobstepsDropdown({ isActive: true })
|
|
191
|
-
```
|
|
192
|
-
|
|
193
|
-
### Single-record lookups
|
|
194
|
-
|
|
195
|
-
Single-record functions always fetch fresh from the server (no IndexedDB):
|
|
196
|
-
|
|
197
|
-
```typescript
|
|
198
|
-
import {
|
|
199
|
-
getEmployee,
|
|
200
|
-
getSupervisorChain,
|
|
201
|
-
getJdeFromEmail,
|
|
202
|
-
verifyIdentity,
|
|
203
|
-
getWorkorder,
|
|
204
|
-
getCostcode,
|
|
205
|
-
getPaytype,
|
|
206
|
-
getBusinessUnit,
|
|
207
|
-
getJobtypejobstep,
|
|
208
|
-
} from '@brownandroot/api/cache'
|
|
209
|
-
|
|
210
|
-
const emp = await getEmployee('12345')
|
|
211
|
-
const chain = await getSupervisorChain('12345')
|
|
212
|
-
const { jde, employee } = await getJdeFromEmail('john@example.com')
|
|
213
|
-
const verified = await verifyIdentity({
|
|
214
|
-
first3FirstName: 'joh',
|
|
215
|
-
first3LastName: 'doe',
|
|
216
|
-
dob: '1985-03-15',
|
|
217
|
-
ssn4: '4321',
|
|
218
|
-
})
|
|
219
|
-
```
|
|
220
|
-
|
|
221
|
-
### Cache management
|
|
222
|
-
|
|
223
|
-
```typescript
|
|
224
|
-
import { clearCache } from '@brownandroot/api/cache'
|
|
225
|
-
|
|
226
|
-
clearCache() // clear all entities
|
|
227
|
-
clearCache('workorders') // clear a specific entity
|
|
228
|
-
clearCache('employees')
|
|
229
|
-
clearCache('costcodes')
|
|
230
|
-
clearCache('paytypes')
|
|
231
|
-
clearCache('businessUnits')
|
|
232
|
-
clearCache('jobtypejobsteps')
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
Call `clearCache(entity)` immediately after any mutation that changes that entity so the next read fetches fresh data.
|
|
236
|
-
|
|
237
|
-
---
|
|
40
|
+
## Unified Domain Contract
|
|
238
41
|
|
|
239
|
-
|
|
42
|
+
Each listable domain exposes the same shape:
|
|
240
43
|
|
|
241
|
-
|
|
44
|
+
- `getAll(filters?)`
|
|
45
|
+
- `dropdown(filters?)`
|
|
46
|
+
- `get(id)` -> returns item or `null`
|
|
242
47
|
|
|
243
|
-
|
|
244
|
-
<script lang="ts">
|
|
245
|
-
import { getEmployees } from '@brownandroot/api/employees'
|
|
246
|
-
import { getBusinessUnits } from '@brownandroot/api/businessUnits'
|
|
48
|
+
Domains:
|
|
247
49
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
50
|
+
- `employees`
|
|
51
|
+
- `workorders`
|
|
52
|
+
- `costcodes`
|
|
53
|
+
- `paytypes`
|
|
54
|
+
- `businessUnits`
|
|
55
|
+
- `jobtypejobsteps`
|
|
56
|
+
- `llm`
|
|
57
|
+
- `rag`
|
|
255
58
|
|
|
256
|
-
|
|
257
|
-
import { query } from '$app/server'
|
|
258
|
-
import { getSupervisorChain } from '@brownandroot/api/employees'
|
|
59
|
+
## Caching Behavior
|
|
259
60
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
61
|
+
- Browser/client: IndexedDB stale-while-revalidate cache for `getAll` and `dropdown`
|
|
62
|
+
- Server/SSR: in-memory TTL cache for `getAll` and `dropdown`
|
|
63
|
+
- Single-record `get(id)` reads are fresh and return `null` when not found
|
|
64
|
+
- Read failures in SSR fail open by default in unified domain APIs:
|
|
65
|
+
- list reads return `[]`
|
|
66
|
+
- single reads return `null`
|
|
67
|
+
- chain/lookup helpers return safe empty defaults
|
|
264
68
|
|
|
265
|
-
|
|
69
|
+
## Error Diagnostics
|
|
266
70
|
|
|
267
|
-
|
|
71
|
+
The package now throws structured `ApiHubError` instances for request-layer failures.
|
|
268
72
|
|
|
269
|
-
|
|
73
|
+
`ApiHubError` includes:
|
|
270
74
|
|
|
271
|
-
|
|
75
|
+
- `status`
|
|
76
|
+
- `path`
|
|
77
|
+
- `url`
|
|
78
|
+
- `responseBody`
|
|
79
|
+
- `retriable`
|
|
80
|
+
- `service`
|
|
272
81
|
|
|
273
|
-
|
|
82
|
+
Request layer behavior:
|
|
274
83
|
|
|
275
|
-
|
|
84
|
+
- timeout with `AbortController` (default `10000ms`)
|
|
85
|
+
- retries for idempotent GETs on `429/502/503/504` (default `retryCount: 2`)
|
|
86
|
+
- optional `onError` callback via `ApiHubClient` options
|
|
276
87
|
|
|
277
|
-
|
|
278
|
-
import { ApiHubClient } from '@brownandroot/api'
|
|
88
|
+
Dropdown defaults:
|
|
279
89
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
apiKey: 'your-api-key',
|
|
283
|
-
cacheTtl: 5 * 60 * 1000, // optional, default 5 minutes (0 to disable)
|
|
284
|
-
})
|
|
285
|
-
```
|
|
90
|
+
- Domains with `isActive` automatically default `isActive: true` for `dropdown(filters?)`
|
|
91
|
+
- Caller can override by passing `isActive` explicitly
|
|
286
92
|
|
|
287
|
-
|
|
93
|
+
## Examples
|
|
288
94
|
|
|
289
|
-
|
|
95
|
+
### Workorders
|
|
290
96
|
|
|
291
|
-
|
|
97
|
+
```ts
|
|
98
|
+
import { workorders } from '@brownandroot/api'
|
|
292
99
|
|
|
293
|
-
|
|
294
|
-
const
|
|
295
|
-
const
|
|
296
|
-
const employee = await client.getEmployee('12345') // throws if not found
|
|
297
|
-
const employeePrivileged = await client.getEmployeePrivileged('12345') // includes hourlyRate and annualSalary
|
|
100
|
+
const rows = await workorders.getAll({ businessUnitId: 'BU001' })
|
|
101
|
+
const options = await workorders.dropdown({ businessUnitId: 'BU001' })
|
|
102
|
+
const one = await workorders.get('WO001') // Workorder | null
|
|
298
103
|
```
|
|
299
104
|
|
|
300
|
-
###
|
|
105
|
+
### Employees
|
|
301
106
|
|
|
302
|
-
```
|
|
303
|
-
|
|
304
|
-
```
|
|
305
|
-
|
|
306
|
-
### Email → JDE lookup
|
|
307
|
-
|
|
308
|
-
```typescript
|
|
309
|
-
const { jde, employee } = await client.getJdeFromEmail('john@example.com')
|
|
310
|
-
// jde: string | null
|
|
311
|
-
// employee: Employee | null
|
|
312
|
-
```
|
|
107
|
+
```ts
|
|
108
|
+
import { employees } from '@brownandroot/api'
|
|
313
109
|
|
|
314
|
-
|
|
110
|
+
const crew = await employees.getAll({ hbu: 'TX01', q: 'john' })
|
|
111
|
+
const list = await employees.dropdown({ businessUnitId: 'BU001' })
|
|
112
|
+
const emp = await employees.get('12345')
|
|
315
113
|
|
|
316
|
-
|
|
317
|
-
const
|
|
114
|
+
const privileged = await employees.getPrivileged('12345')
|
|
115
|
+
const chain = await employees.getSupervisorChain('12345')
|
|
116
|
+
const jde = await employees.getJdeFromEmail('john@example.com')
|
|
117
|
+
const verified = await employees.verifyIdentity({
|
|
318
118
|
first3FirstName: 'joh',
|
|
319
119
|
first3LastName: 'doe',
|
|
320
120
|
dob: '1985-03-15',
|
|
321
121
|
ssn4: '4321',
|
|
322
122
|
})
|
|
323
|
-
// Employee on match, null on no match
|
|
324
|
-
// Throws on 400 (missing fields) or 503 (not configured server-side)
|
|
325
|
-
```
|
|
326
|
-
|
|
327
|
-
### Employee fields
|
|
328
|
-
|
|
329
|
-
```typescript
|
|
330
|
-
interface Employee {
|
|
331
|
-
employeeId: string
|
|
332
|
-
name: string | null
|
|
333
|
-
email: string | null
|
|
334
|
-
personalEmail: string | null
|
|
335
|
-
clientEmail: string | null
|
|
336
|
-
workEmail: string | null
|
|
337
|
-
badgeNumber: string | null
|
|
338
|
-
nccerNumber: string | null
|
|
339
|
-
company: string | null
|
|
340
|
-
businessUnitId: string | null
|
|
341
|
-
hbu: string | null
|
|
342
|
-
departmentCode: string | null
|
|
343
|
-
division: string | null
|
|
344
|
-
sector: string | null
|
|
345
|
-
subsector: string | null
|
|
346
|
-
phone: string | null
|
|
347
|
-
employementStatus: string | null
|
|
348
|
-
employeePayStatus: string | null
|
|
349
|
-
recordType: string | null
|
|
350
|
-
jobType: string | null
|
|
351
|
-
jobStep: string | null
|
|
352
|
-
jobDescription: string | null
|
|
353
|
-
workSchedule: string | null
|
|
354
|
-
shift: string | null
|
|
355
|
-
payClass: string | null
|
|
356
|
-
payFrequency: string | null
|
|
357
|
-
payCycleCode: string | null
|
|
358
|
-
checkRouteCode: string | null
|
|
359
|
-
residentTaxArea: string | null
|
|
360
|
-
workTaxArea: string | null
|
|
361
|
-
benefitGroup: string | null
|
|
362
|
-
topFlexPtoDate: string | null
|
|
363
|
-
clientPtoDate: string | null
|
|
364
|
-
securityLevel: string | null
|
|
365
|
-
reportingLevel: string | null
|
|
366
|
-
supervisor: string | null
|
|
367
|
-
mentor: string | null
|
|
368
|
-
hireDate: string | null
|
|
369
|
-
termDate: string | null
|
|
370
|
-
adjustedServiceDate: string | null
|
|
371
|
-
identityHash: string | null
|
|
372
|
-
source: string | null
|
|
373
|
-
createdAt: string | null
|
|
374
|
-
updatedAtJulian: number | null
|
|
375
|
-
updatedAt: string | null
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
interface EmployeePrivileged extends Employee {
|
|
379
|
-
hourlyRate: string | null
|
|
380
|
-
annualSalary: string | null
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
getEmployees, getEmployee, employee searches, getJdeFromEmail, and verifyIdentity all return the public Employee shape (without compensation fields). Use getEmployeePrivileged when compensation fields are required.
|
|
384
|
-
```
|
|
385
|
-
|
|
386
|
-
---
|
|
387
|
-
|
|
388
|
-
## Business Units
|
|
389
|
-
|
|
390
|
-
```typescript
|
|
391
|
-
const units = await client.getBusinessUnits()
|
|
392
|
-
const dropdown = await client.getBusinessUnitsDropdown() // { value, label }[]
|
|
393
|
-
const unit = await client.getBusinessUnit('BU001')
|
|
394
|
-
```
|
|
395
|
-
|
|
396
|
-
---
|
|
397
|
-
|
|
398
|
-
## Cost Codes
|
|
399
|
-
|
|
400
|
-
```typescript
|
|
401
|
-
const codes = await client.getCostcodes()
|
|
402
|
-
const dropdown = await client.getCostcodesDropdown() // { value, label }[]
|
|
403
|
-
const code = await client.getCostcode('CC001')
|
|
404
|
-
```
|
|
405
|
-
|
|
406
|
-
---
|
|
407
|
-
|
|
408
|
-
## Pay Types
|
|
409
|
-
|
|
410
|
-
```typescript
|
|
411
|
-
const types = await client.getPaytypes()
|
|
412
|
-
const dropdown = await client.getPaytypesDropdown() // { value, label, payClass }[]
|
|
413
|
-
const type = await client.getPaytype('PT001')
|
|
414
|
-
```
|
|
415
|
-
|
|
416
|
-
---
|
|
417
|
-
|
|
418
|
-
## Work Orders
|
|
419
|
-
|
|
420
|
-
```typescript
|
|
421
|
-
const orders = await client.getWorkorders()
|
|
422
|
-
const dropdown = await client.getWorkordersDropdown() // { value, label }[]
|
|
423
|
-
const order = await client.getWorkorder('WO001')
|
|
424
123
|
```
|
|
425
124
|
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
## Job Type / Job Steps
|
|
429
|
-
|
|
430
|
-
```typescript
|
|
431
|
-
const items = await client.getJobtypejobsteps()
|
|
432
|
-
const dropdown = await client.getJobtypejobstepsDropdown() // { value, label }[]
|
|
433
|
-
const item = await client.getJobtypejobstep('JTJS001')
|
|
434
|
-
```
|
|
125
|
+
### LLM and RAG
|
|
435
126
|
|
|
436
|
-
|
|
127
|
+
```ts
|
|
128
|
+
import { llm, rag } from '@brownandroot/api'
|
|
437
129
|
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
```typescript
|
|
443
|
-
const result = await client.chat({
|
|
444
|
-
messages: [{ role: 'user', content: 'Summarize this document...' }],
|
|
130
|
+
const logs = await llm.getLogs()
|
|
131
|
+
const chat = await llm.chat({
|
|
132
|
+
messages: [{ role: 'user', content: 'Summarize this document.' }],
|
|
445
133
|
source: 'my-app',
|
|
446
134
|
user: 'jane.doe',
|
|
447
|
-
function: 'summarize',
|
|
448
|
-
temperature: 0.7,
|
|
449
|
-
maxTokens: 1000,
|
|
450
135
|
})
|
|
451
136
|
|
|
452
|
-
|
|
453
|
-
|
|
137
|
+
const docs = await rag.list()
|
|
138
|
+
const results = await rag.search({ query: 'overtime policy', topK: 5 })
|
|
454
139
|
```
|
|
455
140
|
|
|
456
|
-
|
|
141
|
+
## Cache Management
|
|
457
142
|
|
|
458
|
-
```
|
|
459
|
-
|
|
460
|
-
messages: [{ role: 'user', content: 'Hello' }],
|
|
461
|
-
userContext: { name: 'Jane Doe', department: 'Engineering', roles: ['admin'] },
|
|
462
|
-
useRag: true,
|
|
463
|
-
source: 'my-app',
|
|
464
|
-
})
|
|
465
|
-
// Proxy to the browser, or read the SSE stream directly
|
|
466
|
-
```
|
|
467
|
-
|
|
468
|
-
### LLM logs
|
|
143
|
+
```ts
|
|
144
|
+
import { clearCache } from '@brownandroot/api'
|
|
469
145
|
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
---
|
|
475
|
-
|
|
476
|
-
## Documents (RAG)
|
|
477
|
-
|
|
478
|
-
```typescript
|
|
479
|
-
const doc = await client.uploadDocument('report.pdf', base64Content, 'jane.doe')
|
|
480
|
-
const docs = await client.listDocuments()
|
|
481
|
-
const results = await client.searchDocuments('overtime policy', 5)
|
|
482
|
-
// results: { chunkId, content, fileName, documentType, score }[]
|
|
483
|
-
await client.deleteDocument(doc.id)
|
|
484
|
-
```
|
|
485
|
-
|
|
486
|
-
---
|
|
487
|
-
|
|
488
|
-
## Cache management (ApiHubClient)
|
|
489
|
-
|
|
490
|
-
```typescript
|
|
491
|
-
client.clearCache() // clear everything
|
|
492
|
-
client.clearCache('/employees') // clear a specific path
|
|
146
|
+
clearCache()
|
|
147
|
+
clearCache('workorders')
|
|
148
|
+
clearCache('employees')
|
|
493
149
|
```
|
|
494
150
|
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
## Types
|
|
498
|
-
|
|
499
|
-
```typescript
|
|
500
|
-
import type {
|
|
501
|
-
Employee,
|
|
502
|
-
BusinessUnit,
|
|
503
|
-
Costcode,
|
|
504
|
-
Paytype,
|
|
505
|
-
Workorder,
|
|
506
|
-
Jobtypejobstep,
|
|
507
|
-
LlmLog,
|
|
508
|
-
ChatMessage,
|
|
509
|
-
ChatRequest,
|
|
510
|
-
ChatResponse,
|
|
511
|
-
StreamChatRequest,
|
|
512
|
-
StreamChatUserContext,
|
|
513
|
-
DocumentRecord,
|
|
514
|
-
SearchResult,
|
|
515
|
-
ApiHubClientOptions,
|
|
516
|
-
DropdownOption,
|
|
517
|
-
PaytypeDropdownOption,
|
|
518
|
-
} from '@brownandroot/api'
|
|
519
|
-
|
|
520
|
-
// Filter interfaces (from cache module)
|
|
521
|
-
import type {
|
|
522
|
-
EmployeeFilters,
|
|
523
|
-
WorkorderFilters,
|
|
524
|
-
CostcodeFilters,
|
|
525
|
-
PaytypeFilters,
|
|
526
|
-
BusinessUnitFilters,
|
|
527
|
-
JobtypejobstepFilters,
|
|
528
|
-
} from '@brownandroot/api/cache'
|
|
529
|
-
```
|
|
151
|
+
Call `clearCache(entity)` after mutations so next reads fetch fresh data.
|
|
530
152
|
|
|
531
|
-
|
|
153
|
+
## Advanced Direct Client
|
|
532
154
|
|
|
533
|
-
|
|
155
|
+
`ApiHubClient` is still available for advanced usage (streaming/proxy control/custom behavior):
|
|
534
156
|
|
|
535
|
-
|
|
157
|
+
```ts
|
|
158
|
+
import { ApiHubClient } from '@brownandroot/api'
|
|
536
159
|
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
}
|
|
541
|
-
console.error(err.message) // "Employee not found"
|
|
542
|
-
}
|
|
160
|
+
const client = new ApiHubClient({
|
|
161
|
+
baseUrl: process.env.APIHUB_URL!,
|
|
162
|
+
apiKey: process.env.APIHUB_API_KEY!,
|
|
163
|
+
})
|
|
543
164
|
```
|
|
544
|
-
|
|
545
|
-
`verifyIdentity` returns `null` when no employee matches the inputs, and only throws for request errors (400, 503, network failure).
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
export declare const
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
export declare const businessUnits: {
|
|
2
|
+
getAll: import("@sveltejs/kit").RemoteQueryFunction<void, import("./index.js").BusinessUnit[]>;
|
|
3
|
+
dropdown: import("@sveltejs/kit").RemoteQueryFunction<void, import("./index.js").DropdownOption[]>;
|
|
4
|
+
get: import("@sveltejs/kit").RemoteQueryFunction<string, import("./index.js").BusinessUnit | null>;
|
|
5
|
+
};
|
|
@@ -1,6 +1,26 @@
|
|
|
1
1
|
import { query } from '$app/server';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { getClient } from './client.js';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
function isNotFoundError(error) {
|
|
5
|
+
if (!(error instanceof Error))
|
|
6
|
+
return false;
|
|
7
|
+
return /not found/i.test(error.message);
|
|
8
|
+
}
|
|
9
|
+
async function asNullable(fetcher) {
|
|
10
|
+
try {
|
|
11
|
+
return await fetcher();
|
|
12
|
+
}
|
|
13
|
+
catch (error) {
|
|
14
|
+
if (isNotFoundError(error))
|
|
15
|
+
return null;
|
|
16
|
+
throw error;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
const getAll = query(async () => getClient().getBusinessUnits());
|
|
20
|
+
const dropdown = query(async () => getClient().getBusinessUnitsDropdown());
|
|
21
|
+
const get = query(z.string(), async (id) => asNullable(() => getClient().getBusinessUnit(id)));
|
|
22
|
+
export const businessUnits = {
|
|
23
|
+
getAll,
|
|
24
|
+
dropdown,
|
|
25
|
+
get,
|
|
26
|
+
};
|