@riligar/agents-kit 1.12.0 → 1.14.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.
Files changed (39) hide show
  1. package/.agent/skills/riligar-business-startup/SKILL.md +0 -1
  2. package/.agent/skills/riligar-design-system/SKILL.md +0 -1
  3. package/.agent/skills/riligar-dev-architecture/SKILL.md +7 -8
  4. package/.agent/skills/riligar-dev-auth-elysia/SKILL.md +7 -3
  5. package/.agent/skills/riligar-dev-auth-react/SKILL.md +5 -3
  6. package/.agent/skills/riligar-dev-autopilot/SKILL.md +0 -1
  7. package/.agent/skills/riligar-dev-backend/SKILL.md +0 -1
  8. package/.agent/skills/riligar-dev-clean-code/SKILL.md +0 -1
  9. package/.agent/skills/riligar-dev-code-review/SKILL.md +0 -1
  10. package/.agent/skills/riligar-dev-database/SKILL.md +8 -9
  11. package/.agent/skills/riligar-dev-frontend/SKILL.md +0 -1
  12. package/.agent/skills/riligar-dev-landing-page/SKILL.md +0 -1
  13. package/.agent/skills/riligar-dev-seo/SKILL.md +6 -3
  14. package/.agent/skills/riligar-dev-stripe/SKILL.md +196 -91
  15. package/.agent/skills/riligar-dev-stripe/assets/stripe-client.js +422 -0
  16. package/.agent/skills/riligar-dev-stripe/assets/stripe-server.js +300 -0
  17. package/.agent/skills/riligar-dev-stripe/references/stripe-database.md +369 -0
  18. package/.agent/skills/riligar-dev-stripe/references/stripe-elysia.md +342 -0
  19. package/.agent/skills/riligar-dev-stripe/references/stripe-react.md +478 -0
  20. package/.agent/skills/riligar-dev-stripe/references/stripe-webhooks.md +376 -0
  21. package/.agent/skills/riligar-infrastructure/SKILL.md +0 -1
  22. package/.agent/skills/riligar-marketing-copy/SKILL.md +0 -1
  23. package/.agent/skills/riligar-marketing-email/SKILL.md +0 -1
  24. package/.agent/skills/riligar-marketing-seo/SKILL.md +0 -1
  25. package/.agent/skills/riligar-plan-writing/SKILL.md +0 -1
  26. package/.agent/skills/riligar-tech-stack/SKILL.md +0 -1
  27. package/.agent/skills/skill-creator/SKILL.md +0 -2
  28. package/package.json +1 -1
  29. /package/.agent/skills/riligar-dev-architecture/{context-discovery.md → references/context-discovery.md} +0 -0
  30. /package/.agent/skills/riligar-dev-architecture/{examples.md → references/examples.md} +0 -0
  31. /package/.agent/skills/riligar-dev-architecture/{pattern-selection.md → references/pattern-selection.md} +0 -0
  32. /package/.agent/skills/riligar-dev-architecture/{patterns-reference.md → references/patterns-reference.md} +0 -0
  33. /package/.agent/skills/riligar-dev-architecture/{trade-off-analysis.md → references/trade-off-analysis.md} +0 -0
  34. /package/.agent/skills/riligar-dev-database/{database-selection.md → references/database-selection.md} +0 -0
  35. /package/.agent/skills/riligar-dev-database/{indexing.md → references/indexing.md} +0 -0
  36. /package/.agent/skills/riligar-dev-database/{migrations.md → references/migrations.md} +0 -0
  37. /package/.agent/skills/riligar-dev-database/{optimization.md → references/optimization.md} +0 -0
  38. /package/.agent/skills/riligar-dev-database/{orm-selection.md → references/orm-selection.md} +0 -0
  39. /package/.agent/skills/riligar-dev-database/{schema-design.md → references/schema-design.md} +0 -0
