---
name: "cursor-reference-architecture"
description: |
  Reference architecture for Cursor IDE projects: directory structure, rules organization, indexing
  strategy, and team configuration patterns. Triggers on "cursor architecture", "cursor project structure",
  "cursor best practices", "cursor file structure".
allowed-tools: "Read, Write, Edit, Bash(cmd:*)"
version: 1.0.0
license: MIT
author: "Jeremy Longshore <jeremy@intentsolutions.io>"
compatible-with: claude-code, codex, openclaw
tags: [saas, cursor, cursor-reference]
---
# Cursor Reference Architecture

Reference architecture patterns for optimizing Cursor IDE project setup. Covers directory structure, rules organization, indexing strategy, and multi-project configuration for maximum AI effectiveness.

## Project Layout for Cursor

A well-structured project makes AI features significantly more effective:

```
my-project/
├── .cursor/
│   └── rules/
│       ├── project.mdc          # alwaysApply: true (stack, conventions)
│       ├── security.mdc         # alwaysApply: true (security constraints)
│       ├── typescript.mdc       # globs: "**/*.ts,**/*.tsx"
│       ├── api-routes.mdc       # globs: "src/api/**/*.ts"
│       ├── database.mdc         # globs: "src/db/**/*.ts,prisma/**"
│       └── testing.mdc          # globs: "**/*.test.ts,**/*.spec.ts"
├── .cursorignore                # Exclude from AI + indexing
├── .cursorindexingignore        # Exclude from indexing only
├── .gitignore
├── src/
│   ├── api/                     # API routes
│   ├── services/                # Business logic
│   ├── db/                      # Database layer
│   ├── types/                   # Shared TypeScript types
│   ├── utils/                   # Utility functions
│   └── components/              # UI components
├── tests/
├── prisma/
├── docs/                        # Architecture docs (good for @Docs)
└── package.json
```

### Why This Structure Helps Cursor

1. **Glob patterns work predictably**: `src/api/**/*.ts` cleanly scopes API rules
2. **@Files references are intuitive**: `@src/types/user.ts` is discoverable
3. **Indexing is focused**: clear separation of code vs build output vs data
4. **Rules inheritance**: project-level always-on + directory-scoped rules

## Rules Architecture

### Layer 1: Always-On Global Rules

```yaml
# .cursor/rules/project.mdc
---
description: "Core project context and conventions"
globs: ""
alwaysApply: true
---
# SaaS Dashboard Application

Stack: Next.js 15 (App Router), TypeScript 5.7, PostgreSQL 16, Prisma 6
Auth: NextAuth.js v5 with GitHub OAuth
Styling: Tailwind CSS 4
Testing: Vitest + Playwright
Package manager: pnpm

## Architecture Decisions
- Server Components by default, "use client" only when needed
- Repository pattern for database access
- Zod schemas for all external input validation
- Result types for error handling (never throw from services)
```

### Layer 2: Security (Always-On)

```yaml
# .cursor/rules/security.mdc
---
description: "Security constraints for all AI-generated code"
globs: ""
alwaysApply: true
---
# Security Requirements
- NEVER hardcode secrets, API keys, or passwords
- ALWAYS use parameterized queries (no string interpolation in SQL)
- ALWAYS validate and sanitize user input with Zod
- NEVER disable CORS, CSRF protection, or TLS verification
- Use httpOnly, secure, sameSite cookies for auth tokens
- Rate limit all public API endpoints
```

### Layer 3: Technology-Specific (Glob-Scoped)

```yaml
# .cursor/rules/react-components.mdc
---
description: "React component patterns"
globs: "src/components/**/*.tsx,app/**/*.tsx"
alwaysApply: false
---
# Component Standards
- Named exports only (no default exports)
- Props interface: {ComponentName}Props
- Use forwardRef for interactive components
- Colocate tests: Component.test.tsx next to Component.tsx
- Loading states: use Suspense boundaries, not conditional rendering
```

