@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.
- package/README.md +420 -0
- package/dist/billing-contracts.controller.d.ts +85 -4
- package/dist/billing-contracts.controller.d.ts.map +1 -1
- package/dist/billing-coupons.controller.d.ts +60 -4
- package/dist/billing-coupons.controller.d.ts.map +1 -1
- package/dist/billing-dashboard.controller.d.ts +20 -5
- package/dist/billing-dashboard.controller.d.ts.map +1 -1
- package/dist/billing-entitlements.controller.d.ts +28 -2
- package/dist/billing-entitlements.controller.d.ts.map +1 -1
- package/dist/billing-gateways.controller.d.ts +18 -2
- package/dist/billing-gateways.controller.d.ts.map +1 -1
- package/dist/billing-invoices.controller.d.ts +56 -2
- package/dist/billing-invoices.controller.d.ts.map +1 -1
- package/dist/billing-offers.controller.d.ts +61 -4
- package/dist/billing-offers.controller.d.ts.map +1 -1
- package/dist/billing-orders.controller.d.ts +39 -2
- package/dist/billing-orders.controller.d.ts.map +1 -1
- package/dist/billing-payments.controller.d.ts +16 -1
- package/dist/billing-payments.controller.d.ts.map +1 -1
- package/dist/billing-prices.controller.d.ts +80 -4
- package/dist/billing-prices.controller.d.ts.map +1 -1
- package/dist/billing-products.controller.d.ts +62 -4
- package/dist/billing-products.controller.d.ts.map +1 -1
- package/dist/billing-subscriptions.controller.d.ts +138 -5
- package/dist/billing-subscriptions.controller.d.ts.map +1 -1
- package/dist/billing.service.d.ts +663 -39
- package/dist/billing.service.d.ts.map +1 -1
- package/dist/billing.service.js +135 -16
- package/dist/billing.service.js.map +1 -1
- package/hedhog/data/menu.yaml +1 -1
- package/hedhog/frontend/app/contracts/page.tsx.ejs +68 -64
- package/hedhog/frontend/app/coupons/page.tsx.ejs +81 -77
- package/hedhog/frontend/app/entitlements/page.tsx.ejs +59 -58
- package/hedhog/frontend/app/gateways/page.tsx.ejs +125 -57
- package/hedhog/frontend/app/invoices/page.tsx.ejs +49 -43
- package/hedhog/frontend/app/offers/page.tsx.ejs +68 -64
- package/hedhog/frontend/app/orders/page.tsx.ejs +47 -46
- package/hedhog/frontend/app/page.tsx.ejs +186 -186
- package/hedhog/frontend/app/payments/page.tsx.ejs +51 -45
- package/hedhog/frontend/app/prices/page.tsx.ejs +81 -75
- package/hedhog/frontend/app/products/page.tsx.ejs +79 -73
- package/hedhog/frontend/app/refunds/page.tsx.ejs +50 -44
- package/hedhog/frontend/app/reports/page.tsx.ejs +1 -1
- package/hedhog/frontend/app/seats/page.tsx.ejs +826 -0
- package/hedhog/frontend/app/subscriptions/page.tsx.ejs +95 -90
- package/hedhog/frontend/app/webhooks/page.tsx.ejs +47 -39
- package/hedhog/frontend/messages/en.json +640 -551
- package/hedhog/frontend/messages/pt.json +652 -563
- package/hedhog/table/billing_payment_method.yaml +1 -1
- package/package.json +4 -3
- package/src/billing.service.ts +299 -17
package/README.md
ADDED
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
# @hed-hog/billing
|
|
2
|
+
|
|
3
|
+
## 1. Visão geral do módulo
|
|
4
|
+
|
|
5
|
+
O módulo `@hed-hog/billing` é responsável pela gestão completa do sistema de faturamento, incluindo produtos, preços, ofertas, cupons, pedidos, assinaturas, faturas, pagamentos, reembolsos, direitos (entitlements), contratos, gateways de pagamento, webhooks e dashboard de métricas. Ele oferece uma API RESTful protegida por roles para administração e manipulação dos dados relacionados ao billing.
|
|
6
|
+
|
|
7
|
+
## 2. Escopo e responsabilidades
|
|
8
|
+
|
|
9
|
+
- Gerenciar produtos e seus preços.
|
|
10
|
+
- Controlar ofertas e cupons de desconto.
|
|
11
|
+
- Registrar e consultar pedidos e assinaturas.
|
|
12
|
+
- Emitir e consultar faturas e pagamentos.
|
|
13
|
+
- Gerenciar reembolsos e direitos de acesso (entitlements).
|
|
14
|
+
- Administrar contratos e alocações de assentos.
|
|
15
|
+
- Configurar gateways de pagamento.
|
|
16
|
+
- Registrar eventos de webhooks.
|
|
17
|
+
- Fornecer dados resumidos para dashboard de billing.
|
|
18
|
+
- Garantir autenticação e autorização via roles específicas.
|
|
19
|
+
|
|
20
|
+
## 3. Endpoints
|
|
21
|
+
|
|
22
|
+
Todos os endpoints são protegidos e requerem autenticação com roles `admin` ou `admin-billing`.
|
|
23
|
+
|
|
24
|
+
### Dashboard
|
|
25
|
+
|
|
26
|
+
- **GET** `/billing/dashboard`
|
|
27
|
+
Retorna dados resumidos do dashboard de billing, incluindo assinaturas ativas, pagamentos falhados, faturas em atraso, receita do mês e pagamentos recentes.
|
|
28
|
+
|
|
29
|
+
### Produtos
|
|
30
|
+
|
|
31
|
+
- **GET** `/billing/products`
|
|
32
|
+
Lista produtos com paginação.
|
|
33
|
+
|
|
34
|
+
- **GET** `/billing/products/:id`
|
|
35
|
+
Obtém detalhes de um produto pelo ID, incluindo preços associados.
|
|
36
|
+
|
|
37
|
+
- **POST** `/billing/products`
|
|
38
|
+
Cria um novo produto.
|
|
39
|
+
**Body:** `CreateProductDto`
|
|
40
|
+
|
|
41
|
+
- **PATCH** `/billing/products/:id`
|
|
42
|
+
Atualiza um produto existente.
|
|
43
|
+
**Body:** `UpdateProductDto`
|
|
44
|
+
|
|
45
|
+
- **DELETE** `/billing/products/:id`
|
|
46
|
+
Remove um produto pelo ID.
|
|
47
|
+
|
|
48
|
+
### Preços
|
|
49
|
+
|
|
50
|
+
- **GET** `/billing/prices`
|
|
51
|
+
Lista preços com paginação, incluindo dados básicos do produto.
|
|
52
|
+
|
|
53
|
+
- **GET** `/billing/prices/:id`
|
|
54
|
+
Obtém detalhes de um preço pelo ID, incluindo o produto associado.
|
|
55
|
+
|
|
56
|
+
- **POST** `/billing/prices`
|
|
57
|
+
Cria um novo preço.
|
|
58
|
+
**Body:** `CreatePriceDto`
|
|
59
|
+
|
|
60
|
+
- **PATCH** `/billing/prices/:id`
|
|
61
|
+
Atualiza um preço existente.
|
|
62
|
+
**Body:** `UpdatePriceDto`
|
|
63
|
+
|
|
64
|
+
- **DELETE** `/billing/prices/:id`
|
|
65
|
+
Remove um preço pelo ID.
|
|
66
|
+
|
|
67
|
+
### Ofertas
|
|
68
|
+
|
|
69
|
+
- **GET** `/billing/offers`
|
|
70
|
+
Lista ofertas com paginação.
|
|
71
|
+
|
|
72
|
+
- **GET** `/billing/offers/:id`
|
|
73
|
+
Obtém detalhes de uma oferta pelo ID, incluindo preços associados.
|
|
74
|
+
|
|
75
|
+
- **POST** `/billing/offers`
|
|
76
|
+
Cria uma nova oferta.
|
|
77
|
+
**Body:** `CreateOfferDto`
|
|
78
|
+
|
|
79
|
+
- **PATCH** `/billing/offers/:id`
|
|
80
|
+
Atualiza uma oferta existente.
|
|
81
|
+
**Body:** `UpdateOfferDto`
|
|
82
|
+
|
|
83
|
+
- **DELETE** `/billing/offers/:id`
|
|
84
|
+
Remove uma oferta pelo ID.
|
|
85
|
+
|
|
86
|
+
### Cupons
|
|
87
|
+
|
|
88
|
+
- **GET** `/billing/coupons`
|
|
89
|
+
Lista cupons com paginação.
|
|
90
|
+
|
|
91
|
+
- **GET** `/billing/coupons/:id`
|
|
92
|
+
Obtém detalhes de um cupom pelo ID.
|
|
93
|
+
|
|
94
|
+
- **POST** `/billing/coupons`
|
|
95
|
+
Cria um novo cupom.
|
|
96
|
+
**Body:** `CreateCouponDto`
|
|
97
|
+
|
|
98
|
+
- **PATCH** `/billing/coupons/:id`
|
|
99
|
+
Atualiza um cupom existente.
|
|
100
|
+
**Body:** `UpdateCouponDto`
|
|
101
|
+
|
|
102
|
+
- **DELETE** `/billing/coupons/:id`
|
|
103
|
+
Remove um cupom pelo ID.
|
|
104
|
+
|
|
105
|
+
### Pedidos
|
|
106
|
+
|
|
107
|
+
- **GET** `/billing/orders`
|
|
108
|
+
Lista pedidos com paginação.
|
|
109
|
+
|
|
110
|
+
- **GET** `/billing/orders/:id`
|
|
111
|
+
Obtém detalhes de um pedido pelo ID, incluindo itens do pedido.
|
|
112
|
+
|
|
113
|
+
- **POST** `/billing/orders`
|
|
114
|
+
Cria um novo pedido.
|
|
115
|
+
**Body:** `CreateOrderDto`
|
|
116
|
+
|
|
117
|
+
### Assinaturas
|
|
118
|
+
|
|
119
|
+
- **GET** `/billing/subscriptions`
|
|
120
|
+
Lista assinaturas com paginação, incluindo dados básicos do produto e preço.
|
|
121
|
+
|
|
122
|
+
- **GET** `/billing/subscriptions/:id`
|
|
123
|
+
Obtém detalhes de uma assinatura pelo ID, incluindo itens, produto, preço e últimas faturas.
|
|
124
|
+
|
|
125
|
+
- **POST** `/billing/subscriptions`
|
|
126
|
+
Cria uma nova assinatura.
|
|
127
|
+
**Body:** `CreateSubscriptionDto`
|
|
128
|
+
|
|
129
|
+
- **PATCH** `/billing/subscriptions/:id/cancel`
|
|
130
|
+
Cancela uma assinatura.
|
|
131
|
+
|
|
132
|
+
- **PATCH** `/billing/subscriptions/:id/pause`
|
|
133
|
+
Pausa uma assinatura.
|
|
134
|
+
|
|
135
|
+
- **PATCH** `/billing/subscriptions/:id/resume`
|
|
136
|
+
Retoma uma assinatura pausada.
|
|
137
|
+
|
|
138
|
+
### Faturas
|
|
139
|
+
|
|
140
|
+
- **GET** `/billing/invoices`
|
|
141
|
+
Lista faturas com paginação.
|
|
142
|
+
|
|
143
|
+
- **GET** `/billing/invoices/:id`
|
|
144
|
+
Obtém detalhes de uma fatura pelo ID, incluindo itens e pagamentos relacionados.
|
|
145
|
+
|
|
146
|
+
- **POST** `/billing/invoices`
|
|
147
|
+
Cria uma nova fatura.
|
|
148
|
+
**Body:** Objeto genérico com dados da fatura.
|
|
149
|
+
|
|
150
|
+
### Pagamentos
|
|
151
|
+
|
|
152
|
+
- **GET** `/billing/payments`
|
|
153
|
+
Lista pagamentos com paginação.
|
|
154
|
+
|
|
155
|
+
- **GET** `/billing/payments/:id`
|
|
156
|
+
Obtém detalhes de um pagamento pelo ID.
|
|
157
|
+
|
|
158
|
+
### Reembolsos
|
|
159
|
+
|
|
160
|
+
- **GET** `/billing/refunds`
|
|
161
|
+
Lista reembolsos com paginação.
|
|
162
|
+
|
|
163
|
+
### Direitos (Entitlements)
|
|
164
|
+
|
|
165
|
+
- **GET** `/billing/entitlements`
|
|
166
|
+
Lista direitos com paginação.
|
|
167
|
+
|
|
168
|
+
- **POST** `/billing/entitlements`
|
|
169
|
+
Cria um novo direito.
|
|
170
|
+
**Body:** `CreateEntitlementDto`
|
|
171
|
+
|
|
172
|
+
- **DELETE** `/billing/entitlements/:id`
|
|
173
|
+
Revoga um direito (status alterado para "revoked").
|
|
174
|
+
|
|
175
|
+
### Contratos
|
|
176
|
+
|
|
177
|
+
- **GET** `/billing/contracts`
|
|
178
|
+
Lista contratos com paginação.
|
|
179
|
+
|
|
180
|
+
- **GET** `/billing/contracts/:id`
|
|
181
|
+
Obtém detalhes de um contrato pelo ID, incluindo assentos e alocações.
|
|
182
|
+
|
|
183
|
+
- **POST** `/billing/contracts`
|
|
184
|
+
Cria um novo contrato.
|
|
185
|
+
**Body:** `CreateContractDto`
|
|
186
|
+
|
|
187
|
+
- **PATCH** `/billing/contracts/:id`
|
|
188
|
+
Atualiza um contrato existente.
|
|
189
|
+
**Body:** `UpdateContractDto`
|
|
190
|
+
|
|
191
|
+
- **DELETE** `/billing/contracts/:id`
|
|
192
|
+
Remove um contrato pelo ID.
|
|
193
|
+
|
|
194
|
+
### Gateways de Pagamento
|
|
195
|
+
|
|
196
|
+
- **GET** `/billing/gateways`
|
|
197
|
+
Lista gateways de pagamento ativos.
|
|
198
|
+
|
|
199
|
+
- **PATCH** `/billing/gateways/:slug`
|
|
200
|
+
Atualiza ou cria um gateway pelo slug.
|
|
201
|
+
**Body:** Objeto genérico com dados do gateway.
|
|
202
|
+
|
|
203
|
+
### Webhooks
|
|
204
|
+
|
|
205
|
+
- **GET** `/billing/webhooks`
|
|
206
|
+
Lista eventos de webhooks com paginação.
|
|
207
|
+
|
|
208
|
+
## 4. Regras de autenticação e autorização
|
|
209
|
+
|
|
210
|
+
- Todos os endpoints requerem autenticação.
|
|
211
|
+
- Acesso restrito a usuários com roles `admin` ou `admin-billing`.
|
|
212
|
+
- Roles definidas no sistema:
|
|
213
|
+
- `admin-billing`: Administrador com acesso total ao billing, pagamentos, assinaturas e faturamento.
|
|
214
|
+
|
|
215
|
+
## 5. Estruturas de request/response
|
|
216
|
+
|
|
217
|
+
### DTOs principais para criação e atualização
|
|
218
|
+
|
|
219
|
+
- `CreateProductDto` / `UpdateProductDto`
|
|
220
|
+
Campos: `name` (string, obrigatório), `code` (string, opcional), `description` (string, opcional), `product_type` (enum: saas, physical, service, addon), `category` (string, opcional), `is_active` (boolean, opcional).
|
|
221
|
+
|
|
222
|
+
- `CreatePriceDto` / `UpdatePriceDto`
|
|
223
|
+
Campos: `product_id` (number, obrigatório), `name` (string, obrigatório), `billing_type` (enum: one_time, recurring), `currency` (string, opcional), `amount_cents` (number, opcional), `interval_unit` (enum: day, week, month, year), `interval_count` (number, opcional), `trial_days` (number, opcional), `setup_fee_cents` (number, opcional), `is_active` (boolean, opcional), `starts_at` (string datetime, opcional), `ends_at` (string datetime, opcional).
|
|
224
|
+
|
|
225
|
+
- `CreateOfferDto` / `UpdateOfferDto`
|
|
226
|
+
Campos: `code` (string, obrigatório), `name` (string, obrigatório), `description` (string, opcional), `status` (string, opcional).
|
|
227
|
+
|
|
228
|
+
- `CreateCouponDto` / `UpdateCouponDto`
|
|
229
|
+
Campos: `code` (string, obrigatório), `name` (string, obrigatório), `discount_type` (enum: percentage, fixed), `discount_value` (number, opcional), `currency` (string, opcional), `max_uses` (number, opcional), `starts_at` (string datetime, opcional), `ends_at` (string datetime, opcional), `status` (enum: active, inactive, expired).
|
|
230
|
+
|
|
231
|
+
- `CreateOrderDto`
|
|
232
|
+
Campos opcionais: `contact_id`, `company_contact_id`, `status` (enum: draft, pending, paid, canceled, refunded), `currency`, `subtotal_cents`, `discount_cents`, `total_cents`, `source`, `notes`.
|
|
233
|
+
|
|
234
|
+
- `CreateSubscriptionDto`
|
|
235
|
+
Campos opcionais: `contact_id`, `product_id`, `price_id`, `gateway`, `gateway_subscription_id`, `status` (enum: trialing, active, past_due, canceled, paused, unpaid), `started_at`, `trial_ends_at`, `current_period_start`, `current_period_end`, `cancel_at_period_end`.
|
|
236
|
+
|
|
237
|
+
- `CreateContractDto` / `UpdateContractDto`
|
|
238
|
+
Campos: `contact_id` (number, obrigatório), `name` (string, obrigatório), `description` (string, opcional), `starts_at` (string datetime, obrigatório), `ends_at` (string datetime, opcional), `total_seats` (number, opcional), `status` (enum: draft, active, expired, terminated), `signed_at` (string datetime, opcional).
|
|
239
|
+
|
|
240
|
+
- `CreateEntitlementDto`
|
|
241
|
+
Campos: `contact_id` (number, obrigatório), `source_type` (string), `source_id` (number), `target_type` (string), `target_id` (number), `access_type` (string), `starts_at` (string datetime, opcional), `ends_at` (string datetime, opcional), `status` (enum: active, revoked, expired).
|
|
242
|
+
|
|
243
|
+
### Respostas
|
|
244
|
+
|
|
245
|
+
- Listagens retornam objetos paginados com dados conforme entidade.
|
|
246
|
+
- Consultas por ID retornam o objeto completo com relacionamentos conforme descrito nos endpoints.
|
|
247
|
+
- Criações e atualizações retornam o objeto criado/atualizado.
|
|
248
|
+
- Exclusões retornam o objeto excluído ou confirmação da operação.
|
|
249
|
+
|
|
250
|
+
## 6. Erros comuns
|
|
251
|
+
|
|
252
|
+
- `404 Not Found`: Quando o recurso solicitado não existe (ex: produto, preço, oferta, cupom, pedido, assinatura, fatura, pagamento, contrato).
|
|
253
|
+
- `401 Unauthorized`: Quando o usuário não está autenticado.
|
|
254
|
+
- `403 Forbidden`: Quando o usuário não possui a role necessária para acessar o recurso.
|
|
255
|
+
- `400 Bad Request`: Dados inválidos ou faltantes nos DTOs de criação/atualização.
|
|
256
|
+
|
|
257
|
+
## 7. Banco de dados (tabelas YAML)
|
|
258
|
+
|
|
259
|
+
### billing_contract
|
|
260
|
+
|
|
261
|
+
- **Finalidade:** Armazena contratos de billing vinculados a contatos.
|
|
262
|
+
- **Colunas principais:** `id` (PK), `contact_id` (FK para person), `name`, `description` (nullable), `starts_at`, `ends_at` (nullable), `total_seats` (nullable), `status` (enum: draft, active, expired, terminated; default draft), `signed_at` (nullable), timestamps.
|
|
263
|
+
- **Índices:** `contact_id`, `status`, `ends_at`.
|
|
264
|
+
|
|
265
|
+
### billing_coupon
|
|
266
|
+
|
|
267
|
+
- **Finalidade:** Cupons de desconto para billing.
|
|
268
|
+
- **Colunas principais:** `id` (PK), `code` (varchar 64, único), `name`, `discount_type` (enum: percentage, fixed; default percentage), `discount_value` (int, default 0), `currency` (char 3, nullable), `max_uses` (nullable), `uses_count` (default 0), `starts_at` (nullable), `ends_at` (nullable), `status` (enum: active, inactive, expired; default active), timestamps.
|
|
269
|
+
- **Índices:** `code` (único), `status`.
|
|
270
|
+
|
|
271
|
+
### billing_entitlement
|
|
272
|
+
|
|
273
|
+
- **Finalidade:** Direitos de acesso concedidos a contatos.
|
|
274
|
+
- **Colunas principais:** `id` (PK), `contact_id` (FK para person), `source_type`, `source_id`, `target_type`, `target_id`, `access_type`, `starts_at` (nullable), `ends_at` (nullable), `status` (enum: active, revoked, expired; default active), timestamps.
|
|
275
|
+
- **Índices:** `contact_id`, `source_type+source_id`, `target_type+target_id`, `status`, `ends_at`.
|
|
276
|
+
|
|
277
|
+
### billing_invoice
|
|
278
|
+
|
|
279
|
+
- **Finalidade:** Faturas geradas para assinaturas ou pedidos.
|
|
280
|
+
- **Colunas principais:** `id` (PK), `subscription_id` (FK nullable), `order_id` (FK nullable), `contact_id` (FK nullable), `invoice_number` (nullable), `status` (enum: draft, open, paid, void, uncollectible; default draft), `currency` (char 3; default BRL), `subtotal_cents` (default 0), `total_cents` (default 0), `due_date` (nullable), `paid_at` (nullable), timestamps.
|
|
281
|
+
- **Índices:** `subscription_id`, `order_id`, `contact_id`, `invoice_number`, `status`, `due_date`.
|
|
282
|
+
|
|
283
|
+
### billing_payment
|
|
284
|
+
|
|
285
|
+
- **Finalidade:** Registra pagamentos realizados.
|
|
286
|
+
- **Colunas principais:** `id` (PK), `invoice_id` (FK nullable), `order_id` (FK nullable), `contact_id` (FK nullable), `provider` (nullable), `method_type` (enum: card, pix, boleto, bank_transfer, wallet, other; default card), `status` (enum: pending, processing, paid, failed, canceled, refunded; default pending), `amount_cents` (default 0), `currency` (char 3; default BRL), `external_transaction_id` (nullable), `paid_at` (nullable), `raw_response` (nullable), timestamps.
|
|
287
|
+
- **Índices:** `invoice_id`, `order_id`, `contact_id`, `provider`, `status`, `external_transaction_id`, `paid_at`.
|
|
288
|
+
|
|
289
|
+
### billing_product
|
|
290
|
+
|
|
291
|
+
- **Finalidade:** Produtos disponíveis para venda.
|
|
292
|
+
- **Colunas principais:** `id` (PK), `code` (nullable, único), `name`, `description` (nullable), `product_type` (enum: saas, physical, service, addon; default saas), `category` (nullable), `is_active` (default true), timestamps.
|
|
293
|
+
- **Índices:** `code` (único), `product_type`, `is_active`.
|
|
294
|
+
|
|
295
|
+
### billing_subscription
|
|
296
|
+
|
|
297
|
+
- **Finalidade:** Assinaturas de produtos por contatos.
|
|
298
|
+
- **Colunas principais:** `id` (PK), `contact_id` (FK nullable), `product_id` (FK nullable), `price_id` (FK nullable), `gateway` (nullable), `gateway_subscription_id` (nullable), `status` (enum: trialing, active, past_due, canceled, paused, unpaid; default active), `started_at` (nullable), `trial_ends_at` (nullable), `current_period_start` (nullable), `current_period_end` (nullable), `cancel_at_period_end` (boolean; default false), `canceled_at` (nullable), timestamps.
|
|
299
|
+
- **Índices:** `contact_id`, `product_id`, `price_id`, `gateway`, `gateway_subscription_id`, `status`.
|
|
300
|
+
|
|
301
|
+
### billing_order
|
|
302
|
+
|
|
303
|
+
- **Finalidade:** Pedidos realizados.
|
|
304
|
+
- **Colunas principais:** `id` (PK), `contact_id` (FK nullable), `company_contact_id` (FK nullable), `status` (enum: draft, pending, paid, canceled, refunded; default draft), `currency` (char 3; default BRL), `subtotal_cents` (default 0), `discount_cents` (default 0), `total_cents` (default 0), `source` (nullable), `notes` (nullable), timestamps.
|
|
305
|
+
- **Índices:** `contact_id`, `company_contact_id`, `status`, `created_at`.
|
|
306
|
+
|
|
307
|
+
### billing_refund
|
|
308
|
+
|
|
309
|
+
- **Finalidade:** Reembolsos de pagamentos.
|
|
310
|
+
- **Colunas principais:** `id` (PK), `payment_id` (FK), `contact_id` (FK nullable), `amount_cents` (default 0), `reason` (nullable), `status` (enum: pending, completed, failed; default pending), `external_refund_id` (nullable), `completed_at` (nullable), timestamps.
|
|
311
|
+
- **Índices:** `payment_id`, `contact_id`, `status`.
|
|
312
|
+
|
|
313
|
+
### billing_payment_provider
|
|
314
|
+
|
|
315
|
+
- **Finalidade:** Gateways de pagamento configurados.
|
|
316
|
+
- **Colunas principais:** `id` (PK), `slug` (varchar 64, único), `name`, `is_active` (boolean, default true), `config_json` (nullable), timestamps.
|
|
317
|
+
- **Índices:** `slug` (único), `is_active`.
|
|
318
|
+
|
|
319
|
+
### billing_provider_event
|
|
320
|
+
|
|
321
|
+
- **Finalidade:** Eventos recebidos via webhook dos provedores.
|
|
322
|
+
- **Colunas principais:** `id` (PK), `provider_id` (FK), `event_type`, `external_event_id` (nullable), `payload`, `processed` (boolean, default false), `processed_at` (nullable), `created_at`.
|
|
323
|
+
- **Índices:** `provider_id`, `event_type`, `processed`, `external_event_id`.
|
|
324
|
+
|
|
325
|
+
(Outras tabelas seguem padrão similar com chaves primárias, estrangeiras, enums e timestamps.)
|
|
326
|
+
|
|
327
|
+
## 8. Regras de negócio relevantes
|
|
328
|
+
|
|
329
|
+
- Status de entidades são controlados via enums específicos para cada tipo (ex: contratos, cupons, assinaturas).
|
|
330
|
+
- Exclusão de contratos, produtos, preços, ofertas, cupons e outros remove o registro do banco.
|
|
331
|
+
- Revogação de direitos altera status para "revoked" sem exclusão física.
|
|
332
|
+
- Atualização de gateways pode criar ou atualizar registros via upsert pelo slug.
|
|
333
|
+
- Dashboard agrega dados importantes para monitoramento do sistema de billing.
|
|
334
|
+
- Paginação é aplicada em todas as listagens para controle de volume de dados.
|
|
335
|
+
- Assinaturas podem ser canceladas, pausadas e retomadas via endpoints específicos.
|
|
336
|
+
- Faturas podem ser criadas manualmente via API.
|
|
337
|
+
|
|
338
|
+
## 9. Guia rápido de uso (exemplos)
|
|
339
|
+
|
|
340
|
+
### Listar produtos paginados
|
|
341
|
+
|
|
342
|
+
```http
|
|
343
|
+
GET /billing/products
|
|
344
|
+
Authorization: Bearer <token>
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
Resposta:
|
|
348
|
+
|
|
349
|
+
```json
|
|
350
|
+
{
|
|
351
|
+
"items": [
|
|
352
|
+
{
|
|
353
|
+
"id": 1,
|
|
354
|
+
"name": "Produto A",
|
|
355
|
+
"code": "PROD_A",
|
|
356
|
+
"description": "Descrição do produto A",
|
|
357
|
+
"product_type": "saas",
|
|
358
|
+
"is_active": true,
|
|
359
|
+
"created_at": "...",
|
|
360
|
+
"updated_at": "..."
|
|
361
|
+
}
|
|
362
|
+
],
|
|
363
|
+
"total": 100,
|
|
364
|
+
"page": 1,
|
|
365
|
+
"pageSize": 10
|
|
366
|
+
}
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
### Criar um novo cupom
|
|
370
|
+
|
|
371
|
+
```http
|
|
372
|
+
POST /billing/coupons
|
|
373
|
+
Authorization: Bearer <token>
|
|
374
|
+
Content-Type: application/json
|
|
375
|
+
|
|
376
|
+
{
|
|
377
|
+
"code": "DESCONTO10",
|
|
378
|
+
"name": "Desconto 10%",
|
|
379
|
+
"discount_type": "percentage",
|
|
380
|
+
"discount_value": 10,
|
|
381
|
+
"status": "active"
|
|
382
|
+
}
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
Resposta:
|
|
386
|
+
|
|
387
|
+
```json
|
|
388
|
+
{
|
|
389
|
+
"id": 5,
|
|
390
|
+
"code": "DESCONTO10",
|
|
391
|
+
"name": "Desconto 10%",
|
|
392
|
+
"discount_type": "percentage",
|
|
393
|
+
"discount_value": 10,
|
|
394
|
+
"status": "active",
|
|
395
|
+
"created_at": "...",
|
|
396
|
+
"updated_at": "..."
|
|
397
|
+
}
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
### Cancelar uma assinatura
|
|
401
|
+
|
|
402
|
+
```http
|
|
403
|
+
PATCH /billing/subscriptions/123/cancel
|
|
404
|
+
Authorization: Bearer <token>
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
Resposta:
|
|
408
|
+
|
|
409
|
+
```json
|
|
410
|
+
{
|
|
411
|
+
"id": 123,
|
|
412
|
+
"status": "canceled",
|
|
413
|
+
"canceled_at": "2024-06-01T12:00:00Z",
|
|
414
|
+
...
|
|
415
|
+
}
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
---
|
|
419
|
+
|
|
420
|
+
Este módulo é fundamental para a gestão financeira e comercial da plataforma, garantindo controle rigoroso e flexível sobre faturamento, assinaturas e pagamentos.
|
|
@@ -14,9 +14,90 @@ export declare class BillingContractsController {
|
|
|
14
14
|
next: number;
|
|
15
15
|
data: any[];
|
|
16
16
|
}>;
|
|
17
|
-
get(id: number): Promise<
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
get(id: number): Promise<{
|
|
18
|
+
billing_contract_seat: ({
|
|
19
|
+
billing_product: {
|
|
20
|
+
code: string | null;
|
|
21
|
+
name: string;
|
|
22
|
+
id: number;
|
|
23
|
+
description: string | null;
|
|
24
|
+
created_at: Date;
|
|
25
|
+
updated_at: Date;
|
|
26
|
+
is_active: boolean;
|
|
27
|
+
product_type: import("@prisma/client").$Enums.billing_product_product_type_enum;
|
|
28
|
+
category: string | null;
|
|
29
|
+
};
|
|
30
|
+
} & {
|
|
31
|
+
id: number;
|
|
32
|
+
created_at: Date;
|
|
33
|
+
updated_at: Date;
|
|
34
|
+
contract_id: number;
|
|
35
|
+
product_id: number;
|
|
36
|
+
quantity: number;
|
|
37
|
+
price_per_seat_cents: number | null;
|
|
38
|
+
})[];
|
|
39
|
+
billing_seat_allocation: {
|
|
40
|
+
id: number;
|
|
41
|
+
created_at: Date;
|
|
42
|
+
updated_at: Date;
|
|
43
|
+
status: import("@prisma/client").$Enums.billing_seat_allocation_status_enum;
|
|
44
|
+
contract_id: number;
|
|
45
|
+
seat_id: number;
|
|
46
|
+
person_id: number;
|
|
47
|
+
allocated_at: Date;
|
|
48
|
+
released_at: Date | null;
|
|
49
|
+
}[];
|
|
50
|
+
} & {
|
|
51
|
+
name: string;
|
|
52
|
+
id: number;
|
|
53
|
+
description: string | null;
|
|
54
|
+
created_at: Date;
|
|
55
|
+
updated_at: Date;
|
|
56
|
+
status: import("@prisma/client").$Enums.billing_contract_status_enum;
|
|
57
|
+
contact_id: number;
|
|
58
|
+
starts_at: Date;
|
|
59
|
+
ends_at: Date | null;
|
|
60
|
+
total_seats: number | null;
|
|
61
|
+
signed_at: Date | null;
|
|
62
|
+
}>;
|
|
63
|
+
create(dto: CreateContractDto): Promise<{
|
|
64
|
+
name: string;
|
|
65
|
+
id: number;
|
|
66
|
+
description: string | null;
|
|
67
|
+
created_at: Date;
|
|
68
|
+
updated_at: Date;
|
|
69
|
+
status: import("@prisma/client").$Enums.billing_contract_status_enum;
|
|
70
|
+
contact_id: number;
|
|
71
|
+
starts_at: Date;
|
|
72
|
+
ends_at: Date | null;
|
|
73
|
+
total_seats: number | null;
|
|
74
|
+
signed_at: Date | null;
|
|
75
|
+
}>;
|
|
76
|
+
update(id: number, dto: UpdateContractDto): Promise<{
|
|
77
|
+
name: string;
|
|
78
|
+
id: number;
|
|
79
|
+
description: string | null;
|
|
80
|
+
created_at: Date;
|
|
81
|
+
updated_at: Date;
|
|
82
|
+
status: import("@prisma/client").$Enums.billing_contract_status_enum;
|
|
83
|
+
contact_id: number;
|
|
84
|
+
starts_at: Date;
|
|
85
|
+
ends_at: Date | null;
|
|
86
|
+
total_seats: number | null;
|
|
87
|
+
signed_at: Date | null;
|
|
88
|
+
}>;
|
|
89
|
+
remove(id: number): Promise<{
|
|
90
|
+
name: string;
|
|
91
|
+
id: number;
|
|
92
|
+
description: string | null;
|
|
93
|
+
created_at: Date;
|
|
94
|
+
updated_at: Date;
|
|
95
|
+
status: import("@prisma/client").$Enums.billing_contract_status_enum;
|
|
96
|
+
contact_id: number;
|
|
97
|
+
starts_at: Date;
|
|
98
|
+
ends_at: Date | null;
|
|
99
|
+
total_seats: number | null;
|
|
100
|
+
signed_at: Date | null;
|
|
101
|
+
}>;
|
|
21
102
|
}
|
|
22
103
|
//# sourceMappingURL=billing-contracts.controller.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"billing-contracts.controller.d.ts","sourceRoot":"","sources":["../src/billing-contracts.controller.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAWpE,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAE9D,qBAEa,0BAA0B;IACzB,OAAO,CAAC,QAAQ,CAAC,cAAc;gBAAd,cAAc,EAAE,cAAc;IAG3D,IAAI,CAAe,gBAAgB,EAAE,aAAa;;;;;;;;;IAKlD,GAAG,CAA4B,EAAE,EAAE,MAAM
|
|
1
|
+
{"version":3,"file":"billing-contracts.controller.d.ts","sourceRoot":"","sources":["../src/billing-contracts.controller.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAWpE,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAE9D,qBAEa,0BAA0B;IACzB,OAAO,CAAC,QAAQ,CAAC,cAAc;gBAAd,cAAc,EAAE,cAAc;IAG3D,IAAI,CAAe,gBAAgB,EAAE,aAAa;;;;;;;;;IAKlD,GAAG,CAA4B,EAAE,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAKzC,MAAM,CAAS,GAAG,EAAE,iBAAiB;;;;;;;;;;;;;IAKrC,MAAM,CAA4B,EAAE,EAAE,MAAM,EAAU,GAAG,EAAE,iBAAiB;;;;;;;;;;;;;IAK5E,MAAM,CAA4B,EAAE,EAAE,MAAM;;;;;;;;;;;;;CAG7C"}
|
|
@@ -14,9 +14,65 @@ export declare class BillingCouponsController {
|
|
|
14
14
|
next: number;
|
|
15
15
|
data: any[];
|
|
16
16
|
}>;
|
|
17
|
-
get(id: number): Promise<
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
get(id: number): Promise<{
|
|
18
|
+
currency: string | null;
|
|
19
|
+
code: string;
|
|
20
|
+
name: string;
|
|
21
|
+
id: number;
|
|
22
|
+
created_at: Date;
|
|
23
|
+
updated_at: Date;
|
|
24
|
+
status: import("@prisma/client").$Enums.billing_coupon_status_enum;
|
|
25
|
+
starts_at: Date | null;
|
|
26
|
+
ends_at: Date | null;
|
|
27
|
+
discount_type: import("@prisma/client").$Enums.billing_coupon_discount_type_enum;
|
|
28
|
+
discount_value: number;
|
|
29
|
+
max_uses: number | null;
|
|
30
|
+
uses_count: number;
|
|
31
|
+
}>;
|
|
32
|
+
create(dto: CreateCouponDto): Promise<{
|
|
33
|
+
currency: string | null;
|
|
34
|
+
code: string;
|
|
35
|
+
name: string;
|
|
36
|
+
id: number;
|
|
37
|
+
created_at: Date;
|
|
38
|
+
updated_at: Date;
|
|
39
|
+
status: import("@prisma/client").$Enums.billing_coupon_status_enum;
|
|
40
|
+
starts_at: Date | null;
|
|
41
|
+
ends_at: Date | null;
|
|
42
|
+
discount_type: import("@prisma/client").$Enums.billing_coupon_discount_type_enum;
|
|
43
|
+
discount_value: number;
|
|
44
|
+
max_uses: number | null;
|
|
45
|
+
uses_count: number;
|
|
46
|
+
}>;
|
|
47
|
+
update(id: number, dto: UpdateCouponDto): Promise<{
|
|
48
|
+
currency: string | null;
|
|
49
|
+
code: string;
|
|
50
|
+
name: string;
|
|
51
|
+
id: number;
|
|
52
|
+
created_at: Date;
|
|
53
|
+
updated_at: Date;
|
|
54
|
+
status: import("@prisma/client").$Enums.billing_coupon_status_enum;
|
|
55
|
+
starts_at: Date | null;
|
|
56
|
+
ends_at: Date | null;
|
|
57
|
+
discount_type: import("@prisma/client").$Enums.billing_coupon_discount_type_enum;
|
|
58
|
+
discount_value: number;
|
|
59
|
+
max_uses: number | null;
|
|
60
|
+
uses_count: number;
|
|
61
|
+
}>;
|
|
62
|
+
remove(id: number): Promise<{
|
|
63
|
+
currency: string | null;
|
|
64
|
+
code: string;
|
|
65
|
+
name: string;
|
|
66
|
+
id: number;
|
|
67
|
+
created_at: Date;
|
|
68
|
+
updated_at: Date;
|
|
69
|
+
status: import("@prisma/client").$Enums.billing_coupon_status_enum;
|
|
70
|
+
starts_at: Date | null;
|
|
71
|
+
ends_at: Date | null;
|
|
72
|
+
discount_type: import("@prisma/client").$Enums.billing_coupon_discount_type_enum;
|
|
73
|
+
discount_value: number;
|
|
74
|
+
max_uses: number | null;
|
|
75
|
+
uses_count: number;
|
|
76
|
+
}>;
|
|
21
77
|
}
|
|
22
78
|
//# sourceMappingURL=billing-coupons.controller.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"billing-coupons.controller.d.ts","sourceRoot":"","sources":["../src/billing-coupons.controller.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAWpE,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE1D,qBAEa,wBAAwB;IACvB,OAAO,CAAC,QAAQ,CAAC,cAAc;gBAAd,cAAc,EAAE,cAAc;IAG3D,IAAI,CAAe,gBAAgB,EAAE,aAAa;;;;;;;;;IAKlD,GAAG,CAA4B,EAAE,EAAE,MAAM
|
|
1
|
+
{"version":3,"file":"billing-coupons.controller.d.ts","sourceRoot":"","sources":["../src/billing-coupons.controller.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAWpE,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE1D,qBAEa,wBAAwB;IACvB,OAAO,CAAC,QAAQ,CAAC,cAAc;gBAAd,cAAc,EAAE,cAAc;IAG3D,IAAI,CAAe,gBAAgB,EAAE,aAAa;;;;;;;;;IAKlD,GAAG,CAA4B,EAAE,EAAE,MAAM;;;;;;;;;;;;;;;IAKzC,MAAM,CAAS,GAAG,EAAE,eAAe;;;;;;;;;;;;;;;IAKnC,MAAM,CAA4B,EAAE,EAAE,MAAM,EAAU,GAAG,EAAE,eAAe;;;;;;;;;;;;;;;IAK1E,MAAM,CAA4B,EAAE,EAAE,MAAM;;;;;;;;;;;;;;;CAG7C"}
|
|
@@ -3,11 +3,26 @@ export declare class BillingDashboardController {
|
|
|
3
3
|
private readonly billingService;
|
|
4
4
|
constructor(billingService: BillingService);
|
|
5
5
|
getData(): Promise<{
|
|
6
|
-
activeSubscriptions:
|
|
7
|
-
failedPayments:
|
|
8
|
-
overdueInvoices:
|
|
9
|
-
revenueThisMonthCents:
|
|
10
|
-
recentPayments:
|
|
6
|
+
activeSubscriptions: number;
|
|
7
|
+
failedPayments: number;
|
|
8
|
+
overdueInvoices: number;
|
|
9
|
+
revenueThisMonthCents: number;
|
|
10
|
+
recentPayments: {
|
|
11
|
+
currency: string;
|
|
12
|
+
id: number;
|
|
13
|
+
provider: string | null;
|
|
14
|
+
created_at: Date;
|
|
15
|
+
updated_at: Date;
|
|
16
|
+
status: import("@prisma/client").$Enums.billing_payment_status_enum;
|
|
17
|
+
amount_cents: number;
|
|
18
|
+
contact_id: number | null;
|
|
19
|
+
order_id: number | null;
|
|
20
|
+
paid_at: Date | null;
|
|
21
|
+
invoice_id: number | null;
|
|
22
|
+
method_type: import("@prisma/client").$Enums.billing_payment_method_type_enum;
|
|
23
|
+
external_transaction_id: string | null;
|
|
24
|
+
raw_response: string | null;
|
|
25
|
+
}[];
|
|
11
26
|
}>;
|
|
12
27
|
}
|
|
13
28
|
//# sourceMappingURL=billing-dashboard.controller.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"billing-dashboard.controller.d.ts","sourceRoot":"","sources":["../src/billing-dashboard.controller.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,qBAEa,0BAA0B;IACzB,OAAO,CAAC,QAAQ,CAAC,cAAc;gBAAd,cAAc,EAAE,cAAc;IAG3D,OAAO
|
|
1
|
+
{"version":3,"file":"billing-dashboard.controller.d.ts","sourceRoot":"","sources":["../src/billing-dashboard.controller.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,qBAEa,0BAA0B;IACzB,OAAO,CAAC,QAAQ,CAAC,cAAc;gBAAd,cAAc,EAAE,cAAc;IAG3D,OAAO;;;;;;;;;;;;;;;;;;;;;;CAGR"}
|
|
@@ -13,7 +13,33 @@ export declare class BillingEntitlementsController {
|
|
|
13
13
|
next: number;
|
|
14
14
|
data: any[];
|
|
15
15
|
}>;
|
|
16
|
-
create(dto: CreateEntitlementDto): Promise<
|
|
17
|
-
|
|
16
|
+
create(dto: CreateEntitlementDto): Promise<{
|
|
17
|
+
id: number;
|
|
18
|
+
created_at: Date;
|
|
19
|
+
updated_at: Date;
|
|
20
|
+
status: import("@prisma/client").$Enums.billing_entitlement_status_enum;
|
|
21
|
+
source_type: string;
|
|
22
|
+
contact_id: number;
|
|
23
|
+
starts_at: Date | null;
|
|
24
|
+
ends_at: Date | null;
|
|
25
|
+
source_id: number;
|
|
26
|
+
target_type: string;
|
|
27
|
+
target_id: number;
|
|
28
|
+
access_type: string;
|
|
29
|
+
}>;
|
|
30
|
+
remove(id: number): Promise<{
|
|
31
|
+
id: number;
|
|
32
|
+
created_at: Date;
|
|
33
|
+
updated_at: Date;
|
|
34
|
+
status: import("@prisma/client").$Enums.billing_entitlement_status_enum;
|
|
35
|
+
source_type: string;
|
|
36
|
+
contact_id: number;
|
|
37
|
+
starts_at: Date | null;
|
|
38
|
+
ends_at: Date | null;
|
|
39
|
+
source_id: number;
|
|
40
|
+
target_type: string;
|
|
41
|
+
target_id: number;
|
|
42
|
+
access_type: string;
|
|
43
|
+
}>;
|
|
18
44
|
}
|
|
19
45
|
//# sourceMappingURL=billing-entitlements.controller.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"billing-entitlements.controller.d.ts","sourceRoot":"","sources":["../src/billing-entitlements.controller.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAUpE,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAEpE,qBAEa,6BAA6B;IAC5B,OAAO,CAAC,QAAQ,CAAC,cAAc;gBAAd,cAAc,EAAE,cAAc;IAG3D,IAAI,CAAe,gBAAgB,EAAE,aAAa;;;;;;;;;IAKlD,MAAM,CAAS,GAAG,EAAE,oBAAoB
|
|
1
|
+
{"version":3,"file":"billing-entitlements.controller.d.ts","sourceRoot":"","sources":["../src/billing-entitlements.controller.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAUpE,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAEpE,qBAEa,6BAA6B;IAC5B,OAAO,CAAC,QAAQ,CAAC,cAAc;gBAAd,cAAc,EAAE,cAAc;IAG3D,IAAI,CAAe,gBAAgB,EAAE,aAAa;;;;;;;;;IAKlD,MAAM,CAAS,GAAG,EAAE,oBAAoB;;;;;;;;;;;;;;IAKxC,MAAM,CAA4B,EAAE,EAAE,MAAM;;;;;;;;;;;;;;CAG7C"}
|