fitaiProto/AGENTS.md
echo 22c274bb83 routes fix
extensive loging added
2026-03-10 02:22:11 +01:00

367 lines
9.9 KiB
Markdown

# 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)