feat(children): support soft delete child profiles
This commit is contained in:
@@ -88,3 +88,9 @@ export async function updateChild(
|
||||
data,
|
||||
})
|
||||
}
|
||||
|
||||
export async function deleteChild(childId: number): Promise<void> {
|
||||
return request<void>(`/banban/children/${childId}`, {
|
||||
method: 'DELETE',
|
||||
})
|
||||
}
|
||||
|
||||
@@ -42,11 +42,29 @@ class ChildDAO(BaseDAO):
|
||||
async def get_by_id(self, child_id: int) -> Optional[Mapping]:
|
||||
return (
|
||||
await self.execute(
|
||||
"SELECT * FROM children WHERE child_id = :child_id",
|
||||
"SELECT * FROM children WHERE child_id = :child_id AND status = 1",
|
||||
{"child_id": child_id},
|
||||
)
|
||||
).mappings().first()
|
||||
|
||||
async def get_by_parent(self, child_id: int, user_id: int) -> Optional[Mapping]:
|
||||
return (
|
||||
await self.execute(
|
||||
"""
|
||||
SELECT c.*
|
||||
FROM children AS c
|
||||
JOIN parent_child_relations AS pcr
|
||||
ON pcr.child_id = c.child_id
|
||||
WHERE c.child_id = :child_id
|
||||
AND pcr.user_id = :user_id
|
||||
AND c.status = 1
|
||||
AND pcr.status = 1
|
||||
LIMIT 1
|
||||
""",
|
||||
{"child_id": child_id, "user_id": user_id},
|
||||
)
|
||||
).mappings().first()
|
||||
|
||||
async def list_by_parent(self, user_id: int, limit: int = 20, cursor: int = None) -> list[Mapping]:
|
||||
params = {"user_id": user_id, "limit": limit + 1}
|
||||
where = "pcr.user_id = :user_id AND pcr.status = 1 AND c.status = 1"
|
||||
@@ -104,3 +122,41 @@ class ChildDAO(BaseDAO):
|
||||
{"child_id": child_id, "user_id": user_id},
|
||||
)
|
||||
return result.scalar_one_or_none() is not None
|
||||
|
||||
async def soft_delete_for_parent(self, child_id: int, user_id: int) -> bool:
|
||||
if not await self.has_access(child_id, user_id):
|
||||
return False
|
||||
|
||||
await self.execute(
|
||||
"""
|
||||
UPDATE children
|
||||
SET status = 0,
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
WHERE child_id = :child_id
|
||||
AND status = 1
|
||||
""",
|
||||
{"child_id": child_id},
|
||||
)
|
||||
await self.execute(
|
||||
"""
|
||||
UPDATE parent_child_relations
|
||||
SET status = 0,
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
WHERE child_id = :child_id
|
||||
AND user_id = :user_id
|
||||
AND status = 1
|
||||
""",
|
||||
{"child_id": child_id, "user_id": user_id},
|
||||
)
|
||||
await self.execute(
|
||||
"""
|
||||
UPDATE device_bindings
|
||||
SET child_id = NULL,
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
WHERE child_id = :child_id
|
||||
AND owner_user_id = :user_id
|
||||
AND status = 1
|
||||
""",
|
||||
{"child_id": child_id, "user_id": user_id},
|
||||
)
|
||||
return True
|
||||
|
||||
@@ -72,8 +72,9 @@ async def get_child(
|
||||
request: Request,
|
||||
current_user_id: int = Depends(get_current_user_id),
|
||||
) -> ChildResponse:
|
||||
del request
|
||||
service = ChildService()
|
||||
child = await service.get(child_id)
|
||||
child = await service.get(child_id, current_user_id)
|
||||
if not child:
|
||||
raise HTTPException(status_code=404, detail="child not found")
|
||||
return ChildResponse(**child)
|
||||
@@ -94,3 +95,16 @@ async def update_child(
|
||||
if not child:
|
||||
raise HTTPException(status_code=404, detail="child not found")
|
||||
return ChildResponse(**child)
|
||||
|
||||
|
||||
@router.delete("/{child_id}", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def delete_child(
|
||||
child_id: int,
|
||||
request: Request,
|
||||
current_user_id: int = Depends(get_current_user_id),
|
||||
) -> None:
|
||||
del request
|
||||
service = ChildService()
|
||||
deleted = await service.delete(child_id, current_user_id)
|
||||
if not deleted:
|
||||
raise HTTPException(status_code=404, detail="child not found")
|
||||
|
||||
@@ -52,11 +52,11 @@ class ChildService(DatabaseServiceBase):
|
||||
finally:
|
||||
await db_session.close()
|
||||
|
||||
async def get(self, child_id: int) -> Optional[Mapping]:
|
||||
async def get(self, child_id: int, user_id: int) -> Optional[Mapping]:
|
||||
db_session = await self.get_session()
|
||||
try:
|
||||
dao = ChildDAO(db_session)
|
||||
return await dao.get_by_id(child_id)
|
||||
return await dao.get_by_parent(child_id, user_id)
|
||||
finally:
|
||||
await db_session.close()
|
||||
|
||||
@@ -75,6 +75,21 @@ class ChildService(DatabaseServiceBase):
|
||||
raise PermissionError("No access to this child")
|
||||
await dao.update(child_id, child_name, child_gender, child_birthday)
|
||||
await db_session.commit()
|
||||
return await self.get(child_id)
|
||||
return await self.get(child_id, user_id)
|
||||
finally:
|
||||
await db_session.close()
|
||||
|
||||
async def delete(self, child_id: int, user_id: int) -> bool:
|
||||
db_session = await self.get_session()
|
||||
try:
|
||||
dao = ChildDAO(db_session)
|
||||
deleted = await dao.soft_delete_for_parent(child_id, user_id)
|
||||
if not deleted:
|
||||
return False
|
||||
await db_session.commit()
|
||||
return True
|
||||
except Exception:
|
||||
await db_session.rollback()
|
||||
raise
|
||||
finally:
|
||||
await db_session.close()
|
||||
|
||||
Reference in New Issue
Block a user