Ctrl K
ComunidadGuías…

lib/billing-types.ts

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
import type { BillingPlanId, UsageSegmentId } from "@/lib/billing-plans";
import type { UsageHistoryFeature } from "@/lib/usage-features";

/**
 * Response forms for billing routes (MIN-72), shared server/client.
 * `GET /api/billing` → BillingStatusResponse · `GET /api/billing/usage` →
 * UsageSummaryResponse.
 */

export interface BillingStatusResponse {
  planId: BillingPlanId;
  source: "admin_override" | "stripe" | "default";
  /** Present only while an admin override is active. */
  adminOverride: {
    /** null means that the override has no time limit. */
    expiresAt: string | null;
    /** Plan that applies when the override is removed or expires. */
    basePlanId: BillingPlanId;
  } | null;
  /** Stripe service actually operated by this instance. */
  managedBilling: boolean;
  /** AI quota actually operated by this instance. */
  managedAi: boolean;
  stripeConfigured: boolean;
  subscription: {
    status: string | null;
    cancelAtPeriodEnd: boolean;
    currentPeriodEnd: string | null;
  } | null;
}

export interface UsageHistoryEntry {
  runId: string;
  /** Display segment (agents = LLM + sandbox merged) — icon and color. */
  segmentId: UsageSegmentId;
  /**
   * The exact feature of the run, when we know how to name it: it is SHE that the line
   * displays (“Smart-fill”, not “Automations”). `null` on a feature
   * that the UI does not know — the display then falls back to the name of the segment.
   */
  feature: UsageHistoryFeature | null;
  at: string;
  projectName: string | null;
  /** Gross USD cost of the run — the UI converts it to a % of the budget, never displayed as is. */
  usd: number;
}

/** `GET /api/billing/usage-history` — runs of the current window, paginated. */
export interface UsageHistoryResponse {
  total: number;
  entries: UsageHistoryEntry[];
}

export interface UsageDay {
  /** UTC calendar day; partial days are bounded by the effective usage window. */
  day: string;
  usd: number;
  segments: Array<{ id: UsageSegmentId; usd: number }>;
}

/** Full-window aggregates, independent of history pagination. */
export interface UsageAnalyticsResponse {
  periodStart: string;
  periodEnd: string;
  observedAt: string;
  includedUsd: number;
  days: UsageDay[];
}

export interface UsageSummaryResponse {
  planId: BillingPlanId;
  managedBilling: boolean;
  managedAi: boolean;
  /** Monthly usage budget included (USD, gross cost). */
  includedUsd: number;
  usedUsd: number;
  remainingUsd: number;
  periodStart: string;
  /** End of current window = date of next reset. */
  nextResetAt: string;
  /** Breakdown by display segment, in order of USAGE_SEGMENTS. */
  segments: Array<{ id: UsageSegmentId; usd: number }>;
  limits: {
    maxProjects: number | null;
    projectsUsed: number;
    maxIssuesPerProject: number | null;
    allowAgents: boolean;
    /** Guests per project, owner not included. `null` = unlimited. */
    maxMembersPerProject: number | null;
  };
}