@riligar/agents-kit 1.16.0 → 1.18.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.
@@ -151,7 +151,7 @@ Instrua o usuário:
151
151
  >
152
152
  > 1. Acesse https://dashboard.stripe.com/webhooks
153
153
  > 2. Clique em "Add endpoint"
154
- > 3. URL: `https://seu-dominio.com/webhook/stripe`
154
+ > 3. URL: `https://seu-dominio.com/api/webhook`
155
155
  > 4. Selecione os eventos:
156
156
  > - `checkout.session.completed`
157
157
  > - `customer.subscription.updated`
@@ -171,14 +171,15 @@ Gere todos os arquivos necessários usando os templates de [assets/](assets/):
171
171
  | `routes/billing.js` | stripe-server.js (seção 2) |
172
172
  | `routes/webhook.js` | stripe-server.js (seção 3) |
173
173
  | `services/billing.js` | stripe-server.js (seção 4) |
174
- | `config/stripe-prices.js` | Price IDs coletados |
174
+ | `config/stripe-prices.js` | Price IDs coletados (Step 9) |
175
+ | `config/plans.js` | PLAN_MAP + PLAN_LIMITS (Step 9) |
175
176
  | `pages/Pricing.jsx` | stripe-client.js (seção 3) |
176
177
  | `components/BillingSettings.jsx` | stripe-client.js (seção 4) |
177
178
  | `hooks/useSubscription.js` | stripe-client.js (seção 2) |
178
179
 
179
- ### Step 9: Criar Config de Preços
180
+ ### Step 9: Criar Configs de Planos e Preços
180
181
 
181
- Gere o arquivo de configuração com os Price IDs:
182
+ **A) Arquivo de preços (config/stripe-prices.js):**
182
183
 
183
184
  ```javascript
184
185
  // config/stripe-prices.js
@@ -194,6 +195,12 @@ export const STRIPE_PRICES = {
194
195
  name: 'Pro',
195
196
  price: 99,
196
197
  features: ['Projetos ilimitados', 'Suporte prioritário', '10GB storage']
198
+ },
199
+ enterprise: {
200
+ priceId: 'price_COLETADO_ENTERPRISE',
201
+ name: 'Enterprise',
202
+ price: 299,
203
+ features: ['Tudo do Pro', 'Storage ilimitado', 'SLA garantido']
197
204
  }
198
205
  }
199
206
 
@@ -201,6 +208,40 @@ export const getPrice = (plan) => STRIPE_PRICES[plan]
201
208
  export const getPriceId = (plan) => STRIPE_PRICES[plan]?.priceId
202
209
  ```
203
210
 
211
+ **B) Arquivo de mapeamento e limites (config/plans.js):**
212
+
213
+ ```javascript
214
+ // config/plans.js
215
+
216
+ // Mapeia Price IDs do Stripe para nomes de planos internos
217
+ export const PLAN_MAP = {
218
+ 'price_COLETADO_STARTER': 'starter',
219
+ 'price_COLETADO_PRO': 'pro',
220
+ 'price_COLETADO_ENTERPRISE': 'enterprise',
221
+ }
222
+
223
+ // Define limites de features por plano
224
+ export const PLAN_LIMITS = {
225
+ free: {
226
+ maxFlows: 1,
227
+ maxContacts: 100,
228
+ // Adicione outros limites conforme necessário
229
+ },
230
+ starter: {
231
+ maxFlows: 3,
232
+ maxContacts: 500,
233
+ },
234
+ pro: {
235
+ maxFlows: 15,
236
+ maxContacts: 5000,
237
+ },
238
+ enterprise: {
239
+ maxFlows: 55,
240
+ maxContacts: Infinity,
241
+ },
242
+ }
243
+ ```
244
+
204
245
  ---
205
246
 
206
247
  ## Checklist Final
@@ -211,11 +252,13 @@ Ao completar o setup, confirme:
211
252
  - [ ] Chaves no `.env.development` e `.env.production` (backend e frontend)
212
253
  - [ ] Produtos criados no Stripe
213
254
  - [ ] Price IDs configurados em `config/stripe-prices.js`
