from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select from pydantic import BaseModel, EmailStr from app.database import get_db from app.models.user import User from app.models.bankroll import Bankroll from app.utils.auth import hash_password, verify_password, create_access_token, get_current_user router = APIRouter(prefix="/api/auth", tags=["auth"]) class RegisterRequest(BaseModel): email: str password: str name: str = "" class LoginRequest(BaseModel): email: str password: str class UserResponse(BaseModel): id: str email: str name: str | None plan: str streak_days: int total_points: int risk_level: str class Config: from_attributes = True @router.post("/register") async def register(req: RegisterRequest, db: AsyncSession = Depends(get_db)): existing = await db.execute(select(User).where(User.email == req.email)) if existing.scalar_one_or_none(): raise HTTPException(400, "Email already registered") user = User(email=req.email, password_hash=hash_password(req.password), name=req.name) db.add(user) await db.flush() bankroll = Bankroll(user_id=user.id, monthly_budget=500, weekly_limit=150, daily_limit=50) db.add(bankroll) await db.commit() token = create_access_token({"sub": str(user.id)}) return {"access_token": token, "token_type": "bearer", "user": {"id": str(user.id), "email": user.email, "name": user.name}} @router.post("/login") async def login(req: LoginRequest, db: AsyncSession = Depends(get_db)): result = await db.execute(select(User).where(User.email == req.email)) user = result.scalar_one_or_none() if not user or not verify_password(req.password, user.password_hash): raise HTTPException(401, "Invalid email or password") token = create_access_token({"sub": str(user.id)}) return {"access_token": token, "token_type": "bearer", "user": {"id": str(user.id), "email": user.email, "name": user.name, "plan": user.plan}} @router.get("/me") async def me(user: User = Depends(get_current_user)): return {"id": str(user.id), "email": user.email, "name": user.name, "plan": user.plan, "streak_days": user.streak_days, "total_points": user.total_points, "risk_level": user.risk_level}