ultra-dex 1.7.3 → 1.8.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 (81) hide show
  1. package/README.md +16 -2
  2. package/assets/agents/0-orchestration/orchestrator.md +225 -0
  3. package/assets/agents/00-AGENT_INDEX.md +138 -0
  4. package/assets/agents/1-leadership/cto.md +186 -0
  5. package/assets/agents/1-leadership/planner.md +205 -0
  6. package/assets/agents/1-leadership/research.md +285 -0
  7. package/assets/agents/2-development/backend.md +472 -0
  8. package/assets/agents/2-development/database.md +516 -0
  9. package/assets/agents/2-development/frontend.md +144 -0
  10. package/assets/agents/3-security/auth.md +168 -0
  11. package/assets/agents/3-security/security.md +335 -0
  12. package/assets/agents/4-devops/devops.md +587 -0
  13. package/assets/agents/5-quality/debugger.md +188 -0
  14. package/assets/agents/5-quality/documentation.md +167 -0
  15. package/assets/agents/5-quality/reviewer.md +213 -0
  16. package/assets/agents/5-quality/testing.md +280 -0
  17. package/assets/agents/6-specialist/performance.md +323 -0
  18. package/assets/agents/6-specialist/refactoring.md +343 -0
  19. package/assets/agents/AGENT-INSTRUCTIONS.md +315 -0
  20. package/assets/agents/README.md +232 -0
  21. package/assets/cursor-rules/00-ultra-dex-core.mdc +48 -0
  22. package/assets/cursor-rules/01-database.mdc +50 -0
  23. package/assets/cursor-rules/02-api.mdc +81 -0
  24. package/assets/cursor-rules/03-auth.mdc +70 -0
  25. package/assets/cursor-rules/04-frontend.mdc +92 -0
  26. package/assets/cursor-rules/05-payments.mdc +88 -0
  27. package/assets/cursor-rules/06-testing.mdc +104 -0
  28. package/assets/cursor-rules/07-security.mdc +94 -0
  29. package/assets/cursor-rules/08-deployment.mdc +92 -0
  30. package/assets/cursor-rules/09-error-handling.mdc +137 -0
  31. package/assets/cursor-rules/10-performance.mdc +123 -0
  32. package/assets/cursor-rules/11-nextjs-v15.mdc +307 -0
  33. package/assets/cursor-rules/12-multi-tenancy.mdc +282 -0
  34. package/assets/cursor-rules/README.md +78 -0
  35. package/assets/cursor-rules/load.ps1 +108 -0
  36. package/assets/cursor-rules/load.sh +102 -0
  37. package/assets/docs/BUILD-AUTH-30M.md +113 -0
  38. package/assets/docs/CHECKLIST-21-STEP.md +86 -0
  39. package/assets/docs/CODEMAP.md +229 -0
  40. package/assets/docs/CUSTOMIZATION.md +127 -0
  41. package/assets/docs/LAUNCH-POSTS.md +238 -0
  42. package/assets/docs/QUICK-REFERENCE.md +338 -0
  43. package/assets/docs/README.md +21 -0
  44. package/assets/docs/ROADMAP.md +480 -0
  45. package/assets/docs/TROUBLESHOOTING.md +148 -0
  46. package/assets/docs/TUTORIAL.md +182 -0
  47. package/assets/docs/VERIFICATION.md +108 -0
  48. package/assets/docs/VISION-V2.md +187 -0
  49. package/assets/docs/WORKFLOW-DIAGRAMS.md +463 -0
  50. package/assets/docs/index.html +550 -0
  51. package/assets/live-templates/next15-prisma-clerk/.env.example +3 -0
  52. package/assets/live-templates/next15-prisma-clerk/README.md +10 -0
  53. package/assets/live-templates/next15-prisma-clerk/app/layout.tsx +7 -0
  54. package/assets/live-templates/next15-prisma-clerk/app/page.tsx +8 -0
  55. package/assets/live-templates/next15-prisma-clerk/next.config.js +6 -0
  56. package/assets/live-templates/next15-prisma-clerk/package.json +22 -0
  57. package/assets/live-templates/next15-prisma-clerk/prisma/schema.prisma +34 -0
  58. package/assets/live-templates/remix-supabase/.env.example +2 -0
  59. package/assets/live-templates/remix-supabase/README.md +9 -0
  60. package/assets/live-templates/remix-supabase/app/root.tsx +19 -0
  61. package/assets/live-templates/remix-supabase/app/routes/_index.tsx +8 -0
  62. package/assets/live-templates/remix-supabase/app/utils/supabase.server.ts +6 -0
  63. package/assets/live-templates/remix-supabase/package.json +20 -0
  64. package/assets/live-templates/remix-supabase/remix.config.js +6 -0
  65. package/assets/live-templates/sveltekit-drizzle/.env.example +1 -0
  66. package/assets/live-templates/sveltekit-drizzle/README.md +9 -0
  67. package/assets/live-templates/sveltekit-drizzle/drizzle/schema.ts +7 -0
  68. package/assets/live-templates/sveltekit-drizzle/drizzle.config.ts +5 -0
  69. package/assets/live-templates/sveltekit-drizzle/package.json +21 -0
  70. package/assets/live-templates/sveltekit-drizzle/src/lib/db.ts +5 -0
  71. package/assets/live-templates/sveltekit-drizzle/src/routes/+page.svelte +2 -0
  72. package/assets/live-templates/sveltekit-drizzle/svelte.config.js +5 -0
  73. package/assets/live-templates/sveltekit-drizzle/vite.config.js +5 -0
  74. package/assets/saas-plan/04-Imp-Template.md +5546 -0
  75. package/assets/templates/CASE-STUDY-TEMPLATE.md +139 -0
  76. package/assets/templates/MASTER-PLAN-TEMPLATE.md +647 -0
  77. package/assets/templates/ORDER-TRACKER-TEMPLATE.md +731 -0
  78. package/assets/templates/PHASE-TRACKER-TEMPLATE.md +577 -0
  79. package/assets/templates/README.md +419 -0
  80. package/bin/ultra-dex.js +459 -31
  81. package/package.json +3 -3
