@hed-hog/billing 0.0.2 → 0.0.286

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.
Files changed (51) hide show
  1. package/README.md +420 -0
  2. package/dist/billing-contracts.controller.d.ts +85 -4
  3. package/dist/billing-contracts.controller.d.ts.map +1 -1
  4. package/dist/billing-coupons.controller.d.ts +60 -4
  5. package/dist/billing-coupons.controller.d.ts.map +1 -1
  6. package/dist/billing-dashboard.controller.d.ts +20 -5
  7. package/dist/billing-dashboard.controller.d.ts.map +1 -1
  8. package/dist/billing-entitlements.controller.d.ts +28 -2
  9. package/dist/billing-entitlements.controller.d.ts.map +1 -1
  10. package/dist/billing-gateways.controller.d.ts +18 -2
  11. package/dist/billing-gateways.controller.d.ts.map +1 -1
  12. package/dist/billing-invoices.controller.d.ts +56 -2
  13. package/dist/billing-invoices.controller.d.ts.map +1 -1
  14. package/dist/billing-offers.controller.d.ts +61 -4
  15. package/dist/billing-offers.controller.d.ts.map +1 -1
  16. package/dist/billing-orders.controller.d.ts +39 -2
  17. package/dist/billing-orders.controller.d.ts.map +1 -1
  18. package/dist/billing-payments.controller.d.ts +16 -1
  19. package/dist/billing-payments.controller.d.ts.map +1 -1
  20. package/dist/billing-prices.controller.d.ts +80 -4
  21. package/dist/billing-prices.controller.d.ts.map +1 -1
  22. package/dist/billing-products.controller.d.ts +62 -4
  23. package/dist/billing-products.controller.d.ts.map +1 -1
  24. package/dist/billing-subscriptions.controller.d.ts +138 -5
  25. package/dist/billing-subscriptions.controller.d.ts.map +1 -1
  26. package/dist/billing.service.d.ts +663 -39
  27. package/dist/billing.service.d.ts.map +1 -1
  28. package/dist/billing.service.js +135 -16
  29. package/dist/billing.service.js.map +1 -1
  30. package/hedhog/data/menu.yaml +1 -1
  31. package/hedhog/frontend/app/contracts/page.tsx.ejs +68 -64
  32. package/hedhog/frontend/app/coupons/page.tsx.ejs +81 -77
  33. package/hedhog/frontend/app/entitlements/page.tsx.ejs +59 -58
  34. package/hedhog/frontend/app/gateways/page.tsx.ejs +125 -57
  35. package/hedhog/frontend/app/invoices/page.tsx.ejs +49 -43
  36. package/hedhog/frontend/app/offers/page.tsx.ejs +68 -64
  37. package/hedhog/frontend/app/orders/page.tsx.ejs +47 -46
  38. package/hedhog/frontend/app/page.tsx.ejs +186 -186
  39. package/hedhog/frontend/app/payments/page.tsx.ejs +51 -45
  40. package/hedhog/frontend/app/prices/page.tsx.ejs +81 -75
  41. package/hedhog/frontend/app/products/page.tsx.ejs +79 -73
  42. package/hedhog/frontend/app/refunds/page.tsx.ejs +50 -44
  43. package/hedhog/frontend/app/reports/page.tsx.ejs +1 -1
  44. package/hedhog/frontend/app/seats/page.tsx.ejs +826 -0
  45. package/hedhog/frontend/app/subscriptions/page.tsx.ejs +95 -90
  46. package/hedhog/frontend/app/webhooks/page.tsx.ejs +47 -39
  47. package/hedhog/frontend/messages/en.json +640 -551
  48. package/hedhog/frontend/messages/pt.json +652 -563
  49. package/hedhog/table/billing_payment_method.yaml +1 -1
  50. package/package.json +4 -3
  51. package/src/billing.service.ts +299 -17
@@ -10,7 +10,7 @@ columns:
10
10
  - name: provider
11
11
  type: varchar
12
12
  length: 64
13
- - name: type
13
+ - name: method_kind
14
14
  type: enum
