# 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
...
} // UI library components - Named export (forwardRef constant) const Card = React.forwardRef( ({ className, ...props }, ref) => (
) ) 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 } // 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
``` **Mobile App**: StyleSheet.create() at file bottom with theme system ```typescript import { theme } from '../styles/theme' export function MyComponent() { return ... } 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)