Phase1: Schema + skill event tracking
Some checks failed
Build and Push / build (push) Failing after 38s
Some checks failed
Build and Push / build (push) Failing after 38s
This commit is contained in:
@@ -412,3 +412,111 @@ export interface SupportTicketDetail {
|
||||
ticket: SupportTicket;
|
||||
comments: SupportTicketComment[];
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Billing — Phase 1: pricing, lifecycle, and events
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
// All money values are numbers (CHF). The DB stores NUMERIC and the
|
||||
// helpers coerce to Number on read. JS floats are exact for integers
|
||||
// up to 2^53; at this domain (CHF amounts to 2 decimals, unit prices
|
||||
// to 5 decimals) precision is fine. The Phase 2 billing computation
|
||||
// will still do arithmetic carefully (sum in cents, round at the
|
||||
// end) to avoid 0.1 + 0.2 surprises.
|
||||
|
||||
/**
|
||||
* Single-row platform pricing config. Editable via the admin
|
||||
* pricing page (Phase 2). The `vatRateChli` field is the rate
|
||||
* applied to invoices whose billing address resolves to CH/LI;
|
||||
* foreign customers' rates are decided per-invoice from address +
|
||||
* VAT number, not from this config.
|
||||
*/
|
||||
export interface PlatformPricing {
|
||||
tenantMonthlyFeeChf: number;
|
||||
tenantSetupFeeChf: number;
|
||||
threemaMessageChf: number;
|
||||
vatRateChli: number;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Per-package daily price. Phase 2's admin UI restricts setting
|
||||
* these to skill-category packages, but the schema accepts any
|
||||
* package id. A row's existence is what activates billing for that
|
||||
* package; deleting the row makes it free without affecting the
|
||||
* append-only event log.
|
||||
*/
|
||||
export interface SkillPricing {
|
||||
skillId: string;
|
||||
dailyPriceChf: number;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tenant lifecycle bookends mirrored from K8s into Postgres so
|
||||
* deleted tenants still have a billing record for their final
|
||||
* invoice. `createdAt` matches PiecedTenant.metadata.creationTimestamp
|
||||
* at the moment of approval; `deletedAt` is stamped when the admin
|
||||
* delete endpoint runs.
|
||||
*/
|
||||
export interface TenantBillingLifecycle {
|
||||
tenantName: string;
|
||||
zitadelOrgId: string;
|
||||
createdAt: string;
|
||||
deletedAt: string | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append-only enable/disable event for a package on a tenant.
|
||||
* Phase 2's billing computation reads the event stream within the
|
||||
* billing window and collapses it to a set of UTC days during
|
||||
* which the package was active.
|
||||
*/
|
||||
export interface TenantSkillEvent {
|
||||
id: string;
|
||||
tenantName: string;
|
||||
zitadelOrgId: string;
|
||||
skillId: string;
|
||||
eventKind: "enabled" | "disabled";
|
||||
occurredAt: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append-only suspend/resume event. Recorded by the portal at
|
||||
* command time (when PATCH spec.suspend lands), not at operator
|
||||
* reconcile time. The few-second delta is irrelevant for monthly
|
||||
* billing.
|
||||
*/
|
||||
export interface TenantSuspensionEvent {
|
||||
id: string;
|
||||
tenantName: string;
|
||||
zitadelOrgId: string;
|
||||
eventKind: "suspended" | "resumed";
|
||||
occurredAt: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Per-org billing posture and Stripe linkage. Distinct from
|
||||
* OrgBilling (which is the customer-editable address/VAT block):
|
||||
* this one is admin-controlled.
|
||||
*
|
||||
* `payByInvoice` flips the onboarding gate (Phase 4): when true,
|
||||
* tenant requests for this org are approvable without a card on
|
||||
* file. When false, the customer must have a validated Stripe
|
||||
* payment method before admin approval is allowed.
|
||||
*
|
||||
* `stripeCustomerId` is populated by Phase 4's onboarding flow.
|
||||
* `autoInvoiceEnabled` / `autoRemindersEnabled` give admin per-org
|
||||
* kill switches for the Phase 6 cron without disabling the cron
|
||||
* globally.
|
||||
*/
|
||||
export interface OrgBillingConfig {
|
||||
zitadelOrgId: string;
|
||||
payByInvoice: boolean;
|
||||
stripeCustomerId: string | null;
|
||||
autoInvoiceEnabled: boolean;
|
||||
autoRemindersEnabled: boolean;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user