feat(costs): add billing, quota, and budget control plane
This commit is contained in:
@@ -4,6 +4,7 @@ import { approvalComments, approvals } from "@paperclipai/db";
|
||||
import { notFound, unprocessable } from "../errors.js";
|
||||
import { redactCurrentUserText } from "../log-redaction.js";
|
||||
import { agentService } from "./agents.js";
|
||||
import { budgetService } from "./budgets.js";
|
||||
import { notifyHireApproved } from "./hire-hook.js";
|
||||
|
||||
function redactApprovalComment<T extends { body: string }>(comment: T): T {
|
||||
@@ -15,6 +16,7 @@ function redactApprovalComment<T extends { body: string }>(comment: T): T {
|
||||
|
||||
export function approvalService(db: Db) {
|
||||
const agentsSvc = agentService(db);
|
||||
const budgets = budgetService(db);
|
||||
const canResolveStatuses = new Set(["pending", "revision_requested"]);
|
||||
const resolvableStatuses = Array.from(canResolveStatuses);
|
||||
type ApprovalRecord = typeof approvals.$inferSelect;
|
||||
@@ -137,6 +139,20 @@ export function approvalService(db: Db) {
|
||||
hireApprovedAgentId = created?.id ?? null;
|
||||
}
|
||||
if (hireApprovedAgentId) {
|
||||
const budgetMonthlyCents =
|
||||
typeof payload.budgetMonthlyCents === "number" ? payload.budgetMonthlyCents : 0;
|
||||
if (budgetMonthlyCents > 0) {
|
||||
await budgets.upsertPolicy(
|
||||
updated.companyId,
|
||||
{
|
||||
scopeType: "agent",
|
||||
scopeId: hireApprovedAgentId,
|
||||
amount: budgetMonthlyCents,
|
||||
windowKind: "calendar_month_utc",
|
||||
},
|
||||
decidedByUserId,
|
||||
);
|
||||
}
|
||||
void notifyHireApproved(db, {
|
||||
companyId: updated.companyId,
|
||||
agentId: hireApprovedAgentId,
|
||||
|
||||
Reference in New Issue
Block a user