Skip to content

Commit 1081646

Browse files
committed
Add 3 new rules (20 total), upgrade landing page with 6 features + stats
1 parent d971cb4 commit 1081646

4 files changed

Lines changed: 504 additions & 107 deletions

File tree

.cursor/rules/database-design.mdc

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
---
2+
description: Database schema design patterns for Supabase with proper types and relationships
3+
globs: ["**/*.sql", "**/supabase/**", "**/types/**"]
4+
alwaysApply: false
5+
---
6+
7+
# Database Design Patterns
8+
9+
## Table Naming
10+
- Use `snake_case` for tables and columns: `user_profiles`, `created_at`
11+
- NEVER use camelCase in SQL: `userId` → WRONG, `user_id` → CORRECT
12+
- Use plural table names: `profiles`, `posts`, `comments`
13+
14+
## Required Columns (Every Table)
15+
```sql
16+
CREATE TABLE public.example (
17+
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
18+
-- your columns here
19+
created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
20+
updated_at TIMESTAMPTZ DEFAULT NOW() NOT NULL
21+
);
22+
```
23+
ALWAYS include `id`, `created_at`, and `updated_at`.
24+
ALWAYS use UUID for primary keys (not serial/integer).
25+
ALWAYS use TIMESTAMPTZ (not TIMESTAMP) for timezone safety.
26+
27+
## Foreign Key Pattern
28+
```sql
29+
-- Always reference auth.users for user ownership
30+
user_id UUID REFERENCES auth.users(id) ON DELETE CASCADE NOT NULL
31+
```
32+
Use `ON DELETE CASCADE` for user-owned data.
33+
Use `ON DELETE SET NULL` for optional relationships.
34+
35+
## RLS Template (Copy This Every Time)
36+
```sql
37+
ALTER TABLE public.example ENABLE ROW LEVEL SECURITY;
38+
39+
-- Users can only see their own data
40+
CREATE POLICY "Users own data" ON public.example
41+
FOR ALL USING (auth.uid() = user_id);
42+
43+
-- Or for public read + owner write:
44+
CREATE POLICY "Public read" ON public.example
45+
FOR SELECT USING (true);
46+
CREATE POLICY "Owner write" ON public.example
47+
FOR INSERT WITH CHECK (auth.uid() = user_id);
48+
CREATE POLICY "Owner update" ON public.example
49+
FOR UPDATE USING (auth.uid() = user_id);
50+
CREATE POLICY "Owner delete" ON public.example
51+
FOR DELETE USING (auth.uid() = user_id);
52+
```
53+
54+
## Type Generation
55+
After schema changes, regenerate types:
56+
```bash
57+
npx supabase gen types typescript --project-id YOUR_PROJECT_REF > src/types/database.ts
58+
```
59+
ALWAYS use generated types — NEVER manually type database schemas.
60+
61+
## Anti-Patterns
62+
- NEVER use `TEXT` for fields that should be enums — use PostgreSQL enums or CHECK constraints
63+
- NEVER store JSON blobs when structured columns work — use `JSONB` only for truly dynamic data
64+
- NEVER create tables without RLS — see `supabase-rls.mdc`
65+
- NEVER use `SERIAL` for IDs — use `UUID` for security (prevents enumeration attacks)

