WIP checkpoint: Scaffold FastAPI backend project structure

This commit is contained in:
2026-08-17 18:27:26 +00:00
parent 7fd43cc158
commit d11eb7d732
3 changed files with 16 additions and 11 deletions
+1
View File
@@ -11,6 +11,7 @@ from app.database import get_db
from app.models.asset import Asset, AssetType
from app.models.user import User
from app.models.world import World
from app.routers.worlds import get_current_user
from pydantic import BaseModel, Field
router = APIRouter()
+6 -6
View File
@@ -49,11 +49,13 @@ def _create_access_token(data: dict) -> str:
return jwt.encode(to_encode, settings.SECRET_KEY, algorithm=settings.ALGORITHM)
def _verify_password(plain_password: str, hashed_password: str) -> bool:
def verify_password(plain_password: str, hashed_password: str) -> bool:
"""Verify a plain password against a hash."""
return pwd_context.verify(plain_password, hashed_password)
def _get_password_hash(password: str) -> str:
def hash_password(password: str) -> str:
"""Hash a password."""
return pwd_context.hash(password)
@@ -81,7 +83,7 @@ async def register(req: RegisterRequest, db: AsyncSession = Depends(get_db)):
user = User(
username=req.username,
email=req.email,
hashed_password=_get_password_hash(req.password),
hashed_password=hash_password(req.password),
)
db.add(user)
await db.commit()
@@ -97,7 +99,7 @@ async def login(req: LoginRequest, db: AsyncSession = Depends(get_db)):
result = await db.execute(select(User).where(User.username == req.username))
user = result.scalar_one_or_none()
if not user or not _verify_password(req.password, user.hashed_password):
if not user or not verify_password(req.password, user.hashed_password):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Incorrect username or password",
@@ -115,8 +117,6 @@ async def login(req: LoginRequest, db: AsyncSession = Depends(get_db)):
@router.get("/me")
async def get_current_user(
# In production, extract from Authorization header via OAuth2PasswordBearer
# For now, accept a user_id query param for simplicity
user_id: int,
db: AsyncSession = Depends(get_db),
):
+9 -5
View File
@@ -13,7 +13,7 @@ from app.models.user import User
router = APIRouter()
# ── Pydantic schemas ────────────────────────────────────────────────
# ── Pydantic schemas ──────────────────────────────────────────────────────────
class UserCreate(BaseModel):
username: str
@@ -35,14 +35,17 @@ class UserUpdate(BaseModel):
is_active: bool | None = None
# ── Endpoints ────────────────────────────────────────────────────────
# ── Endpoints ─────────────────────────────────────────────────────────────────
@router.post(
"/",
response_model=UserResponse,
status_code=status.HTTP_201_CREATED,
)
async def create_user(user_in: UserCreate, db: Annotated[AsyncSession, Depends(get_db)]):
async def create_user(
user_in: UserCreate,
db: Annotated[AsyncSession, Depends(get_db)],
):
"""Register a new user."""
# Check uniqueness of username
existing = await db.execute(select(User).where(User.username == user_in.username))
@@ -54,8 +57,9 @@ async def create_user(user_in: UserCreate, db: Annotated[AsyncSession, Depends(g
if existing.scalar_one_or_none():
raise HTTPException(status_code=400, detail="Email already registered")
from app.routers.auth import hash_password
hashed = hash_password(user_in.password)
from app.routers.auth import _get_password_hash
hashed = _get_password_hash(user_in.password)
user = User(
username=user_in.username,