@nehorai/payments-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.
- package/LICENSE +21 -0
- package/dist/index.cjs +1310 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +47 -0
- package/dist/index.d.ts +47 -0
- package/dist/index.js +1289 -0
- package/dist/index.js.map +1 -0
- package/dist/provider-health.drizzle-repository-DfRo4qJ8.d.cts +185 -0
- package/dist/provider-health.drizzle-repository-DfRo4qJ8.d.ts +185 -0
- package/dist/repositories/index.cjs +1190 -0
- package/dist/repositories/index.cjs.map +1 -0
- package/dist/repositories/index.d.cts +16 -0
- package/dist/repositories/index.d.ts +16 -0
- package/dist/repositories/index.js +1177 -0
- package/dist/repositories/index.js.map +1 -0
- package/dist/schema/index.cjs +276 -0
- package/dist/schema/index.cjs.map +1 -0
- package/dist/schema/index.d.cts +1729 -0
- package/dist/schema/index.d.ts +1729 -0
- package/dist/schema/index.js +269 -0
- package/dist/schema/index.js.map +1 -0
- package/dist/storage/index.cjs +124 -0
- package/dist/storage/index.cjs.map +1 -0
- package/dist/storage/index.d.cts +52 -0
- package/dist/storage/index.d.ts +52 -0
- package/dist/storage/index.js +96 -0
- package/dist/storage/index.js.map +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/repositories/base-drizzle.repository.ts","../../src/repositories/transaction.drizzle-repository.ts","../../src/schema/payment-transactions.ts","../../src/schema/payment-methods.ts","../../src/schema/webhook-events.ts","../../src/schema/payment-audit-log.ts","../../src/schema/provider-health.ts","../../src/repositories/payment-method.drizzle-repository.ts","../../src/repositories/webhook-event.drizzle-repository.ts","../../src/repositories/audit-log.drizzle-repository.ts","../../src/repositories/provider-health.drizzle-repository.ts","../../src/repositories/index.ts"],"sourcesContent":["/**\n * @nehorai/payments-drizzle - Base Drizzle Repository\n *\n * Common utilities and types for Drizzle repository implementations.\n */\n\n// ============================================================================\n// Database Instance Type\n// ============================================================================\n\n/**\n * Drizzle database instance type\n * Uses a minimal interface to support any Drizzle database instance.\n * Generic enough to work with any Drizzle PostgreSQL database.\n */\nexport type DrizzleDB = {\n /* eslint-disable @typescript-eslint/no-explicit-any */\n select: (...args: any[]) => any\n insert: (table: any) => any\n update: (table: any) => any\n delete: (table: any) => any\n /* eslint-enable @typescript-eslint/no-explicit-any */\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Convert database row to camelCase entity\n */\nexport function toCamelCase<T extends Record<string, unknown>>(row: Record<string, unknown>): T {\n const result: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(row)) {\n const camelKey = key.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase())\n result[camelKey] = value\n }\n return result as T\n}\n\n/**\n * Convert camelCase entity to snake_case for database\n */\nexport function toSnakeCase<T extends Record<string, unknown>>(obj: Record<string, unknown>): T {\n const result: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(obj)) {\n if (value === undefined) continue\n const snakeKey = key.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`)\n result[snakeKey] = value\n }\n return result as T\n}\n\n/**\n * Apply pagination to query results\n */\nexport function applyPagination<T>(\n items: T[],\n total: number,\n limit: number,\n offset: number\n): {\n data: T[]\n total: number\n limit: number\n offset: number\n hasMore: boolean\n} {\n return {\n data: items,\n total,\n limit,\n offset,\n hasMore: offset + items.length < total,\n }\n}\n\n/**\n * Parse numeric string to number (Drizzle returns numeric as string)\n */\nexport function parseNumeric(value: string | number | null | undefined): number {\n if (value === null || value === undefined) return 0\n if (typeof value === 'number') return value\n return parseFloat(value) || 0\n}\n\n/**\n * Convert array filter to SQL-friendly format\n */\nexport function normalizeArrayFilter<T>(value: T | T[] | undefined): T[] | undefined {\n if (value === undefined) return undefined\n return Array.isArray(value) ? value : [value]\n}\n","/**\n * @nehorai/payments-drizzle - Drizzle Transaction Repository\n *\n * Implements ITransactionRepository using Drizzle ORM.\n */\n\nimport { eq, and, gte, lte, inArray, sql, count } from 'drizzle-orm'\nimport type { DrizzleDB } from './base-drizzle.repository.js'\nimport { parseNumeric, applyPagination, normalizeArrayFilter } from './base-drizzle.repository.js'\nimport { paymentTransactions } from '../schema/index.js'\nimport type {\n ITransactionRepository,\n Transaction,\n CreateTransactionInput,\n UpdateTransactionInput,\n TransactionFilter,\n TransactionStatus,\n ProviderName,\n PaginationParams,\n PaginatedResult,\n} from '@nehorai/payments/repository'\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Map database row to Transaction entity\n */\nfunction mapToTransaction(row: typeof paymentTransactions.$inferSelect): Transaction {\n return {\n id: row.id,\n internalPaymentId: row.internal_payment_id,\n idempotencyKey: row.idempotency_key,\n userId: row.user_id,\n transactionType: row.transaction_type,\n status: row.status,\n amountMinor: parseNumeric(row.amount_minor),\n currency: row.currency,\n originalAmountMinor: row.original_amount_minor ? parseNumeric(row.original_amount_minor) : null,\n originalCurrency: row.original_currency,\n currencyConversionRate: row.currency_conversion_rate\n ? parseNumeric(row.currency_conversion_rate)\n : null,\n provider: row.provider as ProviderName,\n providerTransactionId: row.provider_transaction_id,\n providerAuthorizationCode: row.provider_authorization_code,\n providerMetadata: row.provider_metadata,\n authorizedAt: row.authorized_at,\n capturedAt: row.captured_at,\n voidedAt: row.voided_at,\n captureDeadline: row.capture_deadline,\n refundedAmountMinor: parseNumeric(row.refunded_amount_minor),\n lastRefundAt: row.last_refund_at,\n taxInvoiceStatus: row.tax_invoice_status ?? 'pending',\n taxInvoiceNumber: row.tax_invoice_number,\n taxInvoiceUrl: row.tax_invoice_url,\n failureCode: row.failure_code,\n failureMessage: row.failure_message,\n failureDetails: row.failure_details as Record<string, unknown> | null,\n description: row.description,\n metadata: row.metadata,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n }\n}\n\n// ============================================================================\n// Repository Implementation\n// ============================================================================\n\n/**\n * Drizzle implementation of ITransactionRepository\n */\nexport class DrizzleTransactionRepository implements ITransactionRepository {\n constructor(private db: DrizzleDB) {}\n\n async findById(id: string): Promise<Transaction | null> {\n const result = await this.db\n .select()\n .from(paymentTransactions)\n .where(eq(paymentTransactions.id, id))\n .limit(1)\n\n return result[0] ? mapToTransaction(result[0]) : null\n }\n\n async create(data: CreateTransactionInput): Promise<Transaction> {\n const result = await this.db\n .insert(paymentTransactions)\n .values({\n internal_payment_id: data.internalPaymentId,\n idempotency_key: data.idempotencyKey,\n user_id: data.userId,\n transaction_type: data.transactionType,\n status: data.status ?? 'created',\n amount_minor: String(data.amountMinor),\n currency: data.currency,\n provider: data.provider,\n description: data.description,\n metadata: data.metadata,\n })\n .returning()\n\n return mapToTransaction(result[0])\n }\n\n async update(id: string, data: UpdateTransactionInput): Promise<Transaction | null> {\n const updateData: Partial<typeof paymentTransactions.$inferInsert> = {\n updated_at: new Date(),\n }\n\n if (data.status !== undefined) updateData.status = data.status\n if (data.providerTransactionId !== undefined)\n updateData.provider_transaction_id = data.providerTransactionId\n if (data.providerAuthorizationCode !== undefined)\n updateData.provider_authorization_code = data.providerAuthorizationCode\n if (data.providerMetadata !== undefined) updateData.provider_metadata = data.providerMetadata\n if (data.authorizedAt !== undefined) updateData.authorized_at = data.authorizedAt\n if (data.capturedAt !== undefined) updateData.captured_at = data.capturedAt\n if (data.voidedAt !== undefined) updateData.voided_at = data.voidedAt\n if (data.captureDeadline !== undefined) updateData.capture_deadline = data.captureDeadline\n if (data.refundedAmountMinor !== undefined)\n updateData.refunded_amount_minor = String(data.refundedAmountMinor)\n if (data.lastRefundAt !== undefined) updateData.last_refund_at = data.lastRefundAt\n if (data.taxInvoiceStatus !== undefined) updateData.tax_invoice_status = data.taxInvoiceStatus\n if (data.taxInvoiceNumber !== undefined) updateData.tax_invoice_number = data.taxInvoiceNumber\n if (data.taxInvoiceUrl !== undefined) updateData.tax_invoice_url = data.taxInvoiceUrl\n if (data.failureCode !== undefined) updateData.failure_code = data.failureCode\n if (data.failureMessage !== undefined) updateData.failure_message = data.failureMessage\n if (data.failureDetails !== undefined) updateData.failure_details = data.failureDetails\n\n const result = await this.db\n .update(paymentTransactions)\n .set(updateData)\n .where(eq(paymentTransactions.id, id))\n .returning()\n\n return result[0] ? mapToTransaction(result[0]) : null\n }\n\n async delete(id: string): Promise<boolean> {\n const result = await this.db\n .delete(paymentTransactions)\n .where(eq(paymentTransactions.id, id))\n .returning({ id: paymentTransactions.id })\n\n return result.length > 0\n }\n\n async findByInternalPaymentId(internalPaymentId: string): Promise<Transaction | null> {\n const result = await this.db\n .select()\n .from(paymentTransactions)\n .where(eq(paymentTransactions.internal_payment_id, internalPaymentId))\n .limit(1)\n\n return result[0] ? mapToTransaction(result[0]) : null\n }\n\n async findByIdempotencyKey(idempotencyKey: string): Promise<Transaction | null> {\n const result = await this.db\n .select()\n .from(paymentTransactions)\n .where(eq(paymentTransactions.idempotency_key, idempotencyKey))\n .limit(1)\n\n return result[0] ? mapToTransaction(result[0]) : null\n }\n\n async findByProviderTransactionId(\n provider: ProviderName,\n providerTransactionId: string\n ): Promise<Transaction | null> {\n const result = await this.db\n .select()\n .from(paymentTransactions)\n .where(\n and(\n eq(paymentTransactions.provider, provider),\n eq(paymentTransactions.provider_transaction_id, providerTransactionId)\n )\n )\n .limit(1)\n\n return result[0] ? mapToTransaction(result[0]) : null\n }\n\n async findMany(\n filter: TransactionFilter,\n pagination: PaginationParams = {}\n ): Promise<PaginatedResult<Transaction>> {\n const { limit = 20, offset = 0 } = pagination\n const conditions = this.buildFilterConditions(filter)\n\n const [rows, [countResult]] = await Promise.all([\n this.db\n .select()\n .from(paymentTransactions)\n .where(conditions.length > 0 ? and(...conditions) : undefined)\n .orderBy(sql`${paymentTransactions.created_at} DESC`)\n .limit(limit)\n .offset(offset),\n this.db\n .select({ total: count() })\n .from(paymentTransactions)\n .where(conditions.length > 0 ? and(...conditions) : undefined),\n ])\n\n const transactions = rows.map(mapToTransaction)\n return applyPagination(transactions, countResult?.total ?? 0, limit, offset)\n }\n\n async findByUserId(\n userId: string,\n pagination: PaginationParams = {}\n ): Promise<PaginatedResult<Transaction>> {\n return this.findMany({ userId }, pagination)\n }\n\n async updateStatus(\n id: string,\n status: TransactionStatus,\n additionalData: Partial<UpdateTransactionInput> = {}\n ): Promise<Transaction | null> {\n return this.update(id, { ...additionalData, status })\n }\n\n async incrementRefundedAmount(id: string, amountMinor: number): Promise<Transaction | null> {\n const result = await this.db\n .update(paymentTransactions)\n .set({\n refunded_amount_minor: sql`COALESCE(${paymentTransactions.refunded_amount_minor}, '0')::numeric + ${amountMinor}`,\n last_refund_at: new Date(),\n updated_at: new Date(),\n })\n .where(eq(paymentTransactions.id, id))\n .returning()\n\n return result[0] ? mapToTransaction(result[0]) : null\n }\n\n async findExpiredAuthorizations(beforeDate: Date): Promise<Transaction[]> {\n const result = await this.db\n .select()\n .from(paymentTransactions)\n .where(\n and(\n eq(paymentTransactions.status, 'authorized'),\n lte(paymentTransactions.capture_deadline, beforeDate)\n )\n )\n\n return result.map(mapToTransaction)\n }\n\n async countByStatus(filter: TransactionFilter = {}): Promise<Record<TransactionStatus, number>> {\n const conditions = this.buildFilterConditions(filter)\n\n const result = await this.db\n .select({\n status: paymentTransactions.status,\n count: count(),\n })\n .from(paymentTransactions)\n .where(conditions.length > 0 ? and(...conditions) : undefined)\n .groupBy(paymentTransactions.status)\n\n const counts: Record<TransactionStatus, number> = {\n created: 0,\n pending_authorization: 0,\n authorized: 0,\n capturing: 0,\n captured: 0,\n voided: 0,\n failed: 0,\n expired: 0,\n partially_refunded: 0,\n fully_refunded: 0,\n }\n\n for (const row of result) {\n counts[row.status as TransactionStatus] = row.count\n }\n\n return counts\n }\n\n // ============================================================================\n // Private Helpers\n // ============================================================================\n\n private buildFilterConditions(filter: TransactionFilter) {\n const conditions = []\n\n if (filter.userId) {\n conditions.push(eq(paymentTransactions.user_id, filter.userId))\n }\n\n const statuses = normalizeArrayFilter(filter.status)\n if (statuses && statuses.length > 0) {\n if (statuses.length === 1) {\n conditions.push(eq(paymentTransactions.status, statuses[0]))\n } else {\n conditions.push(inArray(paymentTransactions.status, statuses))\n }\n }\n\n const providers = normalizeArrayFilter(filter.provider)\n if (providers && providers.length > 0) {\n if (providers.length === 1) {\n conditions.push(eq(paymentTransactions.provider, providers[0]))\n } else {\n conditions.push(inArray(paymentTransactions.provider, providers))\n }\n }\n\n const transactionTypes = normalizeArrayFilter(filter.transactionType)\n if (transactionTypes && transactionTypes.length > 0) {\n if (transactionTypes.length === 1) {\n conditions.push(eq(paymentTransactions.transaction_type, transactionTypes[0]))\n } else {\n conditions.push(inArray(paymentTransactions.transaction_type, transactionTypes))\n }\n }\n\n if (filter.dateRange?.from) {\n conditions.push(gte(paymentTransactions.created_at, filter.dateRange.from))\n }\n if (filter.dateRange?.to) {\n conditions.push(lte(paymentTransactions.created_at, filter.dateRange.to))\n }\n\n return conditions\n }\n}\n","/**\r\n * PaymentOS - Payment Transactions Schema\r\n *\r\n * Core table for tracking all payment operations.\r\n * Implements Two-Phase Commit (J5) pattern with authorize/capture flow.\r\n *\r\n * Note: User FK is optional and configured via schema-config.ts\r\n */\r\n\r\nimport { pgTable, uuid, text, numeric, timestamp, jsonb, index, unique } from 'drizzle-orm/pg-core'\r\n\r\n// ============================================================================\r\n// Type Definitions\r\n// ============================================================================\r\n\r\n/**\r\n * Payment transaction states (strict state machine)\r\n * @see src/lib/payments/types/state-machine.ts for transition rules\r\n */\r\nexport type PaymentTransactionStatus =\r\n | 'created'\r\n | 'pending_authorization'\r\n | 'authorized'\r\n | 'capturing'\r\n | 'captured'\r\n | 'voided'\r\n | 'failed'\r\n | 'expired'\r\n | 'partially_refunded'\r\n | 'fully_refunded'\r\n\r\n/**\r\n * Payment transaction types\r\n */\r\nexport type PaymentTransactionType =\r\n | 'one_time_purchase'\r\n | 'subscription_initial'\r\n | 'subscription_renewal'\r\n | 'refund'\r\n\r\n/**\r\n * Tax invoice status (Israeli compliance)\r\n */\r\nexport type PaymentTaxInvoiceStatus = 'pending' | 'generated' | 'sent' | 'failed'\r\n\r\n// ============================================================================\r\n// Schema Definition\r\n// ============================================================================\r\n\r\n/**\r\n * Payment transactions table\r\n *\r\n * FK to user table is NOT defined here - it's application-specific.\r\n * The user_id column stores the UUID, but the FK constraint should be\r\n * added via migration if needed for your specific user table.\r\n *\r\n * To add FK constraint, create a migration:\r\n * ```sql\r\n * ALTER TABLE payment_transactions\r\n * ADD CONSTRAINT payment_transactions_user_id_fkey\r\n * FOREIGN KEY (user_id) REFERENCES your_users_table(id) ON DELETE CASCADE;\r\n * ```\r\n */\r\nexport const paymentTransactions = pgTable(\r\n 'payment_transactions',\r\n {\r\n id: uuid('id').defaultRandom().primaryKey(),\r\n\r\n // Idempotency - prevents duplicate charges\r\n internal_payment_id: text('internal_payment_id').notNull(),\r\n idempotency_key: text('idempotency_key'),\r\n\r\n // User association (FK configured at application level)\r\n user_id: uuid('user_id').notNull(),\r\n\r\n // Transaction classification\r\n transaction_type: text('transaction_type').$type<PaymentTransactionType>().notNull(),\r\n status: text('status').$type<PaymentTransactionStatus>().notNull().default('created'),\r\n\r\n // Amounts in smallest currency unit (cents/agorot)\r\n amount_minor: numeric('amount_minor').notNull(),\r\n currency: text('currency').notNull().default('USD'),\r\n\r\n // Original amount if currency converted\r\n original_amount_minor: numeric('original_amount_minor'),\r\n original_currency: text('original_currency'),\r\n currency_conversion_rate: numeric('currency_conversion_rate'),\r\n\r\n // Provider information\r\n provider: text('provider').notNull(), // stripe, hyp, cardcom\r\n provider_transaction_id: text('provider_transaction_id'),\r\n provider_authorization_code: text('provider_authorization_code'),\r\n provider_metadata: jsonb('provider_metadata').$type<Record<string, unknown>>(),\r\n\r\n // Two-phase commit tracking (J5)\r\n authorized_at: timestamp('authorized_at', { withTimezone: true }),\r\n captured_at: timestamp('captured_at', { withTimezone: true }),\r\n voided_at: timestamp('voided_at', { withTimezone: true }),\r\n capture_deadline: timestamp('capture_deadline', { withTimezone: true }),\r\n\r\n // Refund tracking\r\n refunded_amount_minor: numeric('refunded_amount_minor').default('0'),\r\n last_refund_at: timestamp('last_refund_at', { withTimezone: true }),\r\n\r\n // Tax invoice (Israeli requirement)\r\n tax_invoice_status: text('tax_invoice_status')\r\n .$type<PaymentTaxInvoiceStatus>()\r\n .default('pending'),\r\n tax_invoice_number: text('tax_invoice_number'),\r\n tax_invoice_url: text('tax_invoice_url'),\r\n\r\n // Error tracking\r\n failure_code: text('failure_code'),\r\n failure_message: text('failure_message'),\r\n failure_details: jsonb('failure_details'),\r\n\r\n // Application metadata\r\n description: text('description'),\r\n metadata: jsonb('metadata').$type<{\r\n credit_package_id?: string\r\n subscription_plan_id?: string\r\n credits_amount?: number\r\n [key: string]: unknown\r\n }>(),\r\n\r\n // Timestamps\r\n created_at: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),\r\n updated_at: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),\r\n },\r\n (table) => ({\r\n // Performance indexes\r\n userIdx: index('payment_transactions_user_idx').on(table.user_id),\r\n statusIdx: index('payment_transactions_status_idx').on(table.status),\r\n providerIdx: index('payment_transactions_provider_idx').on(table.provider),\r\n providerTxIdx: index('payment_transactions_provider_tx_idx').on(table.provider_transaction_id),\r\n createdAtIdx: index('payment_transactions_created_at_idx').on(table.created_at),\r\n // Unique constraints for idempotency\r\n internalIdUnique: unique('payment_transactions_internal_id_unique').on(\r\n table.internal_payment_id\r\n ),\r\n idempotencyUnique: unique('payment_transactions_idempotency_unique').on(table.idempotency_key),\r\n })\r\n)\r\n","/**\r\n * PaymentOS - Payment Methods Schema\r\n *\r\n * Stores tokenized payment methods (PCI-compliant - no full card numbers).\r\n * Used for saved cards and recurring billing.\r\n *\r\n * Note: User FK is optional and configured via schema-config.ts\r\n */\r\n\r\nimport { pgTable, uuid, text, boolean, timestamp, jsonb, index } from 'drizzle-orm/pg-core'\r\n\r\n// ============================================================================\r\n// Type Definitions\r\n// ============================================================================\r\n\r\n/**\r\n * Payment method types\r\n */\r\nexport type PaymentMethodType = 'card' | 'bank_account' | 'paypal'\r\n\r\n/**\r\n * Card brands\r\n */\r\nexport type CardBrandType =\r\n | 'visa'\r\n | 'mastercard'\r\n | 'amex'\r\n | 'discover'\r\n | 'isracard'\r\n | 'diners'\r\n | 'unknown'\r\n\r\n// ============================================================================\r\n// Schema Definition\r\n// ============================================================================\r\n\r\n/**\r\n * Payment methods table\r\n *\r\n * FK to user table is NOT defined here - it's application-specific.\r\n * The user_id column stores the UUID, but the FK constraint should be\r\n * added via migration if needed for your specific user table.\r\n *\r\n * To add FK constraint, create a migration:\r\n * ```sql\r\n * ALTER TABLE payment_methods\r\n * ADD CONSTRAINT payment_methods_user_id_fkey\r\n * FOREIGN KEY (user_id) REFERENCES your_users_table(id) ON DELETE CASCADE;\r\n * ```\r\n */\r\nexport const paymentMethods = pgTable(\r\n 'payment_methods',\r\n {\r\n id: uuid('id').defaultRandom().primaryKey(),\r\n\r\n // User association (FK configured at application level)\r\n user_id: uuid('user_id').notNull(),\r\n\r\n // Method type\r\n type: text('type').$type<PaymentMethodType>().notNull(),\r\n\r\n // Provider information\r\n provider: text('provider').notNull(), // stripe, hyp, cardcom\r\n provider_payment_method_id: text('provider_payment_method_id').notNull(),\r\n\r\n // Card details (tokenized, never full numbers)\r\n card_brand: text('card_brand').$type<CardBrandType>(),\r\n card_last4: text('card_last4'),\r\n card_exp_month: text('card_exp_month'),\r\n card_exp_year: text('card_exp_year'),\r\n card_bin: text('card_bin'), // First 6-8 digits for routing\r\n\r\n // State\r\n is_default: boolean('is_default').default(false),\r\n is_active: boolean('is_active').default(true),\r\n\r\n // Provider-specific data\r\n provider_metadata: jsonb('provider_metadata').$type<Record<string, unknown>>(),\r\n\r\n // Timestamps\r\n created_at: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),\r\n updated_at: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),\r\n last_used_at: timestamp('last_used_at', { withTimezone: true }),\r\n },\r\n (table) => ({\r\n // Performance indexes\r\n userIdx: index('payment_methods_user_idx').on(table.user_id),\r\n userDefaultIdx: index('payment_methods_user_default_idx').on(table.user_id, table.is_default),\r\n providerIdx: index('payment_methods_provider_idx').on(table.provider),\r\n providerMethodIdx: index('payment_methods_provider_method_idx').on(\r\n table.provider_payment_method_id\r\n ),\r\n cardBinIdx: index('payment_methods_card_bin_idx').on(table.card_bin),\r\n })\r\n)\r\n","import {\r\n pgTable,\r\n uuid,\r\n text,\r\n timestamp,\r\n jsonb,\r\n index,\r\n unique,\r\n} from 'drizzle-orm/pg-core'\r\n\r\n/**\r\n * Webhook processing status\r\n */\r\nexport type WebhookEventStatus =\r\n | 'pending'\r\n | 'processing'\r\n | 'processed'\r\n | 'failed'\r\n | 'ignored'\r\n\r\n/**\r\n * Payment webhook events table\r\n * Stores all incoming webhooks for idempotent processing.\r\n * Ensures each provider event is processed exactly once.\r\n */\r\nexport const paymentWebhookEvents = pgTable(\r\n 'payment_webhook_events',\r\n {\r\n id: uuid('id').defaultRandom().primaryKey(),\r\n\r\n // Event identification\r\n provider: text('provider').notNull(), // stripe, hyp, cardcom\r\n provider_event_id: text('provider_event_id').notNull(),\r\n event_type: text('event_type').notNull(),\r\n\r\n // Processing state\r\n status: text('status')\r\n .$type<WebhookEventStatus>()\r\n .notNull()\r\n .default('pending'),\r\n attempts: text('attempts').default('0'),\r\n last_attempt_at: timestamp('last_attempt_at', { withTimezone: true }),\r\n\r\n // Linked transaction (if applicable)\r\n transaction_id: uuid('transaction_id'),\r\n\r\n // Event payload (store for debugging and retry)\r\n payload: jsonb('payload').$type<Record<string, unknown>>().notNull(),\r\n signature: text('signature'),\r\n\r\n // Error tracking\r\n error_message: text('error_message'),\r\n error_details: jsonb('error_details'),\r\n\r\n // Timestamps\r\n received_at: timestamp('received_at', { withTimezone: true })\r\n .notNull()\r\n .defaultNow(),\r\n processed_at: timestamp('processed_at', { withTimezone: true }),\r\n created_at: timestamp('created_at', { withTimezone: true })\r\n .notNull()\r\n .defaultNow(),\r\n },\r\n (table) => ({\r\n // Unique constraint for idempotency\r\n providerEventUnique: unique('webhook_events_provider_event_unique').on(\r\n table.provider,\r\n table.provider_event_id\r\n ),\r\n // Performance indexes\r\n statusIdx: index('webhook_events_status_idx').on(table.status),\r\n transactionIdx: index('webhook_events_transaction_idx').on(\r\n table.transaction_id\r\n ),\r\n receivedAtIdx: index('webhook_events_received_at_idx').on(table.received_at),\r\n providerIdx: index('webhook_events_provider_idx').on(table.provider),\r\n eventTypeIdx: index('webhook_events_event_type_idx').on(table.event_type),\r\n })\r\n)\r\n","/**\n * @nehorai/payments-drizzle - Payment Audit Log Schema\n *\n * Immutable audit trail for all payment state changes.\n * Used for debugging, compliance, and dispute resolution.\n */\n\nimport {\n pgTable,\n uuid,\n text,\n timestamp,\n jsonb,\n index,\n} from 'drizzle-orm/pg-core'\n\n// ============================================================================\n// Type Definitions\n// ============================================================================\n\n/**\n * Audit log action types\n */\nexport type AuditLogAction =\n | 'created'\n | 'status_changed'\n | 'authorized'\n | 'captured'\n | 'voided'\n | 'refund_initiated'\n | 'refund_completed'\n | 'webhook_received'\n | 'webhook_processed'\n | 'error_occurred'\n | 'retry_attempted'\n | 'manual_intervention'\n\n/**\n * Who/what triggered the action\n */\nexport type AuditLogTrigger =\n | 'user'\n | 'webhook'\n | 'system'\n | 'admin'\n | 'cron'\n | 'api'\n\n// ============================================================================\n// Schema Definition\n// ============================================================================\n\n/**\n * Payment audit log table\n * Immutable audit trail for all payment state changes.\n * Used for debugging, compliance, and dispute resolution.\n */\nexport const paymentAuditLog = pgTable(\n 'payment_audit_log',\n {\n id: uuid('id').defaultRandom().primaryKey(),\n\n // What transaction was affected\n transaction_id: uuid('transaction_id').notNull(),\n\n // What action occurred\n action: text('action').$type<AuditLogAction>().notNull(),\n\n // State before and after\n previous_state: jsonb('previous_state'),\n new_state: jsonb('new_state').notNull(),\n\n // Who/what triggered this change\n triggered_by: text('triggered_by').$type<AuditLogTrigger>().notNull(),\n triggered_by_id: uuid('triggered_by_id'), // User ID if applicable\n\n // Request context\n ip_address: text('ip_address'),\n user_agent: text('user_agent'),\n\n // Correlation for distributed tracing\n correlation_id: text('correlation_id'),\n\n // Additional context\n metadata: jsonb('metadata').$type<Record<string, unknown>>(),\n\n // Immutable timestamp (never updated)\n created_at: timestamp('created_at', { withTimezone: true })\n .notNull()\n .defaultNow(),\n },\n (table) => ({\n // Performance indexes\n transactionIdx: index('payment_audit_log_transaction_idx').on(\n table.transaction_id\n ),\n actionIdx: index('payment_audit_log_action_idx').on(table.action),\n correlationIdx: index('payment_audit_log_correlation_idx').on(\n table.correlation_id\n ),\n createdAtIdx: index('payment_audit_log_created_at_idx').on(table.created_at),\n triggeredByIdx: index('payment_audit_log_triggered_by_idx').on(\n table.triggered_by\n ),\n })\n)\n","/**\n * @nehorai/payments-drizzle - Provider Health Schema\n *\n * Tracks payment provider health for circuit breaker pattern.\n * Used for intelligent failover when providers experience issues.\n */\n\nimport {\n pgTable,\n uuid,\n text,\n numeric,\n timestamp,\n jsonb,\n index,\n unique,\n} from 'drizzle-orm/pg-core'\n\n// ============================================================================\n// Type Definitions\n// ============================================================================\n\n/**\n * Circuit breaker states\n */\nexport type CircuitBreakerState = 'closed' | 'open' | 'half_open'\n\n// ============================================================================\n// Schema Definition\n// ============================================================================\n\n/**\n * Provider health table\n * Tracks payment provider health for circuit breaker pattern.\n * Used for intelligent failover when providers experience issues.\n */\nexport const providerHealth = pgTable(\n 'payment_provider_health',\n {\n id: uuid('id').defaultRandom().primaryKey(),\n\n // Provider identification\n provider: text('provider').notNull(), // stripe, hyp, cardcom\n\n // Circuit breaker state\n circuit_state: text('circuit_state')\n .$type<CircuitBreakerState>()\n .notNull()\n .default('closed'),\n\n // Failure tracking\n failure_count: text('failure_count').default('0'),\n success_count: text('success_count').default('0'),\n last_failure_at: timestamp('last_failure_at', { withTimezone: true }),\n last_success_at: timestamp('last_success_at', { withTimezone: true }),\n\n // Circuit breaker timing\n circuit_opened_at: timestamp('circuit_opened_at', { withTimezone: true }),\n next_retry_at: timestamp('next_retry_at', { withTimezone: true }),\n\n // Performance metrics\n avg_latency_ms: numeric('avg_latency_ms'),\n error_rate: numeric('error_rate'), // 0-1\n request_count_window: text('request_count_window').default('0'),\n\n // Health check results\n last_health_check_at: timestamp('last_health_check_at', { withTimezone: true }),\n health_check_result: jsonb('health_check_result').$type<{\n healthy: boolean\n latency_ms?: number\n error?: string\n }>(),\n\n // Timestamps\n created_at: timestamp('created_at', { withTimezone: true })\n .notNull()\n .defaultNow(),\n updated_at: timestamp('updated_at', { withTimezone: true })\n .notNull()\n .defaultNow(),\n },\n (table) => ({\n // One record per provider\n providerUnique: unique('provider_health_provider_unique').on(table.provider),\n // Performance indexes\n circuitStateIdx: index('provider_health_circuit_state_idx').on(\n table.circuit_state\n ),\n nextRetryIdx: index('provider_health_next_retry_idx').on(table.next_retry_at),\n })\n)\n","/**\n * @nehorai/payments-drizzle - Drizzle Payment Method Repository\n *\n * Implements IPaymentMethodRepository using Drizzle ORM.\n */\n\nimport { eq, and, inArray, sql, count } from 'drizzle-orm'\nimport type { DrizzleDB } from './base-drizzle.repository.js'\nimport { applyPagination, normalizeArrayFilter } from './base-drizzle.repository.js'\nimport { paymentMethods } from '../schema/index.js'\nimport type {\n IPaymentMethodRepository,\n PaymentMethod,\n CreatePaymentMethodInput,\n UpdatePaymentMethodInput,\n PaymentMethodFilter,\n ProviderName,\n CardBrand,\n PaginationParams,\n PaginatedResult,\n} from '@nehorai/payments/repository'\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Map database row to PaymentMethod entity\n */\nfunction mapToPaymentMethod(row: typeof paymentMethods.$inferSelect): PaymentMethod {\n return {\n id: row.id,\n userId: row.user_id,\n type: row.type,\n provider: row.provider as ProviderName,\n providerPaymentMethodId: row.provider_payment_method_id,\n cardBrand: row.card_brand as CardBrand | null,\n cardLast4: row.card_last4,\n cardExpMonth: row.card_exp_month,\n cardExpYear: row.card_exp_year,\n cardBin: row.card_bin,\n isDefault: row.is_default ?? false,\n isActive: row.is_active ?? true,\n providerMetadata: row.provider_metadata,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n lastUsedAt: row.last_used_at,\n }\n}\n\n// ============================================================================\n// Repository Implementation\n// ============================================================================\n\n/**\n * Drizzle implementation of IPaymentMethodRepository\n */\nexport class DrizzlePaymentMethodRepository implements IPaymentMethodRepository {\n constructor(private db: DrizzleDB) {}\n\n async findById(id: string): Promise<PaymentMethod | null> {\n const result = await this.db\n .select()\n .from(paymentMethods)\n .where(eq(paymentMethods.id, id))\n .limit(1)\n\n return result[0] ? mapToPaymentMethod(result[0]) : null\n }\n\n async create(data: CreatePaymentMethodInput): Promise<PaymentMethod> {\n const result = await this.db\n .insert(paymentMethods)\n .values({\n user_id: data.userId,\n type: data.type,\n provider: data.provider,\n provider_payment_method_id: data.providerPaymentMethodId,\n card_brand: data.cardBrand,\n card_last4: data.cardLast4,\n card_exp_month: data.cardExpMonth,\n card_exp_year: data.cardExpYear,\n card_bin: data.cardBin,\n is_default: data.isDefault ?? false,\n provider_metadata: data.providerMetadata,\n })\n .returning()\n\n return mapToPaymentMethod(result[0])\n }\n\n async update(id: string, data: UpdatePaymentMethodInput): Promise<PaymentMethod | null> {\n const updateData: Partial<typeof paymentMethods.$inferInsert> = {\n updated_at: new Date(),\n }\n\n if (data.isDefault !== undefined) updateData.is_default = data.isDefault\n if (data.isActive !== undefined) updateData.is_active = data.isActive\n if (data.cardExpMonth !== undefined) updateData.card_exp_month = data.cardExpMonth\n if (data.cardExpYear !== undefined) updateData.card_exp_year = data.cardExpYear\n if (data.lastUsedAt !== undefined) updateData.last_used_at = data.lastUsedAt\n if (data.providerMetadata !== undefined) updateData.provider_metadata = data.providerMetadata\n\n const result = await this.db\n .update(paymentMethods)\n .set(updateData)\n .where(eq(paymentMethods.id, id))\n .returning()\n\n return result[0] ? mapToPaymentMethod(result[0]) : null\n }\n\n async delete(id: string): Promise<boolean> {\n const result = await this.db\n .delete(paymentMethods)\n .where(eq(paymentMethods.id, id))\n .returning({ id: paymentMethods.id })\n\n return result.length > 0\n }\n\n async findByProviderPaymentMethodId(\n provider: ProviderName,\n providerPaymentMethodId: string\n ): Promise<PaymentMethod | null> {\n const result = await this.db\n .select()\n .from(paymentMethods)\n .where(\n and(\n eq(paymentMethods.provider, provider),\n eq(paymentMethods.provider_payment_method_id, providerPaymentMethodId)\n )\n )\n .limit(1)\n\n return result[0] ? mapToPaymentMethod(result[0]) : null\n }\n\n async findByUserId(\n userId: string,\n filter: Partial<PaymentMethodFilter> = {}\n ): Promise<PaymentMethod[]> {\n const conditions = [eq(paymentMethods.user_id, userId)]\n\n if (filter.isActive !== undefined) {\n conditions.push(eq(paymentMethods.is_active, filter.isActive))\n }\n if (filter.isDefault !== undefined) {\n conditions.push(eq(paymentMethods.is_default, filter.isDefault))\n }\n\n const providers = normalizeArrayFilter(filter.provider)\n if (providers && providers.length > 0) {\n conditions.push(inArray(paymentMethods.provider, providers))\n }\n\n const result = await this.db\n .select()\n .from(paymentMethods)\n .where(and(...conditions))\n .orderBy(sql`${paymentMethods.created_at} DESC`)\n\n return result.map(mapToPaymentMethod)\n }\n\n async findDefaultForUser(userId: string): Promise<PaymentMethod | null> {\n const result = await this.db\n .select()\n .from(paymentMethods)\n .where(\n and(\n eq(paymentMethods.user_id, userId),\n eq(paymentMethods.is_default, true),\n eq(paymentMethods.is_active, true)\n )\n )\n .limit(1)\n\n return result[0] ? mapToPaymentMethod(result[0]) : null\n }\n\n async findMany(\n filter: PaymentMethodFilter,\n pagination: PaginationParams = {}\n ): Promise<PaginatedResult<PaymentMethod>> {\n const { limit = 20, offset = 0 } = pagination\n const conditions = this.buildFilterConditions(filter)\n\n const [rows, [countResult]] = await Promise.all([\n this.db\n .select()\n .from(paymentMethods)\n .where(conditions.length > 0 ? and(...conditions) : undefined)\n .orderBy(sql`${paymentMethods.created_at} DESC`)\n .limit(limit)\n .offset(offset),\n this.db\n .select({ total: count() })\n .from(paymentMethods)\n .where(conditions.length > 0 ? and(...conditions) : undefined),\n ])\n\n const methods = rows.map(mapToPaymentMethod)\n return applyPagination(methods, countResult?.total ?? 0, limit, offset)\n }\n\n async setAsDefault(id: string, userId: string): Promise<PaymentMethod | null> {\n // First, unset all other defaults for user\n await this.db\n .update(paymentMethods)\n .set({ is_default: false, updated_at: new Date() })\n .where(and(eq(paymentMethods.user_id, userId), eq(paymentMethods.is_default, true)))\n\n // Then set this one as default\n return this.update(id, { isDefault: true })\n }\n\n async deactivate(id: string): Promise<boolean> {\n const result = await this.update(id, { isActive: false })\n return result !== null\n }\n\n async markAsUsed(id: string): Promise<PaymentMethod | null> {\n return this.update(id, { lastUsedAt: new Date() })\n }\n\n async findByCardBin(userId: string, cardBin: string): Promise<PaymentMethod[]> {\n const result = await this.db\n .select()\n .from(paymentMethods)\n .where(\n and(\n eq(paymentMethods.user_id, userId),\n eq(paymentMethods.card_bin, cardBin),\n eq(paymentMethods.is_active, true)\n )\n )\n\n return result.map(mapToPaymentMethod)\n }\n\n async countActiveForUser(userId: string): Promise<number> {\n const result = await this.db\n .select({ count: count() })\n .from(paymentMethods)\n .where(and(eq(paymentMethods.user_id, userId), eq(paymentMethods.is_active, true)))\n\n return result[0]?.count ?? 0\n }\n\n // ============================================================================\n // Private Helpers\n // ============================================================================\n\n private buildFilterConditions(filter: PaymentMethodFilter) {\n const conditions = []\n\n if (filter.userId) {\n conditions.push(eq(paymentMethods.user_id, filter.userId))\n }\n if (filter.isDefault !== undefined) {\n conditions.push(eq(paymentMethods.is_default, filter.isDefault))\n }\n if (filter.isActive !== undefined) {\n conditions.push(eq(paymentMethods.is_active, filter.isActive))\n }\n if (filter.cardBin) {\n conditions.push(eq(paymentMethods.card_bin, filter.cardBin))\n }\n\n const providers = normalizeArrayFilter(filter.provider)\n if (providers && providers.length > 0) {\n conditions.push(inArray(paymentMethods.provider, providers))\n }\n\n const types = normalizeArrayFilter(filter.type)\n if (types && types.length > 0) {\n conditions.push(inArray(paymentMethods.type, types))\n }\n\n return conditions\n }\n}\n","/**\n * @nehorai/payments-drizzle - Drizzle Webhook Event Repository\n *\n * Implements IWebhookEventRepository using Drizzle ORM.\n */\n\nimport { eq, and, gte, lte, inArray, sql, count, lt } from 'drizzle-orm'\nimport type { DrizzleDB } from './base-drizzle.repository.js'\nimport { applyPagination, normalizeArrayFilter } from './base-drizzle.repository.js'\nimport { paymentWebhookEvents } from '../schema/index.js'\nimport type {\n IWebhookEventRepository,\n WebhookEvent,\n CreateWebhookEventInput,\n UpdateWebhookEventInput,\n WebhookEventFilter,\n WebhookEventStatus,\n ProviderName,\n PaginationParams,\n PaginatedResult,\n} from '@nehorai/payments/repository'\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Map database row to WebhookEvent entity\n */\nfunction mapToWebhookEvent(row: typeof paymentWebhookEvents.$inferSelect): WebhookEvent {\n return {\n id: row.id,\n provider: row.provider as ProviderName,\n providerEventId: row.provider_event_id,\n eventType: row.event_type,\n status: row.status,\n attempts: parseInt(row.attempts ?? '0', 10),\n lastAttemptAt: row.last_attempt_at,\n transactionId: row.transaction_id,\n payload: row.payload,\n signature: row.signature,\n errorMessage: row.error_message,\n errorDetails: row.error_details as Record<string, unknown> | null,\n receivedAt: row.received_at,\n processedAt: row.processed_at,\n createdAt: row.created_at,\n }\n}\n\n// ============================================================================\n// Repository Implementation\n// ============================================================================\n\n/**\n * Drizzle implementation of IWebhookEventRepository\n */\nexport class DrizzleWebhookEventRepository implements IWebhookEventRepository {\n constructor(private db: DrizzleDB) {}\n\n async findById(id: string): Promise<WebhookEvent | null> {\n const result = await this.db\n .select()\n .from(paymentWebhookEvents)\n .where(eq(paymentWebhookEvents.id, id))\n .limit(1)\n\n return result[0] ? mapToWebhookEvent(result[0]) : null\n }\n\n async create(data: CreateWebhookEventInput): Promise<WebhookEvent> {\n const result = await this.db\n .insert(paymentWebhookEvents)\n .values({\n provider: data.provider,\n provider_event_id: data.providerEventId,\n event_type: data.eventType,\n payload: data.payload,\n signature: data.signature,\n status: 'pending',\n })\n .returning()\n\n return mapToWebhookEvent(result[0])\n }\n\n async update(id: string, data: UpdateWebhookEventInput): Promise<WebhookEvent | null> {\n const updateData: Partial<typeof paymentWebhookEvents.$inferInsert> = {}\n\n if (data.status !== undefined) updateData.status = data.status\n if (data.attempts !== undefined) updateData.attempts = String(data.attempts)\n if (data.lastAttemptAt !== undefined) updateData.last_attempt_at = data.lastAttemptAt\n if (data.transactionId !== undefined) updateData.transaction_id = data.transactionId\n if (data.processedAt !== undefined) updateData.processed_at = data.processedAt\n if (data.errorMessage !== undefined) updateData.error_message = data.errorMessage\n if (data.errorDetails !== undefined) updateData.error_details = data.errorDetails\n\n const result = await this.db\n .update(paymentWebhookEvents)\n .set(updateData)\n .where(eq(paymentWebhookEvents.id, id))\n .returning()\n\n return result[0] ? mapToWebhookEvent(result[0]) : null\n }\n\n async delete(id: string): Promise<boolean> {\n const result = await this.db\n .delete(paymentWebhookEvents)\n .where(eq(paymentWebhookEvents.id, id))\n .returning({ id: paymentWebhookEvents.id })\n\n return result.length > 0\n }\n\n async findByProviderEventId(\n provider: ProviderName,\n providerEventId: string\n ): Promise<WebhookEvent | null> {\n const result = await this.db\n .select()\n .from(paymentWebhookEvents)\n .where(\n and(\n eq(paymentWebhookEvents.provider, provider),\n eq(paymentWebhookEvents.provider_event_id, providerEventId)\n )\n )\n .limit(1)\n\n return result[0] ? mapToWebhookEvent(result[0]) : null\n }\n\n async findByTransactionId(transactionId: string): Promise<WebhookEvent[]> {\n const result = await this.db\n .select()\n .from(paymentWebhookEvents)\n .where(eq(paymentWebhookEvents.transaction_id, transactionId))\n .orderBy(sql`${paymentWebhookEvents.received_at} DESC`)\n\n return result.map(mapToWebhookEvent)\n }\n\n async findMany(\n filter: WebhookEventFilter,\n pagination: PaginationParams = {}\n ): Promise<PaginatedResult<WebhookEvent>> {\n const { limit = 20, offset = 0 } = pagination\n const conditions = this.buildFilterConditions(filter)\n\n const [rows, [countResult]] = await Promise.all([\n this.db\n .select()\n .from(paymentWebhookEvents)\n .where(conditions.length > 0 ? and(...conditions) : undefined)\n .orderBy(sql`${paymentWebhookEvents.received_at} DESC`)\n .limit(limit)\n .offset(offset),\n this.db\n .select({ total: count() })\n .from(paymentWebhookEvents)\n .where(conditions.length > 0 ? and(...conditions) : undefined),\n ])\n\n const events = rows.map(mapToWebhookEvent)\n return applyPagination(events, countResult?.total ?? 0, limit, offset)\n }\n\n async findFailedForRetry(maxAttempts: number, olderThan?: Date): Promise<WebhookEvent[]> {\n const conditions = [\n eq(paymentWebhookEvents.status, 'failed'),\n lt(sql`CAST(${paymentWebhookEvents.attempts} AS INTEGER)`, maxAttempts),\n ]\n\n if (olderThan) {\n conditions.push(lt(paymentWebhookEvents.last_attempt_at, olderThan))\n }\n\n const result = await this.db\n .select()\n .from(paymentWebhookEvents)\n .where(and(...conditions))\n .orderBy(sql`${paymentWebhookEvents.last_attempt_at} ASC`)\n .limit(100)\n\n return result.map(mapToWebhookEvent)\n }\n\n async findPending(limit: number = 100): Promise<WebhookEvent[]> {\n const result = await this.db\n .select()\n .from(paymentWebhookEvents)\n .where(eq(paymentWebhookEvents.status, 'pending'))\n .orderBy(sql`${paymentWebhookEvents.received_at} ASC`)\n .limit(limit)\n\n return result.map(mapToWebhookEvent)\n }\n\n async markAsProcessing(id: string): Promise<boolean> {\n // Optimistic locking - only update if still pending\n const result = await this.db\n .update(paymentWebhookEvents)\n .set({\n status: 'processing',\n last_attempt_at: new Date(),\n attempts: sql`CAST(${paymentWebhookEvents.attempts} AS INTEGER) + 1`,\n })\n .where(and(eq(paymentWebhookEvents.id, id), eq(paymentWebhookEvents.status, 'pending')))\n .returning({ id: paymentWebhookEvents.id })\n\n return result.length > 0\n }\n\n async markAsProcessed(id: string, transactionId?: string): Promise<WebhookEvent | null> {\n return this.update(id, {\n status: 'processed',\n processedAt: new Date(),\n transactionId,\n })\n }\n\n async markAsFailed(\n id: string,\n errorMessage: string,\n errorDetails?: Record<string, unknown>\n ): Promise<WebhookEvent | null> {\n return this.update(id, {\n status: 'failed',\n errorMessage,\n errorDetails,\n })\n }\n\n async incrementAttempts(id: string): Promise<WebhookEvent | null> {\n const result = await this.db\n .update(paymentWebhookEvents)\n .set({\n attempts: sql`CAST(${paymentWebhookEvents.attempts} AS INTEGER) + 1`,\n last_attempt_at: new Date(),\n })\n .where(eq(paymentWebhookEvents.id, id))\n .returning()\n\n return result[0] ? mapToWebhookEvent(result[0]) : null\n }\n\n async isAlreadyProcessed(provider: ProviderName, providerEventId: string): Promise<boolean> {\n const result = await this.db\n .select({ status: paymentWebhookEvents.status })\n .from(paymentWebhookEvents)\n .where(\n and(\n eq(paymentWebhookEvents.provider, provider),\n eq(paymentWebhookEvents.provider_event_id, providerEventId),\n eq(paymentWebhookEvents.status, 'processed')\n )\n )\n .limit(1)\n\n return result.length > 0\n }\n\n async countByStatus(\n filter: WebhookEventFilter = {}\n ): Promise<Record<WebhookEventStatus, number>> {\n const conditions = this.buildFilterConditions(filter)\n\n const result = await this.db\n .select({\n status: paymentWebhookEvents.status,\n count: count(),\n })\n .from(paymentWebhookEvents)\n .where(conditions.length > 0 ? and(...conditions) : undefined)\n .groupBy(paymentWebhookEvents.status)\n\n const counts: Record<WebhookEventStatus, number> = {\n pending: 0,\n processing: 0,\n processed: 0,\n failed: 0,\n ignored: 0,\n }\n\n for (const row of result) {\n counts[row.status as WebhookEventStatus] = row.count\n }\n\n return counts\n }\n\n // ============================================================================\n // Private Helpers\n // ============================================================================\n\n private buildFilterConditions(filter: WebhookEventFilter) {\n const conditions = []\n\n const providers = normalizeArrayFilter(filter.provider)\n if (providers && providers.length > 0) {\n conditions.push(inArray(paymentWebhookEvents.provider, providers))\n }\n\n const eventTypes = normalizeArrayFilter(filter.eventType)\n if (eventTypes && eventTypes.length > 0) {\n conditions.push(inArray(paymentWebhookEvents.event_type, eventTypes))\n }\n\n const statuses = normalizeArrayFilter(filter.status)\n if (statuses && statuses.length > 0) {\n conditions.push(inArray(paymentWebhookEvents.status, statuses))\n }\n\n if (filter.transactionId) {\n conditions.push(eq(paymentWebhookEvents.transaction_id, filter.transactionId))\n }\n\n if (filter.dateRange?.from) {\n conditions.push(gte(paymentWebhookEvents.received_at, filter.dateRange.from))\n }\n if (filter.dateRange?.to) {\n conditions.push(lte(paymentWebhookEvents.received_at, filter.dateRange.to))\n }\n\n return conditions\n }\n}\n","/**\n * @nehorai/payments-drizzle - Drizzle Audit Log Repository\n *\n * Implements IAuditLogRepository using Drizzle ORM.\n * Audit logs are immutable - only create and read operations.\n */\n\nimport { eq, and, inArray, sql, count, gte, lte } from 'drizzle-orm'\nimport type { DrizzleDB } from './base-drizzle.repository.js'\nimport { applyPagination, normalizeArrayFilter } from './base-drizzle.repository.js'\nimport { paymentAuditLog } from '../schema/index.js'\nimport type {\n IAuditLogRepository,\n AuditLogEntry,\n CreateAuditLogInput,\n AuditLogFilter,\n AuditLogAction,\n AuditLogTrigger,\n PaginationParams,\n PaginatedResult,\n} from '@nehorai/payments/repository'\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Map database row to AuditLogEntry entity\n */\nfunction mapToAuditLogEntry(row: typeof paymentAuditLog.$inferSelect): AuditLogEntry {\n return {\n id: row.id,\n transactionId: row.transaction_id,\n action: row.action as AuditLogAction,\n previousState: row.previous_state as Record<string, unknown> | null,\n newState: row.new_state as Record<string, unknown>,\n triggeredBy: row.triggered_by as AuditLogTrigger,\n triggeredById: row.triggered_by_id,\n ipAddress: row.ip_address,\n userAgent: row.user_agent,\n correlationId: row.correlation_id,\n metadata: row.metadata as Record<string, unknown> | null,\n createdAt: row.created_at,\n }\n}\n\n// ============================================================================\n// Repository Implementation\n// ============================================================================\n\n/**\n * Drizzle implementation of IAuditLogRepository\n */\nexport class DrizzleAuditLogRepository implements IAuditLogRepository {\n constructor(private db: DrizzleDB) {}\n\n async findById(id: string): Promise<AuditLogEntry | null> {\n const result = await this.db\n .select()\n .from(paymentAuditLog)\n .where(eq(paymentAuditLog.id, id))\n .limit(1)\n\n return result[0] ? mapToAuditLogEntry(result[0]) : null\n }\n\n async create(data: CreateAuditLogInput): Promise<AuditLogEntry> {\n const result = await this.db\n .insert(paymentAuditLog)\n .values({\n transaction_id: data.transactionId,\n action: data.action,\n previous_state: data.previousState,\n new_state: data.newState,\n triggered_by: data.triggeredBy,\n triggered_by_id: data.triggeredById,\n ip_address: data.ipAddress,\n user_agent: data.userAgent,\n correlation_id: data.correlationId,\n metadata: data.metadata,\n })\n .returning()\n\n return mapToAuditLogEntry(result[0])\n }\n\n async createMany(entries: CreateAuditLogInput[]): Promise<AuditLogEntry[]> {\n if (entries.length === 0) return []\n\n const values = entries.map((data) => ({\n transaction_id: data.transactionId,\n action: data.action,\n previous_state: data.previousState,\n new_state: data.newState,\n triggered_by: data.triggeredBy,\n triggered_by_id: data.triggeredById,\n ip_address: data.ipAddress,\n user_agent: data.userAgent,\n correlation_id: data.correlationId,\n metadata: data.metadata,\n }))\n\n const result = await this.db.insert(paymentAuditLog).values(values).returning()\n\n return result.map(mapToAuditLogEntry)\n }\n\n async findByTransactionId(\n transactionId: string,\n pagination: PaginationParams = {}\n ): Promise<PaginatedResult<AuditLogEntry>> {\n const { limit = 100, offset = 0 } = pagination\n\n const [rows, [countResult]] = await Promise.all([\n this.db\n .select()\n .from(paymentAuditLog)\n .where(eq(paymentAuditLog.transaction_id, transactionId))\n .orderBy(sql`${paymentAuditLog.created_at} ASC`)\n .limit(limit)\n .offset(offset),\n this.db\n .select({ total: count() })\n .from(paymentAuditLog)\n .where(eq(paymentAuditLog.transaction_id, transactionId)),\n ])\n\n const entries = rows.map(mapToAuditLogEntry)\n return applyPagination(entries, countResult?.total ?? 0, limit, offset)\n }\n\n async findMany(\n filter: AuditLogFilter,\n pagination: PaginationParams = {}\n ): Promise<PaginatedResult<AuditLogEntry>> {\n const { limit = 50, offset = 0 } = pagination\n const conditions = this.buildFilterConditions(filter)\n\n const [rows, [countResult]] = await Promise.all([\n this.db\n .select()\n .from(paymentAuditLog)\n .where(conditions.length > 0 ? and(...conditions) : undefined)\n .orderBy(sql`${paymentAuditLog.created_at} DESC`)\n .limit(limit)\n .offset(offset),\n this.db\n .select({ total: count() })\n .from(paymentAuditLog)\n .where(conditions.length > 0 ? and(...conditions) : undefined),\n ])\n\n const entries = rows.map(mapToAuditLogEntry)\n return applyPagination(entries, countResult?.total ?? 0, limit, offset)\n }\n\n async findByCorrelationId(correlationId: string): Promise<AuditLogEntry[]> {\n const result = await this.db\n .select()\n .from(paymentAuditLog)\n .where(eq(paymentAuditLog.correlation_id, correlationId))\n .orderBy(sql`${paymentAuditLog.created_at} ASC`)\n\n return result.map(mapToAuditLogEntry)\n }\n\n async getTransactionHistory(transactionId: string): Promise<AuditLogEntry[]> {\n const result = await this.db\n .select()\n .from(paymentAuditLog)\n .where(eq(paymentAuditLog.transaction_id, transactionId))\n .orderBy(sql`${paymentAuditLog.created_at} ASC`)\n\n return result.map(mapToAuditLogEntry)\n }\n\n async countByAction(filter: AuditLogFilter = {}): Promise<Record<AuditLogAction, number>> {\n const conditions = this.buildFilterConditions(filter)\n\n const result = await this.db\n .select({\n action: paymentAuditLog.action,\n count: count(),\n })\n .from(paymentAuditLog)\n .where(conditions.length > 0 ? and(...conditions) : undefined)\n .groupBy(paymentAuditLog.action)\n\n const counts: Record<AuditLogAction, number> = {\n created: 0,\n status_changed: 0,\n authorized: 0,\n captured: 0,\n voided: 0,\n refund_initiated: 0,\n refund_completed: 0,\n webhook_received: 0,\n webhook_processed: 0,\n error_occurred: 0,\n retry_attempted: 0,\n manual_intervention: 0,\n }\n\n for (const row of result) {\n counts[row.action as AuditLogAction] = row.count\n }\n\n return counts\n }\n\n // ============================================================================\n // Private Helpers\n // ============================================================================\n\n private buildFilterConditions(filter: AuditLogFilter) {\n const conditions = []\n\n if (filter.transactionId) {\n conditions.push(eq(paymentAuditLog.transaction_id, filter.transactionId))\n }\n\n if (filter.correlationId) {\n conditions.push(eq(paymentAuditLog.correlation_id, filter.correlationId))\n }\n\n if (filter.triggeredById) {\n conditions.push(eq(paymentAuditLog.triggered_by_id, filter.triggeredById))\n }\n\n const actions = normalizeArrayFilter(filter.action)\n if (actions && actions.length > 0) {\n conditions.push(inArray(paymentAuditLog.action, actions))\n }\n\n const triggers = normalizeArrayFilter(filter.triggeredBy)\n if (triggers && triggers.length > 0) {\n conditions.push(inArray(paymentAuditLog.triggered_by, triggers))\n }\n\n if (filter.dateRange?.from) {\n conditions.push(gte(paymentAuditLog.created_at, filter.dateRange.from))\n }\n if (filter.dateRange?.to) {\n conditions.push(lte(paymentAuditLog.created_at, filter.dateRange.to))\n }\n\n return conditions\n }\n}\n","/**\n * @nehorai/payments-drizzle - Drizzle Provider Health Repository\n *\n * Implements IProviderHealthRepository using Drizzle ORM.\n * Manages circuit breaker state and provider metrics.\n */\n\nimport { eq, or, sql } from 'drizzle-orm'\nimport type { DrizzleDB } from './base-drizzle.repository.js'\nimport { parseNumeric } from './base-drizzle.repository.js'\nimport { providerHealth } from '../schema/index.js'\nimport type {\n IProviderHealthRepository,\n ProviderHealth,\n UpdateProviderHealthInput,\n HealthCheckResult,\n CircuitBreakerState,\n ProviderName,\n} from '@nehorai/payments/repository'\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Map database row to ProviderHealth entity\n */\nfunction mapToProviderHealth(row: typeof providerHealth.$inferSelect): ProviderHealth {\n return {\n id: row.id,\n provider: row.provider as ProviderName,\n circuitState: row.circuit_state as CircuitBreakerState,\n failureCount: parseInt(row.failure_count ?? '0', 10),\n successCount: parseInt(row.success_count ?? '0', 10),\n lastFailureAt: row.last_failure_at,\n lastSuccessAt: row.last_success_at,\n circuitOpenedAt: row.circuit_opened_at,\n nextRetryAt: row.next_retry_at,\n avgLatencyMs: row.avg_latency_ms ? parseNumeric(row.avg_latency_ms) : null,\n errorRate: row.error_rate ? parseNumeric(row.error_rate) : null,\n requestCountWindow: parseInt(row.request_count_window ?? '0', 10),\n lastHealthCheckAt: row.last_health_check_at,\n healthCheckResult: row.health_check_result as HealthCheckResult | null,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n }\n}\n\n// ============================================================================\n// Repository Implementation\n// ============================================================================\n\n/**\n * Drizzle implementation of IProviderHealthRepository\n */\nexport class DrizzleProviderHealthRepository implements IProviderHealthRepository {\n constructor(private db: DrizzleDB) {}\n\n async findByProvider(provider: ProviderName): Promise<ProviderHealth | null> {\n const result = await this.db\n .select()\n .from(providerHealth)\n .where(eq(providerHealth.provider, provider))\n .limit(1)\n\n return result[0] ? mapToProviderHealth(result[0]) : null\n }\n\n async getOrCreate(provider: ProviderName): Promise<ProviderHealth> {\n const existing = await this.findByProvider(provider)\n if (existing) return existing\n\n const result = await this.db\n .insert(providerHealth)\n .values({\n provider,\n circuit_state: 'closed',\n })\n .returning()\n\n return mapToProviderHealth(result[0])\n }\n\n async update(\n provider: ProviderName,\n data: UpdateProviderHealthInput\n ): Promise<ProviderHealth | null> {\n const updateData: Partial<typeof providerHealth.$inferInsert> = {\n updated_at: new Date(),\n }\n\n if (data.circuitState !== undefined) updateData.circuit_state = data.circuitState\n if (data.failureCount !== undefined) updateData.failure_count = String(data.failureCount)\n if (data.successCount !== undefined) updateData.success_count = String(data.successCount)\n if (data.lastFailureAt !== undefined) updateData.last_failure_at = data.lastFailureAt\n if (data.lastSuccessAt !== undefined) updateData.last_success_at = data.lastSuccessAt\n if (data.circuitOpenedAt !== undefined) updateData.circuit_opened_at = data.circuitOpenedAt\n if (data.nextRetryAt !== undefined) updateData.next_retry_at = data.nextRetryAt\n if (data.avgLatencyMs !== undefined) updateData.avg_latency_ms = String(data.avgLatencyMs)\n if (data.errorRate !== undefined) updateData.error_rate = String(data.errorRate)\n if (data.requestCountWindow !== undefined)\n updateData.request_count_window = String(data.requestCountWindow)\n if (data.lastHealthCheckAt !== undefined)\n updateData.last_health_check_at = data.lastHealthCheckAt\n if (data.healthCheckResult !== undefined)\n updateData.health_check_result = data.healthCheckResult\n\n const result = await this.db\n .update(providerHealth)\n .set(updateData)\n .where(eq(providerHealth.provider, provider))\n .returning()\n\n return result[0] ? mapToProviderHealth(result[0]) : null\n }\n\n async findAll(): Promise<ProviderHealth[]> {\n const result = await this.db\n .select()\n .from(providerHealth)\n .orderBy(sql`${providerHealth.provider} ASC`)\n\n return result.map(mapToProviderHealth)\n }\n\n async recordSuccess(provider: ProviderName, latencyMs: number): Promise<void> {\n await this.getOrCreate(provider)\n\n await this.db\n .update(providerHealth)\n .set({\n success_count: sql`CAST(${providerHealth.success_count} AS INTEGER) + 1`,\n request_count_window: sql`CAST(${providerHealth.request_count_window} AS INTEGER) + 1`,\n last_success_at: new Date(),\n avg_latency_ms: sql`CASE\n WHEN ${providerHealth.avg_latency_ms} IS NULL THEN ${latencyMs}\n ELSE (CAST(${providerHealth.avg_latency_ms} AS DECIMAL) * 0.9 + ${latencyMs} * 0.1)\n END`,\n updated_at: new Date(),\n })\n .where(eq(providerHealth.provider, provider))\n }\n\n async recordFailure(provider: ProviderName, error?: string): Promise<void> {\n await this.getOrCreate(provider)\n\n const updateData: Partial<typeof providerHealth.$inferInsert> = {\n last_failure_at: new Date(),\n updated_at: new Date(),\n }\n\n // Store error in health check result if provided\n if (error) {\n updateData.health_check_result = { healthy: false, error }\n }\n\n await this.db\n .update(providerHealth)\n .set({\n ...updateData,\n failure_count: sql`CAST(${providerHealth.failure_count} AS INTEGER) + 1`,\n request_count_window: sql`CAST(${providerHealth.request_count_window} AS INTEGER) + 1`,\n })\n .where(eq(providerHealth.provider, provider))\n }\n\n async openCircuit(provider: ProviderName, retryAfterMs: number): Promise<void> {\n const now = new Date()\n const nextRetry = new Date(now.getTime() + retryAfterMs)\n\n await this.getOrCreate(provider)\n\n await this.db\n .update(providerHealth)\n .set({\n circuit_state: 'open',\n circuit_opened_at: now,\n next_retry_at: nextRetry,\n updated_at: now,\n })\n .where(eq(providerHealth.provider, provider))\n }\n\n async closeCircuit(provider: ProviderName): Promise<void> {\n await this.db\n .update(providerHealth)\n .set({\n circuit_state: 'closed',\n circuit_opened_at: null,\n next_retry_at: null,\n failure_count: '0',\n updated_at: new Date(),\n })\n .where(eq(providerHealth.provider, provider))\n }\n\n async halfOpenCircuit(provider: ProviderName): Promise<void> {\n await this.db\n .update(providerHealth)\n .set({\n circuit_state: 'half_open',\n updated_at: new Date(),\n })\n .where(eq(providerHealth.provider, provider))\n }\n\n async updateHealthCheck(provider: ProviderName, result: HealthCheckResult): Promise<void> {\n await this.getOrCreate(provider)\n\n await this.db\n .update(providerHealth)\n .set({\n last_health_check_at: new Date(),\n health_check_result: result,\n updated_at: new Date(),\n })\n .where(eq(providerHealth.provider, provider))\n }\n\n async findOpenCircuits(): Promise<ProviderHealth[]> {\n const result = await this.db\n .select()\n .from(providerHealth)\n .where(eq(providerHealth.circuit_state, 'open'))\n\n return result.map(mapToProviderHealth)\n }\n\n async findReadyForRetry(): Promise<ProviderHealth[]> {\n const now = new Date()\n\n const result = await this.db\n .select()\n .from(providerHealth)\n .where(\n or(\n eq(providerHealth.circuit_state, 'half_open'),\n sql`${providerHealth.circuit_state} = 'open' AND ${providerHealth.next_retry_at} <= ${now}`\n )\n )\n\n return result.map(mapToProviderHealth)\n }\n\n async resetStats(provider: ProviderName): Promise<void> {\n await this.db\n .update(providerHealth)\n .set({\n failure_count: '0',\n success_count: '0',\n request_count_window: '0',\n avg_latency_ms: null,\n error_rate: null,\n updated_at: new Date(),\n })\n .where(eq(providerHealth.provider, provider))\n }\n\n async updateErrorRate(provider: ProviderName): Promise<number> {\n const health = await this.findByProvider(provider)\n if (!health || health.requestCountWindow === 0) return 0\n\n const errorRate = health.failureCount / health.requestCountWindow\n\n await this.db\n .update(providerHealth)\n .set({\n error_rate: String(errorRate),\n updated_at: new Date(),\n })\n .where(eq(providerHealth.provider, provider))\n\n return errorRate\n }\n}\n","/**\n * @nehorai/payments-drizzle - Repository Exports\n *\n * All Drizzle ORM repository implementations and factory function.\n */\n\n// Base utilities\nexport {\n type DrizzleDB,\n toCamelCase,\n toSnakeCase,\n applyPagination,\n parseNumeric,\n normalizeArrayFilter,\n} from './base-drizzle.repository.js'\n\n// Repository implementations\nexport { DrizzleTransactionRepository } from './transaction.drizzle-repository.js'\nexport { DrizzlePaymentMethodRepository } from './payment-method.drizzle-repository.js'\nexport { DrizzleWebhookEventRepository } from './webhook-event.drizzle-repository.js'\nexport { DrizzleAuditLogRepository } from './audit-log.drizzle-repository.js'\nexport { DrizzleProviderHealthRepository } from './provider-health.drizzle-repository.js'\n\n// Factory function for creating all repositories\nimport type { DrizzleDB } from './base-drizzle.repository.js'\nimport type { IPaymentRepositories } from '@nehorai/payments/repository'\nimport { DrizzleTransactionRepository } from './transaction.drizzle-repository.js'\nimport { DrizzlePaymentMethodRepository } from './payment-method.drizzle-repository.js'\nimport { DrizzleWebhookEventRepository } from './webhook-event.drizzle-repository.js'\nimport { DrizzleAuditLogRepository } from './audit-log.drizzle-repository.js'\nimport { DrizzleProviderHealthRepository } from './provider-health.drizzle-repository.js'\n\n/**\n * Create all Drizzle repositories with a single database instance\n */\nexport function createDrizzleRepositories(db: DrizzleDB): IPaymentRepositories {\n return {\n transactions: new DrizzleTransactionRepository(db),\n paymentMethods: new DrizzlePaymentMethodRepository(db),\n webhookEvents: new DrizzleWebhookEventRepository(db),\n auditLog: new DrizzleAuditLogRepository(db),\n providerHealth: new DrizzleProviderHealthRepository(db),\n }\n}\n"],"mappings":"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","names":["pgTable","uuid","text","timestamp","jsonb","index","pgTable","uuid","text","timestamp","jsonb","index","unique","pgTable","uuid","text","timestamp","jsonb","index","pgTable","uuid","text","numeric","timestamp","jsonb","index","unique","eq","and","inArray","sql","count","eq","and","inArray","sql","count","eq","and","gte","lte","inArray","sql","count","eq","and","sql","count","inArray","gte","lte","eq","and","inArray","sql","count","gte","lte","eq","sql","count","and","inArray","gte","lte","eq","sql","eq","sql"]}
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/schema/index.ts
|
|
21
|
+
var schema_exports = {};
|
|
22
|
+
__export(schema_exports, {
|
|
23
|
+
paymentAuditLog: () => paymentAuditLog,
|
|
24
|
+
paymentMethods: () => paymentMethods,
|
|
25
|
+
paymentTransactions: () => paymentTransactions,
|
|
26
|
+
paymentWebhookEvents: () => paymentWebhookEvents,
|
|
27
|
+
providerHealth: () => providerHealth
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(schema_exports);
|
|
30
|
+
|
|
31
|
+
// src/schema/payment-transactions.ts
|
|
32
|
+
var import_pg_core = require("drizzle-orm/pg-core");
|
|
33
|
+
var paymentTransactions = (0, import_pg_core.pgTable)(
|
|
34
|
+
"payment_transactions",
|
|
35
|
+
{
|
|
36
|
+
id: (0, import_pg_core.uuid)("id").defaultRandom().primaryKey(),
|
|
37
|
+
// Idempotency - prevents duplicate charges
|
|
38
|
+
internal_payment_id: (0, import_pg_core.text)("internal_payment_id").notNull(),
|
|
39
|
+
idempotency_key: (0, import_pg_core.text)("idempotency_key"),
|
|
40
|
+
// User association (FK configured at application level)
|
|
41
|
+
user_id: (0, import_pg_core.uuid)("user_id").notNull(),
|
|
42
|
+
// Transaction classification
|
|
43
|
+
transaction_type: (0, import_pg_core.text)("transaction_type").$type().notNull(),
|
|
44
|
+
status: (0, import_pg_core.text)("status").$type().notNull().default("created"),
|
|
45
|
+
// Amounts in smallest currency unit (cents/agorot)
|
|
46
|
+
amount_minor: (0, import_pg_core.numeric)("amount_minor").notNull(),
|
|
47
|
+
currency: (0, import_pg_core.text)("currency").notNull().default("USD"),
|
|
48
|
+
// Original amount if currency converted
|
|
49
|
+
original_amount_minor: (0, import_pg_core.numeric)("original_amount_minor"),
|
|
50
|
+
original_currency: (0, import_pg_core.text)("original_currency"),
|
|
51
|
+
currency_conversion_rate: (0, import_pg_core.numeric)("currency_conversion_rate"),
|
|
52
|
+
// Provider information
|
|
53
|
+
provider: (0, import_pg_core.text)("provider").notNull(),
|
|
54
|
+
// stripe, hyp, cardcom
|
|
55
|
+
provider_transaction_id: (0, import_pg_core.text)("provider_transaction_id"),
|
|
56
|
+
provider_authorization_code: (0, import_pg_core.text)("provider_authorization_code"),
|
|
57
|
+
provider_metadata: (0, import_pg_core.jsonb)("provider_metadata").$type(),
|
|
58
|
+
// Two-phase commit tracking (J5)
|
|
59
|
+
authorized_at: (0, import_pg_core.timestamp)("authorized_at", { withTimezone: true }),
|
|
60
|
+
captured_at: (0, import_pg_core.timestamp)("captured_at", { withTimezone: true }),
|
|
61
|
+
voided_at: (0, import_pg_core.timestamp)("voided_at", { withTimezone: true }),
|
|
62
|
+
capture_deadline: (0, import_pg_core.timestamp)("capture_deadline", { withTimezone: true }),
|
|
63
|
+
// Refund tracking
|
|
64
|
+
refunded_amount_minor: (0, import_pg_core.numeric)("refunded_amount_minor").default("0"),
|
|
65
|
+
last_refund_at: (0, import_pg_core.timestamp)("last_refund_at", { withTimezone: true }),
|
|
66
|
+
// Tax invoice (Israeli requirement)
|
|
67
|
+
tax_invoice_status: (0, import_pg_core.text)("tax_invoice_status").$type().default("pending"),
|
|
68
|
+
tax_invoice_number: (0, import_pg_core.text)("tax_invoice_number"),
|
|
69
|
+
tax_invoice_url: (0, import_pg_core.text)("tax_invoice_url"),
|
|
70
|
+
// Error tracking
|
|
71
|
+
failure_code: (0, import_pg_core.text)("failure_code"),
|
|
72
|
+
failure_message: (0, import_pg_core.text)("failure_message"),
|
|
73
|
+
failure_details: (0, import_pg_core.jsonb)("failure_details"),
|
|
74
|
+
// Application metadata
|
|
75
|
+
description: (0, import_pg_core.text)("description"),
|
|
76
|
+
metadata: (0, import_pg_core.jsonb)("metadata").$type(),
|
|
77
|
+
// Timestamps
|
|
78
|
+
created_at: (0, import_pg_core.timestamp)("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
79
|
+
updated_at: (0, import_pg_core.timestamp)("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
80
|
+
},
|
|
81
|
+
(table) => ({
|
|
82
|
+
// Performance indexes
|
|
83
|
+
userIdx: (0, import_pg_core.index)("payment_transactions_user_idx").on(table.user_id),
|
|
84
|
+
statusIdx: (0, import_pg_core.index)("payment_transactions_status_idx").on(table.status),
|
|
85
|
+
providerIdx: (0, import_pg_core.index)("payment_transactions_provider_idx").on(table.provider),
|
|
86
|
+
providerTxIdx: (0, import_pg_core.index)("payment_transactions_provider_tx_idx").on(table.provider_transaction_id),
|
|
87
|
+
createdAtIdx: (0, import_pg_core.index)("payment_transactions_created_at_idx").on(table.created_at),
|
|
88
|
+
// Unique constraints for idempotency
|
|
89
|
+
internalIdUnique: (0, import_pg_core.unique)("payment_transactions_internal_id_unique").on(
|
|
90
|
+
table.internal_payment_id
|
|
91
|
+
),
|
|
92
|
+
idempotencyUnique: (0, import_pg_core.unique)("payment_transactions_idempotency_unique").on(table.idempotency_key)
|
|
93
|
+
})
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
// src/schema/payment-methods.ts
|
|
97
|
+
var import_pg_core2 = require("drizzle-orm/pg-core");
|
|
98
|
+
var paymentMethods = (0, import_pg_core2.pgTable)(
|
|
99
|
+
"payment_methods",
|
|
100
|
+
{
|
|
101
|
+
id: (0, import_pg_core2.uuid)("id").defaultRandom().primaryKey(),
|
|
102
|
+
// User association (FK configured at application level)
|
|
103
|
+
user_id: (0, import_pg_core2.uuid)("user_id").notNull(),
|
|
104
|
+
// Method type
|
|
105
|
+
type: (0, import_pg_core2.text)("type").$type().notNull(),
|
|
106
|
+
// Provider information
|
|
107
|
+
provider: (0, import_pg_core2.text)("provider").notNull(),
|
|
108
|
+
// stripe, hyp, cardcom
|
|
109
|
+
provider_payment_method_id: (0, import_pg_core2.text)("provider_payment_method_id").notNull(),
|
|
110
|
+
// Card details (tokenized, never full numbers)
|
|
111
|
+
card_brand: (0, import_pg_core2.text)("card_brand").$type(),
|
|
112
|
+
card_last4: (0, import_pg_core2.text)("card_last4"),
|
|
113
|
+
card_exp_month: (0, import_pg_core2.text)("card_exp_month"),
|
|
114
|
+
card_exp_year: (0, import_pg_core2.text)("card_exp_year"),
|
|
115
|
+
card_bin: (0, import_pg_core2.text)("card_bin"),
|
|
116
|
+
// First 6-8 digits for routing
|
|
117
|
+
// State
|
|
118
|
+
is_default: (0, import_pg_core2.boolean)("is_default").default(false),
|
|
119
|
+
is_active: (0, import_pg_core2.boolean)("is_active").default(true),
|
|
120
|
+
// Provider-specific data
|
|
121
|
+
provider_metadata: (0, import_pg_core2.jsonb)("provider_metadata").$type(),
|
|
122
|
+
// Timestamps
|
|
123
|
+
created_at: (0, import_pg_core2.timestamp)("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
124
|
+
updated_at: (0, import_pg_core2.timestamp)("updated_at", { withTimezone: true }).notNull().defaultNow(),
|
|
125
|
+
last_used_at: (0, import_pg_core2.timestamp)("last_used_at", { withTimezone: true })
|
|
126
|
+
},
|
|
127
|
+
(table) => ({
|
|
128
|
+
// Performance indexes
|
|
129
|
+
userIdx: (0, import_pg_core2.index)("payment_methods_user_idx").on(table.user_id),
|
|
130
|
+
userDefaultIdx: (0, import_pg_core2.index)("payment_methods_user_default_idx").on(table.user_id, table.is_default),
|
|
131
|
+
providerIdx: (0, import_pg_core2.index)("payment_methods_provider_idx").on(table.provider),
|
|
132
|
+
providerMethodIdx: (0, import_pg_core2.index)("payment_methods_provider_method_idx").on(
|
|
133
|
+
table.provider_payment_method_id
|
|
134
|
+
),
|
|
135
|
+
cardBinIdx: (0, import_pg_core2.index)("payment_methods_card_bin_idx").on(table.card_bin)
|
|
136
|
+
})
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
// src/schema/webhook-events.ts
|
|
140
|
+
var import_pg_core3 = require("drizzle-orm/pg-core");
|
|
141
|
+
var paymentWebhookEvents = (0, import_pg_core3.pgTable)(
|
|
142
|
+
"payment_webhook_events",
|
|
143
|
+
{
|
|
144
|
+
id: (0, import_pg_core3.uuid)("id").defaultRandom().primaryKey(),
|
|
145
|
+
// Event identification
|
|
146
|
+
provider: (0, import_pg_core3.text)("provider").notNull(),
|
|
147
|
+
// stripe, hyp, cardcom
|
|
148
|
+
provider_event_id: (0, import_pg_core3.text)("provider_event_id").notNull(),
|
|
149
|
+
event_type: (0, import_pg_core3.text)("event_type").notNull(),
|
|
150
|
+
// Processing state
|
|
151
|
+
status: (0, import_pg_core3.text)("status").$type().notNull().default("pending"),
|
|
152
|
+
attempts: (0, import_pg_core3.text)("attempts").default("0"),
|
|
153
|
+
last_attempt_at: (0, import_pg_core3.timestamp)("last_attempt_at", { withTimezone: true }),
|
|
154
|
+
// Linked transaction (if applicable)
|
|
155
|
+
transaction_id: (0, import_pg_core3.uuid)("transaction_id"),
|
|
156
|
+
// Event payload (store for debugging and retry)
|
|
157
|
+
payload: (0, import_pg_core3.jsonb)("payload").$type().notNull(),
|
|
158
|
+
signature: (0, import_pg_core3.text)("signature"),
|
|
159
|
+
// Error tracking
|
|
160
|
+
error_message: (0, import_pg_core3.text)("error_message"),
|
|
161
|
+
error_details: (0, import_pg_core3.jsonb)("error_details"),
|
|
162
|
+
// Timestamps
|
|
163
|
+
received_at: (0, import_pg_core3.timestamp)("received_at", { withTimezone: true }).notNull().defaultNow(),
|
|
164
|
+
processed_at: (0, import_pg_core3.timestamp)("processed_at", { withTimezone: true }),
|
|
165
|
+
created_at: (0, import_pg_core3.timestamp)("created_at", { withTimezone: true }).notNull().defaultNow()
|
|
166
|
+
},
|
|
167
|
+
(table) => ({
|
|
168
|
+
// Unique constraint for idempotency
|
|
169
|
+
providerEventUnique: (0, import_pg_core3.unique)("webhook_events_provider_event_unique").on(
|
|
170
|
+
table.provider,
|
|
171
|
+
table.provider_event_id
|
|
172
|
+
),
|
|
173
|
+
// Performance indexes
|
|
174
|
+
statusIdx: (0, import_pg_core3.index)("webhook_events_status_idx").on(table.status),
|
|
175
|
+
transactionIdx: (0, import_pg_core3.index)("webhook_events_transaction_idx").on(
|
|
176
|
+
table.transaction_id
|
|
177
|
+
),
|
|
178
|
+
receivedAtIdx: (0, import_pg_core3.index)("webhook_events_received_at_idx").on(table.received_at),
|
|
179
|
+
providerIdx: (0, import_pg_core3.index)("webhook_events_provider_idx").on(table.provider),
|
|
180
|
+
eventTypeIdx: (0, import_pg_core3.index)("webhook_events_event_type_idx").on(table.event_type)
|
|
181
|
+
})
|
|
182
|
+
);
|
|
183
|
+
|
|
184
|
+
// src/schema/payment-audit-log.ts
|
|
185
|
+
var import_pg_core4 = require("drizzle-orm/pg-core");
|
|
186
|
+
var paymentAuditLog = (0, import_pg_core4.pgTable)(
|
|
187
|
+
"payment_audit_log",
|
|
188
|
+
{
|
|
189
|
+
id: (0, import_pg_core4.uuid)("id").defaultRandom().primaryKey(),
|
|
190
|
+
// What transaction was affected
|
|
191
|
+
transaction_id: (0, import_pg_core4.uuid)("transaction_id").notNull(),
|
|
192
|
+
// What action occurred
|
|
193
|
+
action: (0, import_pg_core4.text)("action").$type().notNull(),
|
|
194
|
+
// State before and after
|
|
195
|
+
previous_state: (0, import_pg_core4.jsonb)("previous_state"),
|
|
196
|
+
new_state: (0, import_pg_core4.jsonb)("new_state").notNull(),
|
|
197
|
+
// Who/what triggered this change
|
|
198
|
+
triggered_by: (0, import_pg_core4.text)("triggered_by").$type().notNull(),
|
|
199
|
+
triggered_by_id: (0, import_pg_core4.uuid)("triggered_by_id"),
|
|
200
|
+
// User ID if applicable
|
|
201
|
+
// Request context
|
|
202
|
+
ip_address: (0, import_pg_core4.text)("ip_address"),
|
|
203
|
+
user_agent: (0, import_pg_core4.text)("user_agent"),
|
|
204
|
+
// Correlation for distributed tracing
|
|
205
|
+
correlation_id: (0, import_pg_core4.text)("correlation_id"),
|
|
206
|
+
// Additional context
|
|
207
|
+
metadata: (0, import_pg_core4.jsonb)("metadata").$type(),
|
|
208
|
+
// Immutable timestamp (never updated)
|
|
209
|
+
created_at: (0, import_pg_core4.timestamp)("created_at", { withTimezone: true }).notNull().defaultNow()
|
|
210
|
+
},
|
|
211
|
+
(table) => ({
|
|
212
|
+
// Performance indexes
|
|
213
|
+
transactionIdx: (0, import_pg_core4.index)("payment_audit_log_transaction_idx").on(
|
|
214
|
+
table.transaction_id
|
|
215
|
+
),
|
|
216
|
+
actionIdx: (0, import_pg_core4.index)("payment_audit_log_action_idx").on(table.action),
|
|
217
|
+
correlationIdx: (0, import_pg_core4.index)("payment_audit_log_correlation_idx").on(
|
|
218
|
+
table.correlation_id
|
|
219
|
+
),
|
|
220
|
+
createdAtIdx: (0, import_pg_core4.index)("payment_audit_log_created_at_idx").on(table.created_at),
|
|
221
|
+
triggeredByIdx: (0, import_pg_core4.index)("payment_audit_log_triggered_by_idx").on(
|
|
222
|
+
table.triggered_by
|
|
223
|
+
)
|
|
224
|
+
})
|
|
225
|
+
);
|
|
226
|
+
|
|
227
|
+
// src/schema/provider-health.ts
|
|
228
|
+
var import_pg_core5 = require("drizzle-orm/pg-core");
|
|
229
|
+
var providerHealth = (0, import_pg_core5.pgTable)(
|
|
230
|
+
"payment_provider_health",
|
|
231
|
+
{
|
|
232
|
+
id: (0, import_pg_core5.uuid)("id").defaultRandom().primaryKey(),
|
|
233
|
+
// Provider identification
|
|
234
|
+
provider: (0, import_pg_core5.text)("provider").notNull(),
|
|
235
|
+
// stripe, hyp, cardcom
|
|
236
|
+
// Circuit breaker state
|
|
237
|
+
circuit_state: (0, import_pg_core5.text)("circuit_state").$type().notNull().default("closed"),
|
|
238
|
+
// Failure tracking
|
|
239
|
+
failure_count: (0, import_pg_core5.text)("failure_count").default("0"),
|
|
240
|
+
success_count: (0, import_pg_core5.text)("success_count").default("0"),
|
|
241
|
+
last_failure_at: (0, import_pg_core5.timestamp)("last_failure_at", { withTimezone: true }),
|
|
242
|
+
last_success_at: (0, import_pg_core5.timestamp)("last_success_at", { withTimezone: true }),
|
|
243
|
+
// Circuit breaker timing
|
|
244
|
+
circuit_opened_at: (0, import_pg_core5.timestamp)("circuit_opened_at", { withTimezone: true }),
|
|
245
|
+
next_retry_at: (0, import_pg_core5.timestamp)("next_retry_at", { withTimezone: true }),
|
|
246
|
+
// Performance metrics
|
|
247
|
+
avg_latency_ms: (0, import_pg_core5.numeric)("avg_latency_ms"),
|
|
248
|
+
error_rate: (0, import_pg_core5.numeric)("error_rate"),
|
|
249
|
+
// 0-1
|
|
250
|
+
request_count_window: (0, import_pg_core5.text)("request_count_window").default("0"),
|
|
251
|
+
// Health check results
|
|
252
|
+
last_health_check_at: (0, import_pg_core5.timestamp)("last_health_check_at", { withTimezone: true }),
|
|
253
|
+
health_check_result: (0, import_pg_core5.jsonb)("health_check_result").$type(),
|
|
254
|
+
// Timestamps
|
|
255
|
+
created_at: (0, import_pg_core5.timestamp)("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
256
|
+
updated_at: (0, import_pg_core5.timestamp)("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
257
|
+
},
|
|
258
|
+
(table) => ({
|
|
259
|
+
// One record per provider
|
|
260
|
+
providerUnique: (0, import_pg_core5.unique)("provider_health_provider_unique").on(table.provider),
|
|
261
|
+
// Performance indexes
|
|
262
|
+
circuitStateIdx: (0, import_pg_core5.index)("provider_health_circuit_state_idx").on(
|
|
263
|
+
table.circuit_state
|
|
264
|
+
),
|
|
265
|
+
nextRetryIdx: (0, import_pg_core5.index)("provider_health_next_retry_idx").on(table.next_retry_at)
|
|
266
|
+
})
|
|
267
|
+
);
|
|
268
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
269
|
+
0 && (module.exports = {
|
|
270
|
+
paymentAuditLog,
|
|
271
|
+
paymentMethods,
|
|
272
|
+
paymentTransactions,
|
|
273
|
+
paymentWebhookEvents,
|
|
274
|
+
providerHealth
|
|
275
|
+
});
|
|
276
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/schema/index.ts","../../src/schema/payment-transactions.ts","../../src/schema/payment-methods.ts","../../src/schema/webhook-events.ts","../../src/schema/payment-audit-log.ts","../../src/schema/provider-health.ts"],"sourcesContent":["/**\n * @nehorai/payments-drizzle - Schema Exports\n *\n * Central export for all payment-related database tables.\n */\n\n// Payment transactions\nexport {\n paymentTransactions,\n type PaymentTransactionStatus,\n type PaymentTransactionType,\n type PaymentTaxInvoiceStatus,\n} from './payment-transactions.js'\n\n// Payment methods\nexport {\n paymentMethods,\n type PaymentMethodType,\n type CardBrandType,\n} from './payment-methods.js'\n\n// Webhook events\nexport {\n paymentWebhookEvents,\n type WebhookEventStatus,\n} from './webhook-events.js'\n\n// Audit log\nexport {\n paymentAuditLog,\n type AuditLogAction,\n type AuditLogTrigger,\n} from './payment-audit-log.js'\n\n// Provider health / circuit breaker\nexport {\n providerHealth,\n type CircuitBreakerState,\n} from './provider-health.js'\n","/**\r\n * PaymentOS - Payment Transactions Schema\r\n *\r\n * Core table for tracking all payment operations.\r\n * Implements Two-Phase Commit (J5) pattern with authorize/capture flow.\r\n *\r\n * Note: User FK is optional and configured via schema-config.ts\r\n */\r\n\r\nimport { pgTable, uuid, text, numeric, timestamp, jsonb, index, unique } from 'drizzle-orm/pg-core'\r\n\r\n// ============================================================================\r\n// Type Definitions\r\n// ============================================================================\r\n\r\n/**\r\n * Payment transaction states (strict state machine)\r\n * @see src/lib/payments/types/state-machine.ts for transition rules\r\n */\r\nexport type PaymentTransactionStatus =\r\n | 'created'\r\n | 'pending_authorization'\r\n | 'authorized'\r\n | 'capturing'\r\n | 'captured'\r\n | 'voided'\r\n | 'failed'\r\n | 'expired'\r\n | 'partially_refunded'\r\n | 'fully_refunded'\r\n\r\n/**\r\n * Payment transaction types\r\n */\r\nexport type PaymentTransactionType =\r\n | 'one_time_purchase'\r\n | 'subscription_initial'\r\n | 'subscription_renewal'\r\n | 'refund'\r\n\r\n/**\r\n * Tax invoice status (Israeli compliance)\r\n */\r\nexport type PaymentTaxInvoiceStatus = 'pending' | 'generated' | 'sent' | 'failed'\r\n\r\n// ============================================================================\r\n// Schema Definition\r\n// ============================================================================\r\n\r\n/**\r\n * Payment transactions table\r\n *\r\n * FK to user table is NOT defined here - it's application-specific.\r\n * The user_id column stores the UUID, but the FK constraint should be\r\n * added via migration if needed for your specific user table.\r\n *\r\n * To add FK constraint, create a migration:\r\n * ```sql\r\n * ALTER TABLE payment_transactions\r\n * ADD CONSTRAINT payment_transactions_user_id_fkey\r\n * FOREIGN KEY (user_id) REFERENCES your_users_table(id) ON DELETE CASCADE;\r\n * ```\r\n */\r\nexport const paymentTransactions = pgTable(\r\n 'payment_transactions',\r\n {\r\n id: uuid('id').defaultRandom().primaryKey(),\r\n\r\n // Idempotency - prevents duplicate charges\r\n internal_payment_id: text('internal_payment_id').notNull(),\r\n idempotency_key: text('idempotency_key'),\r\n\r\n // User association (FK configured at application level)\r\n user_id: uuid('user_id').notNull(),\r\n\r\n // Transaction classification\r\n transaction_type: text('transaction_type').$type<PaymentTransactionType>().notNull(),\r\n status: text('status').$type<PaymentTransactionStatus>().notNull().default('created'),\r\n\r\n // Amounts in smallest currency unit (cents/agorot)\r\n amount_minor: numeric('amount_minor').notNull(),\r\n currency: text('currency').notNull().default('USD'),\r\n\r\n // Original amount if currency converted\r\n original_amount_minor: numeric('original_amount_minor'),\r\n original_currency: text('original_currency'),\r\n currency_conversion_rate: numeric('currency_conversion_rate'),\r\n\r\n // Provider information\r\n provider: text('provider').notNull(), // stripe, hyp, cardcom\r\n provider_transaction_id: text('provider_transaction_id'),\r\n provider_authorization_code: text('provider_authorization_code'),\r\n provider_metadata: jsonb('provider_metadata').$type<Record<string, unknown>>(),\r\n\r\n // Two-phase commit tracking (J5)\r\n authorized_at: timestamp('authorized_at', { withTimezone: true }),\r\n captured_at: timestamp('captured_at', { withTimezone: true }),\r\n voided_at: timestamp('voided_at', { withTimezone: true }),\r\n capture_deadline: timestamp('capture_deadline', { withTimezone: true }),\r\n\r\n // Refund tracking\r\n refunded_amount_minor: numeric('refunded_amount_minor').default('0'),\r\n last_refund_at: timestamp('last_refund_at', { withTimezone: true }),\r\n\r\n // Tax invoice (Israeli requirement)\r\n tax_invoice_status: text('tax_invoice_status')\r\n .$type<PaymentTaxInvoiceStatus>()\r\n .default('pending'),\r\n tax_invoice_number: text('tax_invoice_number'),\r\n tax_invoice_url: text('tax_invoice_url'),\r\n\r\n // Error tracking\r\n failure_code: text('failure_code'),\r\n failure_message: text('failure_message'),\r\n failure_details: jsonb('failure_details'),\r\n\r\n // Application metadata\r\n description: text('description'),\r\n metadata: jsonb('metadata').$type<{\r\n credit_package_id?: string\r\n subscription_plan_id?: string\r\n credits_amount?: number\r\n [key: string]: unknown\r\n }>(),\r\n\r\n // Timestamps\r\n created_at: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),\r\n updated_at: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),\r\n },\r\n (table) => ({\r\n // Performance indexes\r\n userIdx: index('payment_transactions_user_idx').on(table.user_id),\r\n statusIdx: index('payment_transactions_status_idx').on(table.status),\r\n providerIdx: index('payment_transactions_provider_idx').on(table.provider),\r\n providerTxIdx: index('payment_transactions_provider_tx_idx').on(table.provider_transaction_id),\r\n createdAtIdx: index('payment_transactions_created_at_idx').on(table.created_at),\r\n // Unique constraints for idempotency\r\n internalIdUnique: unique('payment_transactions_internal_id_unique').on(\r\n table.internal_payment_id\r\n ),\r\n idempotencyUnique: unique('payment_transactions_idempotency_unique').on(table.idempotency_key),\r\n })\r\n)\r\n","/**\r\n * PaymentOS - Payment Methods Schema\r\n *\r\n * Stores tokenized payment methods (PCI-compliant - no full card numbers).\r\n * Used for saved cards and recurring billing.\r\n *\r\n * Note: User FK is optional and configured via schema-config.ts\r\n */\r\n\r\nimport { pgTable, uuid, text, boolean, timestamp, jsonb, index } from 'drizzle-orm/pg-core'\r\n\r\n// ============================================================================\r\n// Type Definitions\r\n// ============================================================================\r\n\r\n/**\r\n * Payment method types\r\n */\r\nexport type PaymentMethodType = 'card' | 'bank_account' | 'paypal'\r\n\r\n/**\r\n * Card brands\r\n */\r\nexport type CardBrandType =\r\n | 'visa'\r\n | 'mastercard'\r\n | 'amex'\r\n | 'discover'\r\n | 'isracard'\r\n | 'diners'\r\n | 'unknown'\r\n\r\n// ============================================================================\r\n// Schema Definition\r\n// ============================================================================\r\n\r\n/**\r\n * Payment methods table\r\n *\r\n * FK to user table is NOT defined here - it's application-specific.\r\n * The user_id column stores the UUID, but the FK constraint should be\r\n * added via migration if needed for your specific user table.\r\n *\r\n * To add FK constraint, create a migration:\r\n * ```sql\r\n * ALTER TABLE payment_methods\r\n * ADD CONSTRAINT payment_methods_user_id_fkey\r\n * FOREIGN KEY (user_id) REFERENCES your_users_table(id) ON DELETE CASCADE;\r\n * ```\r\n */\r\nexport const paymentMethods = pgTable(\r\n 'payment_methods',\r\n {\r\n id: uuid('id').defaultRandom().primaryKey(),\r\n\r\n // User association (FK configured at application level)\r\n user_id: uuid('user_id').notNull(),\r\n\r\n // Method type\r\n type: text('type').$type<PaymentMethodType>().notNull(),\r\n\r\n // Provider information\r\n provider: text('provider').notNull(), // stripe, hyp, cardcom\r\n provider_payment_method_id: text('provider_payment_method_id').notNull(),\r\n\r\n // Card details (tokenized, never full numbers)\r\n card_brand: text('card_brand').$type<CardBrandType>(),\r\n card_last4: text('card_last4'),\r\n card_exp_month: text('card_exp_month'),\r\n card_exp_year: text('card_exp_year'),\r\n card_bin: text('card_bin'), // First 6-8 digits for routing\r\n\r\n // State\r\n is_default: boolean('is_default').default(false),\r\n is_active: boolean('is_active').default(true),\r\n\r\n // Provider-specific data\r\n provider_metadata: jsonb('provider_metadata').$type<Record<string, unknown>>(),\r\n\r\n // Timestamps\r\n created_at: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),\r\n updated_at: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),\r\n last_used_at: timestamp('last_used_at', { withTimezone: true }),\r\n },\r\n (table) => ({\r\n // Performance indexes\r\n userIdx: index('payment_methods_user_idx').on(table.user_id),\r\n userDefaultIdx: index('payment_methods_user_default_idx').on(table.user_id, table.is_default),\r\n providerIdx: index('payment_methods_provider_idx').on(table.provider),\r\n providerMethodIdx: index('payment_methods_provider_method_idx').on(\r\n table.provider_payment_method_id\r\n ),\r\n cardBinIdx: index('payment_methods_card_bin_idx').on(table.card_bin),\r\n })\r\n)\r\n","import {\r\n pgTable,\r\n uuid,\r\n text,\r\n timestamp,\r\n jsonb,\r\n index,\r\n unique,\r\n} from 'drizzle-orm/pg-core'\r\n\r\n/**\r\n * Webhook processing status\r\n */\r\nexport type WebhookEventStatus =\r\n | 'pending'\r\n | 'processing'\r\n | 'processed'\r\n | 'failed'\r\n | 'ignored'\r\n\r\n/**\r\n * Payment webhook events table\r\n * Stores all incoming webhooks for idempotent processing.\r\n * Ensures each provider event is processed exactly once.\r\n */\r\nexport const paymentWebhookEvents = pgTable(\r\n 'payment_webhook_events',\r\n {\r\n id: uuid('id').defaultRandom().primaryKey(),\r\n\r\n // Event identification\r\n provider: text('provider').notNull(), // stripe, hyp, cardcom\r\n provider_event_id: text('provider_event_id').notNull(),\r\n event_type: text('event_type').notNull(),\r\n\r\n // Processing state\r\n status: text('status')\r\n .$type<WebhookEventStatus>()\r\n .notNull()\r\n .default('pending'),\r\n attempts: text('attempts').default('0'),\r\n last_attempt_at: timestamp('last_attempt_at', { withTimezone: true }),\r\n\r\n // Linked transaction (if applicable)\r\n transaction_id: uuid('transaction_id'),\r\n\r\n // Event payload (store for debugging and retry)\r\n payload: jsonb('payload').$type<Record<string, unknown>>().notNull(),\r\n signature: text('signature'),\r\n\r\n // Error tracking\r\n error_message: text('error_message'),\r\n error_details: jsonb('error_details'),\r\n\r\n // Timestamps\r\n received_at: timestamp('received_at', { withTimezone: true })\r\n .notNull()\r\n .defaultNow(),\r\n processed_at: timestamp('processed_at', { withTimezone: true }),\r\n created_at: timestamp('created_at', { withTimezone: true })\r\n .notNull()\r\n .defaultNow(),\r\n },\r\n (table) => ({\r\n // Unique constraint for idempotency\r\n providerEventUnique: unique('webhook_events_provider_event_unique').on(\r\n table.provider,\r\n table.provider_event_id\r\n ),\r\n // Performance indexes\r\n statusIdx: index('webhook_events_status_idx').on(table.status),\r\n transactionIdx: index('webhook_events_transaction_idx').on(\r\n table.transaction_id\r\n ),\r\n receivedAtIdx: index('webhook_events_received_at_idx').on(table.received_at),\r\n providerIdx: index('webhook_events_provider_idx').on(table.provider),\r\n eventTypeIdx: index('webhook_events_event_type_idx').on(table.event_type),\r\n })\r\n)\r\n","/**\n * @nehorai/payments-drizzle - Payment Audit Log Schema\n *\n * Immutable audit trail for all payment state changes.\n * Used for debugging, compliance, and dispute resolution.\n */\n\nimport {\n pgTable,\n uuid,\n text,\n timestamp,\n jsonb,\n index,\n} from 'drizzle-orm/pg-core'\n\n// ============================================================================\n// Type Definitions\n// ============================================================================\n\n/**\n * Audit log action types\n */\nexport type AuditLogAction =\n | 'created'\n | 'status_changed'\n | 'authorized'\n | 'captured'\n | 'voided'\n | 'refund_initiated'\n | 'refund_completed'\n | 'webhook_received'\n | 'webhook_processed'\n | 'error_occurred'\n | 'retry_attempted'\n | 'manual_intervention'\n\n/**\n * Who/what triggered the action\n */\nexport type AuditLogTrigger =\n | 'user'\n | 'webhook'\n | 'system'\n | 'admin'\n | 'cron'\n | 'api'\n\n// ============================================================================\n// Schema Definition\n// ============================================================================\n\n/**\n * Payment audit log table\n * Immutable audit trail for all payment state changes.\n * Used for debugging, compliance, and dispute resolution.\n */\nexport const paymentAuditLog = pgTable(\n 'payment_audit_log',\n {\n id: uuid('id').defaultRandom().primaryKey(),\n\n // What transaction was affected\n transaction_id: uuid('transaction_id').notNull(),\n\n // What action occurred\n action: text('action').$type<AuditLogAction>().notNull(),\n\n // State before and after\n previous_state: jsonb('previous_state'),\n new_state: jsonb('new_state').notNull(),\n\n // Who/what triggered this change\n triggered_by: text('triggered_by').$type<AuditLogTrigger>().notNull(),\n triggered_by_id: uuid('triggered_by_id'), // User ID if applicable\n\n // Request context\n ip_address: text('ip_address'),\n user_agent: text('user_agent'),\n\n // Correlation for distributed tracing\n correlation_id: text('correlation_id'),\n\n // Additional context\n metadata: jsonb('metadata').$type<Record<string, unknown>>(),\n\n // Immutable timestamp (never updated)\n created_at: timestamp('created_at', { withTimezone: true })\n .notNull()\n .defaultNow(),\n },\n (table) => ({\n // Performance indexes\n transactionIdx: index('payment_audit_log_transaction_idx').on(\n table.transaction_id\n ),\n actionIdx: index('payment_audit_log_action_idx').on(table.action),\n correlationIdx: index('payment_audit_log_correlation_idx').on(\n table.correlation_id\n ),\n createdAtIdx: index('payment_audit_log_created_at_idx').on(table.created_at),\n triggeredByIdx: index('payment_audit_log_triggered_by_idx').on(\n table.triggered_by\n ),\n })\n)\n","/**\n * @nehorai/payments-drizzle - Provider Health Schema\n *\n * Tracks payment provider health for circuit breaker pattern.\n * Used for intelligent failover when providers experience issues.\n */\n\nimport {\n pgTable,\n uuid,\n text,\n numeric,\n timestamp,\n jsonb,\n index,\n unique,\n} from 'drizzle-orm/pg-core'\n\n// ============================================================================\n// Type Definitions\n// ============================================================================\n\n/**\n * Circuit breaker states\n */\nexport type CircuitBreakerState = 'closed' | 'open' | 'half_open'\n\n// ============================================================================\n// Schema Definition\n// ============================================================================\n\n/**\n * Provider health table\n * Tracks payment provider health for circuit breaker pattern.\n * Used for intelligent failover when providers experience issues.\n */\nexport const providerHealth = pgTable(\n 'payment_provider_health',\n {\n id: uuid('id').defaultRandom().primaryKey(),\n\n // Provider identification\n provider: text('provider').notNull(), // stripe, hyp, cardcom\n\n // Circuit breaker state\n circuit_state: text('circuit_state')\n .$type<CircuitBreakerState>()\n .notNull()\n .default('closed'),\n\n // Failure tracking\n failure_count: text('failure_count').default('0'),\n success_count: text('success_count').default('0'),\n last_failure_at: timestamp('last_failure_at', { withTimezone: true }),\n last_success_at: timestamp('last_success_at', { withTimezone: true }),\n\n // Circuit breaker timing\n circuit_opened_at: timestamp('circuit_opened_at', { withTimezone: true }),\n next_retry_at: timestamp('next_retry_at', { withTimezone: true }),\n\n // Performance metrics\n avg_latency_ms: numeric('avg_latency_ms'),\n error_rate: numeric('error_rate'), // 0-1\n request_count_window: text('request_count_window').default('0'),\n\n // Health check results\n last_health_check_at: timestamp('last_health_check_at', { withTimezone: true }),\n health_check_result: jsonb('health_check_result').$type<{\n healthy: boolean\n latency_ms?: number\n error?: string\n }>(),\n\n // Timestamps\n created_at: timestamp('created_at', { withTimezone: true })\n .notNull()\n .defaultNow(),\n updated_at: timestamp('updated_at', { withTimezone: true })\n .notNull()\n .defaultNow(),\n },\n (table) => ({\n // One record per provider\n providerUnique: unique('provider_health_provider_unique').on(table.provider),\n // Performance indexes\n circuitStateIdx: index('provider_health_circuit_state_idx').on(\n table.circuit_state\n ),\n nextRetryIdx: index('provider_health_next_retry_idx').on(table.next_retry_at),\n })\n)\n"],"mappings":"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","names":["import_pg_core","import_pg_core","import_pg_core","import_pg_core"]}
|