214
- - [ ] Schema do database atualizado
215
- - [ ] Webhook endpoint configurado no Stripe Dashboard
255
+ - [ ] `PLAN_MAP` e `PLAN_LIMITS` configurados em `config/plans.js`
256
+ - [ ] Schema do database atualizado (campos Stripe na tabela users)
257
+ - [ ] Webhook endpoint configurado no Stripe Dashboard (`/api/webhook`)
216
258
  - [ ] Webhook secret nos arquivos de ambiente
217
- - [ ] Rotas de billing funcionando
218
- - [ ] Página de pricing criada
259
+ - [ ] Rotas de billing funcionando (`/api/billing/*`)
260
+ - [ ] Página de pricing criada (com token de auth no ky)
261
+ - [ ] `useSubscription` hook com header Authorization
219
262
  - [ ] Testado com cartão 4242 4242 4242 4242
220
263
 
221
264
  ---
@@ -229,8 +272,8 @@ brew install stripe/stripe-cli/stripe
229
272
  # Login
230
273
  stripe login
231
274
 
232
- # Forward webhooks
233
- stripe listen --forward-to localhost:3000/webhook/stripe
275
+ # Forward webhooks (ajuste a porta conforme seu backend)
276
+ stripe listen --forward-to localhost:3333/api/webhook
234
277
 
235
278
  # Testar checkout
236
279
  stripe trigger checkout.session.completed