@@ -0,0 +1,376 @@
1
+ # Stripe Webhooks
2
+
3
+ Complete patterns for handling Stripe webhook events in Elysia.
4
+
5
+ ## Webhook Endpoint
6
+
7
+ ```javascript
8
+ // routes/webhook.js
9
+ import { Elysia } from 'elysia'
10
+ import Stripe from 'stripe'
11
+
12
+ const stripe = new Stripe(process.env.STRIPE_SECRET_KEY)
13
+
14
+ export const webhookRoutes = new Elysia()
15
+ .post('/webhook/stripe', async ({ request, set }) => {
16
+ const sig = request.headers.get('stripe-signature')
17
+ const body = await request.text()
18
+
19
+ let event
20
+
21
+ try {
22
+ event = stripe.webhooks.constructEvent(
23
+ body,
24
+ sig,
25
+ process.env.STRIPE_WEBHOOK_SECRET
26
+ )
27
+ } catch (err) {
28
+ console.error('Webhook signature verification failed:', err.message)
29
+ set.status = 400
30
+ return { error: 'Invalid signature' }
31
+ }
32
+
33
+ // Handle the event
34
+ try {
35
+ await handleWebhookEvent(event)
36
+ } catch (err) {
37
+ console.error('Webhook handler error:', err)
38
+ set.status = 500
39
+ return { error: 'Webhook handler failed' }
40
+ }
41
+
42
+ return { received: true }
43
+ })
44
+ ```
45
+
46
+ ## Essential Events
47
+
48
+ | Event | When | Action |
49
+ | --- | --- | --- |
50
+ | `checkout.session.completed` | User completes checkout | Provision access, create records |
51
+ | `customer.subscription.created` | New subscription | Store subscription ID |
52
+ | `customer.subscription.updated` | Plan change, renewal | Update plan/status |
53
+ | `customer.subscription.deleted` | Subscription ends | Revoke access |
54
+ | `invoice.paid` | Successful payment | Update billing history |
55
+ | `invoice.payment_failed` | Payment failed | Notify user, retry logic |
56
+ | `customer.created` | New customer | Store customer ID |
57
+
58
+ ## Event Handler
59
+
60
+ ```javascript
61
+ // services/webhook-handlers.js
62
+ import { db } from '../database'
63
+ import { users, subscriptions } from '../database/schema'
64
+ import { eq } from 'drizzle-orm'
65
+
66
+ export async function handleWebhookEvent(event) {
67
+ switch (event.type) {
68
+ case 'checkout.session.completed':
69
+ await handleCheckoutComplete(event.data.object)
70
+ break
71
+
72
+ case 'customer.subscription.created':
73
+ case 'customer.subscription.updated':
74
+ await handleSubscriptionChange(event.data.object)
75
+ break
76
+
77
+ case 'customer.subscription.deleted':
78
+ await handleSubscriptionDeleted(event.data.object)
79
+ break
80
+
81
+ case 'invoice.paid':
82
+ await handleInvoicePaid(event.data.object)
83
+ break
84
+
85
+ case 'invoice.payment_failed':
86
+ await handlePaymentFailed(event.data.object)
87
+ break
88
+
89
+ default:
90
+ console.log(`Unhandled event type: ${event.type}`)
91
+ }
92
+ }
93
+ ```
94
+
95
+ ## Handler Functions
96
+
97
+ ### Checkout Complete
98
+
99
+ ```javascript
100
+ async function handleCheckoutComplete(session) {
101
+ const { customer, subscription, metadata } = session
102
+ const userId = metadata.userId
103
+
104
+ // Update user with Stripe IDs
105
+ await db.update(users)
106
+ .set({
107
+ stripeCustomerId: customer,
108
+ stripeSubscriptionId: subscription,
109
+ plan: 'pro', // or extract from session
110
+ updatedAt: new Date()
111
+ })
112
+ .where(eq(users.id, userId))
113
+
114
+ // Optional: send welcome email
115
+ // await sendWelcomeEmail(userId)
116
+
117
+ console.log(`Checkout completed for user ${userId}`)
118
+ }
119
+ ```
120
+
121
+ ### Subscription Change
122
+
123
+ ```javascript
124
+ async function handleSubscriptionChange(subscription) {
125
+ const { id, status, items, current_period_end, cancel_at_period_end } = subscription
126
+ const priceId = items.data[0].price.id
127
+
128
+ // Find user by subscription ID
129
+ const [user] = await db.select()
130
+ .from(users)
131
+ .where(eq(users.stripeSubscriptionId, id))
132
+ .limit(1)
133
+
134
+ if (!user) {
135
+ console.error(`No user found for subscription ${id}`)
136
+ return
137
+ }
138
+
139
+ // Map price ID to plan name
140
+ const planMap = {
141
+ 'price_starter_monthly': 'starter',
142
+ 'price_pro_monthly': 'pro',
143
+ 'price_enterprise_monthly': 'enterprise'
144
+ }
145
+
146
+ await db.update(users)
147
+ .set({
148
+ plan: planMap[priceId] || 'free',
149
+ subscriptionStatus: status,
150
+ currentPeriodEnd: new Date(current_period_end * 1000),
151
+ cancelAtPeriodEnd: cancel_at_period_end,
152
+ updatedAt: new Date()
153
+ })
154
+ .where(eq(users.id, user.id))
155
+
156
+ console.log(`Subscription ${id} updated to ${status}`)
157
+ }
158
+ ```
159
+
160
+ ### Subscription Deleted
161
+
162
+ ```javascript
163
+ async function handleSubscriptionDeleted(subscription) {
164
+ const { id } = subscription
165
+
166
+ await db.update(users)
167
+ .set({
168
+ plan: 'free',
169
+ subscriptionStatus: 'canceled',
170
+ stripeSubscriptionId: null,
171
+ updatedAt: new Date()
172
+ })
173
+ .where(eq(users.stripeSubscriptionId, id))
174
+
175
+ console.log(`Subscription ${id} deleted`)
176
+ }
177
+ ```
178
+
179
+ ### Invoice Paid
180
+
181
+ ```javascript
182
+ async function handleInvoicePaid(invoice) {
183
+ const { customer, amount_paid, id, hosted_invoice_url } = invoice
184
+
185
+ // Find user by customer ID
186
+ const [user] = await db.select()
187
+ .from(users)
188
+ .where(eq(users.stripeCustomerId, customer))
189
+ .limit(1)
190
+
191
+ if (!user) return
192
+
193
+ // Store invoice record (optional)
194
+ await db.insert(invoices).values({
195
+ userId: user.id,
196
+ stripeInvoiceId: id,
197
+ amount: amount_paid,
198
+ status: 'paid',
199
+ url: hosted_invoice_url,
200
+ createdAt: new Date()
201
+ })
202
+
203
+ console.log(`Invoice ${id} paid: ${amount_paid}`)
204
+ }
205
+ ```
206
+
207
+ ### Payment Failed
208
+
209
+ ```javascript
210
+ async function handlePaymentFailed(invoice) {
211
+ const { customer, attempt_count, next_payment_attempt } = invoice
212
+
213
+ const [user] = await db.select()
214
+ .from(users)
215
+ .where(eq(users.stripeCustomerId, customer))
216
+ .limit(1)
217
+
218
+ if (!user) return
219
+
220
+ // Update subscription status
221
+ await db.update(users)
222
+ .set({
223
+ subscriptionStatus: 'past_due',
224
+ updatedAt: new Date()
225
+ })
226
+ .where(eq(users.id, user.id))
227
+
228
+ // Send notification
229
+ // await sendPaymentFailedEmail(user.email, {
230
+ // attemptCount: attempt_count,
231
+ // nextAttempt: next_payment_attempt
232
+ // })
233
+
234
+ console.log(`Payment failed for customer ${customer}, attempt ${attempt_count}`)
235
+ }
236
+ ```
237
+
238
+ ## Idempotency
239
+
240
+ Webhooks may be sent multiple times. Handle idempotency:
241
+
242
+ ```javascript
243
+ async function handleCheckoutComplete(session) {
244
+ const { id, metadata } = session
245
+ const userId = metadata.userId
246
+
247
+ // Check if already processed
248
+ const [existing] = await db.select()
249
+ .from(webhookEvents)
250
+ .where(eq(webhookEvents.stripeEventId, id))
251
+ .limit(1)
252
+
253
+ if (existing) {
254
+ console.log(`Event ${id} already processed`)
255
+ return
256
+ }
257
+
258
+ // Record event
259
+ await db.insert(webhookEvents).values({
260
+ stripeEventId: id,
261
+ type: 'checkout.session.completed',
262
+ processedAt: new Date()
263
+ })
264
+
265
+ // Process the event
266
+ await db.update(users)
267
+ .set({
268
+ stripeCustomerId: session.customer,
269
+ stripeSubscriptionId: session.subscription,
270
+ plan: 'pro'
271
+ })
272
+ .where(eq(users.id, userId))
273
+ }
274
+ ```
275
+
276
+ ## Testing Locally
277
+
278
+ ```bash
279
+ # Install Stripe CLI
280
+ brew install stripe/stripe-cli/stripe
281
+
282
+ # Login to Stripe
283
+ stripe login
284
+
285
+ # Forward webhooks to local server
286
+ stripe listen --forward-to localhost:3000/webhook/stripe
287
+
288
+ # Copy the webhook signing secret (whsec_...) to .env.development
289
+
290
+ # Trigger specific events
291
+ stripe trigger checkout.session.completed
292
+ stripe trigger customer.subscription.updated
293
+ stripe trigger invoice.payment_failed
294
+ ```
295
+
296
+ ## Webhook Event Types Reference
297
+
298
+ ### Checkout Events
299
+
300
+ | Event | Data Object |
301
+ | --- | --- |
302
+ | `checkout.session.completed` | Session with customer, subscription, metadata |
303
+ | `checkout.session.expired` | Session that expired |
304
+
305
+ ### Subscription Events
306
+
307
+ | Event | Data Object |
308
+ | --- | --- |
309
+ | `customer.subscription.created` | Full subscription object |
310
+ | `customer.subscription.updated` | Full subscription with changes |
311
+ | `customer.subscription.deleted` | Subscription being canceled |
312
+ | `customer.subscription.trial_will_end` | 3 days before trial ends |
313
+
314
+ ### Invoice Events
315
+
316
+ | Event | Data Object |
317
+ | --- | --- |
318
+ | `invoice.paid` | Invoice with payment details |
319
+ | `invoice.payment_failed` | Invoice with failure reason |
320
+ | `invoice.upcoming` | Preview of next invoice |
321
+ | `invoice.finalized` | Invoice ready for payment |
322
+
323
+ ### Payment Events
324
+
325
+ | Event | Data Object |
326
+ | --- | --- |
327
+ | `payment_intent.succeeded` | PaymentIntent completed |
328
+ | `payment_intent.payment_failed` | PaymentIntent failed |
329
+
330
+ ## Error Handling
331
+
332
+ ```javascript
333
+ export const webhookRoutes = new Elysia()
334
+ .post('/webhook/stripe', async ({ request, set }) => {
335
+ const sig = request.headers.get('stripe-signature')
336
+ const body = await request.text()
337
+
338
+ let event
339
+
340
+ // Verify signature
341
+ try {
342
+ event = stripe.webhooks.constructEvent(
343
+ body,
344
+ sig,
345
+ process.env.STRIPE_WEBHOOK_SECRET
346
+ )
347
+ } catch (err) {
348
+ console.error('Invalid signature:', err.message)
349
+ set.status = 400
350
+ return { error: 'Invalid signature' }
351
+ }
352
+
353
+ // Handle event with error catching
354
+ try {
355
+ await handleWebhookEvent(event)
356
+ return { received: true }
357
+ } catch (err) {
358
+ console.error('Handler error:', err)
359
+
360
+ // Return 200 to prevent Stripe retries for permanent failures
361
+ // Return 500 to trigger Stripe retry for temporary failures
362
+ if (isPermanentFailure(err)) {
363
+ console.error('Permanent failure, not retrying')
364
+ return { received: true, error: err.message }
365
+ }
366
+
367
+ set.status = 500
368
+ return { error: 'Internal error' }
369
+ }
370
+ })
371
+
372
+ function isPermanentFailure(err) {
373
+ // User not found, invalid data, etc.
374
+ return err.code === 'USER_NOT_FOUND' || err.code === 'INVALID_DATA'
375
+ }
376
+ ```
@@ -1,6 +1,5 @@
1
1
  ---