```yaml
# .cursor/rules/api-routes.mdc
---
description: "API route handler patterns"
globs: "app/api/**/*.ts,src/api/**/*.ts"
alwaysApply: false
---
# API Route Standards
- All handlers wrapped in withAuth() middleware
- Input validation with Zod (parse body, params, query)
- Response shape: { data: T } or { error: string, code: string }
- HTTP status codes: 200 OK, 201 Created, 400 Bad Request, 401, 403, 404, 500
- Structured logging with requestId for traceability
```

```yaml
# .cursor/rules/database.mdc
---
description: "Database access patterns"
globs: "src/db/**/*.ts,src/repositories/**/*.ts,prisma/**"
alwaysApply: false
---
# Database Conventions
- All queries via repository classes (never raw Prisma in API routes)
- Use transactions for multi-table writes
- Always include select/include to avoid over-fetching
- Pagination: cursor-based for lists, offset for admin tools
- Soft delete: use deletedAt timestamp, never hard delete user data
```

### Layer 4: Manual Reference Rules

```yaml
# .cursor/rules/deployment.mdc
---
description: "Deployment and infrastructure patterns"
globs: ""
alwaysApply: false
---
# Deployment
- Vercel for frontend, Railway for API
- Environment variables managed in Vercel/Railway dashboards
- Database migrations: `prisma migrate deploy` in CI
- Feature flags via LaunchDarkly
```

Reference manually with `@Cursor Rules` in Chat when discussing deployment.

## Indexing Strategy

### Optimized .cursorignore

```gitignore
# Build output
dist/
build/
.next/
out/
.vercel/
.turbo/
coverage/

# Dependencies
node_modules/
.pnpm-store/

# Generated
*.min.js
*.min.css
*.d.ts.map
*.tsbuildinfo
pnpm-lock.yaml

# Data / Assets
*.csv
*.sql
*.sqlite
*.png
*.jpg
*.gif
*.svg
*.ico
*.woff
*.woff2
*.ttf

# Environment
.env*

# IDE
.vscode/
.idea/
```

### .cursorindexingignore for Large References

```gitignore
# Not indexed, but accessible via @Files
docs/api-spec.yaml
tests/fixtures/
scripts/migration-data/
```

## Monorepo Architecture

### Turborepo / pnpm Workspaces

```
monorepo/
├── .cursor/
│   └── rules/
│       ├── monorepo.mdc         # alwaysApply: true (shared conventions)
│       ├── shared-types.mdc     # globs: "packages/shared/**"
│       ├── api.mdc              # globs: "apps/api/**"
│       └── web.mdc              # globs: "apps/web/**"
├── .cursorignore
├── apps/
│   ├── api/
│   ├── web/
│   └── admin/
├── packages/
│   ├── shared/
│   ├── ui/
│   └── config/
├── turbo.json
└── pnpm-workspace.yaml
```

**Key rule for monorepos:**
```yaml
# .cursor/rules/monorepo.mdc
---
description: "Monorepo import conventions"
globs: ""
alwaysApply: true
---
# Import Conventions
- Import shared types: import { User } from '@myorg/shared'
- Import UI components: import { Button } from '@myorg/ui'
- NEVER use relative paths across package boundaries
- Each package has its own tsconfig.json extending root
```

## Configuration Files Summary

| File | Committed to Git | Purpose |
|------|-----------------|---------|
| `.cursor/rules/*.mdc` | Yes | AI behavior rules (team-shared) |
| `.cursorignore` | Yes | File exclusion from AI + indexing |
| `.cursorindexingignore` | Yes | File exclusion from indexing only |
| `settings.json` (Cursor) | No (machine-local) | Editor preferences |
| `keybindings.json` (Cursor) | No (machine-local) | Custom shortcuts |

## Enterprise Considerations

- **Rules as code**: Treat `.cursor/rules/` changes like infrastructure changes -- require PR review
- **Template repository**: Create a company template repo with standard rules, ignore files, and onboarding docs
- **Compliance mapping**: Map security rules to specific compliance controls (SOC 2 CC6.1, etc.)
- **Architecture documentation**: Keep `docs/` directory indexed so AI can reference architecture decisions via `@Docs`

## Resources

- [Cursor Rules Documentation](https://docs.cursor.com/context/rules)
- [Codebase Indexing](https://docs.cursor.com/context/codebase-indexing)
- [Ignore Files](https://docs.cursor.com/context/ignore-files)
