Files
ProxyTrash/backend/app/main.py
2026-05-23 05:33:39 -06:00

80 lines
3.0 KiB
Python

from fastapi import Depends, FastAPI, HTTPException, status
from fastapi.middleware.cors import CORSMiddleware
from sqlalchemy.orm import Session
from .auth import create_access_token
from .core.config import settings
from .crud import authenticate_user, create_address, create_user, get_user_by_email
from .db.session import Base, engine, get_db
from .dependencies import get_current_user
from .models import Address, User
from .schemas import AddressCreate, AddressRead, TokenResponse, UserCreate, UserLogin, UserRead
app = FastAPI(title='Flutter Auth API', version='1.0.0')
app.add_middleware(
CORSMiddleware,
allow_origins=settings.cors_origin_list,
allow_credentials=True,
allow_methods=['*'],
allow_headers=['*'],
)
@app.on_event('startup')
def on_startup() -> None:
Base.metadata.create_all(bind=engine)
@app.get('/health')
def health_check() -> dict[str, str]:
return {'status': 'ok'}
@app.post('/auth/register', response_model=TokenResponse, status_code=status.HTTP_201_CREATED)
def register(payload: UserCreate, db: Session = Depends(get_db)) -> TokenResponse:
existing_user = get_user_by_email(db, payload.email)
if existing_user is not None:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail='Ya existe un usuario con ese correo')
user = create_user(db, payload)
token = create_access_token(user_id=user.id, email=user.email)
return TokenResponse(token=token, user=UserRead.model_validate(user))
@app.post('/auth/login', response_model=TokenResponse)
def login(payload: UserLogin, db: Session = Depends(get_db)) -> TokenResponse:
user = authenticate_user(db, payload.email, payload.password)
if user is None:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail='Correo o contraseña inválidos')
token = create_access_token(user_id=user.id, email=user.email)
return TokenResponse(token=token, user=UserRead.model_validate(user))
@app.get('/me', response_model=UserRead)
def read_me(current_user: User = Depends(get_current_user)) -> UserRead:
return UserRead.model_validate(current_user)
@app.post('/addresses', response_model=AddressRead, status_code=status.HTTP_201_CREATED)
def save_address(
payload: AddressCreate,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
) -> AddressRead:
if payload.email is not None and payload.email != current_user.email:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail='El correo no coincide con el usuario autenticado')
address = create_address(db, current_user, payload)
return AddressRead.model_validate(address)
@app.get('/addresses/me', response_model=list[AddressRead])
def read_my_addresses(
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
) -> list[AddressRead]:
addresses = sorted(current_user.addresses, key=lambda address: address.created_at, reverse=True)
return [AddressRead.model_validate(address) for address in addresses]