# Project Structure ## Backend Architecture ``` app/ ├── main.py # FastAPI app, lifespan, router registration ├── config.py # Pydantic settings from .env ├── database.py # Async SQLAlchemy engine + session factory ├── dependencies.py # DI: DB session, auth guards (require_access, require_admin) ├── exceptions.py # Custom exception hierarchy (ValidationError, NotFoundError, etc.) ├── middleware.py # Global error handler → JSON envelope ├── cache.py # LRU cache with per-ticker invalidation ├── scheduler.py # APScheduler job definitions ├── models/ # SQLAlchemy ORM models ├── schemas/ # Pydantic request/response schemas ├── services/ # Business logic layer ├── providers/ # External data provider integrations └── routers/ # FastAPI route handlers ``` ## Frontend Architecture ``` frontend/src/ ├── App.tsx # Route definitions ├── main.tsx # React entry point ├── api/ # Axios API client modules (one per resource) ├── components/ │ ├── admin/ # User table, job controls, settings, data cleanup │ ├── auth/ # Protected route wrapper │ ├── charts/ # Canvas candlestick chart │ ├── layout/ # App shell, sidebar, mobile nav │ ├── rankings/ # Rankings table, weights form │ ├── scanner/ # Trade table │ ├── ticker/ # Sentiment panel, fundamentals, indicators, S/R overlay │ ├── ui/ # Badge, toast, skeleton, score card, confirm dialog │ └── watchlist/ # Watchlist table, add ticker form ├── hooks/ # React Query hooks (one per resource) ├── lib/ # Types, formatting utilities ├── pages/ # Page components (Login, Register, Watchlist, Ticker, Scanner, Rankings, Admin) ├── stores/ # Zustand auth store └── styles/ # Global CSS with glassmorphism classes ``` ## Key Patterns ### Backend - **Layered architecture**: Router → Service → Model - **Dependency injection**: FastAPI Depends() for DB session and auth - **Exception handling**: Custom exceptions caught by global middleware, returned as JSON envelope - **API envelope**: All responses wrapped in `{ status: "success"|"error", data: any, error?: string }` - **Cascade deletes**: Ticker deletion cascades to all related data (OHLCV, sentiment, fundamentals, S/R, scores, trades, watchlist) - **Async everywhere**: All DB operations use async/await with asyncpg ### Frontend - **API client**: Axios interceptors for JWT injection and envelope unwrapping - **Server state**: TanStack React Query with query keys per resource - **Client state**: Zustand for auth (token, user, login/logout) - **Error handling**: ApiError class, toast notifications for mutations - **Protected routes**: ProtectedRoute wrapper checks auth, redirects to /login - **Glassmorphism**: Frosted glass panels, gradient text, ambient glow, mesh gradient background ## Database Models All models inherit from `Base` (SQLAlchemy declarative base): - `Ticker`: Registry of tracked symbols (cascade delete parent) - `OHLCVRecord`: Price data (open, high, low, close, volume) - `SentimentScore`: Sentiment analysis results with time-decay - `FundamentalData`: P/E, revenue growth, earnings surprise, market cap - `SRLevel`: Support/Resistance levels with strength scoring - `DimensionScore`: Individual dimension scores (technical, sr_quality, sentiment, fundamental, momentum) - `CompositeScore`: Weighted composite score - `TradeSetup`: Detected R:R setups (long/short, entry, stop, target) - `WatchlistEntry`: User watchlist entries (auto/manual) - `User`: Auth and access control - `Settings`: System-wide configuration ## Testing - Backend tests: `tests/unit/` and `tests/property/` - Frontend tests: `frontend/src/**/*.test.tsx` - Fixtures in `tests/conftest.py` - Hypothesis strategies for property-based testing