15
15
  values: [card, pix, bank_account]
16
16
  default: card
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hed-hog/billing",
3
- "version": "0.0.2",
3
+ "version": "0.0.286",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "dependencies": {
@@ -10,10 +10,11 @@
10
10
  "@nestjs/jwt": "^11",
11
11
  "@nestjs/mapped-types": "*",
12
12
  "@hed-hog/api": "0.0.4",
13
+ "@hed-hog/contact": "0.0.286",
14
+ "@hed-hog/api-prisma": "0.0.5",
13
15
  "@hed-hog/api-locale": "0.0.13",
14
16
  "@hed-hog/api-pagination": "0.0.6",
15
- "@hed-hog/api-types": "0.0.1",
16
- "@hed-hog/api-prisma": "0.0.5"
17
+ "@hed-hog/api-types": "0.0.1"
17
18
  },
18
19
  "exports": {
19
20
  ".": {
@@ -1,5 +1,5 @@
1
1
  import { PaginationDTO, PaginationService } from '@hed-hog/api-pagination';
2
- import { PrismaService } from '@hed-hog/api-prisma';
2
+ import { Prisma, PrismaService } from '@hed-hog/api-prisma';
3
3
  import { Injectable, NotFoundException } from '@nestjs/common';
4
4
  import { CreateContractDto } from './dto/create-contract.dto';
5
5
  import { CreateCouponDto } from './dto/create-coupon.dto';
@@ -41,11 +41,39 @@ export class BillingService {
41
41
  }
42
42
 
43
43
  async createProduct(data: CreateProductDto) {
44
- return this.prisma.billing_product.create({ data });
44
+ const createData: Prisma.billing_productUncheckedCreateInput = {
45
+ name: data.name,
46
+ ...(data.code !== undefined ? { code: data.code } : {}),
47
+ ...(data.description !== undefined ? { description: data.description } : {}),
48
+ ...(data.product_type !== undefined
49
+ ? {
50
+ product_type:
51
+ data.product_type as Prisma.billing_productUncheckedCreateInput['product_type'],
52
+ }
53
+ : {}),
54
+ ...(data.category !== undefined ? { category: data.category } : {}),
55
+ ...(data.is_active !== undefined ? { is_active: data.is_active } : {}),
56
+ };
57
+
58
+ return this.prisma.billing_product.create({ data: createData });
45
59
  }
46
60
 
47
61
  async updateProduct(id: number, data: UpdateProductDto) {
48
- return this.prisma.billing_product.update({ where: { id }, data });
62
+ const updateData: Prisma.billing_productUncheckedUpdateInput = {
63
+ ...(data.name !== undefined ? { name: data.name } : {}),
64
+ ...(data.code !== undefined ? { code: data.code } : {}),
65
+ ...(data.description !== undefined ? { description: data.description } : {}),
66
+ ...(data.product_type !== undefined
67
+ ? {
68
+ product_type:
69
+ data.product_type as Prisma.billing_productUncheckedUpdateInput['product_type'],
70
+ }
71
+ : {}),
72
+ ...(data.category !== undefined ? { category: data.category } : {}),
73
+ ...(data.is_active !== undefined ? { is_active: data.is_active } : {}),
74
+ };
75
+
76
+ return this.prisma.billing_product.update({ where: { id }, data: updateData });
49
77
  }
50
78
 
51
79
  async deleteProduct(id: number) {
@@ -75,11 +103,65 @@ export class BillingService {
75
103
  }
76
104
 
77
105
  async createPrice(data: CreatePriceDto) {
78
- return this.prisma.billing_price.create({ data });
106
+ const createData: Prisma.billing_priceUncheckedCreateInput = {
107
+ product_id: data.product_id,
108
+ name: data.name,
109
+ ...(data.billing_type !== undefined
110
+ ? {
111
+ billing_type:
112
+ data.billing_type as Prisma.billing_priceUncheckedCreateInput['billing_type'],
113
+ }
114
+ : {}),
115
+ ...(data.currency !== undefined ? { currency: data.currency } : {}),
116
+ ...(data.amount_cents !== undefined ? { amount_cents: data.amount_cents } : {}),
117
+ ...(data.interval_unit !== undefined
118
+ ? {
119
+ interval_unit:
120
+ data.interval_unit as Prisma.billing_priceUncheckedCreateInput['interval_unit'],
121
+ }
122
+ : {}),
123
+ ...(data.interval_count !== undefined ? { interval_count: data.interval_count } : {}),
124
+ ...(data.trial_days !== undefined ? { trial_days: data.trial_days } : {}),
125
+ ...(data.setup_fee_cents !== undefined
126
+ ? { setup_fee_cents: data.setup_fee_cents }
127
+ : {}),
128
+ ...(data.is_active !== undefined ? { is_active: data.is_active } : {}),
129
+ ...(data.starts_at !== undefined ? { starts_at: data.starts_at } : {}),
130
+ ...(data.ends_at !== undefined ? { ends_at: data.ends_at } : {}),
131
+ };
132
+
133
+ return this.prisma.billing_price.create({ data: createData });
79
134
  }
80
135
 
81
136
  async updatePrice(id: number, data: UpdatePriceDto) {
82
- return this.prisma.billing_price.update({ where: { id }, data });
137
+ const updateData: Prisma.billing_priceUncheckedUpdateInput = {
138
+ ...(data.product_id !== undefined ? { product_id: data.product_id } : {}),
139
+ ...(data.name !== undefined ? { name: data.name } : {}),
140
+ ...(data.billing_type !== undefined
141
+ ? {
142
+ billing_type:
143
+ data.billing_type as Prisma.billing_priceUncheckedUpdateInput['billing_type'],
144
+ }
145
+ : {}),
146
+ ...(data.currency !== undefined ? { currency: data.currency } : {}),
147
+ ...(data.amount_cents !== undefined ? { amount_cents: data.amount_cents } : {}),
148
+ ...(data.interval_unit !== undefined
149
+ ? {
150
+ interval_unit:
151
+ data.interval_unit as Prisma.billing_priceUncheckedUpdateInput['interval_unit'],
152
+ }
153
+ : {}),
154
+ ...(data.interval_count !== undefined ? { interval_count: data.interval_count } : {}),
155
+ ...(data.trial_days !== undefined ? { trial_days: data.trial_days } : {}),
156
+ ...(data.setup_fee_cents !== undefined
157
+ ? { setup_fee_cents: data.setup_fee_cents }
158
+ : {}),
159
+ ...(data.is_active !== undefined ? { is_active: data.is_active } : {}),
160
+ ...(data.starts_at !== undefined ? { starts_at: data.starts_at } : {}),
161
+ ...(data.ends_at !== undefined ? { ends_at: data.ends_at } : {}),
162
+ };
163
+
164
+ return this.prisma.billing_price.update({ where: { id }, data: updateData });
83
165
  }
84
166
 
85
167
  async deletePrice(id: number) {
@@ -106,11 +188,35 @@ export class BillingService {
106
188
  }
107
189
 
108
190
  async createOffer(data: CreateOfferDto) {
109
- return this.prisma.billing_offer.create({ data });
191
+ const createData: Prisma.billing_offerUncheckedCreateInput = {
192
+ code: data.code,
193
+ name: data.name,
194
+ ...(data.description !== undefined ? { description: data.description } : {}),
195
+ ...(data.status !== undefined
196
+ ? {
197
+ status:
198
+ data.status as Prisma.billing_offerUncheckedCreateInput['status'],
199
+ }
200
+ : {}),
201
+ };
202
+
203
+ return this.prisma.billing_offer.create({ data: createData });
110
204
  }
111
205
 
112
206
  async updateOffer(id: number, data: UpdateOfferDto) {
113
- return this.prisma.billing_offer.update({ where: { id }, data });
207
+ const updateData: Prisma.billing_offerUncheckedUpdateInput = {
208
+ ...(data.code !== undefined ? { code: data.code } : {}),
209
+ ...(data.name !== undefined ? { name: data.name } : {}),
210
+ ...(data.description !== undefined ? { description: data.description } : {}),
211
+ ...(data.status !== undefined
212
+ ? {
213
+ status:
214
+ data.status as Prisma.billing_offerUncheckedUpdateInput['status'],
215
+ }
216
+ : {}),
217
+ };
218
+
219
+ return this.prisma.billing_offer.update({ where: { id }, data: updateData });
114
220
  }
115
221
 
116
222
  async deleteOffer(id: number) {
@@ -134,11 +240,55 @@ export class BillingService {
134
240
  }
135
241
 
136
242
  async createCoupon(data: CreateCouponDto) {
137
- return this.prisma.billing_coupon.create({ data });
243
+ const createData: Prisma.billing_couponUncheckedCreateInput = {
244
+ code: data.code,
245
+ name: data.name,
246
+ ...(data.discount_type !== undefined
247
+ ? {
248
+ discount_type:
249
+ data.discount_type as Prisma.billing_couponUncheckedCreateInput['discount_type'],
250
+ }
251
+ : {}),
252
+ ...(data.discount_value !== undefined ? { discount_value: data.discount_value } : {}),
253
+ ...(data.currency !== undefined ? { currency: data.currency } : {}),
254
+ ...(data.max_uses !== undefined ? { max_uses: data.max_uses } : {}),
255
+ ...(data.starts_at !== undefined ? { starts_at: data.starts_at } : {}),
256
+ ...(data.ends_at !== undefined ? { ends_at: data.ends_at } : {}),
257
+ ...(data.status !== undefined
258
+ ? {
259
+ status:
260
+ data.status as Prisma.billing_couponUncheckedCreateInput['status'],
261
+ }
262
+ : {}),
263
+ };
264
+
265
+ return this.prisma.billing_coupon.create({ data: createData });
138
266
  }
139
267
 
140
268
  async updateCoupon(id: number, data: Partial<CreateCouponDto>) {
141
- return this.prisma.billing_coupon.update({ where: { id }, data });
269
+ const updateData: Prisma.billing_couponUncheckedUpdateInput = {
270
+ ...(data.code !== undefined ? { code: data.code } : {}),
271
+ ...(data.name !== undefined ? { name: data.name } : {}),
272
+ ...(data.discount_type !== undefined
273
+ ? {
274
+ discount_type:
275
+ data.discount_type as Prisma.billing_couponUncheckedUpdateInput['discount_type'],
276
+ }
277
+ : {}),
278
+ ...(data.discount_value !== undefined ? { discount_value: data.discount_value } : {}),
279
+ ...(data.currency !== undefined ? { currency: data.currency } : {}),
280
+ ...(data.max_uses !== undefined ? { max_uses: data.max_uses } : {}),
281
+ ...(data.starts_at !== undefined ? { starts_at: data.starts_at } : {}),
282
+ ...(data.ends_at !== undefined ? { ends_at: data.ends_at } : {}),
283
+ ...(data.status !== undefined
284
+ ? {
285
+ status:
286
+ data.status as Prisma.billing_couponUncheckedUpdateInput['status'],
287
+ }
288
+ : {}),
289
+ };
290
+
291
+ return this.prisma.billing_coupon.update({ where: { id }, data: updateData });
142
292
  }
143
293
 
144
294
  async deleteCoupon(id: number) {
@@ -165,7 +315,26 @@ export class BillingService {
165
315
  }
166
316
 
167
317
  async createOrder(data: CreateOrderDto) {
168
- return this.prisma.billing_order.create({ data });
318
+ const createData: Prisma.billing_orderUncheckedCreateInput = {
319
+ ...(data.contact_id !== undefined ? { contact_id: data.contact_id } : {}),
320
+ ...(data.company_contact_id !== undefined
321
+ ? { company_contact_id: data.company_contact_id }
322
+ : {}),
323
+ ...(data.status !== undefined
324
+ ? {
325
+ status:
326
+ data.status as Prisma.billing_orderUncheckedCreateInput['status'],
327
+ }
328
+ : {}),
329
+ ...(data.currency !== undefined ? { currency: data.currency } : {}),
330
+ ...(data.subtotal_cents !== undefined ? { subtotal_cents: data.subtotal_cents } : {}),
331
+ ...(data.discount_cents !== undefined ? { discount_cents: data.discount_cents } : {}),
332
+ ...(data.total_cents !== undefined ? { total_cents: data.total_cents } : {}),
333
+ ...(data.source !== undefined ? { source: data.source } : {}),
334
+ ...(data.notes !== undefined ? { notes: data.notes } : {}),
335
+ };
336
+
337
+ return this.prisma.billing_order.create({ data: createData });
169
338
  }
170
339
 
171
340
  // ─── Subscriptions ────────────────────────────────────────────────────────
@@ -199,7 +368,34 @@ export class BillingService {
199
368
  }
200
369
 
201
370
  async createSubscription(data: CreateSubscriptionDto) {
202
- return this.prisma.billing_subscription.create({ data });
371
+ const createData: Prisma.billing_subscriptionUncheckedCreateInput = {
372
+ ...(data.contact_id !== undefined ? { contact_id: data.contact_id } : {}),
373
+ ...(data.product_id !== undefined ? { product_id: data.product_id } : {}),
374
+ ...(data.price_id !== undefined ? { price_id: data.price_id } : {}),
375
+ ...(data.gateway !== undefined ? { gateway: data.gateway } : {}),
376
+ ...(data.gateway_subscription_id !== undefined
377
+ ? { gateway_subscription_id: data.gateway_subscription_id }
378
+ : {}),
379
+ ...(data.status !== undefined
380
+ ? {
381
+ status:
382
+ data.status as Prisma.billing_subscriptionUncheckedCreateInput['status'],
383
+ }
384
+ : {}),
385
+ ...(data.started_at !== undefined ? { started_at: data.started_at } : {}),
386
+ ...(data.trial_ends_at !== undefined ? { trial_ends_at: data.trial_ends_at } : {}),
387
+ ...(data.current_period_start !== undefined
388
+ ? { current_period_start: data.current_period_start }
389
+ : {}),
390
+ ...(data.current_period_end !== undefined
391
+ ? { current_period_end: data.current_period_end }
392
+ : {}),
393
+ ...(data.cancel_at_period_end !== undefined
394
+ ? { cancel_at_period_end: data.cancel_at_period_end }
395
+ : {}),
396
+ };
397
+
398
+ return this.prisma.billing_subscription.create({ data: createData });
203
399
  }
204
400
 
205
401
  async cancelSubscription(id: number) {
@@ -283,7 +479,24 @@ export class BillingService {
283
479
  }
284
480
 
285
481
  async createEntitlement(data: CreateEntitlementDto) {
286
- return this.prisma.billing_entitlement.create({ data });
482
+ const createData: Prisma.billing_entitlementUncheckedCreateInput = {
483
+ contact_id: data.contact_id,
484
+ source_type: data.source_type,
485
+ source_id: data.source_id,
486
+ target_type: data.target_type,
487
+ target_id: data.target_id,
488
+ access_type: data.access_type,
489
+ ...(data.starts_at !== undefined ? { starts_at: data.starts_at } : {}),
490
+ ...(data.ends_at !== undefined ? { ends_at: data.ends_at } : {}),
491
+ ...(data.status !== undefined
492
+ ? {
493
+ status:
494
+ data.status as Prisma.billing_entitlementUncheckedCreateInput['status'],
495
+ }
496
+ : {}),
497
+ };
498
+
499
+ return this.prisma.billing_entitlement.create({ data: createData });
287
500
  }
288
501
 
289
502
  async deleteEntitlement(id: number) {
@@ -316,11 +529,43 @@ export class BillingService {
316
529
  }
317
530
 
318
531
  async createContract(data: CreateContractDto) {
319
- return this.prisma.billing_contract.create({ data });
532
+ const createData: Prisma.billing_contractUncheckedCreateInput = {
533
+ contact_id: data.contact_id,
534
+ name: data.name,
535
+ starts_at: data.starts_at,
536
+ ...(data.description !== undefined ? { description: data.description } : {}),
537
+ ...(data.ends_at !== undefined ? { ends_at: data.ends_at } : {}),
538
+ ...(data.total_seats !== undefined ? { total_seats: data.total_seats } : {}),
539
+ ...(data.status !== undefined
540
+ ? {
541
+ status:
542
+ data.status as Prisma.billing_contractUncheckedCreateInput['status'],
543
+ }
544
+ : {}),
545
+ ...(data.signed_at !== undefined ? { signed_at: data.signed_at } : {}),
546
+ };
547
+
548
+ return this.prisma.billing_contract.create({ data: createData });
320
549
  }
321
550
 
322
551
  async updateContract(id: number, data: UpdateContractDto) {
323
- return this.prisma.billing_contract.update({ where: { id }, data });
552
+ const updateData: Prisma.billing_contractUncheckedUpdateInput = {
553
+ ...(data.contact_id !== undefined ? { contact_id: data.contact_id } : {}),
554
+ ...(data.name !== undefined ? { name: data.name } : {}),
555
+ ...(data.starts_at !== undefined ? { starts_at: data.starts_at } : {}),
556
+ ...(data.description !== undefined ? { description: data.description } : {}),
557
+ ...(data.ends_at !== undefined ? { ends_at: data.ends_at } : {}),
558
+ ...(data.total_seats !== undefined ? { total_seats: data.total_seats } : {}),
559
+ ...(data.status !== undefined
560
+ ? {
561
+ status:
562
+ data.status as Prisma.billing_contractUncheckedUpdateInput['status'],
563
+ }
564
+ : {}),
565
+ ...(data.signed_at !== undefined ? { signed_at: data.signed_at } : {}),
566
+ };
567
+
568
+ return this.prisma.billing_contract.update({ where: { id }, data: updateData });
324
569
  }
325
570
 
326
571
  async deleteContract(id: number) {
@@ -336,11 +581,48 @@ export class BillingService {
336
581
  }
337
582
 
338
583
  async updateGateway(slug: string, data: Record<string, unknown>) {
339
- return this.prisma.billing_payment_provider.upsert({
584
+ const existing = await this.prisma.billing_payment_provider.findFirst({
340
585
  where: { slug },
341
- update: data as any,
342
- create: { slug, name: slug, ...data } as any,
343
586
  });
587
+
588
+ const rawConfig = data.config_json;
589
+ let normalizedConfig: string | null | undefined;
590
+
591
+ if (rawConfig === undefined) {
592
+ normalizedConfig = undefined;
593
+ } else if (rawConfig === null) {
594
+ normalizedConfig = null;
595
+ } else if (typeof rawConfig === 'string') {
596
+ normalizedConfig = rawConfig;
597
+ } else {
598
+ normalizedConfig = JSON.stringify(rawConfig);
599
+ }
600
+
601
+ const updateData: Prisma.billing_payment_providerUncheckedUpdateInput = {
602
+ ...(typeof data.name === 'string' ? { name: data.name } : {}),
603
+ ...(typeof data.is_active === 'boolean' ? { is_active: data.is_active } : {}),
604
+ ...(normalizedConfig !== undefined ? { config_json: normalizedConfig } : {}),
605
+ };
606
+
607
+ if (existing) {
608
+ if (Object.keys(updateData).length === 0) {
609
+ return existing;
610
+ }
611
+
612
+ return this.prisma.billing_payment_provider.update({
613
+ where: { id: existing.id },
614
+ data: updateData,
615
+ });
616
+ }
617
+
618
+ const createData: Prisma.billing_payment_providerUncheckedCreateInput = {
619
+ slug,
620
+ name: typeof data.name === 'string' ? data.name : slug,
621
+ ...(typeof data.is_active === 'boolean' ? { is_active: data.is_active } : {}),
622
+ ...(normalizedConfig !== undefined ? { config_json: normalizedConfig } : {}),
623
+ };
624
+
625
+ return this.prisma.billing_payment_provider.create({ data: createData });
344
626
  }
345
627
 
346
628
  // ─── Webhooks ─────────────────────────────────────────────────────────────