> ## Documentation Index
> Fetch the complete documentation index at: https://docs.charle.agency/llms.txt
> Use this file to discover all available pages before exploring further.

# Project Structure

> Understanding the CharleOS codebase organization

CharleOS uses Next.js 16 App Router with a feature-based organization. This guide explains how the codebase is structured and where to find (or add) code.

## Overview

```
charle-os/
├── app/                      # Next.js App Router (pages & routes)
├── components/               # React components (feature-based)
├── lib/                      # Shared utilities & business logic
├── hooks/                    # Custom React hooks
├── __tests__/                # Unit tests (Vitest)
├── e2e/                      # E2E tests (Playwright)
├── drizzle/                  # Database migrations
├── trigger/                  # Background jobs (Trigger.dev)
├── emails/                   # Email templates (React Email)
├── scripts/                  # Utility scripts
└── public/                   # Static assets
```

## App Directory (`/app`)

The `app/` directory contains all routes and pages using Next.js App Router.

### Route Groups

CharleOS uses **route groups** to organize pages without affecting URLs:

#### `(dashboard)/` - Main App

The authenticated team member application:

```
app/(dashboard)/
├── layout.tsx               # Dashboard layout (sidebar, header)
├── page.tsx                 # Dashboard home (/dashboard)
├── clients/                 # Client management
│   ├── [id]/               # Client detail page
│   └── page.tsx            # Client list
├── tasks/                   # Task management
├── quotes/                  # Quote management
├── projects/                # Project management
├── schedule/                # Schedule & calendar
├── help-desk/               # Support tickets
├── admin/                   # Admin settings
└── ...
```

**Key features:**

* Shared layout with sidebar navigation
* Role-based access control
* Real-time updates via Pusher

#### `client-portal/` - Client Portal

Separate app for clients to view their work:

```
app/client-portal/
├── (authenticated)/        # After sign-in
│   ├── quotes/            # View quotes
│   ├── tasks/             # View tasks
│   ├── help-desk/         # Submit tickets
│   └── roadmap/           # Project roadmap
├── sign-in/               # Client login
├── invite/                # Client invitation flow
└── layout.tsx             # Client portal layout
```

**Separate from main app:**

* Different authentication (Better Auth with client context)
* Different branding and navigation
* Restricted to client-facing features only

#### `(auth)/` - Authentication Pages

Team member authentication flow:

```
app/(auth)/
├── auth/
│   └── route.tsx          # Better Auth API handler
├── pending-approval/       # Pending role screen
└── layout.tsx             # Minimal auth layout
```

#### `api/` - API Routes

All backend API endpoints:

```
app/api/
├── dashboard/              # Dashboard data
│   ├── day-rates/
│   ├── utilisation/
│   └── ...
├── clients/                # Client CRUD
├── tasks/                  # Task CRUD
├── quotes/                 # Quote CRUD
├── schedule/               # Schedule management
├── time-entries/           # Time tracking
├── admin/                  # Admin operations
└── auth/                   # Better Auth endpoints
```

**Convention:**

* Each route exports `GET`, `POST`, `PUT`, `PATCH`, `DELETE` handlers
* Use `lib/services/` for business logic (keep routes thin)
* Return structured responses with proper error handling

### Special Files

| File            | Purpose                            |
| --------------- | ---------------------------------- |
| `layout.tsx`    | Shared UI wrapper for child routes |
| `page.tsx`      | Route content (actual page)        |
| `loading.tsx`   | Loading state (Suspense fallback)  |
| `error.tsx`     | Error boundary                     |
| `not-found.tsx` | 404 page                           |
| `route.ts`      | API endpoint handler               |

## Components Directory (`/components`)

All React components organized by feature:

### Feature-Based Organization

```
components/
├── ui/                      # shadcn/ui base components
│   ├── button.tsx
│   ├── input.tsx
│   ├── dialog.tsx
│   └── ...                 # 100+ UI primitives
├── tasks/                   # Task-specific components
│   ├── task-card.tsx
│   ├── task-filters.tsx
│   └── wizard/             # Task creation wizard
├── quotes/                  # Quote components
├── calendar/                # Calendar & schedule
├── dashboard/               # Dashboard widgets
├── data-table/              # Reusable table components
├── badge/                   # Status badges
├── client-portal/           # Client portal components
└── ...
```

### Component Naming

* **PascalCase** for components: `TaskCard.tsx`
* **Feature prefixes** for clarity: `TaskStatusBadge`, `QuoteApprovalCard`
* **Index files** for clean imports: `components/tasks/index.ts`

