149 lines · 5.5 KB
import { all } from "../db";
import { accountDb } from "../scoped-db";
import { METERS } from "~/lib/meters";
import type { MeterId } from "~/lib/meters";
import { billingSettings, hardCap } from "./quota";
import type { BillingSettings } from "./quota";
import { periodOf } from "./record";
import { creditBalances } from "./credits";
import { creditPoolFor } from "~/lib/pricing";

export type MeterUsage = {
  meter: MeterId;
  label: string;
  category: string;
  unit: string;
  quantity: number;
  reserved: number;
  included: number | null;
  /** The plan's hard cap plus prepaid credit headroom; null when soft. */
  hardCap: number | null;
  /** Usage this period paid for by prepaid credit. */
  creditCovered: number;
  /** Unspent prepaid credit this meter could still use, in its own units (pools are shared across meters). */
  creditBalance: number;
  overageCents: number;
};

export type UsageSummary = {
  accountId: string;
  period: string;
  plan: { id: string; label: string; billsOverage: boolean };
  spendingLimitCents: number | null;
  totalCents: number;
  meters: MeterUsage[];
  repos: { repoId: string; name: string | null; meter: string; quantity: number }[];
  days: { day: string; meter: string; quantity: number }[];
  alerts: { subject: string; threshold: number; createdAt: number }[];
  /** Unspent prepaid credit per pool, in pool units (compute: standard-1 seconds; ai.tokens: tokens). */
  credits: Record<string, number>;
};