feat: add local auth billing and usage management
This commit is contained in:
1 parent
f642b5e71f
commit
196fdde83f
119 files changed
+15695
-2650
No files matched your search
+223
-5
@@ -1,7 +1,5 @@
|
||||
export type ImageCapability =
|
||||
| "image.generate"
|
||||
| "image.inpaint"
|
||||
| "image.upscale";
|
||||
| "image.generate";
|
||||
|
||||
export type EnabledImageCapability = ImageCapability;
|
||||
|
||||
@@ -9,6 +7,214 @@ export type VideoCapability = "video.generate";
|
||||
|
||||
export type GenerationCapability = ImageCapability | VideoCapability;
|
||||
|
||||
export type GenerationProvider =
|
||||
| "volcengine-visual"
|
||||
| "evolink"
|
||||
| "seedance"
|
||||
| "bailian"
|
||||
| "mock";
|
||||
|
||||
export type BillingCurrency = "CNY";
|
||||
|
||||
export type BillingUnit = "request" | "image" | "video_second";
|
||||
|
||||
export type BillingPriceSource = {
|
||||
url: string;
|
||||
currency: "CNY" | "USD";
|
||||
unitPrice: number;
|
||||
fxRate?: number;
|
||||
basis?: string;
|
||||
observedAt?: string;
|
||||
};
|
||||
|
||||
export type BillingScalar = string | number | boolean;
|
||||
|
||||
export type BillingConditionValue =
|
||||
| BillingScalar
|
||||
| {
|
||||
min?: number;
|
||||
max?: number;
|
||||
values?: BillingScalar[];
|
||||
};
|
||||
|
||||
export type BillingRuleConditions = Record<string, BillingConditionValue>;
|
||||
|
||||
export type BillingQuantitySource = "request" | "image_count" | "duration";
|
||||
|
||||
export type BillingParameterSnapshot = Record<string, BillingScalar>;
|
||||
|
||||
export type BillingParameterTier = {
|
||||
value: BillingScalar;
|
||||
label: string;
|
||||
standardFactor: number;
|
||||
markupMultiplier: number;
|
||||
enabled: boolean;
|
||||
match?: BillingConditionValue;
|
||||
note?: string;
|
||||
};
|
||||
|
||||
export type BillingParameterDimension = {
|
||||
key: string;
|
||||
label: string;
|
||||
baselineValue: BillingScalar;
|
||||
defaultValue?: BillingScalar;
|
||||
tiers: BillingParameterTier[];
|
||||
};
|
||||
|
||||
export type BillingSelectedParameterTier = BillingParameterTier & {
|
||||
dimensionKey: string;
|
||||
dimensionLabel: string;
|
||||
actualValue: BillingScalar;
|
||||
standardUnitPriceFen: number;
|
||||
};
|
||||
|
||||
export type BillingPriceRule = {
|
||||
id: string;
|
||||
provider: GenerationProvider;
|
||||
capability: GenerationCapability;
|
||||
reqKey?: string;
|
||||
variantKey?: string;
|
||||
unit: BillingUnit;
|
||||
standardUnitPriceFen: number;
|
||||
markupMultiplier: number;
|
||||
enabled: boolean;
|
||||
conditions?: BillingRuleConditions;
|
||||
quantitySource?: BillingQuantitySource;
|
||||
priority?: number;
|
||||
note?: string;
|
||||
source?: BillingPriceSource;
|
||||
parameterDimensions?: BillingParameterDimension[];
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
};
|
||||
|
||||
export type BillingQuote = {
|
||||
priceRuleId: string;
|
||||
provider: GenerationProvider;
|
||||
capability: GenerationCapability;
|
||||
reqKey: string;
|
||||
variantKey?: string;
|
||||
unit: BillingUnit;
|
||||
quantity: number;
|
||||
standardUnitPriceFen: number;
|
||||
markupMultiplier: number;
|
||||
amountFen: number;
|
||||
currency: BillingCurrency;
|
||||
conditions?: BillingRuleConditions;
|
||||
quantitySource?: BillingQuantitySource;
|
||||
parameters?: BillingParameterSnapshot;
|
||||
baseStandardUnitPriceFen?: number;
|
||||
parameterTiers?: BillingSelectedParameterTier[];
|
||||
source?: BillingPriceSource;
|
||||
quotaExempt?: boolean;
|
||||
};
|
||||
|
||||
export type BillingJobCharge = BillingQuote & {
|
||||
status: "not_charged" | "pending" | "charged" | "refunded";
|
||||
reservedAmountFen?: number;
|
||||
settlementStatus?: "pending" | "settled" | "estimated";
|
||||
settlementLedgerEntryId?: string;
|
||||
settledAt?: string;
|
||||
settlementReason?: string;
|
||||
providerUsage?: {
|
||||
completionTokens: number;
|
||||
resolution: string;
|
||||
inputVideo: boolean;
|
||||
tokenPriceFenPerMillion: number;
|
||||
};
|
||||
ledgerEntryId?: string;
|
||||
refundLedgerEntryId?: string;
|
||||
chargedAt?: string;
|
||||
refundedAt?: string;
|
||||
refundReason?: string;
|
||||
};
|
||||
|
||||
export type OrganizationWallet = {
|
||||
organizationId: string;
|
||||
balanceFen: number;
|
||||
totalRechargedFen: number;
|
||||
totalChargedFen: number;
|
||||
updatedAt: string;
|
||||
};
|
||||
|
||||
export type BillingLedgerKind = "recharge" | "charge" | "refund" | "adjustment";
|
||||
|
||||
export type BillingLedgerEntry = {
|
||||
id: string;
|
||||
organizationId: string;
|
||||
accountId?: string;
|
||||
jobId?: string;
|
||||
kind: BillingLedgerKind;
|
||||
deltaFen: number;
|
||||
balanceAfterFen: number;
|
||||
currency: BillingCurrency;
|
||||
idempotencyKey: string;
|
||||
description: string;
|
||||
metadata: Record<string, unknown>;
|
||||
createdAt: string;
|
||||
};
|
||||
|
||||
export type BillingAccountConfig = {
|
||||
accountName?: string;
|
||||
bankName?: string;
|
||||
accountNumber?: string;
|
||||
contact?: string;
|
||||
};
|
||||
|
||||
export type UsageSource = "platform" | "api";
|
||||
|
||||
export type PlatformRole = "super_admin" | "organization_admin" | "user";
|
||||
|
||||
export type AccountStatus = "active" | "disabled";
|
||||
|
||||
export type OrganizationStatus = "active" | "disabled";
|
||||
|
||||
export type PlatformOrganization = {
|
||||
id: string;
|
||||
name: string;
|
||||
status: OrganizationStatus;
|
||||
archiveOwnerId: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
};
|
||||
|
||||
export type PlatformUserRecord = {
|
||||
id: string;
|
||||
phone: string;
|
||||
displayName: string;
|
||||
role: PlatformRole;
|
||||
organizationId?: string;
|
||||
status: AccountStatus;
|
||||
passwordHash: string;
|
||||
passwordSalt: string;
|
||||
failedLoginCount: number;
|
||||
lockedUntil?: string;
|
||||
sessionVersion: number;
|
||||
lastLoginAt?: string;
|
||||
legacySubject?: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
};
|
||||
|
||||
export type AccountMigration = {
|
||||
id: string;
|
||||
legacyOwnerId: string;
|
||||
legacyPhone?: string;
|
||||
platformUserId: string;
|
||||
createdAt: string;
|
||||
};
|
||||
|
||||
export type UsageContext = {
|
||||
source: UsageSource;
|
||||
accountId: string;
|
||||
username?: string;
|
||||
displayName: string;
|
||||
role?: PlatformRole;
|
||||
tenantId?: string;
|
||||
organizationId?: string;
|
||||
organizationName?: string;
|
||||
};
|
||||
|
||||
export type AssetKind = "image" | "video" | "mask" | "reference" | "other";
|
||||
|
||||
export type GenerationStatus =
|
||||
@@ -46,7 +252,7 @@ export type GenerationJob = {
|
||||
ownerId: string;
|
||||
externalClientId?: string;
|
||||
capability: GenerationCapability;
|
||||
provider: "volcengine-visual" | "evolink" | "seedance" | "bailian" | "mock";
|
||||
provider: GenerationProvider;
|
||||
reqKey: string;
|
||||
status: GenerationStatus;
|
||||
prompt?: string;
|
||||
@@ -75,6 +281,8 @@ export type GenerationJob = {
|
||||
webhookUrl?: string;
|
||||
webhookAttempts?: number;
|
||||
webhookLastStatus?: WebhookLastStatus;
|
||||
usageContext?: UsageContext;
|
||||
billing?: BillingJobCharge;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
};
|
||||
@@ -83,9 +291,19 @@ export type UsageEvent = {
|
||||
id: string;
|
||||
ownerId: string;
|
||||
jobId: string;
|
||||
source?: UsageSource;
|
||||
capability: GenerationCapability;
|
||||
provider?: GenerationProvider;
|
||||
reqKey?: string;
|
||||
accountUsername?: string;
|
||||
accountDisplayName?: string;
|
||||
tenantId?: string;
|
||||
organizationId?: string;
|
||||
organizationName?: string;
|
||||
quantity: number;
|
||||
estimatedUnit: "image" | "job";
|
||||
estimatedUnit: "image" | "job" | "video_second";
|
||||
chargedAmountFen?: number;
|
||||
currency?: BillingCurrency;
|
||||
createdAt: string;
|
||||
};
|
||||
|
||||
|
||||
Reference in new issue
Block a user