# Agent Development Guide for FitAI

This document provides essential guidelines for AI coding agents working in the FitAI codebase.

## Project Overview

FitAI is a monorepo containing a fitness AI platform with:

- **Admin App** (`apps/admin`): Next.js 16 web application for gym management
- **Mobile App** (`apps/mobile`): React Native/Expo mobile app for clients
- **Shared Packages**: Database (`@fitai/database`) and utilities (`@fitai/shared`)

**Tech Stack**: TypeScript, Next.js 16, React 19, React Native, Expo 54, Drizzle ORM, Clerk Auth, TanStack Query, Tailwind CSS

## Build, Lint, and Test Commands

### From Repository Root (`/home/echo/dev/prototype`)

```bash
# Development
npm run dev              # Start both admin and mobile dev servers
npm run dev:admin        # Start admin dev server (Next.js)
npm run dev:mobile       # Start mobile dev server (Expo)

# Build
npm run build            # Build both apps
npm run build:admin      # Build admin app
npm run build:mobile     # Build mobile app

# Linting
npm run lint             # Lint both apps
npm run lint:admin       # Lint admin app
npm run lint:mobile      # Lint mobile app

# Type Checking
npm run typecheck        # Check types in both apps
npm run typecheck:admin  # Check types in admin
npm run typecheck:mobile # Check types in mobile

# Testing
npm run test             # Run all tests
npm run test:admin       # Run admin tests
npm run test:mobile      # Run mobile tests
```

### Admin App (`apps/admin`)

```bash
cd apps/admin

# Development
npm run dev              # Start Next.js dev server (port 3000)

# Testing
npm test                 # Run all tests
npx jest                 # Run all tests
npx jest path/to/file.test.ts                      # Run specific test file
npx jest --testPathPattern=drizzle                 # Run tests matching pattern
npx jest src/lib/database/__tests__/drizzle.test.ts  # Run specific test

# Build & Lint
npm run build            # Build production bundle
npm run lint             # Run ESLint
npm run typecheck        # Type check without emitting
```

### Mobile App (`apps/mobile`)

```bash
cd apps/mobile

# Development
npm start                # Start Expo dev server
npm run android          # Start on Android emulator
npm run ios              # Start on iOS simulator

# Testing
npm test                 # Run all tests
npx jest path/to/file.test.ts  # Run specific test file
npx jest --testPathPattern=component  # Run tests matching pattern

# Build & Lint
npm run build            # Build with Expo
npm run lint             # Run ESLint
npm run typecheck        # Type check
```

## Code Style Guidelines

### Import Organization

**Order**: External libraries → Internal imports, grouped logically

```typescript
// External: React, Next.js, React Native
import { NextRequest, NextResponse } from "next/server";
import React from "react";

// External: Third-party libraries
import { auth, clerkClient } from "@clerk/nextjs/server";
import bcrypt from "bcryptjs";

// Monorepo packages
import { db, sql } from "@fitai/database";

// Internal: Path aliases or relative imports
import { getDatabase } from "@/lib/database";
import type { User } from "./types";
```

**Key Rules**:

- Use `import type { ... }` for type-only imports
- Admin app uses path aliases: `@/*` → `./src/*`
- Mobile app uses relative paths or `@/*` alias
- No automatic import sorting; manual grouping by category

### Component Structure & Naming

**Components**: PascalCase function components with named exports

```typescript
// Feature components - Named export (function)
export function UserManagement() {
  return <div>...</div>
}

// UI library components - Named export (forwardRef constant)
const Card = React.forwardRef<HTMLDivElement, CardProps>(
  ({ className, ...props }, ref) => (
    <div ref={ref} className={cn("rounded-lg", className)} {...props} />
  )
)
Card.displayName = "Card"
export { Card }
```

**Naming Conventions**:

- Components: `UserManagement`, `GoalProgressCard`
- Functions: `handleEditUser`, `getGreeting`
- Custom hooks: `useUser`, `useAuth`
- API routes: Named exports `GET`, `POST`, `PUT`, `DELETE`

### Type Definitions

**Interfaces** for object shapes and React props; **Types** for unions and aliases

```typescript
// Props interfaces (ComponentNameProps pattern)
interface UserManagementProps {
  userId: string;
  onUpdate?: () => void;
}

// Domain interfaces
interface User {
  id: string;
  email: string;
  firstName: string;
  lastName: string;
}

// Type aliases and unions
type UserRole = "admin" | "trainer" | "client";
type Status = "active" | "inactive" | "pending";

// No I prefix or T prefix
```

### Function Patterns

**Arrow functions** for components and handlers; **function declarations** for utilities