### UI Components (`/components/ui`)

Base components from shadcn/ui:

* Built on Radix UI primitives
* Styled with Tailwind CSS
* Fully customizable
* Don't edit directly - use composition

**Example usage:**

```typescript theme={null}
import { Button } from "@/components/ui/button";
import { Dialog } from "@/components/ui/dialog";
```

## Lib Directory (`/lib`)

Shared utilities, business logic, and configuration:

### Services (`/lib/services`)

Business logic layer - keeps API routes thin:

```
lib/services/
├── tasks.ts                 # Task operations
├── quotes.ts                # Quote operations
├── clients.ts               # Client operations
├── metrics.ts               # Metric calculations
├── billing.ts               # Billing logic
├── schedule-calculator.ts   # Schedule generation
└── ...
```

**Pattern:**

* Functions accept validated input
* Return typed results or throw errors
* Used by API routes and server components

**Example:**

```typescript theme={null}
// lib/services/tasks.ts
export async function createTask(data: CreateTaskInput) {
  // Validate, calculate, insert
  return task;
}

// app/api/tasks/route.ts
export async function POST(req: Request) {
  const data = await req.json();
  const task = await createTask(data);
  return Response.json(task);
}
```

### Database (`/lib/db`)

Database schema and client:

```
lib/db/
├── schema.ts                # Drizzle schema (all tables)
├── index.ts                 # Database client
└── doc-chunks.ts            # RAG document chunks
```

**Key files:**

* `schema.ts` - **Single source of truth** for database structure
* Types auto-generated from schema
* All tables, relations, enums defined here

### Utils (`/lib/utils`)

Utility functions grouped by purpose:

```
lib/utils/
├── billing.ts               # Billing formula (MIN/MAX)
├── tshirt-sizes.ts          # T-shirt size calculations
├── day-rate.ts              # Day rate calculations
├── prorated-revenue.ts      # Revenue proration
├── working-days.ts          # Working day calculations
├── date-formatting.ts       # Date utilities
└── ...
```

### Constants (`/lib/constants`)

Configuration and constants:

```
lib/constants/
├── tshirt-sizes.ts          # T-shirt size definitions
├── capacity.ts              # Capacity constants
├── status.ts                # Status enums & labels
├── target-metrics.ts        # Target thresholds
└── ...
```

### Schemas (`/lib/schemas`)

Zod validation schemas for forms and API:

```
lib/schemas/
├── task.ts                  # Task validation
├── quote.ts                 # Quote validation
├── client.ts                # Client validation
└── ...
```

**Usage:**

```typescript theme={null}
import { createTaskSchema } from "@/lib/schemas/task";

const parsed = createTaskSchema.parse(formData);
```

### AI (`/lib/ai`)

AI features (Alan assistant):

```
lib/ai/
├── agents/                  # AI agents
│   ├── general.ts          # General queries
│   ├── schedule.ts         # Schedule management
│   └── instructions/       # System prompts
├── tools/                   # AI tool functions
│   ├── tasks.ts
│   ├── schedule.ts
│   └── ...
└── rag.ts                   # RAG (doc search)
```

## Hooks Directory (`/hooks`)

Custom React hooks for data fetching and state:

```
hooks/
├── use-task-detail.ts       # Fetch task by ID
├── use-task-list.ts         # Fetch tasks with filters
├── use-client-detail.ts     # Fetch client by ID
└── ...
```

**Pattern (SWR-based):**

```typescript theme={null}
export function useTaskDetail(id: string) {
  return useSWR(`/api/tasks/${id}`, fetcher, {
    // Optimistic updates, revalidation, etc.
  });
}
```

## Tests

### Unit Tests (`/__tests__`)

Vitest tests for utilities and logic:

```
__tests__/
├── billing.test.ts          # Billing formula tests
├── tshirt-sizes.test.ts     # T-shirt size calculations
├── working-days.test.ts     # Date utilities
└── ...
```

**Run tests:**

```bash theme={null}
npm run test          # Run once
npm run test:watch    # Watch mode
```

### E2E Tests (`/e2e`)

Playwright tests for critical flows:

```
e2e/
├── auth.spec.ts             # Authentication flow
├── tasks.spec.ts            # Task creation
├── quotes.spec.ts           # Quote workflow
└── global-setup.ts          # Test setup
```

**Run tests:**

```bash theme={null}
npm run test:e2e      # Headless
npm run test:e2e:ui   # Interactive
```

