261 lines
6.8 KiB
Markdown
261 lines
6.8 KiB
Markdown
|
|
# AGENTS.md - Coding Guidelines for WealthWise
|
||
|
|
|
||
|
|
## Project Overview
|
||
|
|
|
||
|
|
WealthWise is a financial analytics platform with:
|
||
|
|
- **Frontend**: React + TypeScript + Vite + shadcn/ui + Tailwind CSS
|
||
|
|
- **Backend**: FastAPI + SQLModel + PostgreSQL + Poetry
|
||
|
|
|
||
|
|
## Build & Development Commands
|
||
|
|
|
||
|
|
### Frontend (Root Directory)
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Install dependencies
|
||
|
|
npm install
|
||
|
|
|
||
|
|
# Development server (runs on port 7863)
|
||
|
|
npm run dev
|
||
|
|
|
||
|
|
# Production build
|
||
|
|
npm run build
|
||
|
|
|
||
|
|
# Preview production build
|
||
|
|
npm run preview
|
||
|
|
|
||
|
|
# Lint code
|
||
|
|
npm run lint
|
||
|
|
|
||
|
|
# Deploy to Vercel
|
||
|
|
npm run deploy # Production
|
||
|
|
npm run deploy:dev # Development
|
||
|
|
```
|
||
|
|
|
||
|
|
### Backend (`/backend` Directory)
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Install dependencies
|
||
|
|
poetry install
|
||
|
|
|
||
|
|
# Run development server
|
||
|
|
poetry run uvicorn app.main:app --reload --port 8080
|
||
|
|
|
||
|
|
# Run production server
|
||
|
|
poetry run uvicorn app.main:app --host 0.0.0.0 --port 8080
|
||
|
|
|
||
|
|
# Run tests
|
||
|
|
poetry run pytest
|
||
|
|
poetry run pytest -v # Verbose
|
||
|
|
poetry run pytest tests/test_auth.py # Single test file
|
||
|
|
poetry run pytest -k "test_name" # Single test by name
|
||
|
|
poetry run pytest --cov=app # With coverage
|
||
|
|
|
||
|
|
# Format and lint
|
||
|
|
poetry run black .
|
||
|
|
poetry run isort .
|
||
|
|
poetry run flake8
|
||
|
|
poetry run mypy app/
|
||
|
|
|
||
|
|
# Database migrations
|
||
|
|
cd backend
|
||
|
|
poetry run alembic revision --autogenerate -m "description"
|
||
|
|
poetry run alembic upgrade head
|
||
|
|
poetry run alembic downgrade -1
|
||
|
|
```
|
||
|
|
|
||
|
|
## Code Style Guidelines
|
||
|
|
|
||
|
|
### Frontend - TypeScript/React
|
||
|
|
|
||
|
|
#### Imports
|
||
|
|
- Use `@/` path aliases for all internal imports
|
||
|
|
- Group imports: React → External libraries → Internal (@/lib, @/components) → Relative
|
||
|
|
- Use single quotes for string literals
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
import React, { useState, useCallback } from 'react';
|
||
|
|
import { useQuery } from '@tanstack/react-query';
|
||
|
|
import { Button } from '@/components/ui/button';
|
||
|
|
import { cn } from '@/lib/utils';
|
||
|
|
import { useAuth } from '@/hooks/useAuth';
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Components
|
||
|
|
- Use functional components with arrow functions
|
||
|
|
- Add displayName for forwarded ref components
|
||
|
|
- Use `React.FC<Props>` for typing components
|
||
|
|
- Destructure props in function parameters
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
interface ButtonProps {
|
||
|
|
variant?: 'default' | 'outline';
|
||
|
|
onClick?: () => void;
|
||
|
|
}
|
||
|
|
|
||
|
|
const Button: React.FC<ButtonProps> = ({ variant = 'default', onClick }) => {
|
||
|
|
return <button onClick={onClick}>{children}</button>;
|
||
|
|
};
|
||
|
|
|
||
|
|
Button.displayName = 'Button';
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Naming Conventions
|
||
|
|
- Components: PascalCase (e.g., `Dashboard.tsx`)
|
||
|
|
- Hooks: camelCase with `use` prefix (e.g., `useAuth.ts`)
|
||
|
|
- Utils: camelCase (e.g., `utils.ts`)
|
||
|
|
- Types/Interfaces: PascalCase (e.g., `User`, `AuthState`)
|
||
|
|
- CSS Classes: Use Tailwind utility classes with `cn()` helper
|
||
|
|
|
||
|
|
#### Styling (Tailwind + shadcn/ui)
|
||
|
|
- Use `cn()` from `@/lib/utils` for conditional classes
|
||
|
|
- Follow glassmorphic design with `glass`, `widget` classes
|
||
|
|
- Use CSS variables from `index.css` for theme colors
|
||
|
|
- Prefer `rounded-xl`, `rounded-2xl` for border radius
|
||
|
|
|
||
|
|
```tsx
|
||
|
|
<div className={cn(
|
||
|
|
"glass-card hover:scale-[1.02] transition-all",
|
||
|
|
className
|
||
|
|
)}>
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Error Handling
|
||
|
|
- Use try/catch with typed errors
|
||
|
|
- Check for `err.response?.data?.detail` for API errors
|
||
|
|
- Set user-friendly error messages in state
|
||
|
|
|
||
|
|
#### State Management
|
||
|
|
- Use React Query for server state
|
||
|
|
- Use `useState` for local UI state
|
||
|
|
- Use Context API for auth state
|
||
|
|
|
||
|
|
### Backend - Python/FastAPI
|
||
|
|
|
||
|
|
#### Imports
|
||
|
|
- Group: Standard library → Third-party → Local app imports
|
||
|
|
- Use absolute imports for app modules
|
||
|
|
|
||
|
|
```python
|
||
|
|
import time
|
||
|
|
from datetime import datetime
|
||
|
|
|
||
|
|
from fastapi import FastAPI, HTTPException
|
||
|
|
from sqlmodel import Session, select
|
||
|
|
|
||
|
|
from app.core.config import get_settings
|
||
|
|
from app.models.user import User
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Naming Conventions
|
||
|
|
- Files: snake_case (e.g., `auth_service.py`)
|
||
|
|
- Classes: PascalCase (e.g., `AuthService`)
|
||
|
|
- Functions/Variables: snake_case (e.g., `get_current_user`)
|
||
|
|
- Constants: UPPER_SNAKE_CASE
|
||
|
|
|
||
|
|
#### Type Hints
|
||
|
|
- Use type hints on all function parameters and return types
|
||
|
|
- Use `Optional[Type]` for nullable values
|
||
|
|
- Use Pydantic models for request/response schemas
|
||
|
|
|
||
|
|
```python
|
||
|
|
def create_user(
|
||
|
|
email: str,
|
||
|
|
password: str,
|
||
|
|
db: Session
|
||
|
|
) -> Optional[User]:
|
||
|
|
"""Create a new user."""
|
||
|
|
pass
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Docstrings
|
||
|
|
- Use Google-style docstrings
|
||
|
|
- Document args, returns, and raises
|
||
|
|
|
||
|
|
```python
|
||
|
|
def validate_token(token: str) -> TokenPayload:
|
||
|
|
"""Validate JWT token.
|
||
|
|
|
||
|
|
Args:
|
||
|
|
token: JWT token string
|
||
|
|
|
||
|
|
Returns:
|
||
|
|
TokenPayload with user information
|
||
|
|
|
||
|
|
Raises:
|
||
|
|
HTTPException: If token is invalid
|
||
|
|
"""
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Error Handling
|
||
|
|
- Use FastAPI's HTTPException with appropriate status codes
|
||
|
|
- Handle exceptions at router level when possible
|
||
|
|
- Log errors with context
|
||
|
|
|
||
|
|
## Testing
|
||
|
|
|
||
|
|
### Frontend
|
||
|
|
No test framework configured yet. Consider adding Vitest for unit testing.
|
||
|
|
|
||
|
|
### Backend
|
||
|
|
- Tests located in `backend/tests/`
|
||
|
|
- Use pytest with pytest-asyncio for async tests
|
||
|
|
- Use TestClient for FastAPI integration tests
|
||
|
|
- Use `pytest.raises` for exception testing
|
||
|
|
|
||
|
|
```python
|
||
|
|
def test_login_success(client: TestClient):
|
||
|
|
response = client.post("/api/v1/auth/login", json={...})
|
||
|
|
assert response.status_code == 200
|
||
|
|
```
|
||
|
|
|
||
|
|
## Project Structure
|
||
|
|
|
||
|
|
```
|
||
|
|
/ # Frontend (Vite + React)
|
||
|
|
├── src/
|
||
|
|
│ ├── components/ # React components
|
||
|
|
│ │ ├── ui/ # shadcn/ui components
|
||
|
|
│ │ ├── features/ # Feature components
|
||
|
|
│ │ └── *.tsx # Shared components
|
||
|
|
│ ├── hooks/ # Custom React hooks
|
||
|
|
│ ├── context/ # React context providers
|
||
|
|
│ ├── lib/ # Utilities, API clients
|
||
|
|
│ ├── types/ # TypeScript types
|
||
|
|
│ └── pages/ # Page components
|
||
|
|
├── public/ # Static assets
|
||
|
|
└── package.json
|
||
|
|
|
||
|
|
/backend/ # FastAPI backend
|
||
|
|
├── app/
|
||
|
|
│ ├── api/v1/ # API routes
|
||
|
|
│ ├── core/ # Config, db, deps
|
||
|
|
│ ├── models/ # SQLModel models
|
||
|
|
│ └── schemas/ # Pydantic schemas
|
||
|
|
├── tests/ # Test files
|
||
|
|
├── alembic/ # DB migrations
|
||
|
|
└── pyproject.toml # Poetry dependencies
|
||
|
|
```
|
||
|
|
|
||
|
|
## Environment Variables
|
||
|
|
|
||
|
|
Frontend (`.env`):
|
||
|
|
- `VITE_API_URL`: Backend API URL
|
||
|
|
|
||
|
|
Backend (`.env`):
|
||
|
|
- `DATABASE_URL`: PostgreSQL connection string
|
||
|
|
- `SECRET_KEY`: JWT signing key
|
||
|
|
- `SUPABASE_JWT_SECRET`: Supabase JWT secret
|
||
|
|
- `DEBUG`: Debug mode flag
|
||
|
|
|
||
|
|
## Critical Rules
|
||
|
|
|
||
|
|
1. **Never** commit secrets or `.env` files
|
||
|
|
2. **Always** use TypeScript strict mode compliance
|
||
|
|
3. **Always** run `npm run lint` before committing frontend changes
|
||
|
|
4. **Always** run `poetry run black && poetry run flake8` before committing backend changes
|
||
|
|
5. Use `cn()` for conditional Tailwind classes
|
||
|
|
6. Use React Query for all API calls
|
||
|
|
7. Use proper HTTP status codes in backend responses
|
||
|
|
8. Write docstrings for all public functions
|
||
|
|
9. Use Pydantic v2 patterns for validation
|