from datetime import datetime from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.orm import Session import auth import database import models import schemas router = APIRouter(prefix="/auth", tags=["auth"]) def get_current_timestamp() -> str: return datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%fZ") def user_to_out(user: models.User) -> schemas.UserOut: return schemas.UserOut( id=user.id, username=user.username, display_name=user.display_name or user.username, role=user.role or "personal", created_at=user.created_at or get_current_timestamp(), ) @router.post("/register", response_model=schemas.Token) def register( data: schemas.UserCreate, db: Session = Depends(database.get_db), ): username = (data.username or "").strip().lower() password = data.password or "" role = data.role or "personal" if len(username) < 3: raise HTTPException(status_code=400, detail="Username must be at least 3 characters") if len(password) < 6: raise HTTPException(status_code=400, detail="Password must be at least 6 characters") if role not in ("personal", "trainer"): role = "personal" exists = db.query(models.User).filter(models.User.username == username).first() if exists: raise HTTPException(status_code=400, detail="Username already exists") user = models.User( username=username, password_hash=auth.hash_password(password), display_name=(data.display_name or username).strip(), role=role, created_at=get_current_timestamp(), ) db.add(user) db.commit() db.refresh(user) token = auth.create_access_token(user) return schemas.Token( access_token=token, token_type="bearer", user=user_to_out(user), ) @router.post("/login", response_model=schemas.Token) def login( data: schemas.UserLogin, db: Session = Depends(database.get_db), ): username = (data.username or "").strip().lower() password = data.password or "" user = db.query(models.User).filter(models.User.username == username).first() if not user: raise HTTPException(status_code=401, detail="Invalid username or password") if not auth.verify_password(password, user.password_hash): raise HTTPException(status_code=401, detail="Invalid username or password") token = auth.create_access_token(user) return schemas.Token( access_token=token, token_type="bearer", user=user_to_out(user), ) @router.get("/me", response_model=schemas.UserOut) def me( current_user: models.User = Depends(auth.get_current_user), ): return user_to_out(current_user)