@brownandroot/api 0.6.0 → 0.7.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
@@ -1,6 +1,6 @@
1
1
  # @brownandroot/api
2
2
 
3
- TypeScript client for the Brown & Root APIHub employee data service.
3
+ Read-only TypeScript client for the Brown & Root APIHub data service. All methods are GET-only — no create, update, or delete operations are supported.
4
4
 
5
5
  ## Installation
6
6
 
@@ -21,47 +21,67 @@ const client = new ApiHubClient({
21
21
 
22
22
  ## Usage
23
23
 
24
- ### Get all employees
24
+ ### Employees
25
25
 
26
26
  ```typescript
27
27
  const employees = await client.getEmployees()
28
+ const employee = await client.getEmployee(12345)
29
+ const results = await client.searchByName('John')
30
+ const results = await client.searchByEmail('john@example.com')
31
+ const reports = await client.getBySupervisor(12345)
32
+ const chain = await client.getSupervisorChain(12345)
33
+ const { jde, employee } = await client.getJdeFromEmail('john@example.com')
28
34
  ```
29
35
 
30
- ### Get a single employee
36
+ ### Business Units
31
37
 
32
38
  ```typescript
33
- const employee = await client.getEmployee(12345)
39
+ const units = await client.getBusinessUnits()
40
+ const unit = await client.getBusinessUnit('BU001')
34
41
  ```
35
42
 
36
- ### Search by name
37
-
38
- Case-insensitive partial match:
43
+ ### Cost Codes
39
44
 
40
45
  ```typescript
41
- const results = await client.searchByName('John')
46
+ const codes = await client.getCostcodes()
47
+ const code = await client.getCostcode('CC001')
42
48
  ```
43
49
 
44
- ### Get employees by supervisor
50
+ ### Pay Types
45
51
 
46
52
  ```typescript
47
- const reports = await client.getBySupervisor(12345)
53
+ const types = await client.getPaytypes()
54
+ const type = await client.getPaytype('PT001')
48
55
  ```
49
56
 
50
- ### Get supervisor chain
57
+ ### Work Orders
58
+
59
+ ```typescript
60
+ const orders = await client.getWorkorders()
61
+ const order = await client.getWorkorder('WO001')
62
+ ```
51
63
 
52
- Returns the chain of supervisors above an employee (excludes the employee themselves):
64
+ ### LLM Logs
53
65
 
54
66
  ```typescript
55
- const chain = await client.getSupervisorChain(12345)
56
- // [directSupervisor, theirSupervisor, ...]
67
+ const logs = await client.getLlmLogs()
57
68
  ```
58
69
 
59
70
  ## Types
60
71
 
61
- The package exports the `Employee` interface and `ApiHubClientOptions`:
72
+ The package exports interfaces for all resource types:
62
73
 
63
74
  ```typescript
64
- import type { Employee, ApiHubClientOptions } from '@brownandroot/api'
75
+ import type {
76
+ Employee,
77
+ BusinessUnit,
78
+ Costcode,
79
+ Paytype,
80
+ Shift,
81
+ Workorder,
82
+ LlmLog,
83
+ ApiHubClientOptions,
84
+ } from '@brownandroot/api'
65
85
  ```
66
86
 
67
87
  ## Error Handling
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  * Employee type matching the API response shape.
3
3
  */
4
4
  export interface Employee {
5
- employeeId: number | null;
5
+ employeeId: string;
6
6
  name: string | null;
7
7
  email: string | null;
8
8
  badgeNumber: string | null;
@@ -26,22 +26,25 @@ export interface Employee {
26
26
  reportingLevel: string | null;
27
27
  recordType: string | null;
28
28
  payCycleCode: string | null;
29
- dateTimeStamps: string | null;
30
29
  benefitGroup: string | null;
31
- supervisor: number | null;
30
+ supervisor: string | null;
32
31
  adjustedServiceDate: string | null;
33
32
  departmentCode: string | null;
34
- dateUpdated: string | null;
35
33
  nccerNumber: string | null;
36
- mentor: number | null;
34
+ mentor: string | null;
37
35
  source: string | null;
38
36
  createdAt: string | null;
37
+ updatedAtJulian: number | null;
39
38
  updatedAt: string | null;
40
39
  }
41
40
  export interface ApiHubClientOptions {
42
41
  baseUrl: string;
43
42
  apiKey: string;
44
43
  }
44
+ export interface DropdownOption {
45
+ value: number | string;
46
+ label: string;
47
+ }
45
48
  /**
46
49
  * LLM log entry matching the API response shape.
47
50
  */
@@ -55,22 +58,6 @@ export interface LlmLog {
55
58
  totalTokens: number | null;
56
59
  createdAt: string | null;
57
60
  }
58
- export interface CreateLlmLogInput {
59
- source: string;
60
- user: string;
61
- function?: string;
62
- tokensIn?: number;
63
- tokensOut?: number;
64
- totalTokens?: number;
65
- }
66
- export interface UpdateLlmLogInput {
67
- source?: string;
68
- user?: string;
69
- function?: string;
70
- tokensIn?: number;
71
- tokensOut?: number;
72
- totalTokens?: number;
73
- }
74
61
  export interface BusinessUnit {
75
62
  id: string;
76
63
  companyId: string;
@@ -115,21 +102,6 @@ export interface Paytype {
115
102
  perDiemPayType: boolean;
116
103
  type: string | null;
117
104
  }
118
- export interface Shift {
119
- drky: string;
120
- drsy: string | null;
121
- drrt: string | null;
122
- drdl01: string | null;
123
- drdl02: string | null;
124
- drsphd: string | null;
125
- drudco: string | null;
126
- drhrdc: string | null;
127
- druser: string | null;
128
- drpid: string | null;
129
- drumpmj: string | null;
130
- drjobn: string | null;
131
- drupmt: string | null;
132
- }
133
105
  export interface Workorder {
134
106
  id: string;
135
107
  businessUnitId: string;
@@ -152,19 +124,20 @@ export declare class ApiHubClient {
152
124
  private apiKey;
153
125
  constructor(options: ApiHubClientOptions);
154
126
  private request;
155
- private requestWithBody;
156
127
  /** Get all employees */
157
128
  getEmployees(): Promise<Employee[]>;
129
+ /** Get employees formatted for dropdown controls */
130
+ getEmployeesDropdown(): Promise<DropdownOption[]>;
158
131
  /** Get a single employee by employeeId */
159
- getEmployee(employeeId: number): Promise<Employee>;
132
+ getEmployee(employeeId: string): Promise<Employee>;
160
133
  /** Search employees by name (case-insensitive partial match) */
161
134
  searchByName(name: string): Promise<Employee[]>;
162
135
  /** Get all employees reporting to a supervisor */
163
- getBySupervisor(supervisorId: number): Promise<Employee[]>;
136
+ getBySupervisor(supervisorId: string): Promise<Employee[]>;
164
137
  /** Search employees by email (case-insensitive partial match) */
165
138
  searchByEmail(email: string): Promise<Employee[]>;
166
139
  /** Get the supervisor chain above an employee */
167
- getSupervisorChain(employeeId: number): Promise<Employee[]>;
140
+ getSupervisorChain(employeeId: string): Promise<Employee[]>;
168
141
  /** Look up JDE number and employee data from email (with JDEService/CoreService fallback) */
169
142
  getJdeFromEmail(email: string): Promise<{
170
143
  jde: string | null;
@@ -172,33 +145,16 @@ export declare class ApiHubClient {
172
145
  }>;
173
146
  /** List all LLM log entries (newest first) */
174
147
  getLlmLogs(): Promise<LlmLog[]>;
175
- /** Create a new LLM log entry */
176
- createLlmLog(input: CreateLlmLogInput): Promise<LlmLog>;
177
- /** Update an existing LLM log entry */
178
- updateLlmLog(id: number, input: UpdateLlmLogInput): Promise<LlmLog>;
179
148
  getBusinessUnits(): Promise<BusinessUnit[]>;
149
+ getBusinessUnitsDropdown(): Promise<DropdownOption[]>;
180
150
  getBusinessUnit(id: string): Promise<BusinessUnit>;
181
- createBusinessUnit(input: Partial<BusinessUnit>): Promise<BusinessUnit>;
182
- updateBusinessUnit(id: string, input: Partial<BusinessUnit>): Promise<BusinessUnit>;
183
- deleteBusinessUnit(id: string): Promise<BusinessUnit>;
184
151
  getCostcodes(): Promise<Costcode[]>;
152
+ getCostcodesDropdown(): Promise<DropdownOption[]>;
185
153
  getCostcode(id: string): Promise<Costcode>;
186
- createCostcode(input: Partial<Costcode>): Promise<Costcode>;
187
- updateCostcode(id: string, input: Partial<Costcode>): Promise<Costcode>;
188
- deleteCostcode(id: string): Promise<Costcode>;
189
154
  getPaytypes(): Promise<Paytype[]>;
155
+ getPaytypesDropdown(): Promise<DropdownOption[]>;
190
156
  getPaytype(id: string): Promise<Paytype>;
191
- createPaytype(input: Partial<Paytype>): Promise<Paytype>;
192
- updatePaytype(id: string, input: Partial<Paytype>): Promise<Paytype>;
193
- deletePaytype(id: string): Promise<Paytype>;
194
- getShifts(): Promise<Shift[]>;
195
- getShift(id: string): Promise<Shift>;
196
- createShift(input: Partial<Shift>): Promise<Shift>;
197
- updateShift(id: string, input: Partial<Shift>): Promise<Shift>;
198
- deleteShift(id: string): Promise<Shift>;
199
157
  getWorkorders(): Promise<Workorder[]>;
158
+ getWorkordersDropdown(): Promise<DropdownOption[]>;
200
159
  getWorkorder(id: string): Promise<Workorder>;
201
- createWorkorder(input: Partial<Workorder>): Promise<Workorder>;
202
- updateWorkorder(id: string, input: Partial<Workorder>): Promise<Workorder>;
203
- deleteWorkorder(id: string): Promise<Workorder>;
204
160
  }
package/dist/index.js CHANGED
@@ -15,25 +15,17 @@ export class ApiHubClient {
15
15
  }
16
16
  return res.json();
17
17
  }
18
- async requestWithBody(path, method, body) {
19
- const res = await fetch(`${this.baseUrl}${path}`, {
20
- method,
21
- headers: { 'x-api-key': this.apiKey, 'Content-Type': 'application/json' },
22
- body: JSON.stringify(body),
23
- });
24
- if (!res.ok) {
25
- const respBody = await res.json().catch(() => ({}));
26
- throw new Error(respBody.error ?? `Request failed: ${res.status}`);
27
- }
28
- return res.json();
29
- }
30
18
  /** Get all employees */
31
19
  async getEmployees() {
32
20
  return this.request('/employees');
33
21
  }
22
+ /** Get employees formatted for dropdown controls */
23
+ async getEmployeesDropdown() {
24
+ return this.request('/employees/dropdown');
25
+ }
34
26
  /** Get a single employee by employeeId */
35
27
  async getEmployee(employeeId) {
36
- return this.request(`/employees/${employeeId}`);
28
+ return this.request(`/employees/${encodeURIComponent(employeeId)}`);
37
29
  }
38
30
  /** Search employees by name (case-insensitive partial match) */
39
31
  async searchByName(name) {
@@ -41,7 +33,7 @@ export class ApiHubClient {
41
33
  }
42
34
  /** Get all employees reporting to a supervisor */
43
35
  async getBySupervisor(supervisorId) {
44
- return this.request(`/employees/by-supervisor/${supervisorId}`);
36
+ return this.request(`/employees/by-supervisor/${encodeURIComponent(supervisorId)}`);
45
37
  }
46
38
  /** Search employees by email (case-insensitive partial match) */
47
39
  async searchByEmail(email) {
@@ -49,7 +41,7 @@ export class ApiHubClient {
49
41
  }
50
42
  /** Get the supervisor chain above an employee */
51
43
  async getSupervisorChain(employeeId) {
52
- return this.request(`/employees/${employeeId}/supervisor-chain`);
44
+ return this.request(`/employees/${encodeURIComponent(employeeId)}/supervisor-chain`);
53
45
  }
54
46
  /** Look up JDE number and employee data from email (with JDEService/CoreService fallback) */
55
47
  async getJdeFromEmail(email) {
@@ -62,102 +54,52 @@ export class ApiHubClient {
62
54
  async getLlmLogs() {
63
55
  return this.request('/llm-logs');
64
56
  }
65
- /** Create a new LLM log entry */
66
- async createLlmLog(input) {
67
- return this.requestWithBody('/llm-logs', 'POST', input);
68
- }
69
- /** Update an existing LLM log entry */
70
- async updateLlmLog(id, input) {
71
- return this.requestWithBody(`/llm-logs/${id}`, 'PATCH', input);
72
- }
73
57
  // -----------------------------------------------------------------------
74
58
  // Business Units
75
59
  // -----------------------------------------------------------------------
76
60
  async getBusinessUnits() {
77
61
  return this.request('/business-units');
78
62
  }
63
+ async getBusinessUnitsDropdown() {
64
+ return this.request('/business-units/dropdown');
65
+ }
79
66
  async getBusinessUnit(id) {
80
67
  return this.request(`/business-units/${encodeURIComponent(id)}`);
81
68
  }
82
- async createBusinessUnit(input) {
83
- return this.requestWithBody('/business-units', 'POST', input);
84
- }
85
- async updateBusinessUnit(id, input) {
86
- return this.requestWithBody(`/business-units/${encodeURIComponent(id)}`, 'PATCH', input);
87
- }
88
- async deleteBusinessUnit(id) {
89
- return this.requestWithBody(`/business-units/${encodeURIComponent(id)}`, 'DELETE', {});
90
- }
91
69
  // -----------------------------------------------------------------------
92
70
  // Cost Codes
93
71
  // -----------------------------------------------------------------------
94
72
  async getCostcodes() {
95
73
  return this.request('/costcodes');
96
74
  }
75
+ async getCostcodesDropdown() {
76
+ return this.request('/costcodes/dropdown');
77
+ }
97
78
  async getCostcode(id) {
98
79
  return this.request(`/costcodes/${encodeURIComponent(id)}`);
99
80
  }
100
- async createCostcode(input) {
101
- return this.requestWithBody('/costcodes', 'POST', input);
102
- }
103
- async updateCostcode(id, input) {
104
- return this.requestWithBody(`/costcodes/${encodeURIComponent(id)}`, 'PATCH', input);
105
- }
106
- async deleteCostcode(id) {
107
- return this.requestWithBody(`/costcodes/${encodeURIComponent(id)}`, 'DELETE', {});
108
- }
109
81
  // -----------------------------------------------------------------------
110
82
  // Pay Types
111
83
  // -----------------------------------------------------------------------
112
84
  async getPaytypes() {
113
85
  return this.request('/paytypes');
114
86
  }
87
+ async getPaytypesDropdown() {
88
+ return this.request('/paytypes/dropdown');
89
+ }
115
90
  async getPaytype(id) {
116
91
  return this.request(`/paytypes/${encodeURIComponent(id)}`);
117
92
  }
118
- async createPaytype(input) {
119
- return this.requestWithBody('/paytypes', 'POST', input);
120
- }
121
- async updatePaytype(id, input) {
122
- return this.requestWithBody(`/paytypes/${encodeURIComponent(id)}`, 'PATCH', input);
123
- }
124
- async deletePaytype(id) {
125
- return this.requestWithBody(`/paytypes/${encodeURIComponent(id)}`, 'DELETE', {});
126
- }
127
- // -----------------------------------------------------------------------
128
- // Shifts
129
- // -----------------------------------------------------------------------
130
- async getShifts() {
131
- return this.request('/shifts');
132
- }
133
- async getShift(id) {
134
- return this.request(`/shifts/${encodeURIComponent(id)}`);
135
- }
136
- async createShift(input) {
137
- return this.requestWithBody('/shifts', 'POST', input);
138
- }
139
- async updateShift(id, input) {
140
- return this.requestWithBody(`/shifts/${encodeURIComponent(id)}`, 'PATCH', input);
141
- }
142
- async deleteShift(id) {
143
- return this.requestWithBody(`/shifts/${encodeURIComponent(id)}`, 'DELETE', {});
144
- }
145
93
  // -----------------------------------------------------------------------
146
94
  // Work Orders
147
95
  // -----------------------------------------------------------------------
148
96
  async getWorkorders() {
149
97
  return this.request('/workorders');
150
98
  }
99
+ async getWorkordersDropdown() {
100
+ return this.request('/workorders/dropdown');
101
+ }
151
102
  async getWorkorder(id) {
152
103
  return this.request(`/workorders/${encodeURIComponent(id)}`);
153
104
  }
154
- async createWorkorder(input) {
155
- return this.requestWithBody('/workorders', 'POST', input);
156
- }
157
- async updateWorkorder(id, input) {
158
- return this.requestWithBody(`/workorders/${encodeURIComponent(id)}`, 'PATCH', input);
159
- }
160
- async deleteWorkorder(id) {
161
- return this.requestWithBody(`/workorders/${encodeURIComponent(id)}`, 'DELETE', {});
162
- }
163
105
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brownandroot/api",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",