@@ -32,6 +32,20 @@ export const elementsAppearance = {
32
32
  import { useState, useEffect } from 'react'
33
33
  import ky from 'ky'
34
34
 
35
+ const api = ky.create({
36
+ prefixUrl: import.meta.env.VITE_API_URL || 'http://localhost:3333',
37
+ hooks: {
38
+ beforeRequest: [
39
+ request => {
40
+ const token = localStorage.getItem('auth:token')
41
+ if (token) {
42
+ request.headers.set('Authorization', `Bearer ${token}`)
43
+ }
44
+ },
45
+ ],
46
+ },
47
+ })
48
+
35
49
  export function useSubscription() {
36
50
  const [subscription, setSubscription] = useState(null)
37
51
  const [loading, setLoading] = useState(true)
@@ -40,7 +54,7 @@ export function useSubscription() {
40
54
  const fetchSubscription = async () => {
41
55
  setLoading(true)
42
56
  try {
43
- const data = await ky.get('/api/billing/subscription').json()
57
+ const data = await api.get('api/billing/subscription').json()
44
58
  setSubscription(data)
45
59
  setError(null)
46
60
  } catch (err) {
@@ -77,35 +91,52 @@ import { IconCheck } from '@tabler/icons-react'
77
91
  import { useState } from 'react'
78
92
  import ky from 'ky'
79
93
 
94
+ // Importar do arquivo de configuração centralizado
95
+ // import { STRIPE_PRICES } from '../config/stripe-prices'
96
+
80
97
  const plans = [
81
98
  {
82
99
  name: 'Starter',
83
- priceId: 'price_starter_monthly',
100
+ priceId: 'price_starter_monthly', // Substituir pelo valor de STRIPE_PRICES.starter.priceId
84
101
  price: 29,
85
102
  features: ['5 projetos', 'Suporte por email', '1GB de storage']
86
103
  },
87
104
  {
88
105
  name: 'Pro',
89
- priceId: 'price_pro_monthly',
106
+ priceId: 'price_pro_monthly', // Substituir pelo valor de STRIPE_PRICES.pro.priceId
90
107
  price: 99,
91
108
  popular: true,
92
109
  features: ['Projetos ilimitados', 'Suporte prioritário', '10GB de storage', 'API access']
93
110
  },
94
111
  {
95
112
  name: 'Enterprise',
96
- priceId: 'price_enterprise_monthly',
113
+ priceId: 'price_enterprise_monthly', // Substituir pelo valor de STRIPE_PRICES.enterprise.priceId
97
114
  price: 299,
98
115
  features: ['Tudo do Pro', 'Suporte dedicado', 'Storage ilimitado', 'SLA garantido']
99
116
  }
100
117
  ]
101
118
 
119
+ const api = ky.create({
120
+ prefixUrl: import.meta.env.VITE_API_URL || 'http://localhost:3333',
121
+ hooks: {
122
+ beforeRequest: [
123
+ request => {
124
+ const token = localStorage.getItem('auth:token')
125
+ if (token) {
126
+ request.headers.set('Authorization', `Bearer ${token}`)
127
+ }
128
+ },
129
+ ],
130
+ },
131
+ })
132
+
102
133
  export default function Pricing() {
103
134
  const [loading, setLoading] = useState(null)
104
135
 
105
136
  const handleCheckout = async (priceId) => {
106
137
  setLoading(priceId)
107
138
  try {
108
- const { url } = await ky.post('/api/billing/checkout', {
139
+ const { url } = await api.post('api/billing/checkout', {
109
140
  json: { priceId, mode: 'subscription' }
110
141
  }).json()
111
142
  window.location.href = url
@@ -178,12 +209,26 @@ import { Button, Card, Group, Stack, Text, Title, Badge, Divider } from '@mantin
178
209
  import { useState, useEffect } from 'react'
179
210
  import ky from 'ky'
180
211
 
212
+ const api = ky.create({
213
+ prefixUrl: import.meta.env.VITE_API_URL || 'http://localhost:3333',
214
+ hooks: {
215
+ beforeRequest: [
216
+ request => {
217
+ const token = localStorage.getItem('auth:token')
218
+ if (token) {
219
+ request.headers.set('Authorization', `Bearer ${token}`)
220
+ }
221
+ },
222
+ ],
223
+ },
224
+ })
225
+
181
226
  export default function BillingSettings() {
182
227
  const [subscription, setSubscription] = useState(null)
183
228
  const [loading, setLoading] = useState(false)
184
229
 
185
230
  useEffect(() => {
186
- ky.get('/api/billing/subscription').json()
231
+ api.get('api/billing/subscription').json()
187
232
  .then(setSubscription)
188
233
  .catch(console.error)
189
234
  }, [])
@@ -191,7 +236,7 @@ export default function BillingSettings() {
191
236
  const openPortal = async () => {
192
237
  setLoading(true)
193
238
  try {
194
- const { url } = await ky.post('/api/billing/portal').json()
239
+ const { url } = await api.post('api/billing/portal').json()
195
240
  window.location.href = url
196
241
  } finally {
197
242
  setLoading(false)
@@ -201,9 +246,9 @@ export default function BillingSettings() {
201
246
  const cancelSubscription = async () => {
202
247
  setLoading(true)
203
248
  try {
204
- await ky.post('/api/billing/subscription/cancel').json()
249
+ await api.post('api/billing/subscription/cancel').json()
205
250
  // Refresh subscription data
206
- const data = await ky.get('/api/billing/subscription').json()
251
+ const data = await api.get('api/billing/subscription').json()
207
252
  setSubscription(data)
208
253
  } finally {
209
254
  setLoading(false)
@@ -356,12 +401,26 @@ import { IconDownload } from '@tabler/icons-react'
356
401
  import { useState, useEffect } from 'react'
357
402
  import ky from 'ky'
358
403
 
404
+ const api = ky.create({
405
+ prefixUrl: import.meta.env.VITE_API_URL || 'http://localhost:3333',
406
+ hooks: {
407
+ beforeRequest: [
408
+ request => {
409
+ const token = localStorage.getItem('auth:token')
410
+ if (token) {
411
+ request.headers.set('Authorization', `Bearer ${token}`)
412
+ }
413
+ },
414
+ ],
415
+ },
416
+ })
417
+
359
418
  export default function InvoiceList() {
360
419
  const [invoices, setInvoices] = useState([])
361
420
  const [loading, setLoading] = useState(true)
362
421
 
363
422
  useEffect(() => {
364
- ky.get('/api/billing/invoices').json()
423
+ api.get('api/billing/invoices').json()
365
424
  .then(({ data }) => setInvoices(data))
366
425
  .catch(console.error)
367
426
  .finally(() => setLoading(false))