@qazuor/qzpay-drizzle 1.0.1 → 1.2.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/README.md CHANGED
@@ -99,15 +99,173 @@ await storageAdapter.transaction(async () => {
99
99
 
100
100
  ## Repositories
101
101
 
102
- - `QZPayCustomersRepository`
103
- - `QZPaySubscriptionsRepository`
104
- - `QZPayPaymentsRepository`
105
- - `QZPayInvoicesRepository`
106
- - `QZPayPlansRepository`
107
- - `QZPayPricesRepository`
108
- - `QZPayLimitsRepository`
109
- - `QZPayEntitlementsRepository`
110
- - `QZPayEventsRepository`
102
+ ### QZPayCustomersRepository
103
+
104
+ ```typescript
105
+ // Methods
106
+ findById(id: string): Promise<Customer | null>
107
+ findByExternalId(externalId: string): Promise<Customer | null>
108
+ findByEmail(email: string): Promise<Customer | null>
109
+ create(data: CreateCustomerInput): Promise<Customer>
110
+ update(id: string, data: UpdateCustomerInput): Promise<Customer | null>
111
+ delete(id: string): Promise<void>
112
+ list(options?: ListOptions): Promise<PaginatedResult<Customer>>
113
+ ```
114
+
115
+ ### QZPaySubscriptionsRepository
116
+
117
+ ```typescript
118
+ // Methods
119
+ findById(id: string): Promise<Subscription | null>
120
+ findByCustomerId(customerId: string): Promise<Subscription[]>
121
+ findActiveByCustomerId(customerId: string): Promise<Subscription | null>
122
+ create(data: CreateSubscriptionInput): Promise<Subscription>
123
+ update(id: string, data: UpdateSubscriptionInput): Promise<Subscription>
124
+ list(options?: ListOptions): Promise<PaginatedResult<Subscription>>
125
+
126
+ // Lifecycle query methods (for automated processing)
127
+ findExpiringSoon(beforeDate: Date, options?): Promise<Subscription[]>
128
+ findInTrialEndingSoon(beforeDate: Date, options?): Promise<Subscription[]>
129
+ findPastDueInGracePeriod(now: Date, options?): Promise<Subscription[]>
130
+ findNeedingPaymentRetry(beforeDate: Date, options?): Promise<Subscription[]>
131
+ findPendingCancellationAtPeriodEnd(beforeDate: Date, options?): Promise<Subscription[]>
132
+ ```
133
+
134
+ ### QZPayPaymentsRepository
135
+
136
+ ```typescript
137
+ // Methods
138
+ findById(id: string): Promise<Payment | null>
139
+ findByCustomerId(customerId: string): Promise<Payment[]>
140
+ findByInvoiceId(invoiceId: string): Promise<Payment[]>
141
+ create(data: CreatePaymentInput): Promise<Payment>
142
+ update(id: string, data: UpdatePaymentInput): Promise<Payment>
143
+ list(options?: ListOptions): Promise<PaginatedResult<Payment>>
144
+ ```
145
+
146
+ ### QZPayInvoicesRepository
147
+
148
+ ```typescript
149
+ // Methods
150
+ findById(id: string): Promise<Invoice | null>
151
+ findByCustomerId(customerId: string): Promise<Invoice[]>
152
+ findBySubscriptionId(subscriptionId: string): Promise<Invoice[]>
153
+ create(data: CreateInvoiceInput): Promise<Invoice>
154
+ update(id: string, data: UpdateInvoiceInput): Promise<Invoice>
155
+ list(options?: ListOptions): Promise<PaginatedResult<Invoice>>
156
+ ```
157
+
158
+ ### Other Repositories
159
+
160
+ - `QZPayPlansRepository` - Plan CRUD operations
161
+ - `QZPayPricesRepository` - Price configurations
162
+ - `QZPayLimitsRepository` - Usage limit tracking
163
+ - `QZPayEntitlementsRepository` - Feature entitlements
164
+ - `QZPayAddonsRepository` - Add-on management
165
+ - `QZPayPaymentMethodsRepository` - Payment method storage
166
+ - `QZPayPromoCodesRepository` - Promotional codes
167
+ - `QZPayEventsRepository` - Event logging
168
+
169
+ ## Schema Details
170
+
171
+ ### billing_customers
172
+
173
+ | Column | Type | Description |
174
+ |--------|------|-------------|
175
+ | id | UUID | Primary key |
176
+ | external_id | VARCHAR | Your app's user ID |
177
+ | email | VARCHAR | Customer email |
178
+ | name | VARCHAR | Customer name |
179
+ | phone | VARCHAR | Phone number |
180
+ | provider_customer_ids | JSONB | Provider IDs (stripe, mercadopago) |
181
+ | metadata | JSONB | Custom metadata |
182
+ | livemode | BOOLEAN | Live vs test mode |
183
+ | created_at | TIMESTAMP | Creation timestamp |
184
+ | updated_at | TIMESTAMP | Last update timestamp |
185
+
186
+ ### billing_subscriptions
187
+
188
+ | Column | Type | Description |
189
+ |--------|------|-------------|
190
+ | id | UUID | Primary key |
191
+ | customer_id | UUID | FK to customers |
192
+ | plan_id | VARCHAR | Plan identifier |
193
+ | status | VARCHAR | active, trialing, past_due, canceled, paused |
194
+ | current_period_start | TIMESTAMP | Billing period start |
195
+ | current_period_end | TIMESTAMP | Billing period end |
196
+ | trial_end | TIMESTAMP | Trial end date |
197
+ | cancel_at | TIMESTAMP | Scheduled cancellation |
198
+ | cancel_at_period_end | BOOLEAN | Cancel at end of period |
199
+ | canceled_at | TIMESTAMP | When canceled |
200
+ | grace_period_ends_at | TIMESTAMP | Grace period end |
201
+ | next_retry_at | TIMESTAMP | Next payment retry |
202
+ | retry_count | INTEGER | Number of retry attempts |
203
+ | metadata | JSONB | Custom metadata |
204
+ | livemode | BOOLEAN | Live vs test mode |
205
+
206
+ ### billing_payments
207
+
208
+ | Column | Type | Description |
209
+ |--------|------|-------------|
210
+ | id | UUID | Primary key |
211
+ | customer_id | UUID | FK to customers |
212
+ | invoice_id | UUID | FK to invoices |
213
+ | subscription_id | UUID | FK to subscriptions |
214
+ | amount | INTEGER | Amount in cents |
215
+ | currency | VARCHAR | Currency code |
216
+ | status | VARCHAR | pending, succeeded, failed, refunded |
217
+ | idempotency_key | VARCHAR | Prevents duplicate payments |
218
+ | provider_payment_ids | JSONB | Provider payment IDs |
219
+ | failure_code | VARCHAR | Error code if failed |
220
+ | failure_message | TEXT | Error message |
221
+
222
+ ### Table Relationships
223
+
224
+ ```
225
+ billing_customers
226
+ ├── billing_subscriptions (1:N)
227
+ │ ├── billing_payments (1:N)
228
+ │ └── billing_subscription_addons (1:N)
229
+ ├── billing_invoices (1:N)
230
+ │ └── billing_invoice_lines (1:N)
231
+ ├── billing_payments (1:N)
232
+ ├── billing_payment_methods (1:N)
233
+ ├── billing_customer_limits (1:N)
234
+ └── billing_customer_entitlements (1:N)
235
+
236
+ billing_plans
237
+ ├── billing_prices (1:N)
238
+ └── billing_addons (M:N via compatible_plan_ids)
239
+ ```
240
+
241
+ ## Transactions
242
+
243
+ Use transactions for operations that need to be atomic:
244
+
245
+ ```typescript
246
+ import { qzpayWithTransaction } from '@qazuor/qzpay-drizzle';
247
+
248
+ // Using the transaction utility
249
+ await qzpayWithTransaction(db, async (tx) => {
250
+ // All operations use the transaction
251
+ const customer = await customersRepo.create({ ... }, tx);
252
+ const subscription = await subscriptionsRepo.create({
253
+ customerId: customer.id,
254
+ ...
255
+ }, tx);
256
+
257
+ // If any operation fails, all changes are rolled back
258
+ });
259
+
260
+ // Or via the storage adapter
261
+ await storageAdapter.transaction(async () => {
262
+ const customer = await billing.customers.create({ ... });
263
+ const subscription = await billing.subscriptions.create({
264
+ customerId: customer.id,
265
+ ...
266
+ });
267
+ });
268
+ ```
111
269
 
112
270
  ## Migrations
113
271