Refactor household models and repository queries to use dynamic column selection; remove email from invitation schema in OpenAPI
This commit is contained in:
parent
3e4e4fc2ae
commit
e8f44c839a
3 changed files with 15 additions and 39 deletions
|
|
@ -6,15 +6,13 @@ from common import ApiModel
|
|||
|
||||
class Household(ApiModel):
|
||||
KEYS: ClassVar[list[str]] = ["id", "name", "slug"]
|
||||
|
||||
id: int
|
||||
name: str
|
||||
slug: str
|
||||
|
||||
|
||||
class HouseholdMember(ApiModel):
|
||||
KEYS: ClassVar[list[str]] = ["user_id", "household_id", "role"]
|
||||
|
||||
KEYS: ClassVar[list[str]] = ["id", "display_name", "role"]
|
||||
id: int
|
||||
display_name: str
|
||||
role: str
|
||||
|
|
@ -24,16 +22,13 @@ class HouseholdInvitation(ApiModel):
|
|||
KEYS: ClassVar[list[str]] = [
|
||||
"id",
|
||||
"household_id",
|
||||
"email",
|
||||
"invited_by_user_id",
|
||||
"token",
|
||||
"expires_at",
|
||||
"status",
|
||||
]
|
||||
|
||||
id: int
|
||||
household_id: int
|
||||
email: str
|
||||
invited_by_user_id: int
|
||||
token: str
|
||||
expires_at: str
|
||||
|
|
|
|||
|
|
@ -83,9 +83,10 @@ async def are_members(conn, household_id: int, user_ids: list[int]) -> bool:
|
|||
|
||||
async def list_for_user(conn, user_id: int) -> List[Household]:
|
||||
results: List[Household] = []
|
||||
cols = ", ".join([f"h.{k}" for k in Household.KEYS])
|
||||
async with conn.execute(
|
||||
"""
|
||||
SELECT h.id, h.name, h.slug FROM Household h
|
||||
f"""
|
||||
SELECT {cols} FROM Household h
|
||||
JOIN HouseholdMember m ON m.household_id = h.id
|
||||
WHERE m.user_id = ?
|
||||
ORDER BY h.id
|
||||
|
|
@ -93,7 +94,7 @@ async def list_for_user(conn, user_id: int) -> List[Household]:
|
|||
(user_id,),
|
||||
) as c:
|
||||
async for row in c:
|
||||
results.append(Household(id=int(row[0]), name=row[1], slug=row[2]))
|
||||
results.append(Household(**{k: v for k, v in zip(Household.KEYS, row)}))
|
||||
return results
|
||||
|
||||
|
||||
|
|
@ -117,9 +118,10 @@ async def create_for_user(conn, name: str, slug: str, user_id: int) -> Household
|
|||
|
||||
async def list_members(conn, household_id: int) -> List[HouseholdMember]:
|
||||
members: List[HouseholdMember] = []
|
||||
cols = ", ".join([f"u.{k}" for k in ["id", "display_name"]] + ["m.role"])
|
||||
async with conn.execute(
|
||||
"""
|
||||
SELECT u.id, u.display_name, m.role
|
||||
f"""
|
||||
SELECT {cols}
|
||||
FROM HouseholdMember m
|
||||
JOIN User u ON u.id = m.user_id
|
||||
WHERE m.household_id = ?
|
||||
|
|
@ -129,7 +131,7 @@ async def list_members(conn, household_id: int) -> List[HouseholdMember]:
|
|||
) as c:
|
||||
async for row in c:
|
||||
members.append(
|
||||
HouseholdMember(id=int(row[0]), display_name=row[1], role=row[2])
|
||||
HouseholdMember(**{k: v for k, v in zip(HouseholdMember.KEYS, row)})
|
||||
)
|
||||
return members
|
||||
|
||||
|
|
@ -151,14 +153,15 @@ async def create_invitation(
|
|||
|
||||
|
||||
async def get_invitation_by_token(conn, token: str) -> HouseholdInvitation | None:
|
||||
cols = ", ".join(HouseholdInvitation.KEYS)
|
||||
async with conn.execute(
|
||||
"SELECT id, household_id, status FROM HouseholdInvitation WHERE token = ?",
|
||||
f"SELECT {cols} FROM HouseholdInvitation WHERE token = ?",
|
||||
(token,),
|
||||
) as c:
|
||||
row = await c.fetchone()
|
||||
if not row:
|
||||
return None
|
||||
return HouseholdInvitation(id=int(row[0]), household_id=int(row[1]), status=row[2])
|
||||
return HouseholdInvitation(**{k: v for k, v in zip(HouseholdInvitation.KEYS, row)})
|
||||
|
||||
|
||||
async def accept_invitation(conn, invitation_id: int, user_id: int, household_id: int):
|
||||
|
|
@ -173,11 +176,12 @@ async def accept_invitation(conn, invitation_id: int, user_id: int, household_id
|
|||
|
||||
|
||||
async def get_household_by_id(conn, household_id: int) -> Household | None:
|
||||
cols = ", ".join(Household.KEYS)
|
||||
async with conn.execute(
|
||||
"SELECT id, name, slug FROM Household WHERE id = ?",
|
||||
f"SELECT {cols} FROM Household WHERE id = ?",
|
||||
(household_id,),
|
||||
) as c:
|
||||
row = await c.fetchone()
|
||||
if not row:
|
||||
return None
|
||||
return Household(id=int(row[0]), name=row[1], slug=row[2])
|
||||
return Household(**{k: v for k, v in zip(Household.KEYS, row)})
|
||||
|
|
|
|||
23
openapi.json
23
openapi.json
|
|
@ -381,16 +381,6 @@
|
|||
}
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/CreateInvitationBody"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
|
|
@ -1764,19 +1754,6 @@
|
|||
],
|
||||
"title": "CreateHouseholdBody"
|
||||
},
|
||||
"CreateInvitationBody": {
|
||||
"properties": {
|
||||
"email": {
|
||||
"type": "string",
|
||||
"title": "Email"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"email"
|
||||
],
|
||||
"title": "CreateInvitationBody"
|
||||
},
|
||||
"CurrentShoppingList": {
|
||||
"properties": {
|
||||
"outstandingItems": {
|
||||
|
|
|
|||
Loading…
Reference in a new issue