@go-labs-sg/bb 1.1.1 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -9
- package/dist/commands.js +179 -0
- package/dist/filter-enums.js +1 -1
- package/dist/index.js +345 -12
- package/dist/parse-cli-enums.js +2 -2
- package/dist/parse-mutation-payload.js +238 -0
- package/dist/prisma-enums.js +55 -0
- package/package.json +2 -2
- package/dist/api-client.d.ts +0 -5
- package/dist/api-client.d.ts.map +0 -1
- package/dist/commands.d.ts +0 -28
- package/dist/commands.d.ts.map +0 -1
- package/dist/index.d.ts +0 -3
- package/dist/index.d.ts.map +0 -1
- package/dist/load-env.d.ts +0 -2
- package/dist/load-env.d.ts.map +0 -1
- package/dist/parse-args.d.ts +0 -11
- package/dist/parse-args.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -48,19 +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
|
-
**Authoritative command list:** run `bb help` — it includes every command, positional args, and flags
|
|
51
|
+
**Authoritative command list:** run `bb help` — it includes every command, positional args, and flags. MCP exposes a subset of the same tRPC surface; the CLI additionally includes a few procedures mainly used by the web UI (e.g. `reorder-budget-items`, `update-budget-item-supplier`). You can also use MCP-style `snake_case` (e.g. `bb list_bills`); it is normalized to kebab-case.
|
|
52
|
+
|
|
53
|
+
**Mutations with `--payload`:** Commands such as `create-budget`, `create-bill`, `update-supplier`, etc. take a single JSON object (`--payload '<json>'`) matching the corresponding tRPC procedure input. Use ISO strings for date/datetime fields; the CLI coerces them where needed. The API still validates the full shape.
|
|
52
54
|
|
|
53
55
|
### Command overview
|
|
54
56
|
|
|
55
57
|
| Area | Commands (non-exhaustive) |
|
|
56
58
|
| --- | --- |
|
|
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
|
+
| **Budgets** | `list-budgets`, `get-budget`, `get-budget-items`, `get-budget-details`, `get-budget-categories`, `get-budget-versions`, `update-budget-status`, `create-budget` / `update-budget` (`--payload`), `delete-budget`, `create-budget-approval`, `add-budget-items`, `update-budget-item`, `remove-budget-item`, `reorder-budget-items`, `update-budget-item-supplier`, `create-budget-category`, `update-budget-category`, `delete-budget-category`, `update-budget-commission`, `update-budget-discount` (`--payload` where noted) |
|
|
60
|
+
| **Bills** | `list-bills`, `list-claims`, `create-bill` (`--payload`), `update-bill` (`--payload`), `delete-bill`, `create-bill-approval`, `update-bill-status`, `patch-bill-payment`, `patch-bill-invoice-number`, `get-bill-attachments`, `get-bill-details` |
|
|
59
61
|
| **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` |
|
|
62
|
+
| **Companies & projects** | `list-companies`, `get-company`, `create-company`, `update-company` (`--payload`), `delete-company`, `list-projects`, `get-project`, `create-project` (optional `--requestQboAccountantNotification false` to skip QBO accountant emails), `update-project` (`--payload`, optional `requestQboAccountantNotification` in JSON), `delete-project`, `update-project-status` |
|
|
63
|
+
| **Contacts** | `list-contacts`, `create-contact-person` (`--payload`), `update-contact-person` (`--payload`) |
|
|
64
|
+
| **Suppliers & items** | `list-suppliers`, `create-supplier` (`--payload`), `update-supplier` (`--payload`), `delete-suppliers` (`--ids` CSV; admin), `create-certification` / `create-payment-method` / `create-supplier-role` / `create-supplier-tag` (`--name`), `get-supplier-details`, `get-supplier-analytics`, `list-items`, `create-item` (`--payload`), `update-item` (`--payload`), `delete-item`, `get-item`, `list-item-categories`, `create-item-category`, `update-item-category`, `delete-item-categories` (`--ids` CSV; admin) |
|
|
65
|
+
| **Dashboard & users** | `list-users`, `get-user-performance`, `get-dashboard`, `get-monthly-metrics`, `get-system-overview`, `get-estimate-performance`, `get-financial-overview` |
|
|
64
66
|
| **Errors** | `get-recent-errors`, `get-error-metrics` |
|
|
65
67
|
| **Historical / benchmarks** | `get-approved-budgets`, `get-budget-category-benchmarks`, `get-item-pricing-history`, `get-supplier-pricing-history` |
|
|
66
68
|
|
|
@@ -91,8 +93,9 @@ bun run src/index.ts list-budgets
|
|
|
91
93
|
|
|
92
94
|
### Layout
|
|
93
95
|
|
|
94
|
-
- **`src/
|
|
96
|
+
- **`src/prisma-enums.ts`** — Prisma enum string values for runtime; mirror `packages/db/src/generated/prisma/enums.ts` after schema changes.
|
|
97
|
+
- **`src/filter-enums.ts`** — “extended” filter enums (ALL + Prisma enums). Keep in line with `packages/utils/src/filter-enums.ts` when those values change.
|
|
95
98
|
|
|
96
99
|
### Publish
|
|
97
100
|
|
|
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`).
|
|
101
|
+
`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`). Prisma enum **values** used at runtime live in `src/prisma-enums.ts` (kept in sync with `packages/db` generated enums) so npm installs do not need `@bb/db`.
|
package/dist/commands.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { api } from "./api-client.js";
|
|
2
2
|
import { BudgetRole, Deals, ExtendedApprovalStatus, ExtendedApprovalType, ExtendedBudgetStatus, TimeFrame, } from "./filter-enums.js";
|
|
3
3
|
import { billStatusesForApi, } from "./parse-cli-enums.js";
|
|
4
|
+
import { parseBudgetDiscountPayload, parseCompanyUpdatePayload, parseContactCreatePayload, parseContactUpdatePayload, parseCreateBillPayload, parseCreateBudgetPayload, parseItemCreatePayload, parseItemUpdatePayload, parseSupplierCreatePayload, parseSupplierUpdatePayload, parseUpdateBillPayload, parseUpdateBudgetCommissionPayload, parseUpdateBudgetPayload, parseUpdateProjectPayload, } from "./parse-mutation-payload.js";
|
|
4
5
|
const BUDGET = "BUDGET";
|
|
5
6
|
const BILL = "BILL";
|
|
6
7
|
const SUPPLIER = "SUPPLIER";
|
|
@@ -200,6 +201,148 @@ export async function getBudgetDetails(budgetId) {
|
|
|
200
201
|
const detail = await api.budget.getBudgetDetail.query({ id: budgetId });
|
|
201
202
|
out(detail);
|
|
202
203
|
}
|
|
204
|
+
export async function createBudgetFromPayload(raw) {
|
|
205
|
+
const input = parseCreateBudgetPayload(raw);
|
|
206
|
+
const result = await api.budget.createBudget.mutate(input);
|
|
207
|
+
out(result);
|
|
208
|
+
}
|
|
209
|
+
export async function updateBudgetFromPayload(raw) {
|
|
210
|
+
const input = parseUpdateBudgetPayload(raw);
|
|
211
|
+
const result = await api.budget.updateBudget.mutate(input);
|
|
212
|
+
out(result);
|
|
213
|
+
}
|
|
214
|
+
export async function deleteBudgetById(budgetId) {
|
|
215
|
+
const result = await api.budget.deleteBudget.mutate({ id: budgetId });
|
|
216
|
+
out(result);
|
|
217
|
+
}
|
|
218
|
+
export async function deleteProjectById(projectId) {
|
|
219
|
+
const result = await api.project.deleteProject.mutate({ id: projectId });
|
|
220
|
+
out(result);
|
|
221
|
+
}
|
|
222
|
+
export async function deleteCompanyById(companyId) {
|
|
223
|
+
const result = await api.company.deleteCompany.mutate({ id: companyId });
|
|
224
|
+
out(result);
|
|
225
|
+
}
|
|
226
|
+
export async function reorderBudgetItemsCli(opts) {
|
|
227
|
+
const result = await api.budgetItem.reorderBudgetItems.mutate(opts);
|
|
228
|
+
out(result);
|
|
229
|
+
}
|
|
230
|
+
export async function updateBudgetItemSupplierCli(opts) {
|
|
231
|
+
const result = await api.budgetItem.updateBudgetItemSupplier.mutate(opts);
|
|
232
|
+
out(result);
|
|
233
|
+
}
|
|
234
|
+
export async function createBudgetCategory(name) {
|
|
235
|
+
const result = await api.budget.createBudgetCategory.mutate({ name });
|
|
236
|
+
out(result);
|
|
237
|
+
}
|
|
238
|
+
export async function updateBudgetCategory(opts) {
|
|
239
|
+
const result = await api.budget.updateBudgetCategory.mutate(opts);
|
|
240
|
+
out(result);
|
|
241
|
+
}
|
|
242
|
+
export async function deleteBudgetCategory(id) {
|
|
243
|
+
const result = await api.budget.deleteBudgetCategory.mutate({ id });
|
|
244
|
+
out(result);
|
|
245
|
+
}
|
|
246
|
+
export async function updateBudgetCommissionFromPayload(raw) {
|
|
247
|
+
const input = parseUpdateBudgetCommissionPayload(raw);
|
|
248
|
+
const result = await api.budget.updateBudgetCommission.mutate(input);
|
|
249
|
+
out(result);
|
|
250
|
+
}
|
|
251
|
+
export async function updateBudgetDiscountFromPayload(raw) {
|
|
252
|
+
const input = parseBudgetDiscountPayload(raw);
|
|
253
|
+
const result = await api.budget.updateBudgetDiscount.mutate(input);
|
|
254
|
+
out(result);
|
|
255
|
+
}
|
|
256
|
+
export async function deleteItemById(itemId) {
|
|
257
|
+
const result = await api.item.deleteItem.mutate({ id: itemId });
|
|
258
|
+
out(result);
|
|
259
|
+
}
|
|
260
|
+
export async function deleteSuppliersByIds(ids) {
|
|
261
|
+
const result = await api.supplier.deleteSuppliers.mutate({ ids });
|
|
262
|
+
out(result);
|
|
263
|
+
}
|
|
264
|
+
export async function createSupplierCertification(name) {
|
|
265
|
+
const result = await api.supplier.createCertification.mutate({ name });
|
|
266
|
+
out(result);
|
|
267
|
+
}
|
|
268
|
+
export async function createSupplierPaymentMethod(name) {
|
|
269
|
+
const result = await api.supplier.createPaymentMethod.mutate({ name });
|
|
270
|
+
out(result);
|
|
271
|
+
}
|
|
272
|
+
export async function createSupplierRoleOption(name) {
|
|
273
|
+
const result = await api.supplier.createSupplierRole.mutate({ name });
|
|
274
|
+
out(result);
|
|
275
|
+
}
|
|
276
|
+
export async function createSupplierTagOption(name) {
|
|
277
|
+
const result = await api.supplier.createSupplierTag.mutate({ name });
|
|
278
|
+
out(result);
|
|
279
|
+
}
|
|
280
|
+
export async function createItemCategory(name) {
|
|
281
|
+
const result = await api.itemCategory.createItemCategory.mutate({ name });
|
|
282
|
+
out(result);
|
|
283
|
+
}
|
|
284
|
+
export async function updateItemCategory(opts) {
|
|
285
|
+
const result = await api.itemCategory.updateItemCategory.mutate(opts);
|
|
286
|
+
out(result);
|
|
287
|
+
}
|
|
288
|
+
export async function deleteItemCategoriesByIds(ids) {
|
|
289
|
+
const result = await api.itemCategory.deleteItemCategories.mutate({ ids });
|
|
290
|
+
out(result);
|
|
291
|
+
}
|
|
292
|
+
export async function createBillFromPayload(raw) {
|
|
293
|
+
const input = parseCreateBillPayload(raw);
|
|
294
|
+
const result = await api.bill.create.mutate(input);
|
|
295
|
+
out(result);
|
|
296
|
+
}
|
|
297
|
+
export async function updateBillFromPayload(raw) {
|
|
298
|
+
const input = parseUpdateBillPayload(raw);
|
|
299
|
+
const result = await api.bill.update.mutate(input);
|
|
300
|
+
out(result);
|
|
301
|
+
}
|
|
302
|
+
export async function deleteBillById(id) {
|
|
303
|
+
const result = await api.bill.delete.mutate({ id });
|
|
304
|
+
out(result);
|
|
305
|
+
}
|
|
306
|
+
export async function createSupplierFromPayload(raw) {
|
|
307
|
+
const input = parseSupplierCreatePayload(raw);
|
|
308
|
+
const result = await api.supplier.createSupplier.mutate(input);
|
|
309
|
+
out(result);
|
|
310
|
+
}
|
|
311
|
+
export async function updateSupplierFromPayload(raw) {
|
|
312
|
+
const input = parseSupplierUpdatePayload(raw);
|
|
313
|
+
const result = await api.supplier.updateSupplier.mutate(input);
|
|
314
|
+
out(result);
|
|
315
|
+
}
|
|
316
|
+
export async function createItemFromPayload(raw) {
|
|
317
|
+
const input = parseItemCreatePayload(raw);
|
|
318
|
+
const result = await api.item.createItem.mutate(input);
|
|
319
|
+
out(result);
|
|
320
|
+
}
|
|
321
|
+
export async function updateItemFromPayload(raw) {
|
|
322
|
+
const input = parseItemUpdatePayload(raw);
|
|
323
|
+
const result = await api.item.updateItem.mutate(input);
|
|
324
|
+
out(result);
|
|
325
|
+
}
|
|
326
|
+
export async function createContactPersonFromPayload(raw) {
|
|
327
|
+
const input = parseContactCreatePayload(raw);
|
|
328
|
+
const result = await api.contactPerson.createContactPerson.mutate(input);
|
|
329
|
+
out(result);
|
|
330
|
+
}
|
|
331
|
+
export async function updateContactPersonFromPayload(raw) {
|
|
332
|
+
const input = parseContactUpdatePayload(raw);
|
|
333
|
+
const result = await api.contactPerson.updateContactPerson.mutate(input);
|
|
334
|
+
out(result);
|
|
335
|
+
}
|
|
336
|
+
export async function updateProjectFromPayload(raw) {
|
|
337
|
+
const input = parseUpdateProjectPayload(raw);
|
|
338
|
+
const result = await api.project.updateProject.mutate(input);
|
|
339
|
+
out(result);
|
|
340
|
+
}
|
|
341
|
+
export async function updateCompanyFromPayload(raw) {
|
|
342
|
+
const input = parseCompanyUpdatePayload(raw);
|
|
343
|
+
const result = await api.company.updateCompany.mutate(input);
|
|
344
|
+
out(result);
|
|
345
|
+
}
|
|
203
346
|
// --- Approvals: budgets / suppliers / bills (MCP parity) ---
|
|
204
347
|
export async function approveBudget(budgetId) {
|
|
205
348
|
const notifications = await api.budget.getNotifications.query();
|
|
@@ -338,6 +481,9 @@ export async function createProject(opts) {
|
|
|
338
481
|
from: new Date(opts.startDate),
|
|
339
482
|
to: opts.endDate ? new Date(opts.endDate) : undefined,
|
|
340
483
|
},
|
|
484
|
+
...(opts.requestQboAccountantNotification !== undefined && {
|
|
485
|
+
requestQboAccountantNotification: opts.requestQboAccountantNotification,
|
|
486
|
+
}),
|
|
341
487
|
});
|
|
342
488
|
out(result);
|
|
343
489
|
}
|
|
@@ -403,6 +549,39 @@ export async function getDashboard(input) {
|
|
|
403
549
|
});
|
|
404
550
|
out(result);
|
|
405
551
|
}
|
|
552
|
+
export async function getMonthlyMetrics(input) {
|
|
553
|
+
const result = await api.dashboard.getMonthlyMetrics.query({
|
|
554
|
+
userId: input.userId,
|
|
555
|
+
role: input.role ?? "ALL",
|
|
556
|
+
deals: input.deals ?? "ALL",
|
|
557
|
+
timeFrame: input.timeFrame ?? "ALL",
|
|
558
|
+
startDate: input.startDate,
|
|
559
|
+
endDate: input.endDate,
|
|
560
|
+
});
|
|
561
|
+
out(result);
|
|
562
|
+
}
|
|
563
|
+
export async function getSystemOverview(input) {
|
|
564
|
+
const result = await api.dashboard.getSystemOverview.query({
|
|
565
|
+
userId: input.userId,
|
|
566
|
+
role: input.role ?? "ALL",
|
|
567
|
+
deals: input.deals ?? "ALL",
|
|
568
|
+
timeFrame: input.timeFrame ?? "ALL",
|
|
569
|
+
startDate: input.startDate,
|
|
570
|
+
endDate: input.endDate,
|
|
571
|
+
});
|
|
572
|
+
out(result);
|
|
573
|
+
}
|
|
574
|
+
export async function getEstimatePerformance(input) {
|
|
575
|
+
const result = await api.dashboard.getEstimatePerformance.query({
|
|
576
|
+
userId: input.userId,
|
|
577
|
+
role: input.role ?? "ALL",
|
|
578
|
+
deals: input.deals ?? "ALL",
|
|
579
|
+
timeFrame: input.timeFrame ?? "ALL",
|
|
580
|
+
startDate: input.startDate,
|
|
581
|
+
endDate: input.endDate,
|
|
582
|
+
});
|
|
583
|
+
out(result);
|
|
584
|
+
}
|
|
406
585
|
export async function getFinancialOverview(input) {
|
|
407
586
|
const result = await api.dashboard.getFinancialOverview.query({
|
|
408
587
|
userId: input.userId,
|
package/dist/filter-enums.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ApprovalStatus, ApprovalType, BillStatus, BudgetStatus, ErrorSeverity, ErrorStatus, EstimationMode, ProjectStatus, } from "
|
|
1
|
+
import { ApprovalStatus, ApprovalType, BillStatus, BudgetStatus, ErrorSeverity, ErrorStatus, EstimationMode, ProjectStatus, } from "./prisma-enums.js";
|
|
2
2
|
export const ExtendedApprovalStatus = {
|
|
3
3
|
...ApprovalStatus,
|
|
4
4
|
ALL: "ALL",
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import "./load-env.js";
|
|
3
3
|
import { requireApiKey } from "./api-client.js";
|
|
4
|
-
import { addBudgetItems, approveBill, approveBudget, approveSupplier, createBillApproval, createBudgetApproval, createCompany, createProject, getApprovedBudgets, getBillAttachments, getBillDetails, getBudget, getBudgetCategories, getBudgetCategoryBenchmarks, getBudgetDetails, getBudgetItemsOnly, getBudgetVersions, getCompany, getDashboard, getErrorMetrics, getFinancialOverview, getItem, getItemPricingHistory, getProject, getRecentErrors, getSupplierAnalytics, getSupplierDetails, getSupplierPricingHistory, getUserPerformance, listApprovals, listBills, listBudgets, listCompanies, listContacts, listItemCategories, listItems, listProjects, listSuppliers, listUsers, patchBillInvoiceNumber, patchBillPayment, rejectBill, rejectBudget, rejectSupplier, removeBudgetItem, updateBillStatus, updateBudgetItem, updateBudgetStatus, updateProjectStatus, } from "./commands.js";
|
|
4
|
+
import { addBudgetItems, approveBill, approveBudget, approveSupplier, createBillApproval, createBillFromPayload, createBudgetApproval, createBudgetCategory, createBudgetFromPayload, createCompany, createContactPersonFromPayload, createItemCategory, createItemFromPayload, createProject, createSupplierCertification, createSupplierFromPayload, createSupplierPaymentMethod, createSupplierRoleOption, createSupplierTagOption, deleteBillById, deleteBudgetById, deleteBudgetCategory, deleteCompanyById, deleteItemById, deleteItemCategoriesByIds, deleteProjectById, deleteSuppliersByIds, getApprovedBudgets, getBillAttachments, getBillDetails, getBudget, getBudgetCategories, getBudgetCategoryBenchmarks, getBudgetDetails, getBudgetItemsOnly, getBudgetVersions, getCompany, getDashboard, getErrorMetrics, getEstimatePerformance, getFinancialOverview, getItem, getItemPricingHistory, getMonthlyMetrics, getProject, getRecentErrors, getSupplierAnalytics, getSupplierDetails, getSupplierPricingHistory, getSystemOverview, getUserPerformance, listApprovals, listBills, listBudgets, listCompanies, listContacts, listItemCategories, listItems, listProjects, listSuppliers, listUsers, patchBillInvoiceNumber, patchBillPayment, rejectBill, rejectBudget, rejectSupplier, removeBudgetItem, reorderBudgetItemsCli, updateBillFromPayload, updateBillStatus, updateBudgetCategory, updateBudgetCommissionFromPayload, updateBudgetDiscountFromPayload, updateBudgetFromPayload, updateBudgetItem, updateBudgetItemSupplierCli, updateBudgetStatus, updateCompanyFromPayload, updateContactPersonFromPayload, updateItemCategory, updateItemFromPayload, updateProjectFromPayload, updateProjectStatus, updateSupplierFromPayload, } from "./commands.js";
|
|
5
5
|
import { getFlag, parseArgs } from "./parse-args.js";
|
|
6
6
|
import { billStatusesForUpdateHelp, budgetStatusesForHelp, isBudgetStatusUpdate, parseApprovalTypeFlag, parseBillStatusForUpdate, parseCommaSeparatedBillStatuses, parseCommaSeparatedBudgetStatuses, parseCommaSeparatedIds, parseOptionalBillListSortBy, parseOptionalBillListSortDir, parseOptionalDashboardRole, parseOptionalDeals, parseOptionalErrorSeverity, parseOptionalErrorStatus, parseOptionalExtendedProjectStatus, parseOptionalFinancialRole, parseOptionalSupplierAnalyticsTimeFrame, parseOptionalTimeFrame, parseProjectStatusForUpdate, projectStatusesForHelp, } from "./parse-cli-enums.js";
|
|
7
7
|
import { parseJsonFlag, parseOptionalNumber as parseOptNum, } from "./parse-json-flag.js";
|
|
@@ -44,6 +44,18 @@ function parseListBillsFlags(flags) {
|
|
|
44
44
|
pageSize: parsePositiveIntFlag(getFlag(flags, "pageSize"), "--pageSize"),
|
|
45
45
|
};
|
|
46
46
|
}
|
|
47
|
+
function parseDashboardQueryFlags(flags) {
|
|
48
|
+
const roleRaw = getFlag(flags, "role");
|
|
49
|
+
const timeFrameRaw = getFlag(flags, "timeFrame");
|
|
50
|
+
return {
|
|
51
|
+
userId: getFlag(flags, "userId"),
|
|
52
|
+
role: parseOptionalDashboardRole(roleRaw !== undefined ? String(roleRaw) : undefined),
|
|
53
|
+
deals: parseOptionalDeals(getFlag(flags, "deals")),
|
|
54
|
+
timeFrame: parseOptionalTimeFrame(timeFrameRaw !== undefined ? String(timeFrameRaw) : undefined),
|
|
55
|
+
startDate: getFlag(flags, "startDate"),
|
|
56
|
+
endDate: getFlag(flags, "endDate"),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
47
59
|
function printHelp() {
|
|
48
60
|
const help = `
|
|
49
61
|
bb — Budget Builder CLI (parity with MCP tools)
|
|
@@ -61,15 +73,28 @@ Budgets
|
|
|
61
73
|
get-budget-versions <budgetId>
|
|
62
74
|
update-budget-status <id> <status>
|
|
63
75
|
status: ${budgetStatusesForHelp.join(", ")}
|
|
76
|
+
create-budget --payload '<json>' (budget.createBudget; ISO dates for date/startTime/endTime)
|
|
77
|
+
update-budget --payload '<json>' (budget.updateBudget; must include id)
|
|
78
|
+
delete-budget <budgetId>
|
|
64
79
|
create-budget-approval <budgetId>
|
|
65
80
|
add-budget-items --budgetId --items '[{"itemId":"…","quantity":1,"markup":30},…]'
|
|
66
81
|
update-budget-item --id <budgetItemId> [--description] [--note] [--quantity] [--markup] [--cost] [--unitPrice] [--isFreeOfCharge true|false] [--gstInclusive true|false]
|
|
67
82
|
remove-budget-item <budgetItemId>
|
|
83
|
+
reorder-budget-items <budgetId> --itemIds <csv>
|
|
84
|
+
update-budget-item-supplier --budgetItemId --supplierId
|
|
85
|
+
create-budget-category --name <text>
|
|
86
|
+
update-budget-category --id --name
|
|
87
|
+
delete-budget-category <id>
|
|
88
|
+
update-budget-commission --payload '<json>' (budget.updateBudgetCommission)
|
|
89
|
+
update-budget-discount --payload '<json>' (budget.updateBudgetDiscount; type percentage|amount)
|
|
68
90
|
|
|
69
91
|
Bills
|
|
70
92
|
list-bills [--projectId] [--budgetId] [--status CSV] [--search <text>] [--isClaimable true|false] [--createdByIds <csv>] [--sortBy createdAt|amount|status] [--sortDir asc|desc] [--page] [--pageSize]
|
|
71
93
|
list-claims same flags as list-bills; only reimbursable claims (ignores --isClaimable)
|
|
72
94
|
create-bill-approval <billId>
|
|
95
|
+
create-bill --payload '<json>' (bill.create; attachments may be [])
|
|
96
|
+
update-bill --payload '<json>' (bill.update; must include id)
|
|
97
|
+
delete-bill <billId>
|
|
73
98
|
update-bill-status <id> <status> [--rejectionReason] [--paymentTrackingUrl] [--paymentReference]
|
|
74
99
|
status (${billStatusesForUpdateHelp.join(", ")}) — not PENDING_APPROVAL; use create-bill-approval
|
|
75
100
|
patch-bill-payment <billId> [--paymentTrackingUrl] [--paymentReference] [--quickbooksBillId]
|
|
@@ -90,27 +115,49 @@ Companies & projects
|
|
|
90
115
|
list-companies [--name] [--createdBy] [--page] [--perPage]
|
|
91
116
|
get-company <id>
|
|
92
117
|
create-company --name --website <url>
|
|
118
|
+
update-company --payload '<json>' (company.updateCompany; must include id, name, website)
|
|
119
|
+
delete-company <id>
|
|
93
120
|
list-projects [--companyId] [--name] [--status] [--page] [--perPage]
|
|
94
121
|
get-project <id>
|
|
95
|
-
create-project --name --companyId --contactPersonId --startDate <ISO> [--endDate] [--description]
|
|
122
|
+
create-project --name --companyId --contactPersonId --startDate <ISO> [--endDate] [--description] [--requestQboAccountantNotification false]
|
|
123
|
+
update-project --payload '<json>' (project.updateProject; optional requestQboAccountantNotification; default notify like web)
|
|
124
|
+
delete-project <id>
|
|
96
125
|
update-project-status <id> <status>
|
|
97
126
|
status: ${projectStatusesForHelp.join(", ")}
|
|
98
127
|
|
|
99
128
|
Contacts
|
|
100
129
|
list-contacts <companyId>
|
|
130
|
+
create-contact-person --payload '<json>' (contactPerson.createContactPerson; title MR|MRS|MS|DR)
|
|
131
|
+
update-contact-person --payload '<json>' (contactPerson.updateContactPerson; must include id)
|
|
101
132
|
|
|
102
133
|
Suppliers & items
|
|
103
134
|
list-suppliers [--name] [--page] [--perPage]
|
|
135
|
+
create-supplier --payload '<json>' (supplier.createSupplier)
|
|
136
|
+
update-supplier --payload '<json>' (supplier.updateSupplier; must include id)
|
|
137
|
+
delete-suppliers --ids <csv> (supplier.deleteSuppliers; admin)
|
|
138
|
+
create-certification --name (supplier.createCertification)
|
|
139
|
+
create-payment-method --name (supplier.createPaymentMethod)
|
|
140
|
+
create-supplier-role --name (supplier.createSupplierRole)
|
|
141
|
+
create-supplier-tag --name (supplier.createSupplierTag)
|
|
142
|
+
create-item --payload '<json>' (item.createItem)
|
|
143
|
+
update-item --payload '<json>' (item.updateItem; must include id)
|
|
144
|
+
delete-item <id>
|
|
104
145
|
get-supplier-details <supplierId>
|
|
105
146
|
get-supplier-analytics [--name] [--page] [--perPage] [--timeFrame ALL|LAST_YEAR|…]
|
|
106
147
|
list-items [--name] [--page] [--perPage]
|
|
107
148
|
get-item <id>
|
|
108
149
|
list-item-categories [--page] [--perPage]
|
|
150
|
+
create-item-category --name
|
|
151
|
+
update-item-category --id --name
|
|
152
|
+
delete-item-categories --ids <csv> (itemCategory.deleteItemCategories; admin; empty categories only)
|
|
109
153
|
|
|
110
154
|
Dashboard & users
|
|
111
155
|
list-users
|
|
112
156
|
get-user-performance [--userId]
|
|
113
157
|
get-dashboard [--userId] [--role BD|CREATOR|INSIDE_SALES|ALL] [--deals ALL|SUCCESSFUL|LOST] [--timeFrame] [--startDate] [--endDate]
|
|
158
|
+
get-monthly-metrics [same optional flags as get-dashboard] (dashboard.getMonthlyMetrics)
|
|
159
|
+
get-system-overview [same optional flags as get-dashboard] (dashboard.getSystemOverview)
|
|
160
|
+
get-estimate-performance [same optional flags as get-dashboard] (dashboard.getEstimatePerformance)
|
|
114
161
|
get-financial-overview [same optional flags as dashboard; role uses BudgetRole enum]
|
|
115
162
|
|
|
116
163
|
Errors
|
|
@@ -125,8 +172,9 @@ Historical / benchmarks
|
|
|
125
172
|
|
|
126
173
|
Output: JSON to stdout. Errors to stderr; exit 1 on failure.
|
|
127
174
|
|
|
128
|
-
MCP parity: every MCP tool maps to one command above.
|
|
129
|
-
|
|
175
|
+
MCP parity: every MCP tool maps to one command above. The CLI also exposes
|
|
176
|
+
reorder-budget-items and update-budget-item-supplier (web UI–oriented tRPC).
|
|
177
|
+
You may use MCP-style snake_case (e.g. bb list_bills) — normalized to kebab-case.
|
|
130
178
|
|
|
131
179
|
Note: MCP also exposes a Prisma schema resource; the CLI has no equivalent.
|
|
132
180
|
|
|
@@ -215,6 +263,31 @@ async function main() {
|
|
|
215
263
|
await createBudgetApproval(id);
|
|
216
264
|
break;
|
|
217
265
|
}
|
|
266
|
+
case "create-budget": {
|
|
267
|
+
const payloadRaw = getFlag(flags, "payload");
|
|
268
|
+
if (!payloadRaw) {
|
|
269
|
+
throw new Error("create-budget requires --payload '<json>'");
|
|
270
|
+
}
|
|
271
|
+
const raw = parseJsonFlag(String(payloadRaw), "--payload");
|
|
272
|
+
await createBudgetFromPayload(raw);
|
|
273
|
+
break;
|
|
274
|
+
}
|
|
275
|
+
case "update-budget": {
|
|
276
|
+
const payloadRaw = getFlag(flags, "payload");
|
|
277
|
+
if (!payloadRaw) {
|
|
278
|
+
throw new Error("update-budget requires --payload '<json>'");
|
|
279
|
+
}
|
|
280
|
+
const raw = parseJsonFlag(String(payloadRaw), "--payload");
|
|
281
|
+
await updateBudgetFromPayload(raw);
|
|
282
|
+
break;
|
|
283
|
+
}
|
|
284
|
+
case "delete-budget": {
|
|
285
|
+
const id = positional[0];
|
|
286
|
+
if (!id)
|
|
287
|
+
throw new Error("delete-budget requires <budgetId>");
|
|
288
|
+
await deleteBudgetById(id);
|
|
289
|
+
break;
|
|
290
|
+
}
|
|
218
291
|
case "add-budget-items": {
|
|
219
292
|
const budgetId = getFlag(flags, "budgetId");
|
|
220
293
|
if (!budgetId)
|
|
@@ -247,6 +320,74 @@ async function main() {
|
|
|
247
320
|
await removeBudgetItem(id);
|
|
248
321
|
break;
|
|
249
322
|
}
|
|
323
|
+
case "reorder-budget-items": {
|
|
324
|
+
const budgetId = positional[0];
|
|
325
|
+
const itemIdsRaw = getFlag(flags, "itemIds");
|
|
326
|
+
if (!budgetId || itemIdsRaw === undefined) {
|
|
327
|
+
throw new Error("reorder-budget-items requires <budgetId> --itemIds <csv>");
|
|
328
|
+
}
|
|
329
|
+
const itemIds = parseCommaSeparatedIds(String(itemIdsRaw));
|
|
330
|
+
if (!itemIds?.length) {
|
|
331
|
+
throw new Error("reorder-budget-items requires non-empty --itemIds <csv>");
|
|
332
|
+
}
|
|
333
|
+
await reorderBudgetItemsCli({ budgetId, itemIds });
|
|
334
|
+
break;
|
|
335
|
+
}
|
|
336
|
+
case "update-budget-item-supplier": {
|
|
337
|
+
const budgetItemId = getFlag(flags, "budgetItemId");
|
|
338
|
+
const supplierId = getFlag(flags, "supplierId");
|
|
339
|
+
if (!budgetItemId || !supplierId) {
|
|
340
|
+
throw new Error("update-budget-item-supplier requires --budgetItemId and --supplierId");
|
|
341
|
+
}
|
|
342
|
+
await updateBudgetItemSupplierCli({
|
|
343
|
+
budgetItemId: String(budgetItemId),
|
|
344
|
+
supplierId: String(supplierId),
|
|
345
|
+
});
|
|
346
|
+
break;
|
|
347
|
+
}
|
|
348
|
+
case "create-budget-category": {
|
|
349
|
+
const name = getFlag(flags, "name");
|
|
350
|
+
if (!name) {
|
|
351
|
+
throw new Error("create-budget-category requires --name");
|
|
352
|
+
}
|
|
353
|
+
await createBudgetCategory(String(name));
|
|
354
|
+
break;
|
|
355
|
+
}
|
|
356
|
+
case "update-budget-category": {
|
|
357
|
+
const id = getFlag(flags, "id");
|
|
358
|
+
const name = getFlag(flags, "name");
|
|
359
|
+
if (!id || !name) {
|
|
360
|
+
throw new Error("update-budget-category requires --id and --name");
|
|
361
|
+
}
|
|
362
|
+
await updateBudgetCategory({ id: String(id), name: String(name) });
|
|
363
|
+
break;
|
|
364
|
+
}
|
|
365
|
+
case "delete-budget-category": {
|
|
366
|
+
const id = positional[0];
|
|
367
|
+
if (!id) {
|
|
368
|
+
throw new Error("delete-budget-category requires <id>");
|
|
369
|
+
}
|
|
370
|
+
await deleteBudgetCategory(id);
|
|
371
|
+
break;
|
|
372
|
+
}
|
|
373
|
+
case "update-budget-commission": {
|
|
374
|
+
const payloadRaw = getFlag(flags, "payload");
|
|
375
|
+
if (!payloadRaw) {
|
|
376
|
+
throw new Error("update-budget-commission requires --payload '<json>'");
|
|
377
|
+
}
|
|
378
|
+
const raw = parseJsonFlag(String(payloadRaw), "--payload");
|
|
379
|
+
await updateBudgetCommissionFromPayload(raw);
|
|
380
|
+
break;
|
|
381
|
+
}
|
|
382
|
+
case "update-budget-discount": {
|
|
383
|
+
const payloadRaw = getFlag(flags, "payload");
|
|
384
|
+
if (!payloadRaw) {
|
|
385
|
+
throw new Error("update-budget-discount requires --payload '<json>'");
|
|
386
|
+
}
|
|
387
|
+
const raw = parseJsonFlag(String(payloadRaw), "--payload");
|
|
388
|
+
await updateBudgetDiscountFromPayload(raw);
|
|
389
|
+
break;
|
|
390
|
+
}
|
|
250
391
|
case "list-bills": {
|
|
251
392
|
await listBills(parseListBillsFlags(flags));
|
|
252
393
|
break;
|
|
@@ -265,6 +406,31 @@ async function main() {
|
|
|
265
406
|
await createBillApproval(id);
|
|
266
407
|
break;
|
|
267
408
|
}
|
|
409
|
+
case "create-bill": {
|
|
410
|
+
const payloadRaw = getFlag(flags, "payload");
|
|
411
|
+
if (!payloadRaw) {
|
|
412
|
+
throw new Error("create-bill requires --payload '<json>'");
|
|
413
|
+
}
|
|
414
|
+
const raw = parseJsonFlag(String(payloadRaw), "--payload");
|
|
415
|
+
await createBillFromPayload(raw);
|
|
416
|
+
break;
|
|
417
|
+
}
|
|
418
|
+
case "update-bill": {
|
|
419
|
+
const payloadRaw = getFlag(flags, "payload");
|
|
420
|
+
if (!payloadRaw) {
|
|
421
|
+
throw new Error("update-bill requires --payload '<json>'");
|
|
422
|
+
}
|
|
423
|
+
const raw = parseJsonFlag(String(payloadRaw), "--payload");
|
|
424
|
+
await updateBillFromPayload(raw);
|
|
425
|
+
break;
|
|
426
|
+
}
|
|
427
|
+
case "delete-bill": {
|
|
428
|
+
const id = positional[0];
|
|
429
|
+
if (!id)
|
|
430
|
+
throw new Error("delete-bill requires <billId>");
|
|
431
|
+
await deleteBillById(id);
|
|
432
|
+
break;
|
|
433
|
+
}
|
|
268
434
|
case "update-bill-status": {
|
|
269
435
|
const [id, statusRaw] = positional;
|
|
270
436
|
if (!id || !statusRaw) {
|
|
@@ -402,6 +568,22 @@ async function main() {
|
|
|
402
568
|
await createCompany({ name, website });
|
|
403
569
|
break;
|
|
404
570
|
}
|
|
571
|
+
case "update-company": {
|
|
572
|
+
const payloadRaw = getFlag(flags, "payload");
|
|
573
|
+
if (!payloadRaw) {
|
|
574
|
+
throw new Error("update-company requires --payload '<json>'");
|
|
575
|
+
}
|
|
576
|
+
const raw = parseJsonFlag(String(payloadRaw), "--payload");
|
|
577
|
+
await updateCompanyFromPayload(raw);
|
|
578
|
+
break;
|
|
579
|
+
}
|
|
580
|
+
case "delete-company": {
|
|
581
|
+
const id = positional[0];
|
|
582
|
+
if (!id)
|
|
583
|
+
throw new Error("delete-company requires <id>");
|
|
584
|
+
await deleteCompanyById(id);
|
|
585
|
+
break;
|
|
586
|
+
}
|
|
405
587
|
case "list-projects": {
|
|
406
588
|
const statusRaw = getFlag(flags, "status");
|
|
407
589
|
await listProjects({
|
|
@@ -435,9 +617,26 @@ async function main() {
|
|
|
435
617
|
startDate,
|
|
436
618
|
endDate: getFlag(flags, "endDate"),
|
|
437
619
|
description: getFlag(flags, "description"),
|
|
620
|
+
requestQboAccountantNotification: parseOptionalBoolFlag(flags, "requestQboAccountantNotification"),
|
|
438
621
|
});
|
|
439
622
|
break;
|
|
440
623
|
}
|
|
624
|
+
case "update-project": {
|
|
625
|
+
const payloadRaw = getFlag(flags, "payload");
|
|
626
|
+
if (!payloadRaw) {
|
|
627
|
+
throw new Error("update-project requires --payload '<json>'");
|
|
628
|
+
}
|
|
629
|
+
const raw = parseJsonFlag(String(payloadRaw), "--payload");
|
|
630
|
+
await updateProjectFromPayload(raw);
|
|
631
|
+
break;
|
|
632
|
+
}
|
|
633
|
+
case "delete-project": {
|
|
634
|
+
const id = positional[0];
|
|
635
|
+
if (!id)
|
|
636
|
+
throw new Error("delete-project requires <id>");
|
|
637
|
+
await deleteProjectById(id);
|
|
638
|
+
break;
|
|
639
|
+
}
|
|
441
640
|
case "update-project-status": {
|
|
442
641
|
const [id, statusRaw] = positional;
|
|
443
642
|
if (!id || !statusRaw) {
|
|
@@ -453,6 +652,24 @@ async function main() {
|
|
|
453
652
|
await listContacts(id);
|
|
454
653
|
break;
|
|
455
654
|
}
|
|
655
|
+
case "create-contact-person": {
|
|
656
|
+
const payloadRaw = getFlag(flags, "payload");
|
|
657
|
+
if (!payloadRaw) {
|
|
658
|
+
throw new Error("create-contact-person requires --payload '<json>'");
|
|
659
|
+
}
|
|
660
|
+
const raw = parseJsonFlag(String(payloadRaw), "--payload");
|
|
661
|
+
await createContactPersonFromPayload(raw);
|
|
662
|
+
break;
|
|
663
|
+
}
|
|
664
|
+
case "update-contact-person": {
|
|
665
|
+
const payloadRaw = getFlag(flags, "payload");
|
|
666
|
+
if (!payloadRaw) {
|
|
667
|
+
throw new Error("update-contact-person requires --payload '<json>'");
|
|
668
|
+
}
|
|
669
|
+
const raw = parseJsonFlag(String(payloadRaw), "--payload");
|
|
670
|
+
await updateContactPersonFromPayload(raw);
|
|
671
|
+
break;
|
|
672
|
+
}
|
|
456
673
|
case "list-suppliers": {
|
|
457
674
|
await listSuppliers({
|
|
458
675
|
name: getFlag(flags, "name"),
|
|
@@ -461,6 +678,64 @@ async function main() {
|
|
|
461
678
|
});
|
|
462
679
|
break;
|
|
463
680
|
}
|
|
681
|
+
case "create-supplier": {
|
|
682
|
+
const payloadRaw = getFlag(flags, "payload");
|
|
683
|
+
if (!payloadRaw) {
|
|
684
|
+
throw new Error("create-supplier requires --payload '<json>'");
|
|
685
|
+
}
|
|
686
|
+
const raw = parseJsonFlag(String(payloadRaw), "--payload");
|
|
687
|
+
await createSupplierFromPayload(raw);
|
|
688
|
+
break;
|
|
689
|
+
}
|
|
690
|
+
case "update-supplier": {
|
|
691
|
+
const payloadRaw = getFlag(flags, "payload");
|
|
692
|
+
if (!payloadRaw) {
|
|
693
|
+
throw new Error("update-supplier requires --payload '<json>'");
|
|
694
|
+
}
|
|
695
|
+
const raw = parseJsonFlag(String(payloadRaw), "--payload");
|
|
696
|
+
await updateSupplierFromPayload(raw);
|
|
697
|
+
break;
|
|
698
|
+
}
|
|
699
|
+
case "delete-suppliers": {
|
|
700
|
+
const idsRaw = getFlag(flags, "ids");
|
|
701
|
+
if (idsRaw === undefined) {
|
|
702
|
+
throw new Error("delete-suppliers requires --ids <csv>");
|
|
703
|
+
}
|
|
704
|
+
const ids = parseCommaSeparatedIds(String(idsRaw));
|
|
705
|
+
if (!ids?.length) {
|
|
706
|
+
throw new Error("delete-suppliers requires non-empty --ids");
|
|
707
|
+
}
|
|
708
|
+
await deleteSuppliersByIds(ids);
|
|
709
|
+
break;
|
|
710
|
+
}
|
|
711
|
+
case "create-certification": {
|
|
712
|
+
const name = getFlag(flags, "name");
|
|
713
|
+
if (!name)
|
|
714
|
+
throw new Error("create-certification requires --name");
|
|
715
|
+
await createSupplierCertification(String(name));
|
|
716
|
+
break;
|
|
717
|
+
}
|
|
718
|
+
case "create-payment-method": {
|
|
719
|
+
const name = getFlag(flags, "name");
|
|
720
|
+
if (!name)
|
|
721
|
+
throw new Error("create-payment-method requires --name");
|
|
722
|
+
await createSupplierPaymentMethod(String(name));
|
|
723
|
+
break;
|
|
724
|
+
}
|
|
725
|
+
case "create-supplier-role": {
|
|
726
|
+
const name = getFlag(flags, "name");
|
|
727
|
+
if (!name)
|
|
728
|
+
throw new Error("create-supplier-role requires --name");
|
|
729
|
+
await createSupplierRoleOption(String(name));
|
|
730
|
+
break;
|
|
731
|
+
}
|
|
732
|
+
case "create-supplier-tag": {
|
|
733
|
+
const name = getFlag(flags, "name");
|
|
734
|
+
if (!name)
|
|
735
|
+
throw new Error("create-supplier-tag requires --name");
|
|
736
|
+
await createSupplierTagOption(String(name));
|
|
737
|
+
break;
|
|
738
|
+
}
|
|
464
739
|
case "get-supplier-analytics": {
|
|
465
740
|
const tfRaw = getFlag(flags, "timeFrame");
|
|
466
741
|
await getSupplierAnalytics({
|
|
@@ -486,6 +761,31 @@ async function main() {
|
|
|
486
761
|
await getItem(id);
|
|
487
762
|
break;
|
|
488
763
|
}
|
|
764
|
+
case "create-item": {
|
|
765
|
+
const payloadRaw = getFlag(flags, "payload");
|
|
766
|
+
if (!payloadRaw) {
|
|
767
|
+
throw new Error("create-item requires --payload '<json>'");
|
|
768
|
+
}
|
|
769
|
+
const raw = parseJsonFlag(String(payloadRaw), "--payload");
|
|
770
|
+
await createItemFromPayload(raw);
|
|
771
|
+
break;
|
|
772
|
+
}
|
|
773
|
+
case "update-item": {
|
|
774
|
+
const payloadRaw = getFlag(flags, "payload");
|
|
775
|
+
if (!payloadRaw) {
|
|
776
|
+
throw new Error("update-item requires --payload '<json>'");
|
|
777
|
+
}
|
|
778
|
+
const raw = parseJsonFlag(String(payloadRaw), "--payload");
|
|
779
|
+
await updateItemFromPayload(raw);
|
|
780
|
+
break;
|
|
781
|
+
}
|
|
782
|
+
case "delete-item": {
|
|
783
|
+
const id = positional[0];
|
|
784
|
+
if (!id)
|
|
785
|
+
throw new Error("delete-item requires <id>");
|
|
786
|
+
await deleteItemById(id);
|
|
787
|
+
break;
|
|
788
|
+
}
|
|
489
789
|
case "list-item-categories": {
|
|
490
790
|
await listItemCategories({
|
|
491
791
|
page: parsePositiveIntFlag(getFlag(flags, "page"), "--page"),
|
|
@@ -493,6 +793,34 @@ async function main() {
|
|
|
493
793
|
});
|
|
494
794
|
break;
|
|
495
795
|
}
|
|
796
|
+
case "create-item-category": {
|
|
797
|
+
const name = getFlag(flags, "name");
|
|
798
|
+
if (!name)
|
|
799
|
+
throw new Error("create-item-category requires --name");
|
|
800
|
+
await createItemCategory(String(name));
|
|
801
|
+
break;
|
|
802
|
+
}
|
|
803
|
+
case "update-item-category": {
|
|
804
|
+
const id = getFlag(flags, "id");
|
|
805
|
+
const name = getFlag(flags, "name");
|
|
806
|
+
if (!id || !name) {
|
|
807
|
+
throw new Error("update-item-category requires --id and --name");
|
|
808
|
+
}
|
|
809
|
+
await updateItemCategory({ id: String(id), name: String(name) });
|
|
810
|
+
break;
|
|
811
|
+
}
|
|
812
|
+
case "delete-item-categories": {
|
|
813
|
+
const idsRaw = getFlag(flags, "ids");
|
|
814
|
+
if (idsRaw === undefined) {
|
|
815
|
+
throw new Error("delete-item-categories requires --ids <csv>");
|
|
816
|
+
}
|
|
817
|
+
const ids = parseCommaSeparatedIds(String(idsRaw));
|
|
818
|
+
if (!ids?.length) {
|
|
819
|
+
throw new Error("delete-item-categories requires non-empty --ids");
|
|
820
|
+
}
|
|
821
|
+
await deleteItemCategoriesByIds(ids);
|
|
822
|
+
break;
|
|
823
|
+
}
|
|
496
824
|
case "list-users": {
|
|
497
825
|
await listUsers();
|
|
498
826
|
break;
|
|
@@ -502,14 +830,19 @@ async function main() {
|
|
|
502
830
|
break;
|
|
503
831
|
}
|
|
504
832
|
case "get-dashboard": {
|
|
505
|
-
await getDashboard(
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
833
|
+
await getDashboard(parseDashboardQueryFlags(flags));
|
|
834
|
+
break;
|
|
835
|
+
}
|
|
836
|
+
case "get-monthly-metrics": {
|
|
837
|
+
await getMonthlyMetrics(parseDashboardQueryFlags(flags));
|
|
838
|
+
break;
|
|
839
|
+
}
|
|
840
|
+
case "get-system-overview": {
|
|
841
|
+
await getSystemOverview(parseDashboardQueryFlags(flags));
|
|
842
|
+
break;
|
|
843
|
+
}
|
|
844
|
+
case "get-estimate-performance": {
|
|
845
|
+
await getEstimatePerformance(parseDashboardQueryFlags(flags));
|
|
513
846
|
break;
|
|
514
847
|
}
|
|
515
848
|
case "get-financial-overview": {
|
package/dist/parse-cli-enums.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { BillStatus, BudgetStatus, ProjectStatus } from "@bb/db/enums";
|
|
2
1
|
import { BudgetRole, Deals, ExtendedBillStatus, ExtendedErrorSeverity, ExtendedErrorStatus, ExtendedProjectStatus, TimeFrame, } from "./filter-enums.js";
|
|
2
|
+
import { BillStatus, BudgetStatus, ProjectStatus } from "./prisma-enums.js";
|
|
3
3
|
const BUDGET_STATUS_VALUES = new Set(Object.values(BudgetStatus));
|
|
4
4
|
const BILL_STATUS_VALUES = new Set(Object.values(BillStatus));
|
|
5
5
|
const PROJECT_STATUS_VALUES = new Set(Object.values(ProjectStatus));
|
|
@@ -209,7 +209,7 @@ export function parseApprovalTypeFlag(raw) {
|
|
|
209
209
|
}
|
|
210
210
|
return u;
|
|
211
211
|
}
|
|
212
|
-
/** For help text / error messages (
|
|
212
|
+
/** For help text / error messages (values from `./prisma-enums.js`, synced with Prisma). */
|
|
213
213
|
export const budgetStatusesForHelp = Object.values(BudgetStatus);
|
|
214
214
|
export const billStatusesForHelp = Object.values(BillStatus);
|
|
215
215
|
export const billStatusesForUpdateHelp = Object.values(BillStatus).filter((s) => s !== BillStatus.PENDING_APPROVAL);
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
function requireObject(raw, label) {
|
|
2
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) {
|
|
3
|
+
throw new Error(`${label} must be a JSON object.`);
|
|
4
|
+
}
|
|
5
|
+
return raw;
|
|
6
|
+
}
|
|
7
|
+
function toDate(value, field) {
|
|
8
|
+
if (value instanceof Date && !Number.isNaN(value.getTime())) {
|
|
9
|
+
return value;
|
|
10
|
+
}
|
|
11
|
+
if (typeof value === "string") {
|
|
12
|
+
const d = new Date(value);
|
|
13
|
+
if (!Number.isNaN(d.getTime()))
|
|
14
|
+
return d;
|
|
15
|
+
}
|
|
16
|
+
throw new Error(`${field} must be an ISO date/datetime string.`);
|
|
17
|
+
}
|
|
18
|
+
function optionalString(v) {
|
|
19
|
+
if (v === undefined || v === null)
|
|
20
|
+
return undefined;
|
|
21
|
+
const s = String(v);
|
|
22
|
+
return s === "" ? undefined : s;
|
|
23
|
+
}
|
|
24
|
+
/** Required string fields: rejects null/undefined, whitespace-only, and avoids String(undefined) → "undefined" passing Zod .min(1). */
|
|
25
|
+
function requiredString(value, fieldLabel) {
|
|
26
|
+
if (value === undefined || value === null) {
|
|
27
|
+
throw new Error(`${fieldLabel} is required.`);
|
|
28
|
+
}
|
|
29
|
+
const s = typeof value === "string" ? value : String(value);
|
|
30
|
+
const t = s.trim();
|
|
31
|
+
if (t === "") {
|
|
32
|
+
throw new Error(`${fieldLabel} is required.`);
|
|
33
|
+
}
|
|
34
|
+
return t;
|
|
35
|
+
}
|
|
36
|
+
/** Matches budget.createBudget — dates may be ISO strings in JSON. */
|
|
37
|
+
export function parseCreateBudgetPayload(raw) {
|
|
38
|
+
const o = requireObject(raw, "create-budget payload");
|
|
39
|
+
return {
|
|
40
|
+
name: requiredString(o.name, "create-budget payload.name"),
|
|
41
|
+
date: toDate(o.date, "date"),
|
|
42
|
+
startTime: toDate(o.startTime, "startTime"),
|
|
43
|
+
endTime: toDate(o.endTime, "endTime"),
|
|
44
|
+
pax: requiredString(o.pax, "create-budget payload.pax"),
|
|
45
|
+
venue: requiredString(o.venue, "create-budget payload.venue"),
|
|
46
|
+
budget: requiredString(o.budget, "create-budget payload.budget"),
|
|
47
|
+
paymentTerm: requiredString(o.paymentTerm, "create-budget payload.paymentTerm"),
|
|
48
|
+
categoryId: requiredString(o.categoryId, "create-budget payload.categoryId"),
|
|
49
|
+
projectId: requiredString(o.projectId, "create-budget payload.projectId"),
|
|
50
|
+
insideSalesId: requiredString(o.insideSalesId, "create-budget payload.insideSalesId"),
|
|
51
|
+
businessDevelopmentId: requiredString(o.businessDevelopmentId, "create-budget payload.businessDevelopmentId"),
|
|
52
|
+
asanaTaskId: requiredString(o.asanaTaskId, "create-budget payload.asanaTaskId"),
|
|
53
|
+
sourceBudgetId: optionalString(o.sourceBudgetId),
|
|
54
|
+
pipedriveDealId: optionalString(o.pipedriveDealId),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/** Matches budget.updateBudget — same as create plus id. */
|
|
58
|
+
export function parseUpdateBudgetPayload(raw) {
|
|
59
|
+
const o = requireObject(raw, "update-budget payload");
|
|
60
|
+
const id = requiredString(o.id, "update-budget payload.id");
|
|
61
|
+
const base = parseCreateBudgetPayload(raw);
|
|
62
|
+
return { ...base, id };
|
|
63
|
+
}
|
|
64
|
+
export function parseUpdateBudgetCommissionPayload(raw) {
|
|
65
|
+
const o = requireObject(raw, "update-budget-commission payload");
|
|
66
|
+
return {
|
|
67
|
+
budgetId: requiredString(o.budgetId, "update-budget-commission payload.budgetId"),
|
|
68
|
+
name: requiredString(o.name, "update-budget-commission payload.name"),
|
|
69
|
+
percentage: requiredString(o.percentage, "update-budget-commission payload.percentage"),
|
|
70
|
+
totalSellingAfterDiscount: Number(o.totalSellingAfterDiscount),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
export function parseBudgetDiscountPayload(raw) {
|
|
74
|
+
const o = requireObject(raw, "update-budget-discount payload");
|
|
75
|
+
const type = o.type;
|
|
76
|
+
if (type !== "percentage" && type !== "amount") {
|
|
77
|
+
throw new Error('update-budget-discount payload.type must be "percentage" or "amount".');
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
budgetId: requiredString(o.budgetId, "update-budget-discount payload.budgetId"),
|
|
81
|
+
name: requiredString(o.name, "update-budget-discount payload.name"),
|
|
82
|
+
type,
|
|
83
|
+
value: requiredString(o.value, "update-budget-discount payload.value"),
|
|
84
|
+
totalSellingBeforeDiscount: Number(o.totalSellingBeforeDiscount),
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
const billAttachment = (x, i) => {
|
|
88
|
+
const label = `create-bill payload.attachments[${i}]`;
|
|
89
|
+
const a = requireObject(x, label);
|
|
90
|
+
return {
|
|
91
|
+
id: requiredString(a.id, `${label}.id`),
|
|
92
|
+
name: requiredString(a.name, `${label}.name`),
|
|
93
|
+
key: requiredString(a.key, `${label}.key`),
|
|
94
|
+
size: Number(a.size),
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
/** Matches bill.create — invoiceDate may be ISO string; attachments default to []. */
|
|
98
|
+
export function parseCreateBillPayload(raw) {
|
|
99
|
+
const o = requireObject(raw, "create-bill payload");
|
|
100
|
+
const isClaimable = o.isClaimable;
|
|
101
|
+
if (typeof isClaimable !== "boolean") {
|
|
102
|
+
throw new Error("create-bill payload.isClaimable must be boolean.");
|
|
103
|
+
}
|
|
104
|
+
const budgetItemIds = o.budgetItemIds;
|
|
105
|
+
if (!Array.isArray(budgetItemIds) || budgetItemIds.length === 0) {
|
|
106
|
+
throw new Error("create-bill payload.budgetItemIds must be a non-empty string array.");
|
|
107
|
+
}
|
|
108
|
+
const attachmentsRaw = o.attachments;
|
|
109
|
+
const attachments = Array.isArray(attachmentsRaw)
|
|
110
|
+
? attachmentsRaw.map((x, i) => billAttachment(x, i))
|
|
111
|
+
: [];
|
|
112
|
+
let verificationResults;
|
|
113
|
+
const vr = o.verificationResults;
|
|
114
|
+
if (vr !== undefined && vr !== null) {
|
|
115
|
+
const v = requireObject(vr, "verificationResults");
|
|
116
|
+
verificationResults = {
|
|
117
|
+
status: v.status,
|
|
118
|
+
extractedAmount: v.extractedAmount === null || v.extractedAmount === undefined
|
|
119
|
+
? null
|
|
120
|
+
: Number(v.extractedAmount),
|
|
121
|
+
difference: v.difference === null || v.difference === undefined
|
|
122
|
+
? null
|
|
123
|
+
: Number(v.difference),
|
|
124
|
+
confidence: v.confidence === null || v.confidence === undefined
|
|
125
|
+
? null
|
|
126
|
+
: Number(v.confidence),
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
const verificationStatus = o.verificationStatus;
|
|
130
|
+
let vs;
|
|
131
|
+
if (verificationStatus === "PENDING" ||
|
|
132
|
+
verificationStatus === "PASS" ||
|
|
133
|
+
verificationStatus === "FAIL" ||
|
|
134
|
+
verificationStatus === "MANUAL_REVIEW") {
|
|
135
|
+
vs = verificationStatus;
|
|
136
|
+
}
|
|
137
|
+
else if (verificationStatus !== undefined && verificationStatus !== null) {
|
|
138
|
+
throw new Error("create-bill payload.verificationStatus must be PENDING | PASS | FAIL | MANUAL_REVIEW.");
|
|
139
|
+
}
|
|
140
|
+
const amount = Number(o.amount);
|
|
141
|
+
if (!Number.isFinite(amount) || amount < 0) {
|
|
142
|
+
throw new Error("create-bill payload.amount must be a number >= 0.");
|
|
143
|
+
}
|
|
144
|
+
return {
|
|
145
|
+
budgetId: requiredString(o.budgetId, "create-bill payload.budgetId"),
|
|
146
|
+
projectId: requiredString(o.projectId, "create-bill payload.projectId"),
|
|
147
|
+
supplierId: requiredString(o.supplierId, "create-bill payload.supplierId"),
|
|
148
|
+
amount,
|
|
149
|
+
budgetItemIds: budgetItemIds.map((id, i) => requiredString(id, `create-bill payload.budgetItemIds[${i}]`)),
|
|
150
|
+
comment: optionalString(o.comment),
|
|
151
|
+
isClaimable,
|
|
152
|
+
attachments,
|
|
153
|
+
extractedSupplierName: optionalString(o.extractedSupplierName),
|
|
154
|
+
extractedAmount: o.extractedAmount === undefined || o.extractedAmount === null
|
|
155
|
+
? undefined
|
|
156
|
+
: Number(o.extractedAmount),
|
|
157
|
+
invoiceNumber: o.invoiceNumber === undefined || o.invoiceNumber === null
|
|
158
|
+
? ""
|
|
159
|
+
: typeof o.invoiceNumber === "string"
|
|
160
|
+
? o.invoiceNumber
|
|
161
|
+
: String(o.invoiceNumber),
|
|
162
|
+
invoiceDate: o.invoiceDate === undefined || o.invoiceDate === null
|
|
163
|
+
? undefined
|
|
164
|
+
: toDate(o.invoiceDate, "invoiceDate"),
|
|
165
|
+
verificationStatus: vs,
|
|
166
|
+
verificationResults,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
/** Matches bill.update */
|
|
170
|
+
export function parseUpdateBillPayload(raw) {
|
|
171
|
+
const o = requireObject(raw, "update-bill payload");
|
|
172
|
+
return {
|
|
173
|
+
...parseCreateBillPayload(raw),
|
|
174
|
+
id: requiredString(o.id, "update-bill payload.id"),
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
/** Matches project.updateProject — dateRange.from/to may be ISO strings. */
|
|
178
|
+
export function parseUpdateProjectPayload(raw) {
|
|
179
|
+
const o = requireObject(raw, "update-project payload");
|
|
180
|
+
const dr = o.dateRange;
|
|
181
|
+
if (dr === null || typeof dr !== "object" || Array.isArray(dr)) {
|
|
182
|
+
throw new Error("update-project payload.dateRange must be an object.");
|
|
183
|
+
}
|
|
184
|
+
const range = dr;
|
|
185
|
+
const notification = o.requestQboAccountantNotification;
|
|
186
|
+
let requestQboAccountantNotification;
|
|
187
|
+
if (typeof notification === "boolean") {
|
|
188
|
+
requestQboAccountantNotification = notification;
|
|
189
|
+
}
|
|
190
|
+
else if (notification !== undefined && notification !== null) {
|
|
191
|
+
throw new Error("update-project payload.requestQboAccountantNotification must be a boolean when set.");
|
|
192
|
+
}
|
|
193
|
+
return {
|
|
194
|
+
id: requiredString(o.id, "update-project payload.id"),
|
|
195
|
+
name: requiredString(o.name, "update-project payload.name"),
|
|
196
|
+
description: optionalString(o.description),
|
|
197
|
+
companyId: requiredString(o.companyId, "update-project payload.companyId"),
|
|
198
|
+
contactPersonId: requiredString(o.contactPersonId, "update-project payload.contactPersonId"),
|
|
199
|
+
dateRange: {
|
|
200
|
+
from: toDate(range.from, "dateRange.from"),
|
|
201
|
+
to: range.to === undefined || range.to === null
|
|
202
|
+
? undefined
|
|
203
|
+
: toDate(range.to, "dateRange.to"),
|
|
204
|
+
},
|
|
205
|
+
...(requestQboAccountantNotification !== undefined && {
|
|
206
|
+
requestQboAccountantNotification,
|
|
207
|
+
}),
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
/** Server validates with Zod; CLI only checks top-level shape is object. */
|
|
211
|
+
export function parseSupplierCreatePayload(raw) {
|
|
212
|
+
requireObject(raw, "create-supplier payload");
|
|
213
|
+
return raw;
|
|
214
|
+
}
|
|
215
|
+
export function parseSupplierUpdatePayload(raw) {
|
|
216
|
+
requireObject(raw, "update-supplier payload");
|
|
217
|
+
return raw;
|
|
218
|
+
}
|
|
219
|
+
export function parseItemCreatePayload(raw) {
|
|
220
|
+
requireObject(raw, "create-item payload");
|
|
221
|
+
return raw;
|
|
222
|
+
}
|
|
223
|
+
export function parseItemUpdatePayload(raw) {
|
|
224
|
+
requireObject(raw, "update-item payload");
|
|
225
|
+
return raw;
|
|
226
|
+
}
|
|
227
|
+
export function parseContactCreatePayload(raw) {
|
|
228
|
+
requireObject(raw, "create-contact-person payload");
|
|
229
|
+
return raw;
|
|
230
|
+
}
|
|
231
|
+
export function parseContactUpdatePayload(raw) {
|
|
232
|
+
requireObject(raw, "update-contact-person payload");
|
|
233
|
+
return raw;
|
|
234
|
+
}
|
|
235
|
+
export function parseCompanyUpdatePayload(raw) {
|
|
236
|
+
requireObject(raw, "update-company payload");
|
|
237
|
+
return raw;
|
|
238
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime Prisma enum values the CLI needs. Mirrors
|
|
3
|
+
* `packages/db/src/generated/prisma/enums.ts` — keep in sync when the schema changes.
|
|
4
|
+
*/
|
|
5
|
+
export const EstimationMode = {
|
|
6
|
+
MICRO: "MICRO",
|
|
7
|
+
MANPOWER_SPECIFIED: "MANPOWER_SPECIFIED",
|
|
8
|
+
};
|
|
9
|
+
export const ProjectStatus = {
|
|
10
|
+
NOT_STARTED: "NOT_STARTED",
|
|
11
|
+
IN_PROGRESS: "IN_PROGRESS",
|
|
12
|
+
COMPLETED: "COMPLETED",
|
|
13
|
+
CANCELLED: "CANCELLED",
|
|
14
|
+
};
|
|
15
|
+
export const BudgetStatus = {
|
|
16
|
+
DRAFT: "DRAFT",
|
|
17
|
+
PENDING_APPROVAL: "PENDING_APPROVAL",
|
|
18
|
+
APPROVED: "APPROVED",
|
|
19
|
+
REJECTED: "REJECTED",
|
|
20
|
+
ESTIMATE_CREATED: "ESTIMATE_CREATED",
|
|
21
|
+
ESTIMATE_SENT: "ESTIMATE_SENT",
|
|
22
|
+
ESTIMATE_ACCEPTED: "ESTIMATE_ACCEPTED",
|
|
23
|
+
ESTIMATE_REJECTED: "ESTIMATE_REJECTED",
|
|
24
|
+
ESTIMATE_CLOSED: "ESTIMATE_CLOSED",
|
|
25
|
+
};
|
|
26
|
+
export const ApprovalStatus = {
|
|
27
|
+
PENDING_APPROVAL: "PENDING_APPROVAL",
|
|
28
|
+
APPROVED: "APPROVED",
|
|
29
|
+
REJECTED: "REJECTED",
|
|
30
|
+
};
|
|
31
|
+
export const ApprovalType = {
|
|
32
|
+
BUDGET: "BUDGET",
|
|
33
|
+
SUPPLIER: "SUPPLIER",
|
|
34
|
+
BILL: "BILL",
|
|
35
|
+
};
|
|
36
|
+
export const ErrorSeverity = {
|
|
37
|
+
LOW: "LOW",
|
|
38
|
+
MEDIUM: "MEDIUM",
|
|
39
|
+
HIGH: "HIGH",
|
|
40
|
+
CRITICAL: "CRITICAL",
|
|
41
|
+
};
|
|
42
|
+
export const ErrorStatus = {
|
|
43
|
+
UNRESOLVED: "UNRESOLVED",
|
|
44
|
+
INVESTIGATING: "INVESTIGATING",
|
|
45
|
+
RESOLVED: "RESOLVED",
|
|
46
|
+
IGNORED: "IGNORED",
|
|
47
|
+
};
|
|
48
|
+
export const BillStatus = {
|
|
49
|
+
DRAFT: "DRAFT",
|
|
50
|
+
PENDING_APPROVAL: "PENDING_APPROVAL",
|
|
51
|
+
CHECKED: "CHECKED",
|
|
52
|
+
APPROVED: "APPROVED",
|
|
53
|
+
PAID: "PAID",
|
|
54
|
+
REJECTED: "REJECTED",
|
|
55
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@go-labs-sg/bb",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"description": "Budget Builder CLI — list budgets, bills, approvals, suppliers; approve bills; change status. For AI agents (e.g. Chuck/OpenClaw).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"postpack": "node scripts/restore-package-json.js"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@trpc/client": "^11.
|
|
24
|
+
"@trpc/client": "^11.16.0",
|
|
25
25
|
"dotenv": "^17.2.4",
|
|
26
26
|
"superjson": "^2.2.6"
|
|
27
27
|
},
|
package/dist/api-client.d.ts
DELETED
package/dist/api-client.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAGN,KAAK,qBAAqB,EAC1B,MAAM,cAAc,CAAC;AAetB,eAAO,MAAM,GAAG,EAAE,qBAAqB,CAAC,SAAS,CAgB/C,CAAC;AAEH,wBAAgB,aAAa,IAAI,MAAM,CAOtC"}
|
package/dist/commands.d.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import type { BudgetStatus } from "@bb/db/enums";
|
|
2
|
-
import type { ExtendedBudgetStatus } from "@bb/utils/filter-enums";
|
|
3
|
-
export declare function listBudgets(opts: {
|
|
4
|
-
projectId?: string;
|
|
5
|
-
name?: string;
|
|
6
|
-
statuses?: ExtendedBudgetStatus[];
|
|
7
|
-
page?: number;
|
|
8
|
-
perPage?: number;
|
|
9
|
-
}): Promise<void>;
|
|
10
|
-
export declare function getBudget(id: string): Promise<void>;
|
|
11
|
-
export declare function updateBudgetStatus(budgetId: string, status: BudgetStatus): Promise<void>;
|
|
12
|
-
export declare function listBills(opts: {
|
|
13
|
-
projectId?: string;
|
|
14
|
-
budgetId?: string;
|
|
15
|
-
status?: string;
|
|
16
|
-
page?: number;
|
|
17
|
-
pageSize?: number;
|
|
18
|
-
}): Promise<void>;
|
|
19
|
-
export declare function approveBill(billId: string): Promise<void>;
|
|
20
|
-
export declare function listApprovals(opts: {
|
|
21
|
-
type?: string;
|
|
22
|
-
}): Promise<void>;
|
|
23
|
-
export declare function listSuppliers(opts: {
|
|
24
|
-
name?: string;
|
|
25
|
-
page?: number;
|
|
26
|
-
perPage?: number;
|
|
27
|
-
}): Promise<void>;
|
|
28
|
-
//# sourceMappingURL=commands.d.ts.map
|
package/dist/commands.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAWnE,wBAAsB,WAAW,CAAC,IAAI,EAAE;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,oBAAoB,EAAE,CAAC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,IAAI,CAAC,CAShB;AAED,wBAAsB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAMzD;AAED,wBAAsB,kBAAkB,CACvC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,YAAY,GAClB,OAAO,CAAC,IAAI,CAAC,CAMf;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAAC,IAAI,CAAC,CAehB;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmB/D;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA6C1E;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,IAAI,CAAC,CAOhB"}
|
package/dist/index.d.ts
DELETED
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,eAAe,CAAC"}
|
package/dist/load-env.d.ts
DELETED
package/dist/load-env.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"load-env.d.ts","sourceRoot":"","sources":["../src/load-env.ts"],"names":[],"mappings":""}
|
package/dist/parse-args.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Minimal argv parser for bb CLI.
|
|
3
|
-
* Supports: command [positional...] [--key=value] [--key value]
|
|
4
|
-
*/
|
|
5
|
-
export declare function parseArgs(argv: string[]): {
|
|
6
|
-
command: string;
|
|
7
|
-
positional: string[];
|
|
8
|
-
flags: Record<string, string | true>;
|
|
9
|
-
};
|
|
10
|
-
export declare function getFlag<T extends string | number>(flags: Record<string, string | true>, key: string, parse?: (s: string) => T): T | undefined;
|
|
11
|
-
//# sourceMappingURL=parse-args.d.ts.map
|
package/dist/parse-args.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"parse-args.d.ts","sourceRoot":"","sources":["../src/parse-args.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;CACrC,CA8BA;AAED,wBAAgB,OAAO,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EAChD,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,EACpC,GAAG,EAAE,MAAM,EACX,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,CAAC,GACtB,CAAC,GAAG,SAAS,CAIf"}
|