Phase2: Invoicecomputation/AdminpricingUI/Ainvoicemgnt
Some checks failed
Build and Push / build (push) Failing after 28s
Some checks failed
Build and Push / build (push) Failing after 28s
This commit is contained in:
@@ -520,3 +520,130 @@ export interface OrgBillingConfig {
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Billing — Phase 2: invoices and lines
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export type InvoiceStatus =
|
||||
| "draft"
|
||||
| "open"
|
||||
| "paid"
|
||||
| "overdue"
|
||||
| "void"
|
||||
| "uncollectible";
|
||||
|
||||
export type InvoicePaymentMethod = "invoice" | "card";
|
||||
|
||||
export type InvoiceLineKind =
|
||||
| "tenant_monthly"
|
||||
| "tenant_setup"
|
||||
| "ai_usage"
|
||||
| "threema_messages"
|
||||
| "skill_usage"
|
||||
| "adjustment";
|
||||
|
||||
/**
|
||||
* Snapshot of the customer's billing details captured at invoice
|
||||
* issue time. Subsequent edits to org_billing do not mutate
|
||||
* historical invoices.
|
||||
*
|
||||
* Field names mirror OrgBilling (minus the timestamps) so the
|
||||
* snapshot is a straightforward copy at issue time.
|
||||
*/
|
||||
export interface InvoiceBillingSnapshot {
|
||||
companyName: string;
|
||||
streetAddress: string;
|
||||
postalCode: string;
|
||||
city: string;
|
||||
country: string;
|
||||
vatNumber: string | null;
|
||||
billingEmail: string;
|
||||
notes: string | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* One line on an invoice. The `metadata` shape varies by `kind`:
|
||||
* tenant_monthly: { proration_days, days_in_month, billable_days, suspended_days }
|
||||
* tenant_setup: {}
|
||||
* ai_usage: { litellm_key_alias, spend_chf, requests }
|
||||
* threema_messages: { in_count, out_count, total_count }
|
||||
* skill_usage: { skill_id, billable_days, event_count }
|
||||
* adjustment: { reason, admin_user_id }
|
||||
*/
|
||||
export interface InvoiceLine {
|
||||
id: string;
|
||||
invoiceId: string;
|
||||
tenantName: string | null;
|
||||
kind: InvoiceLineKind;
|
||||
description: string;
|
||||
quantity: number;
|
||||
unitLabel: string | null;
|
||||
unitPriceChf: number;
|
||||
amountChf: number;
|
||||
metadata: Record<string, unknown> | null;
|
||||
displayOrder: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Immutable invoice record. The PDF blob is fetched separately via
|
||||
* the download endpoint to avoid loading bytea on every list query.
|
||||
*/
|
||||
export interface Invoice {
|
||||
id: string;
|
||||
invoiceNumber: string;
|
||||
zitadelOrgId: string;
|
||||
periodStart: string; // ISO date (YYYY-MM-DD)
|
||||
periodEnd: string;
|
||||
issuedAt: string;
|
||||
dueAt: string;
|
||||
subtotalChf: number;
|
||||
vatRate: number;
|
||||
vatAmountChf: number;
|
||||
totalChf: number;
|
||||
status: InvoiceStatus;
|
||||
locale: string;
|
||||
paymentMethod: InvoicePaymentMethod;
|
||||
billingSnapshot: InvoiceBillingSnapshot;
|
||||
stripePaymentIntentId: string | null;
|
||||
pdfFilename: string | null;
|
||||
hasPdf: boolean; // computed: pdf_data IS NOT NULL
|
||||
adminNotes: string | null;
|
||||
paidAt: string | null;
|
||||
paidBy: string | null;
|
||||
paidMethodDetail: string | null;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
/** Invoice with its line items, used by detail views. */
|
||||
export interface InvoiceDetail {
|
||||
invoice: Invoice;
|
||||
lines: InvoiceLine[];
|
||||
}
|
||||
|
||||
/**
|
||||
* In-memory draft produced by the computation pipeline before the
|
||||
* invoice is allocated a number and persisted. Used by both the
|
||||
* preview endpoint (return without persisting) and the commit
|
||||
* endpoint (compute → persist atomically).
|
||||
*/
|
||||
export interface InvoiceDraft {
|
||||
zitadelOrgId: string;
|
||||
periodStart: string;
|
||||
periodEnd: string;
|
||||
dueAt: string;
|
||||
locale: string;
|
||||
paymentMethod: InvoicePaymentMethod;
|
||||
billingSnapshot: InvoiceBillingSnapshot;
|
||||
lines: Omit<InvoiceLine, "id" | "invoiceId">[];
|
||||
subtotalChf: number;
|
||||
vatRate: number;
|
||||
vatAmountChf: number;
|
||||
totalChf: number;
|
||||
/**
|
||||
* Non-blocking warnings the compute pipeline surfaced — e.g.
|
||||
* "tenant X has no LiteLLM team, AI usage skipped". Rendered in
|
||||
* the admin UI to help the operator decide whether to commit.
|
||||
*/
|
||||
warnings: string[];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user