Skip to content

Commit 0e46735

Browse files
authored
Merge pull request #6 from HublastX/feat/multiple-updates
Feat/multiple updates
2 parents c9039e7 + 92ef67c commit 0e46735

File tree

5 files changed

+163
-1
lines changed

5 files changed

+163
-1
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
from fastapi import HTTPException, status
2+
from sqlalchemy.orm import Session
3+
4+
from app.repository.theme_repository import ThemeRepository
5+
6+
7+
def delete_theme(theme_id: str, user_id: str, db: Session) -> dict:
8+
try:
9+
repository = ThemeRepository(db)
10+
11+
theme = repository.get_theme_by_id(theme_id)
12+
if not theme:
13+
raise HTTPException(
14+
status_code=status.HTTP_404_NOT_FOUND,
15+
detail="Theme not found"
16+
)
17+
18+
if theme.user_id != user_id:
19+
raise HTTPException(
20+
status_code=status.HTTP_403_FORBIDDEN,
21+
detail="Access denied"
22+
)
23+
24+
deleted = repository.delete_theme(theme_id)
25+
26+
if not deleted:
27+
raise HTTPException(
28+
status_code=status.HTTP_404_NOT_FOUND,
29+
detail="Theme not found"
30+
)
31+
32+
return {"message": "Theme deleted successfully"}
33+
34+
except HTTPException:
35+
raise
36+
37+
except Exception as e:
38+
raise HTTPException(
39+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
40+
detail=f"Error deleting theme: {str(e)}"
41+
)
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
from fastapi import HTTPException, status
2+
from sqlalchemy.orm import Session
3+
4+
from app.repository.theme_repository import ThemeRepository
5+
from app.schemas.theme_schemas import ThemeUpdateSchema, ThemeResponseSchema
6+
7+
8+
def update_theme(
9+
theme_id: str,
10+
user_id: str,
11+
data: ThemeUpdateSchema,
12+
db: Session
13+
) -> ThemeResponseSchema:
14+
15+
try:
16+
repository = ThemeRepository(db)
17+
theme = repository.get_theme_by_id(theme_id)
18+
19+
if not theme:
20+
raise HTTPException(
21+
status_code=status.HTTP_404_NOT_FOUND,
22+
detail="Theme not found"
23+
)
24+
25+
if theme.user_id != user_id:
26+
raise HTTPException(
27+
status_code=status.HTTP_403_FORBIDDEN,
28+
detail="Access denied"
29+
)
30+
31+
update_data = data.model_dump(exclude_unset=True)
32+
33+
if not update_data:
34+
raise HTTPException(
35+
status_code=status.HTTP_400_BAD_REQUEST,
36+
detail="At least one field must be provided for update"
37+
)
38+
39+
if "title" in update_data and update_data["title"] is not None:
40+
if not update_data["title"].strip():
41+
raise HTTPException(
42+
status_code=status.HTTP_400_BAD_REQUEST,
43+
detail="Title cannot be empty"
44+
)
45+
46+
if "description" in update_data and update_data["description"] is not None:
47+
if not update_data["description"].strip():
48+
raise HTTPException(
49+
status_code=status.HTTP_400_BAD_REQUEST,
50+
detail="Description cannot be empty"
51+
)
52+
53+
updated_theme = repository.update_theme(theme_id, update_data)
54+
55+
return ThemeResponseSchema.model_validate(updated_theme)
56+
57+
except HTTPException:
58+
raise
59+
60+
except Exception as e:
61+
raise HTTPException(
62+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
63+
detail=f"Error updating theme: {str(e)}"
64+
)

backend/app/api/routes/private/theme_routes/theme_routes.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@
33

44
from app.api.controller.theme.create_theme import create_theme
55
from app.api.controller.theme.get_theme import get_theme_by_id, get_themes_by_user_id
6+
from app.api.controller.theme.update_theme import update_theme
7+
from app.api.controller.theme.delete_theme import delete_theme
8+
69
from app.api.dependencies.auth import get_current_user
710
from app.core.database.database import get_db
811
from app.model.user_model import User
9-
from app.schemas.theme_schemas import ThemeCreateSchema, ThemeResponseSchema
12+
from app.schemas.theme_schemas import ThemeCreateSchema, ThemeResponseSchema, ThemeUpdateSchema
1013

1114
router = APIRouter()
1215

@@ -36,3 +39,21 @@ def get_themes_route(
3639
):
3740
return get_themes_by_user_id(current_user.id, db)
3841

42+
43+
@router.patch("/{theme_id}", response_model=ThemeResponseSchema)
44+
def update_theme_route(
45+
theme_id: str,
46+
theme_update: ThemeUpdateSchema,
47+
current_user: User = Depends(get_current_user),
48+
db: Session = Depends(get_db),
49+
):
50+
return update_theme(theme_id, theme_update, current_user.id, db)
51+
52+
@router.delete("/{theme_id}")
53+
def delete_theme_route(
54+
theme_id: str,
55+
current_user: User = Depends(get_current_user),
56+
db: Session = Depends(get_db),
57+
):
58+
delete_theme(theme_id, current_user.id, db)
59+
return {"message": "Theme deleted successfully"}

backend/app/repository/theme_repository.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,34 @@ def get_theme_by_id(self, theme_id: str) -> Theme | None:
2929
def get_themes_by_user_id(self, user_id: str) -> list[Theme]:
3030
return self.db.query(Theme).filter(Theme.user_id == user_id).all()
3131

32+
def update_theme(self, theme_id: str, update_data: dict) -> Theme | None:
33+
try:
34+
theme = self.get_theme_by_id(theme_id)
35+
if not theme:
36+
return None
37+
38+
for key, value in update_data.items():
39+
if value is not None:
40+
setattr(theme, key, value)
41+
42+
self.db.commit()
43+
self.db.refresh(theme)
44+
return theme
45+
46+
except Exception:
47+
self.db.rollback()
48+
raise
49+
50+
def delete_theme(self, theme_id: str) -> bool:
51+
try:
52+
theme = self.get_theme_by_id(theme_id)
53+
if theme:
54+
self.db.delete(theme)
55+
self.db.commit()
56+
return True
57+
58+
return False
59+
60+
except Exception:
61+
self.db.rollback()
62+
raise

backend/app/schemas/theme_schemas.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ class ThemeCreateSchema(BaseModel):
77
description: str
88

99

10+
class ThemeUpdateSchema(BaseModel):
11+
title: str | None = None
12+
description: str | None = None
13+
14+
1015
class ThemeResponseSchema(BaseModel):
1116
id: str
1217
title: str

0 commit comments

Comments
 (0)