import { Type, type Static } from "@sinclair/typebox"; import { CreditSummarySchema } from "./auth.js"; const uuidPattern = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$"; const isoTimestampPattern = "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\\.[0-9]{3}Z$"; export const CreditEntryTypeSchema = Type.Union([ Type.Literal("registration_grant"), Type.Literal("generation_reserve"), Type.Literal("generation_commit"), Type.Literal("generation_release"), Type.Literal("admin_adjustment"), ], { $id: "CreditEntryType" }); export const CreditEntryStatusSchema = Type.Union([ Type.Literal("succeeded"), Type.Literal("frozen"), Type.Literal("committed"), Type.Literal("released"), ], { $id: "CreditEntryStatus" }); export const CreditReferenceTypeSchema = Type.Union([ Type.Literal("registration"), Type.Literal("generation"), Type.Literal("admin_adjustment"), ], { $id: "CreditReferenceType" }); export const CreditBalanceResponseSchema = Type.Object({ ...CreditSummarySchema.properties, updated_at: Type.String({ pattern: isoTimestampPattern }), }, { additionalProperties: false, $id: "CreditBalanceResponse" }); export const CreditLedgerEntrySchema = Type.Object({ amount: Type.Integer(), available_after: Type.Integer(), available_before: Type.Integer(), created_at: Type.String({ pattern: isoTimestampPattern }), entry_id: Type.String({ pattern: uuidPattern }), entry_type: Type.Ref(CreditEntryTypeSchema), model_id: Type.Union([Type.String({ maxLength: 160, minLength: 1 }), Type.Null()]), reason: Type.Union([Type.String({ maxLength: 500, minLength: 1 }), Type.Null()]), reference_id: Type.Union([Type.String({ pattern: uuidPattern }), Type.Null()]), reference_type: Type.Union([Type.Ref(CreditReferenceTypeSchema), Type.Null()]), reserved_after: Type.Integer({ minimum: 0 }), reserved_before: Type.Integer({ minimum: 0 }), status: Type.Ref(CreditEntryStatusSchema), }, { additionalProperties: false, $id: "CreditLedgerEntry" }); export const CreditLedgerQuerySchema = Type.Object({ cursor: Type.Optional(Type.String({ maxLength: 300, minLength: 1, pattern: "^[A-Za-z0-9_-]+$" })), event_type: Type.Optional(Type.Ref(CreditEntryTypeSchema)), from: Type.Optional(Type.String({ pattern: isoTimestampPattern })), limit: Type.Optional(Type.Integer({ maximum: 100, minimum: 1 })), to: Type.Optional(Type.String({ pattern: isoTimestampPattern })), }, { additionalProperties: false, $id: "CreditLedgerQuery" }); export const CreditLedgerResponseSchema = Type.Object({ credits: Type.Ref(CreditSummarySchema), entries: Type.Array(Type.Ref(CreditLedgerEntrySchema), { maxItems: 100 }), next_cursor: Type.Union([Type.String({ maxLength: 300, minLength: 1 }), Type.Null()]), updated_at: Type.String({ pattern: isoTimestampPattern }), }, { additionalProperties: false, $id: "CreditLedgerResponse" }); export const AdminCreditParamsSchema = Type.Object({ userId: Type.String({ pattern: uuidPattern }), }, { additionalProperties: false, $id: "AdminCreditParams" }); export const CreditAdjustmentHeadersSchema = Type.Object({ "idempotency-key": Type.String({ maxLength: 200, minLength: 32, pattern: "^[A-Za-z0-9_-]+$" }), "x-csrf-token": Type.String({ maxLength: 64, minLength: 43, pattern: "^[A-Za-z0-9_-]+$" }), }, { additionalProperties: true, $id: "CreditAdjustmentHeaders" }); export const CreditAdjustmentRequestSchema = Type.Object({ adjustment_id: Type.String({ pattern: uuidPattern }), amount: Type.Union([Type.Integer({ maximum: -1 }), Type.Integer({ minimum: 1 })]), reason: Type.String({ maxLength: 500, minLength: 1 }), }, { additionalProperties: false, $id: "CreditAdjustmentRequest" }); export const CreditAdjustmentResponseSchema = Type.Object({ adjustment_id: Type.String({ pattern: uuidPattern }), available_balance: Type.Integer(), reserved_balance: Type.Integer({ minimum: 0 }), status: Type.Literal("adjusted"), }, { additionalProperties: false, $id: "CreditAdjustmentResponse" }); export type CreditLedgerQuery = Static; export type AdminCreditParams = Static; export type CreditAdjustmentHeaders = Static; export type CreditAdjustmentRequest = Static;