```typescript
// Component functions
export function UserCard() {
  const handleClick = () => { /* ... */ }  // Arrow function for handlers
  return <button onClick={handleClick}>Click</button>
}

// Exported utility functions
export async function setUserRole(userId: string, role: UserRole) {
  // ... implementation
}

// Always use async/await (never .then() chains)
const fetchData = async () => {
  try {
    const response = await fetch(url)
    const data = await response.json()
    return data
  } catch (error) {
    console.error('Failed to fetch:', error)
  }
}
```

### Error Handling

**API Routes** (Next.js):

```typescript
export async function POST(request: NextRequest) {
  try {
    const { email, password } = await request.json();

    // Early returns for validation
    if (!email || !password) {
      return NextResponse.json(
        { error: "Email and password are required" },
        { status: 400 },
      );
    }

    // ... logic
    return NextResponse.json({ success: true });
  } catch (error) {
    console.error("Login error:", error);
    return NextResponse.json(
      { error: "Internal server error" },
      { status: 500 },
    );
  }
}
```

**React Components**:

```typescript
// Admin: Use try-catch with console.error
const handleSave = async () => {
  try {
    await updateUser(userId, data);
  } catch (error) {
    console.error("Failed to update user:", error);
    // Show error to user (toast, alert, etc.)
  }
};

// Mobile: Use Alert for confirmations
const handleDelete = () => {
  Alert.alert("Delete Goal", "Are you sure?", [
    { text: "Cancel", style: "cancel" },
    { text: "Delete", style: "destructive", onPress: onDelete },
  ]);
};
```

### Comments & Documentation

Use JSDoc for public APIs; inline comments for complex logic only

```typescript
/**
 * Set a user's role in Clerk public metadata
 *
 * @param userId - Clerk user ID
 * @param role - Role to assign (admin, trainer, or client)
 * @returns Updated user object
 *
 * @example
 * await setUserRole('user_abc123', 'admin')
 */
export async function setUserRole(userId: string, role: UserRole) {
  // Implementation
}

// Inline comments for clarification
// Optimistically update local state so grid reflects changes immediately
setUsers((prev) => prev.map((u) => (u.id === id ? { ...u, ...updates } : u)));
```

### File Naming Conventions

```
apps/admin/src/
├── app/
│   ├── api/*/route.ts              # API routes (lowercase route.ts)
│   └── */page.tsx                  # Pages (lowercase page.tsx)
├── components/
│   ├── ui/button.tsx               # UI primitives (kebab-case)
│   └── users/UserManagement.tsx    # Feature components (PascalCase)
├── lib/
│   ├── database/index.ts           # Utilities (kebab-case)
│   └── clerk-helpers.ts            # Helpers (kebab-case)

apps/mobile/src/
├── app/
│   └── (tabs)/index.tsx            # Routes (lowercase)
├── components/
│   └── GoalProgressCard.tsx        # All components (PascalCase)
└── services/
    └── fitnessGoals.ts             # Services (camelCase)
```

### Styling

**Admin App**: Tailwind CSS with utility classes

```typescript
<div className="flex items-center gap-2 rounded-lg border p-4">
  <Button className="bg-primary text-white hover:bg-primary/90">
    Click me
  </Button>
</div>
```

**Mobile App**: StyleSheet.create() at file bottom with theme system

```typescript
import { theme } from '../styles/theme'

export function MyComponent() {
  return <View style={styles.container}>...</View>
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: theme.colors.background,
    padding: theme.spacing.md,
  },
})
```

## ESLint Rules (Admin)

- `@typescript-eslint/no-unused-vars`: error
- `@typescript-eslint/no-explicit-any`: warn (allowed but discouraged)
- `prefer-const`: error
- `no-var`: error
- Extends: `next/core-web-vitals`, `@typescript-eslint/recommended`

## TypeScript Configuration

- **Strict mode enabled**: All strict type checking options on
- **Path aliases**: `@/*` maps to `./src/*`
- **Module resolution**: `bundler` (admin), `node` (mobile)
- **Target**: ES5 (admin), ESNext (mobile)
- Always provide explicit return types for exported functions

## Testing Best Practices

- Tests in `__tests__/` directories or `*.test.ts` files
- Use `@jest-environment node` comment for Node.js API tests
- Admin: Jest + ts-jest + @testing-library/react
- Mobile: Jest + react-native preset + @testing-library/react-native
- Test file naming: `component.test.ts` or `feature.test.tsx`
- Always test error cases and edge cases

## Key Patterns

1. **State Management**: Multiple `useState` declarations grouped together
2. **Destructuring**: Props in function signature, responses inline
3. **Type Safety**: Explicit return types, const assertions for readonly arrays
4. **Database**: Factory pattern with singleton (`getDatabase()`)
5. **Forms**: React Hook Form + Zod validation
6. **Data Fetching**: TanStack Query for server state
7. **Authentication**: Clerk for both admin and mobile (different packages)

## Node & Package Manager

- **Node**: >=18.0.0
- **Package Manager**: npm (>=9.0.0)
- Use `npm install` (not yarn or pnpm)