@@ -0,0 +1,307 @@
1
+ # Next.js 15 Production Patterns
2
+
3
+ > Modern App Router patterns for production-grade Next.js 15 applications
4
+
5
+ ## Architecture Rules
6
+
7
+ 1. **ALWAYS use App Router** - `src/app/` directory structure
8
+ 2. **Route Groups** for organization - `(marketing)/`, `(dashboard)/`, `(auth)/`
9
+ 3. **Parallel Routes** for complex layouts - `@modal`, `@sidebar`
10
+ 4. **Intercepting Routes** for modals - `(.)photo/[id]`
11
+
12
+ ## File Structure
13
+
14
+ ```
15
+ src/app/
16
+ ├── (marketing)/
17
+ │ ├── page.tsx # Landing page
18
+ │ ├── pricing/page.tsx
19
+ │ └── layout.tsx # Marketing layout
20
+ ├── (dashboard)/
21
+ │ ├── dashboard/
22
+ │ │ ├── page.tsx # Main dashboard
23
+ │ │ ├── loading.tsx # Suspense fallback
24
+ │ │ └── error.tsx # Error boundary
25
+ │ ├── settings/page.tsx
26
+ │ └── layout.tsx # Dashboard layout with sidebar
27
+ ├── (auth)/
28
+ │ ├── login/page.tsx
29
+ │ ├── signup/page.tsx
30
+ │ └── layout.tsx # Auth layout (no navbar)
31
+ ├── api/
32
+ │ └── [...]/route.ts # API routes
33
+ ├── layout.tsx # Root layout
34
+ └── globals.css
35
+ ```
36
+
37
+ ## Server Components (Default)
38
+
39
+ ```tsx
40
+ // This is a Server Component by default
41
+ export default async function DashboardPage() {
42
+ const data = await prisma.user.findMany()
43
+
44
+ return (
45
+ <div>
46
+ {data.map(user => <UserCard key={user.id} user={user} />)}
47
+ </div>
48
+ )
49
+ }
50
+ ```
51
+
52
+ ## Client Components (When Needed)
53
+
54
+ ```tsx
55
+ 'use client'
56
+
57
+ import { useState } from 'react'
58
+
59
+ export function Counter() {
60
+ const [count, setCount] = useState(0)
61
+ return <button onClick={() => setCount(c => c + 1)}>{count}</button>
62
+ }
63
+ ```
64
+
65
+ ## Server Actions
66
+
67
+ ```tsx
68
+ // app/actions.ts
69
+ 'use server'
70
+
71
+ import { revalidatePath } from 'next/cache'
72
+ import { redirect } from 'next/navigation'
73
+
74
+ export async function createPost(formData: FormData) {
75
+ const title = formData.get('title') as string
76
+
77
+ await prisma.post.create({ data: { title } })
78
+
79
+ revalidatePath('/posts')
80
+ redirect('/posts')
81
+ }
82
+ ```
83
+
84
+ ## Loading States
85
+
86
+ ```tsx
87
+ // app/dashboard/loading.tsx
88
+ export default function Loading() {
89
+ return (
90
+ <div className="animate-pulse">
91
+ <div className="h-8 bg-gray-200 rounded w-1/4 mb-4" />
92
+ <div className="h-4 bg-gray-200 rounded w-full mb-2" />
93
+ <div className="h-4 bg-gray-200 rounded w-3/4" />
94
+ </div>
95
+ )
96
+ }
97
+ ```
98
+
99
+ ## Error Boundaries
100
+
101
+ ```tsx
102
+ // app/dashboard/error.tsx
103
+ 'use client'
104
+
105
+ export default function Error({
106
+ error,
107
+ reset,
108
+ }: {
109
+ error: Error & { digest?: string }
110
+ reset: () => void
111
+ }) {
112
+ return (
113
+ <div className="p-4 bg-red-50 rounded-lg">
114
+ <h2 className="text-red-800 font-semibold">Something went wrong!</h2>
115
+ <button
116
+ onClick={() => reset()}
117
+ className="mt-2 px-4 py-2 bg-red-600 text-white rounded"
118
+ >
119
+ Try again
120
+ </button>
121
+ </div>
122
+ )
123
+ }
124
+ ```
125
+
126
+ ## Middleware for Auth/Tenant
127
+
128
+ ```tsx
129
+ // middleware.ts
130
+ import { NextResponse } from 'next/server'
131
+ import type { NextRequest } from 'next/server'
132
+
133
+ export function middleware(request: NextRequest) {
134
+ // Get tenant from subdomain or header
135
+ const hostname = request.headers.get('host') || ''
136
+ const subdomain = hostname.split('.')[0]
137
+
138
+ // Add tenant to headers for downstream use
139
+ const response = NextResponse.next()
140
+ response.headers.set('x-tenant-id', subdomain)
141
+
142
+ // Auth check
143
+ const session = request.cookies.get('session')
144
+ if (!session && request.nextUrl.pathname.startsWith('/dashboard')) {
145
+ return NextResponse.redirect(new URL('/login', request.url))
146
+ }
147
+
148
+ return response
149
+ }
150
+
151
+ export const config = {
152
+ matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
153
+ }
154
+ ```
155
+
156
+ ## Streaming with Suspense
157
+
158
+ ```tsx
159
+ import { Suspense } from 'react'
160
+
161
+ export default function Dashboard() {
162
+ return (
163
+ <div>
164
+ <h1>Dashboard</h1>
165
+
166
+ {/* This loads immediately */}
167
+ <StaticContent />
168
+
169
+ {/* This streams in when ready */}
170
+ <Suspense fallback={<LoadingStats />}>
171
+ <AsyncStats />
172
+ </Suspense>
173
+
174
+ {/* This streams separately */}
175
+ <Suspense fallback={<LoadingChart />}>
176
+ <AsyncChart />
177
+ </Suspense>
178
+ </div>
179
+ )
180
+ }
181
+ ```
182
+
183
+ ## Metadata API
184
+
185
+ ```tsx
186
+ // app/dashboard/page.tsx
187
+ import { Metadata } from 'next'
188
+
189
+ export const metadata: Metadata = {
190
+ title: 'Dashboard | MyApp',
191
+ description: 'Your personal dashboard',
192
+ }
193
+
194
+ // Dynamic metadata
195
+ export async function generateMetadata({ params }): Promise<Metadata> {
196
+ const user = await getUser(params.id)
197
+ return {
198
+ title: `${user.name}'s Profile`,
199
+ openGraph: {
200
+ images: [user.avatar],
201
+ },
202
+ }
203
+ }
204
+ ```
205
+
206
+ ## Data Fetching Patterns
207
+
208
+ ```tsx
209
+ // Parallel data fetching
210
+ async function Dashboard() {
211
+ // These run in parallel
212
+ const [user, posts, stats] = await Promise.all([
213
+ getUser(),
214
+ getPosts(),
215
+ getStats(),
216
+ ])
217
+
218
+ return <DashboardView user={user} posts={posts} stats={stats} />
219
+ }
220
+
221
+ // Sequential (when dependent)
222
+ async function Profile({ params }) {
223
+ const user = await getUser(params.id)
224
+ const posts = await getPostsByUser(user.id) // Needs user.id
225
+
226
+ return <ProfileView user={user} posts={posts} />
227
+ }
228
+ ```
229
+
230
+ ## Route Handlers (API)
231
+
232
+ ```tsx
233
+ // app/api/users/route.ts
234
+ import { NextResponse } from 'next/server'
235
+
236
+ export async function GET(request: Request) {
237
+ const users = await prisma.user.findMany()
238
+ return NextResponse.json(users)
239
+ }
240
+
241
+ export async function POST(request: Request) {
242
+ const body = await request.json()
243
+ const user = await prisma.user.create({ data: body })
244
+ return NextResponse.json(user, { status: 201 })
245
+ }
246
+ ```
247
+
248
+ ## Multi-Tenancy Pattern
249
+
250
+ ```tsx
251
+ // lib/tenant.ts
252
+ import { headers } from 'next/headers'
253
+
254
+ export async function getTenant() {
255
+ const headersList = headers()
256
+ const tenantId = headersList.get('x-tenant-id')
257
+
258
+ if (!tenantId) throw new Error('No tenant')
259
+
260
+ return prisma.organization.findUniqueOrThrow({
261
+ where: { subdomain: tenantId },
262
+ })
263
+ }
264
+
265
+ // Usage in any server component
266
+ export default async function Dashboard() {
267
+ const tenant = await getTenant()
268
+ const data = await prisma.post.findMany({
269
+ where: { organizationId: tenant.id },
270
+ })
271
+ // ...
272
+ }
273
+ ```
274
+
275
+ ## Vercel AI SDK Integration
276
+
277
+ ```tsx
278
+ // app/api/chat/route.ts
279
+ import { openai } from '@ai-sdk/openai'
280
+ import { streamText } from 'ai'
281
+
282
+ export async function POST(req: Request) {
283
+ const { messages } = await req.json()
284
+
285
+ const result = await streamText({
286
+ model: openai('gpt-4-turbo'),
287
+ messages,
288
+ })
289
+
290
+ return result.toDataStreamResponse()
291
+ }
292
+ ```
293
+
294
+ ## Production Checklist
295
+
296
+ - [ ] All routes have `loading.tsx`
297
+ - [ ] All routes have `error.tsx`
298
+ - [ ] Metadata on all pages
299
+ - [ ] Server Actions for mutations
300
+ - [ ] Proper auth middleware
301
+ - [ ] Multi-tenant isolation (if applicable)
302
+ - [ ] Streaming for slow data
303
+ - [ ] Edge runtime where beneficial
304
+
305
+ ---
306
+
307
+ *Ultra-Dex v1.7.0 - Next.js 15 Production Patterns*
@@ -0,0 +1,282 @@
1
+ # SaaS Multi-Tenancy Patterns
2
+
3
+ > Patterns for building secure multi-tenant SaaS applications
4
+
5
+ ## Core Principles
6
+
7
+ 1. **Tenant Isolation** - Data from one tenant NEVER visible to another
8
+ 2. **Consistent Filtering** - ALL queries must include tenant context
9
+ 3. **Defense in Depth** - Multiple layers of tenant validation
10
+
11
+ ## Tenant Identification
12
+
13
+ ### Subdomain-Based (Recommended for SaaS)
14
+ ```typescript
15
+ // middleware.ts
16
+ import { NextResponse } from 'next/server'
17
+ import type { NextRequest } from 'next/server'
18
+
19
+ export function middleware(request: NextRequest) {
20
+ const hostname = request.headers.get('host') || ''
21
+ const subdomain = hostname.split('.')[0]
22
+
23
+ // Skip for main domain
24
+ if (subdomain === 'www' || subdomain === 'app') {
25
+ return NextResponse.next()
26
+ }
27
+
28
+ const response = NextResponse.next()
29
+ response.headers.set('x-tenant-id', subdomain)
30
+ return response
31
+ }
32
+ ```
33
+
34
+ ### Header-Based (API Clients)
35
+ ```typescript
36
+ // For API-first architectures
37
+ const tenantId = request.headers.get('x-tenant-id')
38
+ if (!tenantId) {
39
+ return Response.json({ error: 'Tenant ID required' }, { status: 400 })
40
+ }
41
+ ```
42
+
43
+ ### User Association (After Auth)
44
+ ```typescript
45
+ // Get tenant from authenticated user
46
+ const session = await getSession()
47
+ const tenantId = session?.user?.organizationId
48
+ ```
49
+
50
+ ## Database Patterns
51
+
52
+ ### Row-Level Security (Recommended)
53
+
54
+ **Prisma Schema:**
55
+ ```prisma
56
+ model Organization {
57
+ id String @id @default(cuid())
58
+ subdomain String @unique
59
+ name String
60
+ users User[]
61
+ posts Post[]
62
+ // All tenant-owned data has organizationId
63
+ }
64
+
65
+ model User {
66
+ id String @id @default(cuid())
67
+ email String @unique
68
+ organization Organization @relation(fields: [organizationId], references: [id])
69
+ organizationId String
70
+ posts Post[]
71
+ }
72
+
73
+ model Post {
74
+ id String @id @default(cuid())
75
+ title String
76
+ content String
77
+ organization Organization @relation(fields: [organizationId], references: [id])
78
+ organizationId String
79
+ author User @relation(fields: [authorId], references: [id])
80
+ authorId String
81
+
82
+ @@index([organizationId]) // ALWAYS index tenant column
83
+ }
84
+ ```
85
+
86
+ **Query Pattern (ALWAYS include organizationId):**
87
+ ```typescript
88
+ // lib/db.ts - Tenant-scoped client
89
+ export function getTenantDb(organizationId: string) {
90
+ return {
91
+ post: {
92
+ findMany: (args?: Prisma.PostFindManyArgs) =>
93
+ prisma.post.findMany({
94
+ ...args,
95
+ where: { ...args?.where, organizationId }
96
+ }),
97
+ create: (data: Prisma.PostCreateInput) =>
98
+ prisma.post.create({
99
+ data: { ...data, organizationId }
100
+ }),
101
+ // ... other methods
102
+ }
103
+ }
104
+ }
105
+
106
+ // Usage
107
+ const db = getTenantDb(session.user.organizationId)
108
+ const posts = await db.post.findMany() // Auto-filtered
109
+ ```
110
+
111
+ ### PostgreSQL Row-Level Security (RLS)
112
+
113
+ ```sql
114
+ -- Enable RLS
115
+ ALTER TABLE posts ENABLE ROW LEVEL SECURITY;
116
+
117
+ -- Policy: Users can only see their org's posts
118
+ CREATE POLICY posts_tenant_isolation ON posts
119
+ USING (organization_id = current_setting('app.current_tenant')::text);
120
+
121
+ -- Set tenant context in your app
122
+ SET app.current_tenant = 'org_123';
123
+ SELECT * FROM posts; -- Only org_123 posts returned
124
+ ```
125
+
126
+ ### Schema-Per-Tenant (Enterprise)
127
+
128
+ ```typescript
129
+ // For highest isolation (enterprise customers)
130
+ const schema = `tenant_${tenantId}`
131
+
132
+ // Prisma with schema
133
+ const prisma = new PrismaClient({
134
+ datasources: {
135
+ db: {
136
+ url: `${DATABASE_URL}?schema=${schema}`
137
+ }
138
+ }
139
+ })
140
+ ```
141
+
142
+ ## Middleware Pattern
143
+
144
+ ```typescript
145
+ // lib/tenant.ts
146
+ import { headers } from 'next/headers'
147
+ import { cache } from 'react'
148
+
149
+ export const getTenant = cache(async () => {
150
+ const headersList = headers()
151
+ const tenantId = headersList.get('x-tenant-id')
152
+
153
+ if (!tenantId) {
154
+ throw new Error('Tenant context required')
155
+ }
156
+
157
+ const tenant = await prisma.organization.findUnique({
158
+ where: { subdomain: tenantId }
159
+ })
160
+
161
+ if (!tenant) {
162
+ throw new Error('Tenant not found')
163
+ }
164
+
165
+ return tenant
166
+ })
167
+
168
+ // Usage in any Server Component or API route
169
+ export default async function Dashboard() {
170
+ const tenant = await getTenant()
171
+ const posts = await prisma.post.findMany({
172
+ where: { organizationId: tenant.id }
173
+ })
174
+ // ...
175
+ }
176
+ ```
177
+
178
+ ## API Route Pattern
179
+
180
+ ```typescript
181
+ // app/api/posts/route.ts
182
+ import { getTenant } from '@/lib/tenant'
183
+ import { getSession } from '@/lib/auth'
184
+
185
+ export async function GET() {
186
+ const session = await getSession()
187
+ if (!session) {
188
+ return Response.json({ error: 'Unauthorized' }, { status: 401 })
189
+ }
190
+
191
+ const tenant = await getTenant()
192
+
193
+ // Verify user belongs to this tenant
194
+ if (session.user.organizationId !== tenant.id) {
195
+ return Response.json({ error: 'Forbidden' }, { status: 403 })
196
+ }
197
+
198
+ const posts = await prisma.post.findMany({
199
+ where: { organizationId: tenant.id }
200
+ })
201
+
202
+ return Response.json(posts)
203
+ }
204
+ ```
205
+
206
+ ## Testing Multi-Tenancy
207
+
208
+ ```typescript
209
+ // tests/multi-tenancy.test.ts
210
+ describe('Tenant Isolation', () => {
211
+ it('should not leak data between tenants', async () => {
212
+ // Create data for tenant A
213
+ const tenantA = await createTenant('tenant-a')
214
+ const postA = await createPost({
215
+ title: 'Secret',
216
+ organizationId: tenantA.id
217
+ })
218
+
219
+ // Create tenant B
220
+ const tenantB = await createTenant('tenant-b')
221
+
222
+ // Query as tenant B - should NOT see tenant A's post
223
+ const postsForB = await prisma.post.findMany({
224
+ where: { organizationId: tenantB.id }
225
+ })
226
+
227
+ expect(postsForB).not.toContainEqual(
228
+ expect.objectContaining({ id: postA.id })
229
+ )
230
+ })
231
+
232
+ it('should prevent cross-tenant access via API', async () => {
233
+ const response = await fetch('/api/posts', {
234
+ headers: {
235
+ 'x-tenant-id': 'wrong-tenant',
236
+ 'Authorization': `Bearer ${validToken}`
237
+ }
238
+ })
239
+
240
+ expect(response.status).toBe(403)
241
+ })
242
+ })
243
+ ```
244
+
245
+ ## Checklist
246
+
247
+ - [ ] All database tables have `organizationId` column
248
+ - [ ] All queries filter by `organizationId`
249
+ - [ ] Middleware extracts tenant from subdomain/header
250
+ - [ ] API routes verify user belongs to tenant
251
+ - [ ] Indexes on `organizationId` columns
252
+ - [ ] Cross-tenant access tests written
253
+ - [ ] No raw SQL without tenant filter
254
+ - [ ] Admin routes have additional protection
255
+
256
+ ## Common Mistakes
257
+
258
+ ```typescript
259
+ // ❌ BAD - No tenant filter
260
+ const posts = await prisma.post.findMany()
261
+
262
+ // ✅ GOOD - Always filter
263
+ const posts = await prisma.post.findMany({
264
+ where: { organizationId: tenant.id }
265
+ })
266
+
267
+ // ❌ BAD - Trusting client-provided tenant ID for data access
268
+ const { tenantId } = req.body
269
+ const posts = await prisma.post.findMany({
270
+ where: { organizationId: tenantId }
271
+ })
272
+
273
+ // ✅ GOOD - Use server-verified tenant context
274
+ const tenant = await getTenant() // From middleware/session
275
+ const posts = await prisma.post.findMany({
276
+ where: { organizationId: tenant.id }
277
+ })
278
+ ```
279
+
280
+ ---
281
+
282
+ *Ultra-Dex v1.7.1 - Multi-Tenancy Patterns for Production SaaS*
@@ -0,0 +1,78 @@
1
+ # Ultra-Dex Cursor Rules
2
+
3
+ > Modular AI rules for Cursor, Copilot, and other AI coding assistants.
4
+
5
+ ## What is This?
6
+
7
+ The 34-section Ultra-Dex template, atomized into small, focused rule files. Each file is under 200 lines and optimized for AI context windows.
8
+
9
+ ## How to Use
10
+
11
+ ### Option 1: Copy to `.cursor/rules/`
12
+
13
+ ```bash
14
+ # In your project root
15
+ mkdir -p .cursor/rules
16
+ cp path/to/ultra-dex/cursor-rules/*.mdc .cursor/rules/
17
+ ```
18
+
19
+ ### Option 2: Reference in System Prompt
20
+
21
+ Paste the relevant rule into your AI assistant's system prompt when working on that domain.
22
+
23
+ ### Option 3: Selective Loading
24
+
25
+ Only load rules relevant to your current task:
26
+
27
+ | Working On | Load These |
28
+ |------------|------------|
29
+ | Database schema | `00-ultra-dex-core.mdc` + `01-database.mdc` |
30
+ | API endpoints | `00-ultra-dex-core.mdc` + `02-api.mdc` |
31
+ | Authentication | `00-ultra-dex-core.mdc` + `03-auth.mdc` |
32
+ | Frontend components | `00-ultra-dex-core.mdc` + `04-frontend.mdc` |
33
+ | Payments | `00-ultra-dex-core.mdc` + `05-payments.mdc` |
34
+ | Testing | `00-ultra-dex-core.mdc` + `06-testing.mdc` |
35
+ | Security review | `00-ultra-dex-core.mdc` + `07-security.mdc` |
36
+ | Deployment | `00-ultra-dex-core.mdc` + `08-deployment.mdc` |
37
+ | Error handling | `00-ultra-dex-core.mdc` + `09-error-handling.mdc` |
38
+ | Performance | `00-ultra-dex-core.mdc` + `10-performance.mdc` |
39
+ | Next.js 15 app | `00-ultra-dex-core.mdc` + `11-nextjs-v15.mdc` |
40
+ | Multi-tenant SaaS | `00-ultra-dex-core.mdc` + `12-multi-tenancy.mdc` |
41
+
42
+ ## Files
43
+
44
+ | File | Lines | Purpose |
45
+ |------|-------|---------|
46
+ | `00-ultra-dex-core.mdc` | ~60 | Base rules (always load) |
47
+ | `01-database.mdc` | ~70 | Prisma, schema, queries |
48
+ | `02-api.mdc` | ~100 | API routes, validation, responses |
49
+ | `03-auth.mdc` | ~70 | NextAuth configuration |
50
+ | `04-frontend.mdc` | ~100 | React, components, state |
51
+ | `05-payments.mdc` | ~90 | Stripe integration |
52
+ | `06-testing.mdc` | ~100 | Vitest, Playwright |
53
+ | `07-security.mdc` | ~100 | Input validation, auth, headers |
54
+ | `08-deployment.mdc` | ~90 | Vercel, CI/CD, migrations |
55
+ | `09-error-handling.mdc` | ~100 | Error patterns, logging |
56
+ | `10-performance.mdc` | ~100 | Optimization, caching |
57
+ | `11-nextjs-v15.mdc` | ~200 | Next.js 15 App Router patterns |
58
+ | `12-multi-tenancy.mdc` | ~200 | SaaS multi-tenant patterns |
59
+
60
+ ## Why Modular?
61
+
62
+ 1. **AI Context Limits**: LLMs perform better with focused context (<500 lines)
63
+ 2. **"Lost in the Middle"**: Long contexts degrade AI attention on middle content
64
+ 3. **Relevance**: Load only what you need for the current task
65
+ 4. **Maintainability**: Update one domain without touching others
66
+
67
+ ## Customization
68
+
69
+ These are starting points. Customize for your stack:
70
+
71
+ - Using Supabase instead of Prisma? Modify `01-database.mdc`
72
+ - Using Clerk instead of NextAuth? Replace `03-auth.mdc`
73
+ - Using Paddle instead of Stripe? Replace `05-payments.mdc`
74
+
75
+ ## Full Template
76
+
77
+ For the complete 34-section template with all details:
78
+ - [04-Imp-Template.md](../@%20Ultra%20DeX/Saas%20plan/04-Imp-Template.md)