2
2
  name: riligar-infrastructure
3
- type: infrastructure
4
3
  description: Especialista em Infraestrutura da RiLiGar. Use para configurar deployments no Fly.io, DNS e proxying no Cloudflare, e garantir padrões de infraestrutura e deployment.
5
4
  ---
6
5
 
@@ -1,6 +1,5 @@
1
1
  ---
2
2
  name: riligar-marketing-copy
3
- type: marketing
4
3
  description: Generate compelling marketing copy using the Elevated Direct Response framework. Use when creating landing pages, headlines, email campaigns, ad copy, CTAs, value propositions, or any persuasive marketing content.
5
4
  ---
6
5
 
@@ -1,6 +1,5 @@
1
1
  ---
2
2
  name: riligar-marketing-email
3
- type: marketing
4
3
  description: Email sequence design and optimization. Use when creating drip campaigns, automated flows, nurture sequences, onboarding emails, welcome sequences, re-engagement emails, or lifecycle email programs.
5
4
  ---
6
5
 
@@ -1,6 +1,5 @@
1
1
  ---
2
2
  name: riligar-marketing-seo
3
- type: marketing
4
3
  description: Design and evaluate programmatic SEO strategies for creating SEO-driven pages at scale. Use when working with programmatic SEO, template pages, directory pages, location pages, or keyword-pattern page generation.