.cursor/rules/env-management.mdc

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
---
2+
description: Environment variable management and secrets handling
3+
globs: ["**/*.ts", "**/*.tsx", "**/.env*"]
4+
alwaysApply: false
5+
---
6+
7+
# Environment Variable Management
8+
9+
## Classification Rules
10+
| Prefix | Visibility | Use For |
11+
|--------|-----------|---------|
12+
| `NEXT_PUBLIC_` | Client + Server | Non-sensitive public values (Supabase URL, Stripe publishable key) |
13+
| No prefix | Server Only | ALL secrets (API keys, webhook secrets, database URLs) |
14+
15+
## NEVER Expose These to the Client
16+
```
17+
STRIPE_SECRET_KEY → Server only (NEVER NEXT_PUBLIC_)
18+
STRIPE_WEBHOOK_SECRET → Server only
19+
SUPABASE_SERVICE_ROLE_KEY → Server only (admin bypass key)
20+
RESEND_API_KEY → Server only
21+
DATABASE_URL → Server only
22+
```
23+
24+
## Safe for Client
25+
```
26+
NEXT_PUBLIC_SUPABASE_URL → Public Supabase endpoint
27+
NEXT_PUBLIC_SUPABASE_ANON_KEY → Rate-limited client key (RLS protects data)
28+
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY → Stripe public key (payment form only)
29+
NEXT_PUBLIC_APP_URL → Your app's URL
30+
```
31+
32+
## Validation Pattern
33+
Use `src/lib/env.ts` to validate at startup:
34+
```typescript
35+
function getEnvVar(key: string, required = true): string {
36+
const value = process.env[key]
37+
if (!value && required) {
38+
throw new Error(`❌ Missing required env var: ${key}`)
39+
}
40+
return value ?? ''
41+
}
42+
```
43+
44+
## .env.local Structure
45+
```bash
46+
# Supabase (required)
47+
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
48+
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJ...
49+
50+
# Stripe (optional in dev)
51+
STRIPE_SECRET_KEY=sk_test_...
52+
STRIPE_WEBHOOK_SECRET=whsec_...
53+
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_...
54+
55+
# Email (optional in dev)
56+
RESEND_API_KEY=re_...
57+
58+
# App
59+
NEXT_PUBLIC_APP_URL=http://localhost:3000
60+
```
61+
62+
## Anti-Patterns
63+
- NEVER commit `.env.local` — it's in `.gitignore`
64+
- NEVER use `process.env.X` directly in components — use the centralized `env` config
65+
- NEVER hardcode API keys or secrets in source code
66+
- NEVER use `NEXT_PUBLIC_` for write-access API keys

.cursor/rules/file-naming.mdc

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
---
2+
description: File naming conventions and project organization rules
3+
globs: ["**/*.ts", "**/*.tsx"]
4+
alwaysApply: false
5+
---
6+
7+
# File Naming & Organization
8+
9+
## Naming Conventions
10+
- **Components:** PascalCase → `UserProfile.tsx`, `DashboardLayout.tsx`
11+
- **Utilities/Libs:** camelCase → `formatDate.ts`, `createClient.ts`
12+
- **Constants:** SCREAMING_SNAKE → `export const MAX_RETRIES = 3`
13+
- **Types files:** camelCase → `types/index.ts`, `types/database.ts`
14+
- **Server Actions:** camelCase in grouped files → `actions.ts` (not one file per action)
15+
- **Route Handlers:** always `route.ts` (Next.js convention)
16+
17+
## Directory Rules
18+
- Components in `src/components/` — NEVER in `src/app/`
19+
- Page-specific components in `src/app/[route]/_components/` (underscore prefix = private)
20+
- Shared types in `src/types/` — NEVER define types inline in components
21+
- Business logic in `src/lib/` — NEVER put business logic in components
22+
- Server actions in the nearest `actions.ts` to where they're used
23+
24+
## Import Order (enforce in every file)
25+
```typescript
26+
// 1. React/Next.js imports
27+
import { Suspense } from 'react'
28+
import Link from 'next/link'
29+
30+
// 2. Third-party libraries
31+
import { z } from 'zod'
32+
33+
// 3. Internal aliases (@/)
34+
import { Button } from '@/components/ui/button'
35+
import { createClient } from '@/lib/supabase/server'
36+
import type { UserProfile } from '@/types'
37+
38+
// 4. Relative imports (only for co-located files)
39+
import { columns } from './columns'
40+
```
41+
42+
## Anti-Patterns
43+
- NEVER create `utils/helpers.ts` catch-all files — name files by what they do
44+
- NEVER put more than 1 exported component per file
45+
- NEVER use default exports for utilities — use named exports
46+
- NEVER create `index.ts` barrel files that re-export everything (breaks tree-shaking)

0 commit comments

Comments
 (0)