Skip to content

Commit 9e72713

Browse files
committed
feat: add stripe-webhooks.mdc + react19-patterns.mdc (29 rules total) - Stripe webhook signature verification, raw body parsing, useFormStatus extraction, useActionState migration, forwardRef deprecation
1 parent 7160e4c commit 9e72713

4 files changed

Lines changed: 171 additions & 7 deletions

File tree

.cursor/rules/react19-patterns.mdc

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
---
2+
description: Prevent common React 19 and Next.js 15 migration pitfalls
3+
globs: ["**/*.tsx", "**/*.ts"]
4+
alwaysApply: false
5+
---
6+
7+
# React 19 / Next.js 15 Migration Traps
8+
9+
## RULE 1: useFormStatus Must Be Inside <form>
10+
11+
`useFormStatus()` only works when the component using it is a CHILD of a `<form>`
12+
element that uses a Server Action. It does NOT work if used in the same component
13+
that renders the form.
14+
15+
```tsx
16+
// ❌ WRONG — useFormStatus returns { pending: false } always
17+
'use client'
18+
export function MyForm() {
19+
const { pending } = useFormStatus() // Always false here
20+
return (
21+
<form action={createItem}>
22+
<Button disabled={pending}>Submit</Button>
23+
</form>
24+
)
25+
}
26+
27+
// ✅ CORRECT — extract the submit button to a child component
28+
'use client'
29+
import { useFormStatus } from 'react-dom'
30+
31+
function SubmitButton() {
32+
const { pending } = useFormStatus()
33+
return <Button disabled={pending}>{pending ? 'Saving...' : 'Submit'}</Button>
34+
}
35+
36+
export function MyForm() {
37+
return (
38+
<form action={createItem}>
39+
<SubmitButton />
40+
</form>
41+
)
42+
}
43+
```
44+
45+
## RULE 2: useActionState Replaces useFormState
46+
47+
`useFormState` is DEPRECATED in React 19. Use `useActionState` instead.
48+
49+
```typescript
50+
// ❌ DEPRECATED
51+
import { useFormState } from 'react-dom'
52+
53+
// ✅ CORRECT — React 19
54+
import { useActionState } from 'react'
55+
56+
const [state, formAction, isPending] = useActionState(serverAction, initialState)
57+
```
58+
59+
## RULE 3: ref Is a Regular Prop in React 19
60+
61+
`forwardRef()` is no longer required. `ref` is passed as a regular prop.
62+
63+
```tsx
64+
// ❌ DEPRECATED — verbose, unnecessary in React 19
65+
const MyInput = forwardRef<HTMLInputElement, InputProps>((props, ref) => {
66+
return <input ref={ref} {...props} />
67+
})
68+
69+
// ✅ CORRECT — React 19
70+
function MyInput({ ref, ...props }: InputProps & { ref?: React.Ref<HTMLInputElement> }) {
71+
return <input ref={ref} {...props} />
72+
}
73+
```
74+
75+
## RULE 4: use() Hook for Promises and Context
76+
77+
React 19 `use()` can unwrap Promises in render. Use it instead of useEffect for
78+
data fetching in client components.
79+
80+
```tsx
81+
// ✅ React 19 — use() for context (replaces useContext)
82+
import { use } from 'react'
83+
const theme = use(ThemeContext)
84+
```

.cursor/rules/stripe-webhooks.mdc

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
---
2+
description: Stripe webhook verification patterns and payment security
3+
globs: ["**/api/webhooks/**", "**/stripe/**"]
4+
alwaysApply: false
5+
---
6+
7+
# Stripe Webhook Security
8+
9+
## RULE 1: ALWAYS Verify Webhook Signatures First
10+
11+
The AI will generate webhook handlers that process the payload directly.
12+
This is a CRITICAL vulnerability — anyone can POST to your webhook endpoint
13+
and trigger subscription changes, refunds, or account modifications.
14+
15+
```typescript
16+
import Stripe from 'stripe'
17+
18+
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!)
19+
20+
export async function POST(request: Request) {
21+
const body = await request.text() // Must be raw text, NOT .json()
22+
const signature = request.headers.get('stripe-signature')
23+
24+
if (!signature) {
25+
return Response.json({ error: 'Missing signature' }, { status: 400 })
26+
}
27+
28+
let event: Stripe.Event
29+
30+
try {
31+
event = stripe.webhooks.constructEvent(
32+
body,
33+
signature,
34+
process.env.STRIPE_WEBHOOK_SECRET!
35+
)
36+
} catch (err) {
37+
console.error('[STRIPE_WEBHOOK_VERIFICATION_FAILED]', err)
38+
return Response.json({ error: 'Invalid signature' }, { status: 400 })
39+
}
40+
41+
// NOW it's safe to process the event
42+
switch (event.type) {
43+
case 'checkout.session.completed':
44+
await handleCheckoutCompleted(event.data.object)
45+
break
46+
case 'customer.subscription.updated':
47+
await handleSubscriptionUpdated(event.data.object)
48+
break
49+
case 'customer.subscription.deleted':
50+
await handleSubscriptionDeleted(event.data.object)
51+
break
52+
}
53+
54+
return Response.json({ received: true })
55+
}
56+
```
57+
58+
## RULE 2: NEVER Use request.json() for Webhooks
59+
60+
Stripe signature verification requires the RAW request body as a string.
61+
If you parse it with `request.json()` first, the verification will ALWAYS fail
62+
because JSON.stringify produces different whitespace than the original payload.
63+
64+
```typescript
65+
// ❌ WRONG — signature verification will always fail
66+
const body = await request.json()
67+
stripe.webhooks.constructEvent(JSON.stringify(body), sig, secret)
68+
69+
// ✅ CORRECT — use raw text
70+
const body = await request.text()
71+
stripe.webhooks.constructEvent(body, sig, secret)
72+
```
73+
74+
## RULE 3: Stripe Keys Are Server-Only
75+
76+
- `STRIPE_SECRET_KEY` — NEVER in `NEXT_PUBLIC_` variables
77+
- `STRIPE_WEBHOOK_SECRET` — NEVER in `NEXT_PUBLIC_` variables
78+
- `NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY` — This is the ONLY Stripe key safe for client

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
### Stop fixing AI-generated bugs. Start shipping production apps.
44

5-
A **Next.js 15 + Supabase boilerplate** with **27 `.mdc` architecture rules** that physically prevent AI coding assistants from hallucinating insecure auth, deprecated packages, and broken patterns.
5+
A **Next.js 15 + Supabase boilerplate** with **29 `.mdc` architecture rules** that physically prevent AI coding assistants from hallucinating insecure auth, deprecated packages, and broken patterns.
66

77
[![Next.js 15](https://img.shields.io/badge/Next.js-15-black?logo=next.js)](https://nextjs.org/)
88
[![React 19](https://img.shields.io/badge/React-19-blue?logo=react)](https://react.dev/)
@@ -63,7 +63,7 @@ The free rules are the foundation. The **AI Builder's Complete System** is the e
6363

6464
**For developers who already have a project** and want to stop fixing AI hallucinations.
6565

66-
- ✅ All **27 battle-tested `.mdc` rules** (20 more than the free tier):
66+
- ✅ All **29 battle-tested `.mdc` rules** (20 more than the free tier):
6767
- `security.mdc` — OWASP Top 10 with rate limiting examples
6868
- `stripe-payments.mdc` — Server-only Stripe, webhook signature verification
6969
- `typescript-strict.mdc` — Bans `any`, enforces Zod at every boundary
@@ -135,7 +135,7 @@ src/
135135

136136
| Feature | Vibe Stack (Free) | Vibe Stack ($149) | ShipFast ($169) | MakerKit ($299) |
137137
|---|:---:|:---:|:---:|:---:|
138-
| AI Architecture Rules | 5 rules | **27 rules** |||
138+
| AI Architecture Rules | 5 rules | **29 rules** |||
139139
| MCP Integrations || ✅ 4 servers |||
140140
| n8n Automations || ✅ 3 workflows |||
141141
| AGENTS.md |||||

llms.txt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# Vibe Stack
22

3-
> The AI Builder's Complete System — 27 .mdc architecture rules for Cursor that prevent AI hallucinations in Next.js 15 + Supabase production applications.
3+
> The AI Builder's Complete System — 29 .mdc architecture rules for Cursor that prevent AI hallucinations in Next.js 15 + Supabase production applications.
44

55
## Overview
6-
Vibe Stack is a battle-tested Next.js 15 + Supabase boilerplate with 27 `.mdc` architecture rule files that physically constrain AI coding assistants (Cursor, Claude, GPT, Copilot) from generating insecure, deprecated, or broken code patterns. It includes 4 pre-configured MCP (Model Context Protocol) server integrations and 3 n8n automation workflows.
6+
Vibe Stack is a battle-tested Next.js 15 + Supabase boilerplate with 29 `.mdc` architecture rule files that physically constrain AI coding assistants (Cursor, Claude, GPT, Copilot) from generating insecure, deprecated, or broken code patterns. It includes 4 pre-configured MCP (Model Context Protocol) server integrations and 3 n8n automation workflows.
77

88
## Problem Solved
99
AI models generate code that compiles perfectly but contains critical vulnerabilities. These are the 5 most dangerous patterns:
@@ -17,7 +17,7 @@ AI models generate code that compiles perfectly but contains critical vulnerabil
1717
## How It Works
1818
Each `.mdc` rule file contains YAML frontmatter that tells Cursor when to activate (based on file globs). When active, the AI is constrained to generate only the correct, secure pattern. Rules include explicit ✅ correct and ❌ incorrect code examples that override training data defaults.
1919

20-
## Architecture Rules (27 files in `.cursor/rules/`)
20+
## Architecture Rules (29 files in `.cursor/rules/`)
2121
- supabase-auth-security.mdc — Bans getSession(), enforces getUser()
2222
- nextjs15-params.mdc — Prevents synchronous params access
2323
- supabase-ssr-only.mdc — Blocks deprecated auth-helpers imports
@@ -45,6 +45,8 @@ Each `.mdc` rule file contains YAML frontmatter that tells Cursor when to activa
4545
- project-context.mdc — Global architecture context
4646
- verify-before-use.mdc — Forces verification after code generation
4747
- context-management.mdc — Prevents context window bloat in long sessions
48+
- stripe-webhooks.mdc — Webhook signature verification, raw body parsing
49+
- react19-patterns.mdc — useFormStatus, useActionState, forwardRef deprecation
4850

4951
## MCP Integrations (4 servers in `.cursor/mcp.json`)
5052
- GitHub MCP — AI reads PRs, commits, and issues
@@ -79,7 +81,7 @@ Each `.mdc` rule file contains YAML frontmatter that tells Cursor when to activa
7981

8082
## Free vs Paid
8183
- **Free (GitHub):** 5 foundational rules + working auth boilerplate + Phase 1 of Vibe Coding guide
82-
- **Rules Pack ($29):** All 27 rules + lifetime updates
84+
- **Rules Pack ($29):** All 29 rules + lifetime updates
8385
- **Builder System ($69):** Rules + 4 MCP configs + Architecture docs + SQL migrations
8486
- **Complete Vault ($149):** Full boilerplate + Stripe + email + n8n workflows + Masterclass
8587

0 commit comments

Comments
 (0)