5
4
  ---
6
5
 
@@ -1,6 +1,5 @@
1
1
  ---
2
2
  name: riligar-plan-writing
3
- type: development
4
3
  description: Structured task planning with clear breakdowns, dependencies, and verification criteria. Use when implementing features, refactoring, or any multi-step work.
5
4
  ---
6
5
 
@@ -1,6 +1,5 @@
1
1
  ---
2
2
  name: riligar-tech-stack
3
- type: development
4
3
  description: Especialista na Tech Stack da RiLiGar. Use para criar projetos React/Vite, componentes com Mantine, APIs Bun/Elysia, e garantir padrões de código e estrutura de projetos.
5
4
  ---
6
5
 
@@ -1,6 +1,5 @@
1
1
  ---
2
2
  name: skill-creator
3
- type: meta
4
3
  description: Guide for creating effective skills. Use when creating a new skill or updating an existing skill that extends Claude's capabilities with specialized knowledge, workflows, or tool integrations.
5
4
  ---
6
5
 
@@ -337,7 +336,6 @@ Write the YAML frontmatter with `name`, `type`, and `description`:
337
336
  ```yaml
338
337
  ---
339
338
  name: riligar-dev-example
340
- type: development
341
339
  description: Brief description of what the skill does. Use when [specific triggers].
342
340
  ---
343
341
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riligar/agents-kit",
3
- "version": "1.12.0",
3
+ "version": "1.14.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },