@nehorai/credits-drizzle 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/schema/index.ts","../src/repository/index.ts"],"sourcesContent":["export * from './schema/index.js'\nexport * from './repository/index.js'\n","import { sql } from 'drizzle-orm'\nimport {\n boolean,\n index,\n integer,\n jsonb,\n numeric,\n pgTable,\n text,\n timestamp,\n uniqueIndex,\n uuid,\n} from 'drizzle-orm/pg-core'\n\nexport const creditBalances = pgTable('credit_balances', {\n userId: uuid('user_id').primaryKey(),\n balance: numeric('balance', { precision: 12, scale: 2 }).notNull().default('0'),\n bonusCredits: numeric('bonus_credits', { precision: 12, scale: 2 }).notNull().default('0'),\n reserved: numeric('reserved', { precision: 12, scale: 2 }).notNull().default('0'),\n tier: text('tier').notNull().default('free'),\n monthlyLimit: numeric('monthly_limit', { precision: 12, scale: 2 }).notNull().default('0'),\n monthlyUsed: numeric('monthly_used', { precision: 12, scale: 2 }).notNull().default('0'),\n monthlyResetAt: timestamp('monthly_reset_at', { withTimezone: true }).notNull(),\n subscriptionExpiresAt: timestamp('subscription_expires_at', { withTimezone: true }),\n createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),\n updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),\n})\n\nexport const creditReservations = pgTable(\n 'credit_reservations',\n {\n id: uuid('id').primaryKey().defaultRandom(),\n userId: uuid('user_id').notNull(),\n amount: numeric('amount', { precision: 12, scale: 2 }).notNull(),\n operationType: text('operation_type').notNull(),\n status: text('status').notNull().default('reserved'),\n expiresAt: timestamp('expires_at', { withTimezone: true }).notNull(),\n completedAt: timestamp('completed_at', { withTimezone: true }),\n createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),\n },\n (table) => ({\n userIdx: index('credit_reservations_user_idx').on(table.userId),\n statusExpiresIdx: index('credit_reservations_status_expires_idx').on(table.status, table.expiresAt),\n })\n)\n\nexport const creditPluginTransactions = pgTable(\n 'credit_plugin_transactions',\n {\n id: uuid('id').primaryKey().defaultRandom(),\n userId: uuid('user_id').notNull(),\n type: text('type').notNull(),\n amount: numeric('amount', { precision: 12, scale: 2 }).notNull(),\n description: text('description').notNull(),\n paymentRef: text('payment_ref'),\n previousBalance: numeric('previous_balance', { precision: 12, scale: 2 }).notNull(),\n newBalance: numeric('new_balance', { precision: 12, scale: 2 }).notNull(),\n createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),\n },\n (table) => ({\n userCreatedIdx: index('credit_plugin_transactions_user_created_idx').on(table.userId, table.createdAt),\n paymentRefUnique: uniqueIndex('credit_plugin_transactions_payment_ref_unique')\n .on(table.paymentRef)\n .where(sql`${table.paymentRef} is not null`),\n })\n)\n\nexport const creditUsageLogs = pgTable(\n 'credit_usage_logs',\n {\n id: uuid('id').primaryKey().defaultRandom(),\n userId: uuid('user_id').notNull(),\n operationType: text('operation_type').notNull(),\n provider: text('provider').notNull(),\n creditsUsed: numeric('credits_used', { precision: 12, scale: 2 }).notNull(),\n success: boolean('success').notNull(),\n errorMessage: text('error_message'),\n resourceId: text('resource_id'),\n resourceType: text('resource_type'),\n requestId: text('request_id'),\n metadata: jsonb('metadata').$type<Record<string, unknown>>(),\n createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),\n },\n (table) => ({\n userCreatedIdx: index('credit_usage_logs_user_created_idx').on(table.userId, table.createdAt),\n operationIdx: index('credit_usage_logs_operation_idx').on(table.operationType),\n successIdx: index('credit_usage_logs_success_idx').on(table.success),\n })\n)\n\nexport const creditJournalEntries = pgTable(\n 'credit_journal_entries',\n {\n id: uuid('id').primaryKey().defaultRandom(),\n userId: uuid('user_id').notNull(),\n entryType: text('entry_type').notNull(),\n amount: numeric('amount', { precision: 12, scale: 2 }).notNull(),\n balanceAfter: numeric('balance_after', { precision: 12, scale: 2 }).notNull(),\n source: text('source').notNull(),\n referenceId: text('reference_id').notNull(),\n referenceType: text('reference_type').notNull(),\n description: text('description').notNull(),\n metadata: jsonb('metadata').$type<Record<string, unknown>>(),\n createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),\n },\n (table) => ({\n userCreatedIdx: index('credit_journal_entries_user_created_idx').on(table.userId, table.createdAt),\n sourceIdx: index('credit_journal_entries_source_idx').on(table.source),\n referenceIdx: index('credit_journal_entries_reference_idx').on(table.referenceId, table.referenceType),\n })\n)\n\nexport type CreditBalanceRow = typeof creditBalances.$inferSelect\nexport type CreditReservationRow = typeof creditReservations.$inferSelect\nexport type CreditPluginTransactionRow = typeof creditPluginTransactions.$inferSelect\nexport type CreditUsageLogRow = typeof creditUsageLogs.$inferSelect\nexport type CreditJournalEntryRow = typeof creditJournalEntries.$inferSelect\n","import { and, count, desc, eq, gte, lte, lt, sql } from 'drizzle-orm'\nimport type {\n AIProviderType,\n CreateJournalEntryInput,\n CreateReservationInput,\n CreateTransactionInput,\n CreateUsageLogInput,\n CreditBalanceUpdate,\n CreditOperationType,\n ICreditRepository,\n JournalEntryQuery,\n JournalReferenceType,\n MonthlyResetResult,\n PortableJournalEntry,\n PortableReservation,\n PortableTransaction,\n PortableUsageLog,\n PortableUserCredits,\n ReservationStatus,\n SubscriptionExpiryResult,\n SubscriptionTier,\n TierUpdateInput,\n UsageLogQuery,\n} from '@nehorai/credits'\nimport {\n getConfigMonthlyLimit,\n getConfigTierConfig,\n} from '@nehorai/credits'\nimport { getNextMonthlyReset } from '@nehorai/credits'\nimport {\n creditBalances,\n creditJournalEntries,\n creditPluginTransactions,\n creditReservations,\n creditUsageLogs,\n type CreditBalanceRow,\n type CreditJournalEntryRow,\n type CreditPluginTransactionRow,\n type CreditReservationRow,\n type CreditUsageLogRow,\n} from '../schema/index.js'\n\nexport interface DrizzleLikeDB {\n select: (...args: any[]) => any\n insert: (...args: any[]) => any\n update: (...args: any[]) => any\n transaction?: <T>(callback: (tx: DrizzleLikeDB) => Promise<T>) => Promise<T>\n}\n\nfunction numberValue(value: unknown): number {\n if (value === null || value === undefined) return 0\n if (typeof value === 'number') return value\n const parsed = Number(value)\n return Number.isFinite(parsed) ? parsed : 0\n}\n\nfunction dateValue(value: Date | string | null | undefined): Date | null {\n if (!value) return null\n return value instanceof Date ? value : new Date(value)\n}\n\nfunction iso(value: Date | string | null | undefined): string {\n if (!value) return new Date().toISOString()\n return value instanceof Date ? value.toISOString() : new Date(value).toISOString()\n}\n\nfunction toUserCredits(row: CreditBalanceRow): PortableUserCredits {\n return {\n userId: row.userId,\n balance: numberValue(row.balance),\n bonusCredits: numberValue(row.bonusCredits),\n reserved: numberValue(row.reserved),\n tier: row.tier as SubscriptionTier,\n monthlyLimit: numberValue(row.monthlyLimit),\n monthlyUsed: numberValue(row.monthlyUsed),\n monthlyResetAt: iso(row.monthlyResetAt),\n subscriptionExpiresAt: row.subscriptionExpiresAt ? iso(row.subscriptionExpiresAt) : null,\n createdAt: iso(row.createdAt),\n updatedAt: iso(row.updatedAt),\n }\n}\n\nfunction toReservation(row: CreditReservationRow): PortableReservation {\n return {\n id: row.id,\n userId: row.userId,\n amount: numberValue(row.amount),\n operationType: row.operationType as CreditOperationType,\n status: row.status as ReservationStatus,\n createdAt: iso(row.createdAt),\n expiresAt: iso(row.expiresAt),\n completedAt: row.completedAt ? iso(row.completedAt) : undefined,\n }\n}\n\nfunction toTransaction(row: CreditPluginTransactionRow): PortableTransaction {\n return {\n id: row.id,\n userId: row.userId,\n type: row.type as PortableTransaction['type'],\n amount: numberValue(row.amount),\n description: row.description,\n paymentRef: row.paymentRef ?? undefined,\n previousBalance: numberValue(row.previousBalance),\n newBalance: numberValue(row.newBalance),\n createdAt: iso(row.createdAt),\n }\n}\n\nfunction toUsageLog(row: CreditUsageLogRow): PortableUsageLog {\n return {\n id: row.id,\n userId: row.userId,\n operationType: row.operationType as CreditOperationType,\n provider: row.provider as AIProviderType,\n creditsUsed: numberValue(row.creditsUsed),\n success: row.success,\n errorMessage: row.errorMessage ?? undefined,\n resourceId: row.resourceId ?? undefined,\n resourceType: row.resourceType ?? undefined,\n requestId: row.requestId ?? undefined,\n metadata: row.metadata ?? undefined,\n createdAt: iso(row.createdAt),\n }\n}\n\nfunction toJournalEntry(row: CreditJournalEntryRow): PortableJournalEntry {\n return {\n id: row.id,\n userId: row.userId,\n entryType: row.entryType as 'debit' | 'credit',\n amount: numberValue(row.amount),\n balanceAfter: numberValue(row.balanceAfter),\n source: row.source as PortableJournalEntry['source'],\n referenceId: row.referenceId,\n referenceType: row.referenceType as JournalReferenceType,\n description: row.description,\n metadata: row.metadata ?? undefined,\n createdAt: iso(row.createdAt),\n }\n}\n\nexport class DrizzleCreditRepository implements ICreditRepository {\n constructor(private readonly db: DrizzleLikeDB) {}\n\n private async withTx<T>(callback: (tx: DrizzleLikeDB) => Promise<T>): Promise<T> {\n if (this.db.transaction) {\n return this.db.transaction(callback)\n }\n return callback(this.db)\n }\n\n private async ensureUserCredits(\n db: DrizzleLikeDB,\n userId: string,\n tier: SubscriptionTier = 'free'\n ): Promise<PortableUserCredits> {\n const existing = await db.select().from(creditBalances).where(eq(creditBalances.userId, userId)).limit(1)\n if (existing[0]) return toUserCredits(existing[0])\n\n const monthlyLimit = getConfigMonthlyLimit(tier)\n const initialBalance = Number.isFinite(monthlyLimit) ? monthlyLimit : 0\n const inserted = await db\n .insert(creditBalances)\n .values({\n userId,\n tier,\n balance: String(initialBalance),\n monthlyLimit: String(initialBalance),\n monthlyResetAt: getNextMonthlyReset(),\n })\n .onConflictDoNothing()\n .returning()\n\n if (inserted[0]) return toUserCredits(inserted[0])\n\n const afterConflict = await db.select().from(creditBalances).where(eq(creditBalances.userId, userId)).limit(1)\n if (!afterConflict[0]) {\n throw new Error(`Failed to initialize credits for user ${userId}`)\n }\n return toUserCredits(afterConflict[0])\n }\n\n async getUserCredits(userId: string): Promise<PortableUserCredits | null> {\n const rows = await this.db.select().from(creditBalances).where(eq(creditBalances.userId, userId)).limit(1)\n return rows[0] ? toUserCredits(rows[0]) : null\n }\n\n async initializeUserCredits(\n userId: string,\n tier: SubscriptionTier,\n initialBalance: number\n ): Promise<PortableUserCredits> {\n const monthlyLimit = getConfigMonthlyLimit(tier)\n const rows = await this.db\n .insert(creditBalances)\n .values({\n userId,\n tier,\n balance: String(initialBalance),\n monthlyLimit: String(Number.isFinite(monthlyLimit) ? monthlyLimit : 0),\n monthlyResetAt: getNextMonthlyReset(),\n })\n .onConflictDoUpdate({\n target: creditBalances.userId,\n set: { updatedAt: new Date() },\n })\n .returning()\n\n return toUserCredits(rows[0])\n }\n\n async updateUserCredits(userId: string, updates: CreditBalanceUpdate): Promise<void> {\n const set: Record<string, unknown> = { updatedAt: new Date() }\n if (updates.balance !== undefined) set.balance = String(updates.balance)\n if (updates.bonusCredits !== undefined) set.bonusCredits = String(updates.bonusCredits)\n if (updates.reserved !== undefined) set.reserved = String(updates.reserved)\n if (updates.tier !== undefined) set.tier = updates.tier\n if (updates.monthlyLimit !== undefined) set.monthlyLimit = String(updates.monthlyLimit)\n if (updates.monthlyUsed !== undefined) set.monthlyUsed = String(updates.monthlyUsed)\n if (updates.monthlyResetAt !== undefined) set.monthlyResetAt = dateValue(updates.monthlyResetAt)\n if (updates.subscriptionExpiresAt !== undefined) set.subscriptionExpiresAt = dateValue(updates.subscriptionExpiresAt)\n\n await this.db\n .update(creditBalances)\n .set({\n ...set,\n balance:\n updates.balanceIncrement !== undefined\n ? sql`${creditBalances.balance} + ${updates.balanceIncrement}`\n : set.balance,\n bonusCredits:\n updates.bonusCreditsIncrement !== undefined\n ? sql`${creditBalances.bonusCredits} + ${updates.bonusCreditsIncrement}`\n : set.bonusCredits,\n reserved:\n updates.reservedIncrement !== undefined\n ? sql`${creditBalances.reserved} + ${updates.reservedIncrement}`\n : set.reserved,\n monthlyUsed:\n updates.monthlyUsedIncrement !== undefined\n ? sql`${creditBalances.monthlyUsed} + ${updates.monthlyUsedIncrement}`\n : set.monthlyUsed,\n } as any)\n .where(eq(creditBalances.userId, userId))\n }\n\n async updateUserTier(userId: string, input: TierUpdateInput): Promise<void> {\n await this.db\n .update(creditBalances)\n .set({\n tier: input.tier,\n monthlyLimit: String(input.monthlyLimit),\n balance: input.balance !== undefined ? String(input.balance) : undefined,\n monthlyUsed: input.monthlyUsed !== undefined ? String(input.monthlyUsed) : undefined,\n subscriptionExpiresAt:\n input.subscriptionExpiresAt !== undefined ? dateValue(input.subscriptionExpiresAt) : undefined,\n updatedAt: new Date(),\n } as any)\n .where(eq(creditBalances.userId, userId))\n }\n\n async createReservation(input: CreateReservationInput): Promise<PortableReservation> {\n const rows = await this.db\n .insert(creditReservations)\n .values({\n userId: input.userId,\n amount: String(input.amount),\n operationType: input.operationType,\n expiresAt: input.expiresAt,\n })\n .returning()\n return toReservation(rows[0])\n }\n\n async getReservation(userId: string, reservationId: string): Promise<PortableReservation | null> {\n const rows = await this.db\n .select()\n .from(creditReservations)\n .where(and(eq(creditReservations.userId, userId), eq(creditReservations.id, reservationId)))\n .limit(1)\n return rows[0] ? toReservation(rows[0]) : null\n }\n\n async updateReservationStatus(\n userId: string,\n reservationId: string,\n status: ReservationStatus,\n completedAt?: Date\n ): Promise<void> {\n await this.db\n .update(creditReservations)\n .set({ status, completedAt: completedAt ?? new Date() })\n .where(and(eq(creditReservations.userId, userId), eq(creditReservations.id, reservationId)))\n }\n\n async reserveCreditsAtomic(\n userId: string,\n amount: number,\n operationType: CreditOperationType,\n expiresAt: Date\n ): Promise<PortableReservation> {\n return this.withTx(async (tx) => {\n await this.ensureUserCredits(tx, userId)\n const updated = await tx\n .update(creditBalances)\n .set({\n reserved: sql`${creditBalances.reserved} + ${amount}`,\n updatedAt: new Date(),\n })\n .where(\n and(\n eq(creditBalances.userId, userId),\n sql`${creditBalances.balance} + ${creditBalances.bonusCredits} - ${creditBalances.reserved} >= ${amount}`\n )\n )\n .returning()\n\n if (!updated[0]) {\n throw new Error(`Insufficient credits for user ${userId}`)\n }\n\n const reservation = await tx\n .insert(creditReservations)\n .values({\n userId,\n amount: String(amount),\n operationType,\n expiresAt,\n })\n .returning()\n return toReservation(reservation[0])\n })\n }\n\n async commitReservationAtomic(userId: string, reservationId: string): Promise<void> {\n await this.withTx(async (tx) => {\n const reservationRows = await tx\n .select()\n .from(creditReservations)\n .where(and(eq(creditReservations.userId, userId), eq(creditReservations.id, reservationId)))\n .limit(1)\n const reservation = reservationRows[0]\n if (!reservation) throw new Error(`Reservation ${reservationId} not found`)\n if (reservation.status === 'committed') return\n if (reservation.status !== 'reserved') {\n throw new Error(`Cannot commit reservation in ${reservation.status} state`)\n }\n\n const creditRows = await tx.select().from(creditBalances).where(eq(creditBalances.userId, userId)).limit(1)\n const credits = creditRows[0]\n if (!credits) throw new Error(`User credits not found for user ${userId}`)\n\n const amount = numberValue(reservation.amount)\n const balance = numberValue(credits.balance)\n const bonusCredits = numberValue(credits.bonusCredits)\n if (balance + bonusCredits < amount) {\n throw new Error(`Insufficient credits to commit reservation ${reservationId}`)\n }\n\n const balanceDeduction = Math.min(balance, amount)\n const bonusDeduction = amount - balanceDeduction\n const previousTotal = balance + bonusCredits\n const newTotal = previousTotal - amount\n\n await tx\n .update(creditBalances)\n .set({\n balance: String(balance - balanceDeduction),\n bonusCredits: String(bonusCredits - bonusDeduction),\n reserved: sql`greatest(${creditBalances.reserved} - ${amount}, 0)`,\n monthlyUsed: sql`${creditBalances.monthlyUsed} + ${amount}`,\n updatedAt: new Date(),\n })\n .where(eq(creditBalances.userId, userId))\n\n await tx\n .update(creditReservations)\n .set({ status: 'committed', completedAt: new Date() })\n .where(and(eq(creditReservations.userId, userId), eq(creditReservations.id, reservationId)))\n\n await tx.insert(creditJournalEntries).values({\n userId,\n entryType: 'debit',\n amount: String(amount),\n balanceAfter: String(newTotal),\n source: 'operation_commit',\n referenceId: reservationId,\n referenceType: 'reservation',\n description: `Committed ${amount} credits`,\n })\n })\n }\n\n async releaseReservationAtomic(userId: string, reservationId: string): Promise<void> {\n await this.withTx(async (tx) => {\n const reservationRows = await tx\n .select()\n .from(creditReservations)\n .where(and(eq(creditReservations.userId, userId), eq(creditReservations.id, reservationId)))\n .limit(1)\n const reservation = reservationRows[0]\n if (!reservation) throw new Error(`Reservation ${reservationId} not found`)\n if (reservation.status !== 'reserved') return\n\n const amount = numberValue(reservation.amount)\n await tx\n .update(creditBalances)\n .set({\n reserved: sql`greatest(${creditBalances.reserved} - ${amount}, 0)`,\n updatedAt: new Date(),\n })\n .where(eq(creditBalances.userId, userId))\n await tx\n .update(creditReservations)\n .set({ status: 'released', completedAt: new Date() })\n .where(and(eq(creditReservations.userId, userId), eq(creditReservations.id, reservationId)))\n })\n }\n\n async addCreditsAtomic(\n userId: string,\n amount: number,\n description: string,\n paymentRef?: string\n ): Promise<void> {\n await this.withTx(async (tx) => {\n if (paymentRef) {\n const existing = await tx\n .select()\n .from(creditPluginTransactions)\n .where(eq(creditPluginTransactions.paymentRef, paymentRef))\n .limit(1)\n if (existing[0]) return\n }\n\n const credits = await this.ensureUserCredits(tx, userId)\n const previousBalance = credits.balance + credits.bonusCredits\n const newBalance = previousBalance + amount\n\n await tx\n .update(creditBalances)\n .set({\n bonusCredits: sql`${creditBalances.bonusCredits} + ${amount}`,\n updatedAt: new Date(),\n })\n .where(eq(creditBalances.userId, userId))\n\n const inserted = await tx\n .insert(creditPluginTransactions)\n .values({\n userId,\n type: 'purchase',\n amount: String(amount),\n description,\n paymentRef,\n previousBalance: String(previousBalance),\n newBalance: String(newBalance),\n })\n .returning()\n\n await tx.insert(creditJournalEntries).values({\n userId,\n entryType: 'credit',\n amount: String(amount),\n balanceAfter: String(newBalance),\n source: 'purchase',\n referenceId: inserted[0]?.id ?? paymentRef ?? 'unknown',\n referenceType: 'transaction',\n description,\n metadata: paymentRef ? { paymentRef } : undefined,\n })\n })\n }\n\n async deductCreditsAtomic(userId: string, amount: number): Promise<{ previousBalance: number; newBalance: number }> {\n return this.withTx(async (tx) => {\n const creditRows = await tx.select().from(creditBalances).where(eq(creditBalances.userId, userId)).limit(1)\n const credits = creditRows[0]\n if (!credits) throw new Error(`User credits not found for user ${userId}`)\n\n const balance = numberValue(credits.balance)\n const bonusCredits = numberValue(credits.bonusCredits)\n const reserved = numberValue(credits.reserved)\n const available = balance + bonusCredits - reserved\n if (available < amount) {\n throw new Error(`Insufficient credits. Available: ${available}, requested: ${amount}`)\n }\n\n const balanceDeduction = Math.min(balance, amount)\n const bonusDeduction = amount - balanceDeduction\n const previousBalance = balance + bonusCredits\n const newBalance = previousBalance - amount\n\n await tx\n .update(creditBalances)\n .set({\n balance: String(balance - balanceDeduction),\n bonusCredits: String(bonusCredits - bonusDeduction),\n updatedAt: new Date(),\n })\n .where(eq(creditBalances.userId, userId))\n\n return { previousBalance, newBalance }\n })\n }\n\n async createTransaction(input: CreateTransactionInput): Promise<PortableTransaction> {\n const rows = await this.db\n .insert(creditPluginTransactions)\n .values({\n userId: input.userId,\n type: input.type,\n amount: String(input.amount),\n description: input.description,\n paymentRef: input.paymentRef,\n previousBalance: String(input.previousBalance),\n newBalance: String(input.newBalance),\n })\n .returning()\n return toTransaction(rows[0])\n }\n\n async getTransactions(userId: string, limit = 50, offset = 0): Promise<PortableTransaction[]> {\n const rows = await this.db\n .select()\n .from(creditPluginTransactions)\n .where(eq(creditPluginTransactions.userId, userId))\n .orderBy(desc(creditPluginTransactions.createdAt))\n .limit(limit)\n .offset(offset)\n return rows.map(toTransaction)\n }\n\n async logUsage(input: CreateUsageLogInput): Promise<PortableUsageLog> {\n const rows = await this.db\n .insert(creditUsageLogs)\n .values({\n userId: input.userId,\n operationType: input.operationType,\n provider: input.provider,\n creditsUsed: String(input.creditsUsed),\n success: input.success,\n errorMessage: input.errorMessage,\n resourceId: input.resourceId,\n resourceType: input.resourceType,\n requestId: input.requestId,\n metadata: input.metadata,\n })\n .returning()\n return toUsageLog(rows[0])\n }\n\n async getUsageLogs(query: UsageLogQuery): Promise<PortableUsageLog[]> {\n const filters = this.usageFilters(query)\n const rows = await this.db\n .select()\n .from(creditUsageLogs)\n .where(filters.length ? and(...filters) : undefined)\n .orderBy(desc(creditUsageLogs.createdAt))\n .limit(query.limit ?? 50)\n .offset(query.offset ?? 0)\n return rows.map(toUsageLog)\n }\n\n async getUsageLogsCount(query: Omit<UsageLogQuery, 'limit' | 'offset'>): Promise<number> {\n const filters = this.usageFilters(query)\n const rows = await this.db\n .select({ value: count() })\n .from(creditUsageLogs)\n .where(filters.length ? and(...filters) : undefined)\n return Number(rows[0]?.value ?? 0)\n }\n\n async findAndExpireReservations(batchSize = 100, maxIterations = 100): Promise<{\n expiredCount: number\n creditsReleased: number\n errors: string[]\n }> {\n const errors: string[] = []\n let expiredCount = 0\n let creditsReleased = 0\n\n for (let i = 0; i < maxIterations; i += 1) {\n const rows = await this.db\n .select()\n .from(creditReservations)\n .where(and(eq(creditReservations.status, 'reserved'), lt(creditReservations.expiresAt, new Date())))\n .limit(batchSize)\n if (rows.length === 0) break\n\n for (const row of rows) {\n try {\n await this.releaseReservationAtomic(row.userId, row.id)\n await this.db\n .update(creditReservations)\n .set({ status: 'expired', completedAt: new Date() })\n .where(eq(creditReservations.id, row.id))\n expiredCount += 1\n creditsReleased += numberValue(row.amount)\n } catch (error) {\n errors.push(`Failed to expire reservation ${row.id}: ${String(error)}`)\n }\n }\n }\n\n return { expiredCount, creditsReleased, errors }\n }\n\n async atomicMonthlyReset(\n userId: string,\n tier: SubscriptionTier,\n expectedResetAt: Date | string\n ): Promise<MonthlyResetResult> {\n const newBalance = getConfigMonthlyLimit(tier)\n const nextReset = getNextMonthlyReset()\n const expected = dateValue(expectedResetAt)\n const rows = await this.db\n .update(creditBalances)\n .set({\n balance: Number.isFinite(newBalance) ? String(newBalance) : sql`${creditBalances.balance}`,\n monthlyUsed: '0',\n monthlyResetAt: nextReset,\n updatedAt: new Date(),\n } as any)\n .where(and(eq(creditBalances.userId, userId), eq(creditBalances.monthlyResetAt, expected as Date)))\n .returning()\n\n if (rows[0]) return { wasReset: true, credits: toUserCredits(rows[0]) }\n const current = await this.getUserCredits(userId)\n if (!current) throw new Error(`User ${userId} not found`)\n return { wasReset: false, credits: current }\n }\n\n async checkAndHandleSubscriptionExpiry(userId: string, gracePeriodDays = 3): Promise<SubscriptionExpiryResult> {\n const credits = await this.getUserCredits(userId)\n if (!credits) throw new Error(`User ${userId} not found`)\n\n const tierConfig = getConfigTierConfig(credits.tier) as { isFree?: boolean }\n if ((tierConfig.isFree ?? credits.tier === 'free') || !credits.subscriptionExpiresAt) {\n return { wasDowngraded: false, inGracePeriod: false, graceDaysRemaining: 0, credits }\n }\n\n const expiresAt = new Date(credits.subscriptionExpiresAt)\n const daysSinceExpiry = (Date.now() - expiresAt.getTime()) / (1000 * 60 * 60 * 24)\n if (daysSinceExpiry <= 0) {\n return { wasDowngraded: false, inGracePeriod: false, graceDaysRemaining: 0, credits }\n }\n if (daysSinceExpiry <= gracePeriodDays) {\n return {\n wasDowngraded: false,\n inGracePeriod: true,\n graceDaysRemaining: Math.ceil(gracePeriodDays - daysSinceExpiry),\n credits,\n }\n }\n\n const defaultTier = 'free' as SubscriptionTier\n const defaultTierConfig = getConfigTierConfig(defaultTier)\n await this.updateUserTier(userId, {\n tier: defaultTier,\n monthlyLimit: defaultTierConfig.monthlyCredits,\n balance: Math.min(credits.balance, defaultTierConfig.monthlyCredits),\n subscriptionExpiresAt: null,\n })\n const updatedCredits = (await this.getUserCredits(userId)) ?? credits\n return { wasDowngraded: true, inGracePeriod: false, graceDaysRemaining: 0, credits: updatedCredits }\n }\n\n async createJournalEntry(input: CreateJournalEntryInput): Promise<PortableJournalEntry> {\n const rows = await this.db\n .insert(creditJournalEntries)\n .values({\n userId: input.userId,\n entryType: input.entryType,\n amount: String(input.amount),\n balanceAfter: String(input.balanceAfter),\n source: input.source,\n referenceId: input.referenceId,\n referenceType: input.referenceType,\n description: input.description,\n metadata: input.metadata,\n })\n .returning()\n return toJournalEntry(rows[0])\n }\n\n async getJournalEntries(query: JournalEntryQuery): Promise<PortableJournalEntry[]> {\n const filters = this.journalFilters(query)\n const rows = await this.db\n .select()\n .from(creditJournalEntries)\n .where(filters.length ? and(...filters) : undefined)\n .orderBy(desc(creditJournalEntries.createdAt))\n .limit(query.limit ?? 50)\n .offset(query.offset ?? 0)\n return rows.map(toJournalEntry)\n }\n\n async getJournalEntriesCount(query: Omit<JournalEntryQuery, 'limit' | 'offset'>): Promise<number> {\n const filters = this.journalFilters(query)\n const rows = await this.db\n .select({ value: count() })\n .from(creditJournalEntries)\n .where(filters.length ? and(...filters) : undefined)\n return Number(rows[0]?.value ?? 0)\n }\n\n private usageFilters(query: Omit<UsageLogQuery, 'limit' | 'offset'>): any[] {\n const filters: any[] = []\n if (query.userId) filters.push(eq(creditUsageLogs.userId, query.userId))\n if (query.operationType) filters.push(eq(creditUsageLogs.operationType, query.operationType))\n if (query.success !== undefined) filters.push(eq(creditUsageLogs.success, query.success))\n if (query.startDate) filters.push(gte(creditUsageLogs.createdAt, query.startDate))\n if (query.endDate) filters.push(lte(creditUsageLogs.createdAt, query.endDate))\n return filters\n }\n\n private journalFilters(query: Omit<JournalEntryQuery, 'limit' | 'offset'>): any[] {\n const filters: any[] = [eq(creditJournalEntries.userId, query.userId)]\n if (query.source) filters.push(eq(creditJournalEntries.source, query.source))\n if (query.referenceType) filters.push(eq(creditJournalEntries.referenceType, query.referenceType))\n if (query.startDate) filters.push(gte(creditJournalEntries.createdAt, query.startDate))\n if (query.endDate) filters.push(lte(creditJournalEntries.createdAt, query.endDate))\n return filters\n }\n}\n\nexport function createDrizzleCreditRepository(db: DrizzleLikeDB): DrizzleCreditRepository {\n return new DrizzleCreditRepository(db)\n}\n"],"mappings":"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","names":["import_drizzle_orm","import_credits"]}
@@ -0,0 +1,4 @@
1
+ export { CreditBalanceRow, CreditJournalEntryRow, CreditPluginTransactionRow, CreditReservationRow, CreditUsageLogRow, creditBalances, creditJournalEntries, creditPluginTransactions, creditReservations, creditUsageLogs } from './schema/index.cjs';
2
+ export { DrizzleCreditRepository, DrizzleLikeDB, createDrizzleCreditRepository } from './repository/index.cjs';
3
+ import 'drizzle-orm/pg-core';
4
+ import '@nehorai/credits';
@@ -0,0 +1,4 @@
1
+ export { CreditBalanceRow, CreditJournalEntryRow, CreditPluginTransactionRow, CreditReservationRow, CreditUsageLogRow, creditBalances, creditJournalEntries, creditPluginTransactions, creditReservations, creditUsageLogs } from './schema/index.js';
2
+ export { DrizzleCreditRepository, DrizzleLikeDB, createDrizzleCreditRepository } from './repository/index.js';
3
+ import 'drizzle-orm/pg-core';
4
+ import '@nehorai/credits';
package/dist/index.js ADDED
@@ -0,0 +1,21 @@
1
+ import {
2
+ DrizzleCreditRepository,
3
+ createDrizzleCreditRepository
4
+ } from "./chunk-ZIOAIRV6.js";
5
+ import {
6
+ creditBalances,
7
+ creditJournalEntries,
8
+ creditPluginTransactions,
9
+ creditReservations,
10
+ creditUsageLogs
11
+ } from "./chunk-7R6F67RH.js";
12
+ export {
13
+ DrizzleCreditRepository,
14
+ createDrizzleCreditRepository,
15
+ creditBalances,
16
+ creditJournalEntries,
17
+ creditPluginTransactions,
18
+ creditReservations,
19
+ creditUsageLogs
20
+ };
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}