@go-labs-sg/bb 1.0.4 → 1.1.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/README.md CHANGED
@@ -1,12 +1,12 @@
1
1
  # bb
2
2
 
3
- Command-line interface for **Budget Builder**. Call budgets, bills, approvals, and suppliers from your terminal or from tools that don’t support MCP (e.g. some AI agents). Responses are JSON on stdout.
3
+ Command-line interface for **Budget Builder**. Call budgets, bills, approvals, suppliers, dashboard, and more from your terminal or from tools that don’t support MCP (e.g. some AI agents). Responses are JSON on stdout.
4
4
 
5
5
  **Registry:** [`@go-labs-sg/bb`](https://www.npmjs.com/package/@go-labs-sg/bb)
6
6
 
7
7
  ## Requirements
8
8
 
9
- - **Node.js** 18+
9
+ - **Node.js** 18+ (ESM; relative imports in `dist` use `.js` extensions)
10
10
  - A **Budget Builder API key** (same key used for the MCP server)
11
11
 
12
12
  ## Install
@@ -48,17 +48,21 @@ bb list-suppliers
48
48
 
49
49
  Global options and flags use `--key=value` or `--key value` (see `bb help`).
50
50
 
51
- ## Commands
51
+ **Authoritative command list:** run `bb help` — it includes every command, positional args, and flags (kept in sync with the MCP tool surface). You can also use MCP-style `snake_case` (e.g. `bb list_bills`); it is normalized to kebab-case.
52
52
 
53
- | Command | Description |
53
+ ### Command overview
54
+
55
+ | Area | Commands (non-exhaustive) |
54
56
  | --- | --- |
55
- | `list-budgets` | List budgets. Flags: `--projectId`, `--name`, `--status` (comma-separated), `--page`, `--perPage` |
56
- | `get-budget <id>` | Budget details and line items |
57
- | `update-budget-status <id> <status>` | Change budget status (e.g. `APPROVED`, `REJECTED`, `DRAFT`, …) |
58
- | `list-bills` | List bills. Flags: `--projectId`, `--budgetId`, `--status`, `--page`, `--pageSize` |
59
- | `approve-bill <id>` | Approve a pending bill (matches your pending bill approvals) |
60
- | `list-approvals` | Pending approvals. Flag: `--type` = `budget`, `supplier`, `bill`, or `all` |
61
- | `list-suppliers` | List suppliers. Flags: `--name`, `--page`, `--perPage` |
57
+ | **Budgets** | `list-budgets`, `get-budget`, `get-budget-items`, `get-budget-details`, `get-budget-categories`, `get-budget-versions`, `update-budget-status`, `create-budget-approval`, `add-budget-items`, `update-budget-item`, `remove-budget-item` |
58
+ | **Bills** | `list-bills`, `list-claims`, `create-bill-approval`, `update-bill-status`, `patch-bill-payment`, `patch-bill-invoice-number`, `get-bill-attachments`, `get-bill-details` |
59
+ | **Approvals** | `list-approvals` / `get-pending-approvals`, `approve-bill`, `reject-bill`, `approve-budget`, `reject-budget`, `approve-supplier`, `reject-supplier` |
60
+ | **Companies & projects** | `list-companies`, `get-company`, `create-company`, `list-projects`, `get-project`, `create-project`, `update-project-status` |
61
+ | **Contacts** | `list-contacts` |
62
+ | **Suppliers & items** | `list-suppliers`, `get-supplier-details`, `get-supplier-analytics`, `list-items`, `get-item`, `list-item-categories` |
63
+ | **Dashboard & users** | `list-users`, `get-user-performance`, `get-dashboard`, `get-financial-overview` |
64
+ | **Errors** | `get-recent-errors`, `get-error-metrics` |
65
+ | **Historical / benchmarks** | `get-approved-budgets`, `get-budget-category-benchmarks`, `get-item-pricing-history`, `get-supplier-pricing-history` |
62
66
 
63
67
  ## Output
64
68
 
@@ -70,7 +74,7 @@ A `.env` file in the **current working directory** is loaded automatically (for
70
74
 
71
75
  ## Developing in this repo
72
76
 
73
- From the monorepo root:
77
+ From the monorepo root (after `bun install`):
74
78
 
75
79
  ```bash
76
80
  export BB_API_KEY=...
@@ -80,5 +84,15 @@ bun run bb -- list-budgets
80
84
  Or from `packages/cli`:
81
85
 
82
86
  ```bash
87
+ bun run build # emit dist/ via tsc
88
+ bun run typecheck # tsc --noEmit
83
89
  bun run src/index.ts list-budgets
84
90
  ```
91
+
92
+ ### Layout
93
+
94
+ - **`src/filter-enums.ts`** — “extended” filter enums (ALL + Prisma enums), maintained here so the published package does not depend on unpublished workspace packages. Keep in line with `packages/utils/src/filter-enums.ts` when those values change.
95
+
96
+ ### Publish
97
+
98
+ `prepublishOnly` strips `workspace:` / `catalog:` entries from this package’s `package.json`, runs `tsc`, then `postpack` restores the file — so the npm tarball does not contain monorepo protocol dependencies. Types from `@bb/api` are compile-time only (`import type`). Enum **values** in emitted JS import `@bb/db/enums` (workspace `@bb/db` during monorepo development).
package/dist/commands.js CHANGED
@@ -1,13 +1,12 @@
1
1
  import { api } from "./api-client.js";
2
+ import { BudgetRole, Deals, ExtendedApprovalStatus, ExtendedApprovalType, ExtendedBudgetStatus, TimeFrame, } from "./filter-enums.js";
3
+ import { billStatusesForApi, } from "./parse-cli-enums.js";
2
4
  const BUDGET = "BUDGET";
3
5
  const BILL = "BILL";
4
6
  const SUPPLIER = "SUPPLIER";
5
7
  function isPendingRequest(n) {
6
8
  return n.notificationType === "request" && n.status === "PENDING_APPROVAL";
7
9
  }
8
- function isApprovalType(s) {
9
- return s === BUDGET || s === BILL || s === SUPPLIER;
10
- }
11
10
  const out = (data) => {
12
11
  console.log(JSON.stringify(data, null, 2));
13
12
  };
@@ -16,6 +15,11 @@ export async function listBudgets(opts) {
16
15
  projectId: opts.projectId,
17
16
  name: opts.name,
18
17
  statuses: opts.statuses,
18
+ createdBy: opts.createdBy,
19
+ dateFrom: opts.dateFrom,
20
+ dateTo: opts.dateTo,
21
+ sortBy: opts.sortBy,
22
+ sortDir: opts.sortDir,
19
23
  page: opts.page ?? 1,
20
24
  perPage: opts.perPage ?? 20,
21
25
  };
@@ -30,18 +34,24 @@ export async function getBudget(id) {
30
34
  out({ budget, items });
31
35
  }
32
36
  export async function updateBudgetStatus(budgetId, status) {
33
- const input = {
37
+ const result = await api.budget.updateBudgetStatus.mutate({
34
38
  id: budgetId,
35
- status: status,
36
- };
37
- const result = await api.budget.updateBudgetStatus.mutate(input);
39
+ status,
40
+ });
38
41
  out(result);
39
42
  }
40
43
  export async function listBills(opts) {
41
44
  const input = {
42
45
  projectId: opts.projectId,
43
46
  budgetId: opts.budgetId,
44
- status: opts.status,
47
+ statuses: billStatusesForApi(opts.statuses),
48
+ search: opts.search?.trim() || undefined,
49
+ isClaimable: opts.isClaimable,
50
+ createdByIds: opts.createdByIds && opts.createdByIds.length > 0
51
+ ? opts.createdByIds
52
+ : undefined,
53
+ sortBy: opts.sortBy,
54
+ sortDir: opts.sortDir,
45
55
  page: opts.page ?? 1,
46
56
  pageSize: opts.pageSize ?? 20,
47
57
  };
@@ -61,19 +71,17 @@ export async function approveBill(billId) {
61
71
  billApprovalId: approval.id,
62
72
  status: "APPROVED",
63
73
  });
64
- out({ ...result, success: true, message: "Bill approved" });
74
+ out(result);
65
75
  }
66
76
  export async function listApprovals(opts) {
67
77
  const notifications = await api.budget.getNotifications.query();
68
78
  const pending = notifications.filter(isPendingRequest);
69
- const raw = opts.type?.toUpperCase();
70
- if (raw !== undefined && raw !== "ALL" && !isApprovalType(raw)) {
71
- throw new Error("Invalid --type. Use one of: budget, supplier, bill, all.");
72
- }
73
- const typeFilter = !opts.type || opts.type.toLowerCase() === "all"
79
+ const typeFilter = opts.type === undefined || opts.type === "ALL"
74
80
  ? (_n) => true
75
- : (n) => raw !== undefined && isApprovalType(raw) && n.type === raw;
76
- const filtered = pending.filter(typeFilter);
81
+ : (n) => n.type === opts.type;
82
+ const filtered = pending
83
+ .filter(typeFilter)
84
+ .filter((n) => n.type !== BUDGET || !n.budget?.quickbooksEstimateId);
77
85
  const items = filtered.map((n) => {
78
86
  let id;
79
87
  let name;
@@ -116,3 +124,377 @@ export async function listSuppliers(opts) {
116
124
  });
117
125
  out(result);
118
126
  }
127
+ // --- Bills (MCP parity) ---
128
+ export async function createBillApproval(billId) {
129
+ const result = await api.bill.createApproval.mutate({ billId });
130
+ out(result);
131
+ }
132
+ export async function updateBillStatus(opts) {
133
+ const result = await api.bill.updateStatus.mutate({
134
+ id: opts.id,
135
+ status: opts.status,
136
+ rejectionReason: opts.rejectionReason,
137
+ paymentTrackingUrl: opts.paymentTrackingUrl,
138
+ paymentReference: opts.paymentReference,
139
+ });
140
+ out(result);
141
+ }
142
+ export async function patchBillPayment(opts) {
143
+ const result = await api.bill.patchPayment.mutate({
144
+ id: opts.id,
145
+ paymentTrackingUrl: opts.paymentTrackingUrl,
146
+ paymentReference: opts.paymentReference,
147
+ quickbooksBillId: opts.quickbooksBillId,
148
+ });
149
+ out(result);
150
+ }
151
+ export async function patchBillInvoiceNumber(id, invoiceNumber) {
152
+ const result = await api.bill.patchInvoiceNumber.mutate({
153
+ id,
154
+ invoiceNumber,
155
+ });
156
+ out(result);
157
+ }
158
+ export async function getBillAttachments(id) {
159
+ const result = await api.bill.getAttachments.query({ id });
160
+ out(result);
161
+ }
162
+ export async function getBillDetails(id) {
163
+ const result = await api.bill.getById.query({ id });
164
+ out(result);
165
+ }
166
+ // --- Budgets (MCP parity) ---
167
+ export async function getBudgetItemsOnly(budgetId) {
168
+ const items = await api.budget.getBudgetItems.query({ budgetId });
169
+ out(items);
170
+ }
171
+ export async function addBudgetItems(opts) {
172
+ const result = await api.budgetItem.addBudgetItems.mutate(opts);
173
+ out(result);
174
+ }
175
+ export async function updateBudgetItem(input) {
176
+ const result = await api.budgetItem.updateBudgetItem.mutate(input);
177
+ out(result);
178
+ }
179
+ export async function removeBudgetItem(budgetItemId) {
180
+ const result = await api.budgetItem.removeBudgetItem.mutate({
181
+ budgetItemId,
182
+ });
183
+ out(result);
184
+ }
185
+ export async function getBudgetCategories() {
186
+ const categories = await api.budget.getBudgetCategories.query();
187
+ out(categories);
188
+ }
189
+ export async function getBudgetVersions(budgetId) {
190
+ const versions = await api.budgetVersion.getBudgetVersions.query({
191
+ budgetId,
192
+ });
193
+ out(versions);
194
+ }
195
+ export async function createBudgetApproval(budgetId) {
196
+ const result = await api.budget.createBudgetApproval.mutate({ budgetId });
197
+ out(result);
198
+ }
199
+ export async function getBudgetDetails(budgetId) {
200
+ const detail = await api.budget.getBudgetDetail.query({ id: budgetId });
201
+ out(detail);
202
+ }
203
+ // --- Approvals: budgets / suppliers / bills (MCP parity) ---
204
+ export async function approveBudget(budgetId) {
205
+ const notifications = await api.budget.getNotifications.query();
206
+ const pending = notifications.filter((n) => n.notificationType === "request" &&
207
+ n.status === ExtendedApprovalStatus.PENDING_APPROVAL &&
208
+ n.type === ExtendedApprovalType.BUDGET &&
209
+ (n.budgetId === budgetId ||
210
+ n.budget?.id === budgetId));
211
+ const approval = pending[0];
212
+ if (!approval) {
213
+ throw new Error("No pending budget approval found for this budget and approver.");
214
+ }
215
+ await api.budget.updateBudgetApproval.mutate({
216
+ budgetApprovalId: approval.id,
217
+ status: ExtendedApprovalStatus.APPROVED,
218
+ });
219
+ out({ success: true, message: "Budget approved successfully" });
220
+ }
221
+ export async function rejectBudget(budgetId, reason) {
222
+ const notifications = await api.budget.getNotifications.query();
223
+ const pending = notifications.filter((n) => n.notificationType === "request" &&
224
+ n.status === ExtendedApprovalStatus.PENDING_APPROVAL &&
225
+ n.type === ExtendedApprovalType.BUDGET &&
226
+ (n.budgetId === budgetId ||
227
+ n.budget?.id === budgetId));
228
+ const approval = pending[0];
229
+ if (!approval) {
230
+ throw new Error("No pending budget approval found for this budget and approver.");
231
+ }
232
+ await api.budget.updateBudgetApproval.mutate({
233
+ budgetApprovalId: approval.id,
234
+ status: ExtendedApprovalStatus.REJECTED,
235
+ rejectionReason: reason,
236
+ });
237
+ out({ success: true, message: "Budget rejected" });
238
+ }
239
+ export async function getSupplierDetails(supplierId) {
240
+ const supplier = await api.supplier.getSupplierById.query({
241
+ id: supplierId,
242
+ });
243
+ out(supplier);
244
+ }
245
+ export async function approveSupplier(supplierId) {
246
+ const notifications = await api.budget.getNotifications.query();
247
+ const pending = notifications.filter((n) => n.notificationType === "request" &&
248
+ n.status === ExtendedApprovalStatus.PENDING_APPROVAL &&
249
+ n.type === ExtendedApprovalType.SUPPLIER &&
250
+ (n.supplierId === supplierId || n.supplier?.id === supplierId));
251
+ const approval = pending[0];
252
+ if (!approval) {
253
+ throw new Error("No pending supplier approval found.");
254
+ }
255
+ await api.supplier.updateSupplierApproval.mutate({
256
+ supplierApprovalId: approval.id,
257
+ status: ExtendedApprovalStatus.APPROVED,
258
+ });
259
+ out({ success: true, message: "Supplier approved successfully" });
260
+ }
261
+ export async function rejectSupplier(supplierId, reason) {
262
+ const notifications = await api.budget.getNotifications.query();
263
+ const pending = notifications.filter((n) => n.notificationType === "request" &&
264
+ n.status === ExtendedApprovalStatus.PENDING_APPROVAL &&
265
+ n.type === ExtendedApprovalType.SUPPLIER &&
266
+ (n.supplierId === supplierId || n.supplier?.id === supplierId));
267
+ const approval = pending[0];
268
+ if (!approval) {
269
+ throw new Error("No pending supplier approval found.");
270
+ }
271
+ await api.supplier.updateSupplierApproval.mutate({
272
+ supplierApprovalId: approval.id,
273
+ status: ExtendedApprovalStatus.REJECTED,
274
+ rejectionReason: reason,
275
+ });
276
+ out({ success: true, message: "Supplier rejected" });
277
+ }
278
+ export async function rejectBill(billId, reason) {
279
+ const notifications = await api.budget.getNotifications.query();
280
+ const pending = notifications.filter((n) => n.notificationType === "request" &&
281
+ n.status === ExtendedApprovalStatus.PENDING_APPROVAL &&
282
+ n.type === ExtendedApprovalType.BILL &&
283
+ (n.billId === billId || n.bill?.id === billId));
284
+ const approval = pending[0];
285
+ if (!approval) {
286
+ throw new Error("No pending bill approval found.");
287
+ }
288
+ await api.bill.updateApproval.mutate({
289
+ billApprovalId: approval.id,
290
+ status: ExtendedApprovalStatus.REJECTED,
291
+ rejectionReason: reason,
292
+ });
293
+ out({ success: true, message: "Bill rejected" });
294
+ }
295
+ // --- Companies & projects ---
296
+ export async function listCompanies(opts) {
297
+ const result = await api.company.getCompanies.query({
298
+ name: opts.name,
299
+ createdBy: opts.createdBy,
300
+ page: opts.page ?? 1,
301
+ perPage: opts.perPage ?? 20,
302
+ });
303
+ out(result);
304
+ }
305
+ export async function getCompany(id) {
306
+ const company = await api.company.getCompanyById.query({ id });
307
+ out(company);
308
+ }
309
+ export async function createCompany(opts) {
310
+ const result = await api.company.createCompany.mutate(opts);
311
+ out(result);
312
+ }
313
+ export async function listProjects(opts) {
314
+ const result = await api.project.getAllProjects.query({
315
+ companyId: opts.companyId,
316
+ name: opts.name,
317
+ status: opts.status,
318
+ page: opts.page ?? 1,
319
+ perPage: opts.perPage ?? 20,
320
+ });
321
+ out(result);
322
+ }
323
+ export async function getProject(id) {
324
+ const [project, budgetsOverview, billsOverview] = await Promise.all([
325
+ api.project.getProjectDetailsById.query({ id }),
326
+ api.project.getProjectBudgetsOverview.query({ projectId: id }),
327
+ api.project.getProjectBillsOverview.query({ projectId: id }),
328
+ ]);
329
+ out({ project, budgetsOverview, billsOverview });
330
+ }
331
+ export async function createProject(opts) {
332
+ const result = await api.project.createProject.mutate({
333
+ name: opts.name,
334
+ description: opts.description,
335
+ companyId: opts.companyId,
336
+ contactPersonId: opts.contactPersonId,
337
+ dateRange: {
338
+ from: new Date(opts.startDate),
339
+ to: opts.endDate ? new Date(opts.endDate) : undefined,
340
+ },
341
+ });
342
+ out(result);
343
+ }
344
+ export async function updateProjectStatus(id, status) {
345
+ const result = await api.project.updateProjectStatus.mutate({ id, status });
346
+ out(result);
347
+ }
348
+ // --- Contacts ---
349
+ export async function listContacts(companyId) {
350
+ const contacts = await api.contactPerson.getContactPersonByCompanyId.query({
351
+ companyId,
352
+ });
353
+ out(contacts);
354
+ }
355
+ // --- Items ---
356
+ export async function listItems(opts) {
357
+ const result = await api.item.getItems.query({
358
+ page: opts.page ?? 1,
359
+ perPage: opts.perPage ?? 20,
360
+ name: opts.name,
361
+ });
362
+ out(result);
363
+ }
364
+ export async function getItem(id) {
365
+ const item = await api.item.getItem.query({ id });
366
+ out(item);
367
+ }
368
+ export async function listItemCategories(opts) {
369
+ const result = await api.itemCategory.getItemCategories.query({
370
+ page: opts.page ?? 1,
371
+ perPage: opts.perPage ?? 50,
372
+ });
373
+ out(result);
374
+ }
375
+ // --- Supplier analytics ---
376
+ export async function getSupplierAnalytics(opts) {
377
+ const result = await api.dashboard.getSupplierTableData.query({
378
+ page: opts.page ?? 1,
379
+ perPage: opts.perPage ?? 20,
380
+ sort: [],
381
+ name: opts.name,
382
+ timeFrame: (opts.timeFrame ?? "ALL"),
383
+ });
384
+ out(result);
385
+ }
386
+ // --- Dashboard / analytics ---
387
+ export async function listUsers() {
388
+ const users = await api.user.getAllUsers.query();
389
+ out(users);
390
+ }
391
+ export async function getUserPerformance(userId) {
392
+ const result = await api.dashboard.getUserPerformance.query({ userId });
393
+ out(result);
394
+ }
395
+ export async function getDashboard(input) {
396
+ const result = await api.dashboard.getDashboard.query({
397
+ userId: input.userId,
398
+ role: input.role ?? "ALL",
399
+ deals: input.deals ?? "ALL",
400
+ timeFrame: input.timeFrame ?? "ALL",
401
+ startDate: input.startDate,
402
+ endDate: input.endDate,
403
+ });
404
+ out(result);
405
+ }
406
+ export async function getFinancialOverview(input) {
407
+ const result = await api.dashboard.getFinancialOverview.query({
408
+ userId: input.userId,
409
+ role: input.role ?? BudgetRole.ALL,
410
+ deals: input.deals ?? Deals.ALL,
411
+ timeFrame: input.timeFrame ?? TimeFrame.ALL,
412
+ startDate: input.startDate,
413
+ endDate: input.endDate,
414
+ });
415
+ out(result);
416
+ }
417
+ // --- Error logs ---
418
+ export async function getRecentErrors(opts) {
419
+ const result = await api.errorLog.getRecentErrors.query({
420
+ page: opts.page ?? 1,
421
+ perPage: opts.perPage ?? 10,
422
+ severity: opts.severity,
423
+ status: opts.status,
424
+ });
425
+ out(result);
426
+ }
427
+ export async function getErrorMetrics() {
428
+ const result = await api.errorLog.getErrorMetrics.query({});
429
+ out(result);
430
+ }
431
+ // --- Historical / benchmarks ---
432
+ export async function getApprovedBudgets(opts) {
433
+ const perPage = Math.min(opts.limit ?? 50, 100);
434
+ const { budgets, totalCount } = await api.budget.getAllBudgets.query({
435
+ projectId: opts.projectId,
436
+ statuses: [
437
+ ExtendedBudgetStatus.APPROVED,
438
+ ExtendedBudgetStatus.ESTIMATE_ACCEPTED,
439
+ ExtendedBudgetStatus.ESTIMATE_CLOSED,
440
+ ],
441
+ page: 1,
442
+ perPage,
443
+ });
444
+ const items = (budgets ?? []).map((b) => {
445
+ const calc = b;
446
+ const revenue = calc.totalSellingAfterDiscount ?? 0;
447
+ const cost = calc.totalCostWithoutGst ?? 0;
448
+ const gp = calc.gpPercentage ?? 0;
449
+ const date = b.date instanceof Date ? b.date.toISOString() : String(b.date);
450
+ const createdAt = b.createdAt instanceof Date
451
+ ? b.createdAt.toISOString()
452
+ : String(b.createdAt);
453
+ return {
454
+ id: b.id,
455
+ name: b.name,
456
+ categoryId: b.categoryId,
457
+ company: b.project?.company?.name,
458
+ date,
459
+ pax: b.pax,
460
+ revenue: Number(revenue.toFixed(2)),
461
+ cost: Number(cost.toFixed(2)),
462
+ gpPercentage: Number(gp.toFixed(2)),
463
+ createdAt,
464
+ };
465
+ });
466
+ let filtered = items;
467
+ if (opts.minRevenue != null) {
468
+ const minR = opts.minRevenue;
469
+ filtered = filtered.filter((i) => i.revenue >= minR);
470
+ }
471
+ if (opts.maxRevenue != null) {
472
+ const maxR = opts.maxRevenue;
473
+ filtered = filtered.filter((i) => i.revenue <= maxR);
474
+ }
475
+ out({ budgets: filtered, count: filtered.length, totalCount });
476
+ }
477
+ export async function getBudgetCategoryBenchmarks(opts) {
478
+ const result = await api.budget.getBudgetCategoryBenchmarks.query({
479
+ categoryId: opts.categoryId,
480
+ limit: opts.limit ?? 100,
481
+ });
482
+ out(result);
483
+ }
484
+ export async function getItemPricingHistory(opts) {
485
+ const result = await api.budget.getItemPricingHistory.query({
486
+ itemName: opts.itemName,
487
+ categoryId: opts.categoryId,
488
+ supplierId: opts.supplierId,
489
+ limit: opts.limit ?? 100,
490
+ });
491
+ out(result);
492
+ }
493
+ export async function getSupplierPricingHistory(opts) {
494
+ const result = await api.budget.getSupplierPricingHistory.query({
495
+ supplierId: opts.supplierId,
496
+ itemCategoryId: opts.itemCategoryId,
497
+ limit: opts.limit ?? 100,
498
+ });
499
+ out(result);
500
+ }
@@ -0,0 +1,58 @@
1
+ import { ApprovalStatus, ApprovalType, BillStatus, BudgetStatus, ErrorSeverity, ErrorStatus, EstimationMode, ProjectStatus, } from "@bb/db/enums";
2
+ export const ExtendedApprovalStatus = {
3
+ ...ApprovalStatus,
4
+ ALL: "ALL",
5
+ };
6
+ export const ExtendedApprovalType = {
7
+ ...ApprovalType,
8
+ ALL: "ALL",
9
+ };
10
+ export const ExtendedProjectStatus = {
11
+ ...ProjectStatus,
12
+ ALL: "ALL",
13
+ };
14
+ export const ExtendedBudgetStatus = {
15
+ ...BudgetStatus,
16
+ ALL: "ALL",
17
+ };
18
+ export const ExtendedBillStatus = {
19
+ ...BillStatus,
20
+ ALL: "ALL",
21
+ };
22
+ export const ExtendedEstimationMode = {
23
+ ...EstimationMode,
24
+ ALL: "ALL",
25
+ };
26
+ export const BudgetRole = {
27
+ ALL: "ALL",
28
+ BD: "BD",
29
+ CREATOR: "CREATOR",
30
+ INSIDE_SALES: "INSIDE_SALES",
31
+ };
32
+ export const Deals = {
33
+ ALL: "ALL",
34
+ SUCCESSFUL: "SUCCESSFUL",
35
+ LOST: "LOST",
36
+ };
37
+ export const TimeFrame = {
38
+ ALL: "ALL",
39
+ LAST_YEAR: "LAST_YEAR",
40
+ LAST_6_MONTHS: "LAST_6_MONTHS",
41
+ LAST_3_MONTHS: "LAST_3_MONTHS",
42
+ CUSTOM: "CUSTOM",
43
+ };
44
+ export const ChartTimeFrame = {
45
+ LAST_30_DAYS: "last_30_days",
46
+ LAST_3_MONTHS: "last_3_months",
47
+ LAST_6_MONTHS: "last_6_months",
48
+ LAST_1_YEAR: "last_1_year",
49
+ ALL_TIME: "all_time",
50
+ };
51
+ export const ExtendedErrorSeverity = {
52
+ ALL: "ALL",
53
+ ...ErrorSeverity,
54
+ };
55
+ export const ExtendedErrorStatus = {
56
+ ALL: "ALL",
57
+ ...ErrorStatus,
58
+ };