export type ImageCapability = | "image.generate"; export type EnabledImageCapability = ImageCapability; 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; export type BillingQuantitySource = "request" | "image_count" | "duration"; export type BillingParameterSnapshot = Record; 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; 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 = | "queued" | "running" | "succeeded" | "failed" | "expired" | "cancelled"; export type WebhookLastStatus = { ok: boolean; status?: number; error?: string; attemptedAt: string; nextAttemptAt?: string; }; export type Asset = { id: string; ownerId: string; kind: AssetKind; name: string; url: string; storagePath?: string; source: "upload" | "generated" | "edited" | "upscaled" | "external" | "seed"; tags: string[]; metadata: Record; createdAt: string; updatedAt: string; }; export type GenerationJob = { id: string; ownerId: string; externalClientId?: string; capability: GenerationCapability; provider: GenerationProvider; reqKey: string; status: GenerationStatus; prompt?: string; inputAssetIds: string[]; inputUrls: string[]; outputAssetIds: string[]; providerTaskId?: string; requestPayload: Record; responsePayload?: Record; error?: { code?: string | number; message: string; retryable?: boolean; }; retryOf?: string; idempotencyKey?: string; idempotencyFingerprint?: string; priority?: number; attempts?: number; maxAttempts?: number; scheduledAt?: string; lockedAt?: string; lockedBy?: string; startedAt?: string; completedAt?: string; webhookUrl?: string; webhookAttempts?: number; webhookLastStatus?: WebhookLastStatus; usageContext?: UsageContext; billing?: BillingJobCharge; createdAt: string; updatedAt: string; }; 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" | "video_second"; chargedAmountFen?: number; currency?: BillingCurrency; createdAt: string; }; export type Project = { id: string; ownerId: string; name: string; brief: string; type: "brand" | "store" | "commerce" | "event" | "course" | "ip" | "custom"; assetIds: string[]; createdAt: string; updatedAt: string; }; export type ImageTemplateSettings = { engine?: "jimeng" | "evolink" | "bailian"; width?: number; height?: number; forceSingle?: boolean; scale?: number; quality?: "low" | "medium" | "high"; }; export type ImageTemplate = { id: string; ownerId: string; name: string; description?: string; prompt: string; previewImageUrl?: string; settings: ImageTemplateSettings; sortOrder: number; createdAt: string; updatedAt: string; }; export type AppState = { users: Array<{ id: string; email: string; displayName: string; }>; assets: Asset[]; generationJobs: GenerationJob[]; usageEvents: UsageEvent[]; projects: Project[]; imageTemplates: ImageTemplate[]; }; export type VisualTaskSubmitResponse = { code: number; message: string; request_id?: string; data?: { task_id?: string; } | null; status?: number; time_elapsed?: string; }; export type VisualTaskQueryResponse = { code: number; message: string; request_id?: string; task_id?: string; data?: { binary_data_base64?: string[] | null; image_urls?: string[] | null; status?: "in_queue" | "generating" | "done" | "not_found" | "expired"; resp_data?: string; } | null; status?: number; time_elapsed?: string; };