from __future__ import annotations import re from typing import List import aiosqlite from fastapi import APIRouter, Depends, Request from api.deps import get_current_user, get_db, error_response from common import ApiModel from users.models import User router = APIRouter(tags=["households"]) class CreateHouseholdBody(ApiModel): name: str class HouseholdResponse(ApiModel): id: int name: str slug: str def slugify(name: str) -> str: s = re.sub(r"[^a-z0-9]+", "-", name.lower()).strip("-") return s or "household" @router.get("/users/me/households", response_model=List[HouseholdResponse]) async def list_my_households( request: Request, user: User = Depends(get_current_user), conn: aiosqlite.Connection = Depends(get_db) ): results: list[HouseholdResponse] = [] async with conn.execute( """ SELECT h.id, h.name, h.slug FROM Household h JOIN HouseholdMember m ON m.household_id = h.id WHERE m.user_id = ? ORDER BY h.id """, (user.id,), ) as c: async for row in c: results.append(HouseholdResponse(id=int(row[0]), name=row[1], slug=row[2])) return results @router.post("/households", response_model=HouseholdResponse) async def create_household( request: Request, body: CreateHouseholdBody, user: User = Depends(get_current_user), conn: aiosqlite.Connection = Depends(get_db), ): slug = slugify(body.name) try: async with conn.execute( "INSERT INTO Household (name, slug) VALUES (?, ?)", (body.name, slug) ) as cur: lrid = cur.lastrowid if lrid is None: return error_response(request, 400, "Unable to create household") hid = int(lrid) await conn.execute( "INSERT INTO HouseholdMember (user_id, household_id, role) VALUES (?, ?, ?)", (user.id, hid, "admin"), ) return HouseholdResponse(id=hid, name=body.name, slug=slug) except Exception: return error_response(request, 400, "Unable to create household")