## Other Directories

### Drizzle (`/drizzle`)

Database migrations (auto-generated):

```
drizzle/
├── 0001_initial.sql
├── 0002_add_users.sql
├── meta/                    # Migration metadata
└── ...
```

**Don't edit manually** - generate with `npm run db:generate`

### Trigger (`/trigger`)

Background jobs (Trigger.dev):

```
trigger/
├── calculate-day-rates.ts   # Daily metric calculation
├── schedule-reminders.ts    # Notification jobs
└── ...
```

### Emails (`/emails`)

React Email templates:

```
emails/
├── quote-approved.tsx
├── task-assigned.tsx
└── components/
    └── layout.tsx           # Email layout
```

### Scripts (`/scripts`)

Utility scripts:

```
scripts/
├── seed-dev-data.ts         # Seed development data
├── index-user-guide.ts      # Index docs for Algolia
└── ...
```

## File Naming Conventions

| Type       | Convention                  | Example                    |
| ---------- | --------------------------- | -------------------------- |
| Components | PascalCase                  | `TaskCard.tsx`             |
| Utilities  | kebab-case                  | `tshirt-sizes.ts`          |
| Hooks      | camelCase with `use` prefix | `use-task-detail.ts`       |
| API routes | kebab-case                  | `route.ts` in `day-rates/` |
| Types      | PascalCase                  | `TaskStatus`               |
| Constants  | SCREAMING\_SNAKE\_CASE      | `DEFAULT_CAPACITY`         |

## Code Organization Principles

### 1. Colocation

Keep related code close together:

* Task components in `components/tasks/`
* Task services in `lib/services/tasks.ts`
* Task schemas in `lib/schemas/task.ts`
* Task API in `app/api/tasks/`

### 2. Feature-Based Structure

Organize by feature, not by type:

**✅ Good:**

```
components/
├── tasks/
│   ├── task-card.tsx
│   ├── task-filters.tsx
│   └── task-wizard.tsx
```

**❌ Bad:**

```
components/
├── cards/
│   └── task-card.tsx
├── filters/
│   └── task-filters.tsx
└── wizards/
    └── task-wizard.tsx
```

### 3. Shared vs Feature Code

* **Shared code** → `lib/`, `components/ui/`, `hooks/`
* **Feature code** → Feature-specific directories

### 4. Thin Routes, Fat Services

API routes should be thin wrappers:

```typescript theme={null}
// ✅ Good: Thin route, logic in service
export async function POST(req: Request) {
  const data = await req.json();
  const task = await taskService.create(data);
  return Response.json(task);
}

// ❌ Bad: Business logic in route
export async function POST(req: Request) {
  // 100 lines of validation, calculation, database queries...
}
```

## Adding New Features

When adding a new feature, follow this structure:

<Steps>
  <Step title="Create Database Schema">
    Add tables to `lib/db/schema.ts` and run `npm run db:push`
  </Step>

  <Step title="Add Service Layer">
    Create `lib/services/your-feature.ts` with business logic
  </Step>

  <Step title="Create API Routes">
    Add routes in `app/api/your-feature/route.ts`
  </Step>

  <Step title="Build Components">
    Add components in `components/your-feature/`
  </Step>

  <Step title="Create Hooks">
    Add `hooks/use-your-feature.ts` for data fetching
  </Step>

  <Step title="Add Pages">
    Create pages in `app/(dashboard)/your-feature/`
  </Step>
</Steps>

## Import Paths

CharleOS uses path aliases for clean imports:

```typescript theme={null}
// ✅ Good: Path aliases
import { Button } from "@/components/ui/button";
import { createTask } from "@/lib/services/tasks";
import { useTaskDetail } from "@/hooks/use-task-detail";

// ❌ Bad: Relative paths
import { Button } from "../../../components/ui/button";
```

**Configured in `tsconfig.json`:**

* `@/*` → Root directory
* `@/components/*` → Components
* `@/lib/*` → Library code

## Related Documentation

<CardGroup cols={2}>
  <Card title="Local Setup" icon="rocket" href="/developer/getting-started/local-setup">
    Set up your development environment
  </Card>

  <Card title="Database" icon="database" href="/developer/database">
    Working with the database schema
  </Card>

  <Card title="Authentication" icon="lock" href="/developer/auth">
    How auth is structured
  </Card>

  <Card title="Testing" icon="flask-conical" href="/developer/testing">
    Writing and running tests
  </Card>
</CardGroup>
