Files
WealthySmart/backend/app/api/v1/endpoints/auth.py
Carlos Escalante 7dfe2da2a9 OpenAPI type codegen with CI drift gate (plan 3.4, ARCH-16, FE-14)
Every dict-returning route the SPA consumes now declares a response
model (auth, bulk, sync-status, notifications). api-types.gen.ts is
generated from app.openapi() via openapi-typescript, and the 22 hand-
written read interfaces in api.ts are now aliases onto the generated
schemas — backend schema drift becomes a typecheck failure, and CI
regenerates the file and fails the deploy if it's stale. The aliasing
immediately caught two real drifts: RecurringItemType was missing
SAVINGS, and raw_charges (untyped JSON column) is now explicitly
shaped at the boundary.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 07:53:00 -06:00

35 lines
958 B
Python

from fastapi import APIRouter, Depends, Request
from pydantic import BaseModel
from fastapi.security import OAuth2PasswordRequestForm
from app.auth import (
check_login_rate_limit,
create_access_token,
get_current_user_cookie_or_bearer,
verify_admin_credentials,
)
router = APIRouter(prefix="/auth", tags=["auth"])
class TokenResponse(BaseModel):
access_token: str
token_type: str
class MeResponse(BaseModel):
username: str
@router.post("/login", response_model=TokenResponse)
def login(request: Request, form_data: OAuth2PasswordRequestForm = Depends()):
check_login_rate_limit(request)
verify_admin_credentials(form_data.username, form_data.password)
token = create_access_token(form_data.username)
return {"access_token": token, "token_type": "bearer"}
@router.get("/me", response_model=MeResponse)
def me(username: str = Depends(get_current_user_cookie_or_bearer)):
return {"username": username}