---
description: 
globs: 
alwaysApply: true
---
# Project Structure Guidelines

Follow these guidelines when creating new files to maintain consistent project organization.

## Directory Structure

```
├── app/                    # Next.js app router pages and API routes
│   ├── api/               # API routes
│   ├── _actions/          # Server actions (private)
│   ├── actions/           # Server actions (public)
│   ├── [route]/          # Route directories
│   │   ├── page.tsx      # Page component
│   │   ├── layout.tsx    # Layout component
│   │   └── components/   # Route-specific components
├── components/            # Shared UI components
│   ├── ui/               # Basic UI components
│   └── [feature]/        # Feature-specific components
├── convex/                # Convex schema, functions, and backend logic
├── lib/                   # Utility functions and services
│   ├── services/         # Business logic and data services (Convex client wrappers)
│   ├── validations/      # Form and data validation
│   ├── convex/           # Convex client configuration and utilities
│   └── config/           # Configuration files
├── types/                # TypeScript type definitions
└── public/              # Static assets

```

## File Location Guidelines

1. **Components**
   - Reusable UI components → `/components/ui/`
   - Feature-specific shared components → `/components/[feature]/`
   - Route-specific components → `/app/[route]/components/`

2. **Business Logic**
   - Convex backend logic → `/convex/`
   - Database services (Convex client wrappers) → `/lib/services/`
   - Utility functions → `/lib/utils.ts`
   - Type definitions → `/types/`
   - Form validation → `/lib/validations/`
   - Convex client config → `/lib/convex/`

3. **Server Actions**
   - Private actions → `/app/_actions/`
   - Public actions → `/app/actions/`

4. **API Routes**
   - All API routes → `/app/api/`

## Naming Conventions

1. **Files**
   - React components and Utilities: kebab-case (e.g., `auth-utils.ts`)
   - Pages: `page.tsx`
   - Layouts: `layout.tsx`
   - Server actions: kebab-case (e.g., `create-sponsor.ts`)
   - Convex functions: kebab-case (e.g., `record-visit.ts`)

2. **Directories**
   - Route directories: kebab-case
   - Component directories: kebab-case
   - Feature directories: kebab-case
   - Convex modules: kebab-case

## File Sizes

Prefer to keep files to 300 lines of code. Split larger components into separate imports.

## Examples

### Good: New Component Location
```typescript
// ✅ /components/ui/button.tsx
export function Button() { ... }

// ✅ /components/sponsors/sponsor-card.tsx
export function SponsorCard() { ... }

// ✅ /app/sponsors/[slug]/components/tier-selector.tsx
export function TierSelector() { ... }
```

### Good: New Service Location
```typescript
// ✅ /lib/services/visit-service.ts
export async function recordVisit(args) { ... }

// ✅ /lib/validations/sponsor-schema.ts
export const sponsorSchema = { ... }
```

### Good: New Server Action Location
```typescript
// ✅ /app/_actions/create-sponsor.ts
export async function createSponsor() { ... }
```

### Good: New Convex Function Location
```typescript
// ✅ /convex/visits.ts
export const recordVisit = mutation({ ... })
```

### Good: New Convex Client Config Location
```typescript
// ✅ /lib/convex/client.ts
import { ConvexClient } from "convex/browser";
export const convex = new ConvexClient(process.env.NEXT_PUBLIC_CONVEX_URL!);
```

## Convex + Clerk Access Control Pattern

When using Convex as your backend database and Clerk for authentication:

- **All access control and identity validation should be handled by Clerk in your Next.js server** (API routes, server actions, or server components).
- **Convex should only be called from the server for any protected/private data.**
- **The client should never call Convex directly for private or user-specific data.**
- For public data, you may expose Convex queries directly to the client if desired.

**Recommended Flow:**

1. Client makes a request to your Next.js API route or server action.
2. The server validates the user/session using Clerk.
3. If authorized, the server calls Convex using the Convex Node client.
4. The server returns the result to the client.

**Benefits:**
- Single source of truth for authentication and access control (Clerk)
- No need to configure JWT templates for Convex in Clerk
- Maximum security: only your server can access private Convex data

**Example:**
```typescript
// app/api/secure-data/route.ts
import { auth } from "@clerk/nextjs/server";
import { convexClient } from "@/lib/convex"; // Your Convex Node client

export async function POST(req: Request) {
  const { userId } = await auth();
  if (!userId) {
    return new Response("Unauthorized", { status: 401 });
  }
  // Now you can safely call Convex with trusted userId
  const result = await convexClient.mutation("secureFunction", { userId, ... });
  return Response.json(result);
}
```
