Skip to content

Commit 0a8e222

Browse files
authored
Merge pull request #12 from 9git9git/SCRUM-132-BE-Comprehensive_Evaluation-API-개발
[SCRUM-132] ✨ Comprehensive Evaluation API 추가
2 parents 945307a + f1a5681 commit 0a8e222

File tree

6 files changed

+347
-1
lines changed

6 files changed

+347
-1
lines changed
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
from app.schemas.base import ResponseBase
2+
from app.schemas.comprehensive_evaluation import (
3+
ComprehensiveEvaluationResponse,
4+
ComprehensiveEvaluationCreate,
5+
ComprehensiveEvaluationUpdate,
6+
)
7+
from app.services.comprehensive_evaluation import (
8+
select_comprehensive_evaluation,
9+
select_comprehensive_evaluations,
10+
add_comprehensive_evaluation,
11+
update_comprehensive_evaluation_service,
12+
delete_comprehensive_evaluation_service,
13+
)
14+
from fastapi import APIRouter, Depends
15+
from sqlalchemy.ext.asyncio import AsyncSession
16+
from app.db.session import get_db
17+
from uuid import UUID
18+
from typing import List
19+
from fastapi import HTTPException
20+
from fastapi import status
21+
22+
router = APIRouter()
23+
24+
25+
@router.get(
26+
"/",
27+
response_model=ResponseBase[List[ComprehensiveEvaluationResponse]],
28+
)
29+
async def get_comprehensive_evaluations(
30+
user_id: UUID,
31+
db: AsyncSession = Depends(get_db),
32+
) -> ResponseBase[List[ComprehensiveEvaluationResponse]]:
33+
34+
try:
35+
comprehensive_evaluations = await select_comprehensive_evaluations(db, user_id)
36+
return ResponseBase(
37+
status_code=status.HTTP_200_OK, data=comprehensive_evaluations
38+
)
39+
except HTTPException as e:
40+
return ResponseBase(status_code=e.status_code, error=e.detail)
41+
except Exception as e:
42+
return ResponseBase(
43+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, error=str(e)
44+
)
45+
46+
47+
@router.get(
48+
"/{comprehensive_evaluation_id}",
49+
response_model=ResponseBase[ComprehensiveEvaluationResponse],
50+
)
51+
async def get_comprehensive_evaluation(
52+
user_id: UUID,
53+
comprehensive_evaluation_id: UUID,
54+
db: AsyncSession = Depends(get_db),
55+
) -> ResponseBase[ComprehensiveEvaluationResponse]:
56+
try:
57+
comprehensive_evaluation = await select_comprehensive_evaluation(
58+
db, user_id, comprehensive_evaluation_id
59+
)
60+
return ResponseBase(
61+
status_code=status.HTTP_200_OK, data=comprehensive_evaluation
62+
)
63+
except HTTPException as e:
64+
return ResponseBase(status_code=e.status_code, error=e.detail)
65+
except Exception as e:
66+
return ResponseBase(
67+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, error=str(e)
68+
)
69+
70+
71+
@router.post(
72+
"/",
73+
response_model=ResponseBase[ComprehensiveEvaluationResponse],
74+
)
75+
async def post_comprehensive_evaluation(
76+
comprehensive_evaluation: ComprehensiveEvaluationCreate,
77+
user_id: UUID,
78+
db: AsyncSession = Depends(get_db),
79+
) -> ResponseBase[ComprehensiveEvaluationResponse]:
80+
try:
81+
comprehensive_evaluation = await add_comprehensive_evaluation(
82+
db, user_id, comprehensive_evaluation
83+
)
84+
return ResponseBase(
85+
status_code=status.HTTP_201_CREATED, data=comprehensive_evaluation
86+
)
87+
except HTTPException as e:
88+
return ResponseBase(status_code=e.status_code, error=e.detail)
89+
except Exception as e:
90+
return ResponseBase(
91+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, error=str(e)
92+
)
93+
94+
95+
@router.put(
96+
"/{comprehensive_evaluation_id}",
97+
response_model=ResponseBase[ComprehensiveEvaluationResponse],
98+
)
99+
async def put_comprehensive_evaluation(
100+
user_id: UUID,
101+
comprehensive_evaluation_id: UUID,
102+
comprehensive_evaluation: ComprehensiveEvaluationUpdate,
103+
db: AsyncSession = Depends(get_db),
104+
) -> ResponseBase[ComprehensiveEvaluationResponse]:
105+
try:
106+
comprehensive_evaluation = await update_comprehensive_evaluation_service(
107+
db, user_id, comprehensive_evaluation_id, comprehensive_evaluation
108+
)
109+
return ResponseBase(
110+
status_code=status.HTTP_200_OK, data=comprehensive_evaluation
111+
)
112+
except HTTPException as e:
113+
return ResponseBase(status_code=e.status_code, error=e.detail)
114+
except Exception as e:
115+
return ResponseBase(
116+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, error=str(e)
117+
)
118+
119+
120+
@router.delete("/{comprehensive_evaluation_id}", response_model=ResponseBase[bool])
121+
async def delete_comprehensive_evaluation(
122+
user_id: UUID,
123+
comprehensive_evaluation_id: UUID,
124+
db: AsyncSession = Depends(get_db),
125+
) -> ResponseBase[bool]:
126+
try:
127+
result = await delete_comprehensive_evaluation_service(
128+
db, user_id, comprehensive_evaluation_id
129+
)
130+
return ResponseBase(status_code=status.HTTP_200_OK, data=result)
131+
except HTTPException as e:
132+
return ResponseBase(status_code=e.status_code, error=e.detail)
133+
except Exception as e:
134+
return ResponseBase(
135+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, error=str(e)
136+
)

app/api/v1/router.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
from fastapi import APIRouter
2-
from app.api.v1.endpoints import auth, user, character, user_character
2+
from app.api.v1.endpoints import (
3+
auth,
4+
user,
5+
character,
6+
user_character,
7+
comprehensive_evaluation,
8+
)
39

410
router = APIRouter()
511

@@ -9,3 +15,8 @@
915
router.include_router(
1016
user_character.router, prefix="/user_characters", tags=["user_characters"]
1117
)
18+
router.include_router(
19+
comprehensive_evaluation.router,
20+
prefix="/users/{user_id}/comprehensive_evaluations",
21+
tags=["comprehensive_evaluations"],
22+
)
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
from sqlalchemy.ext.asyncio import AsyncSession
2+
from app.models.evaluation import ComprehensiveEvaluation
3+
from uuid import UUID
4+
from typing import List
5+
from sqlalchemy import select, delete
6+
from app.schemas.comprehensive_evaluation import (
7+
ComprehensiveEvaluationCreate,
8+
ComprehensiveEvaluationResponse,
9+
ComprehensiveEvaluationUpdate,
10+
)
11+
from app.utils.to_snake_case import camel_to_snake
12+
13+
14+
async def create_comprehensive_evaluation(
15+
db: AsyncSession,
16+
user_id: UUID,
17+
comprehensive_evaluation: ComprehensiveEvaluationCreate,
18+
) -> ComprehensiveEvaluationResponse:
19+
20+
db_comprehensive_evaluation = ComprehensiveEvaluation(
21+
user_id=user_id,
22+
overall_achievement_rate=comprehensive_evaluation.overallAchievementRate,
23+
evaluation_text=comprehensive_evaluation.evaluationText,
24+
strength_achievement_rate=comprehensive_evaluation.strengthAchievementRate,
25+
strength_text=comprehensive_evaluation.strengthText,
26+
improvement_achievement_rate=comprehensive_evaluation.improvementAchievementRate,
27+
)
28+
29+
db.add(db_comprehensive_evaluation)
30+
await db.commit()
31+
await db.refresh(db_comprehensive_evaluation)
32+
return db_comprehensive_evaluation
33+
34+
35+
async def read_comprehensive_evaluations(
36+
db: AsyncSession, user_id: UUID
37+
) -> List[ComprehensiveEvaluationResponse]:
38+
comprehensive_evaluations = await db.execute(
39+
select(ComprehensiveEvaluation).where(
40+
ComprehensiveEvaluation.user_id == user_id
41+
)
42+
)
43+
return comprehensive_evaluations.scalars().all()
44+
45+
46+
async def read_comprehensive_evaluation(
47+
db: AsyncSession, user_id: UUID, comprehensive_evaluation_id: UUID
48+
) -> ComprehensiveEvaluationResponse:
49+
comprehensive_evaluation = await db.execute(
50+
select(ComprehensiveEvaluation).where(
51+
ComprehensiveEvaluation.id == comprehensive_evaluation_id,
52+
ComprehensiveEvaluation.user_id == user_id,
53+
)
54+
)
55+
56+
return comprehensive_evaluation.scalars().first()
57+
58+
59+
async def update_comprehensive_evaluation(
60+
db: AsyncSession,
61+
user_id: UUID,
62+
comprehensive_evaluation_id: UUID,
63+
comprehensive_evaluation: ComprehensiveEvaluationUpdate,
64+
) -> ComprehensiveEvaluationResponse:
65+
db_comprehensive_evaluation = await read_comprehensive_evaluation(
66+
db, user_id, comprehensive_evaluation_id
67+
)
68+
69+
update_data = comprehensive_evaluation.model_dump(exclude_unset=True)
70+
71+
# 변환된 키-값 쌍으로 ORM 객체 업데이트
72+
for key, value in update_data.items():
73+
snake_key = camel_to_snake(key)
74+
75+
setattr(db_comprehensive_evaluation, snake_key, value)
76+
77+
await db.commit()
78+
await db.refresh(db_comprehensive_evaluation)
79+
return db_comprehensive_evaluation
80+
81+
82+
async def delete_comprehensive_evaluation(
83+
db: AsyncSession, user_id: UUID, comprehensive_evaluation_id: UUID
84+
) -> bool:
85+
86+
delete_statement = delete(ComprehensiveEvaluation).where(
87+
ComprehensiveEvaluation.id == comprehensive_evaluation_id,
88+
ComprehensiveEvaluation.user_id == user_id,
89+
)
90+
await db.execute(delete_statement)
91+
await db.commit()
92+
return True
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from app.schemas.base import BaseModel
2+
from uuid import UUID
3+
4+
5+
class ComprehensiveEvaluationCreate(BaseModel):
6+
overallAchievementRate: float
7+
evaluationText: str
8+
strengthAchievementRate: float
9+
strengthText: str
10+
improvementAchievementRate: float
11+
improvementText: str
12+
13+
14+
class ComprehensiveEvaluationResponse(BaseModel):
15+
id: UUID
16+
user_id: UUID
17+
overall_achievement_rate: float
18+
evaluation_text: str
19+
strength_achievement_rate: float
20+
strength_text: str
21+
improvement_achievement_rate: float
22+
23+
24+
class ComprehensiveEvaluationUpdate(BaseModel):
25+
overallAchievementRate: float
26+
evaluationText: str
27+
strengthAchievementRate: float
28+
strengthText: str
29+
improvementAchievementRate: float
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
from app.schemas.comprehensive_evaluation import (
2+
ComprehensiveEvaluationCreate,
3+
ComprehensiveEvaluationResponse,
4+
ComprehensiveEvaluationUpdate,
5+
)
6+
from typing import List
7+
from sqlalchemy.ext.asyncio import AsyncSession
8+
from fastapi import HTTPException
9+
from app.crud.comprehensive_evaluation import (
10+
read_comprehensive_evaluation,
11+
read_comprehensive_evaluations,
12+
create_comprehensive_evaluation,
13+
update_comprehensive_evaluation,
14+
delete_comprehensive_evaluation,
15+
)
16+
17+
from uuid import UUID
18+
19+
20+
async def select_comprehensive_evaluation(
21+
db: AsyncSession, user_id: UUID, comprehensive_evaluation_id: UUID
22+
) -> ComprehensiveEvaluationResponse:
23+
return await read_comprehensive_evaluation(db, user_id, comprehensive_evaluation_id)
24+
25+
26+
async def select_comprehensive_evaluations(
27+
db: AsyncSession, user_id: UUID
28+
) -> List[ComprehensiveEvaluationResponse]:
29+
return await read_comprehensive_evaluations(db, user_id)
30+
31+
32+
async def add_comprehensive_evaluation(
33+
db: AsyncSession,
34+
user_id: UUID,
35+
comprehensive_evaluation: ComprehensiveEvaluationCreate,
36+
) -> ComprehensiveEvaluationResponse:
37+
return await create_comprehensive_evaluation(db, user_id, comprehensive_evaluation)
38+
39+
40+
async def update_comprehensive_evaluation_service(
41+
db: AsyncSession,
42+
user_id: UUID,
43+
comprehensive_evaluation_id: UUID,
44+
comprehensive_evaluation: ComprehensiveEvaluationUpdate,
45+
) -> ComprehensiveEvaluationResponse:
46+
db_comprehensive_evaluation = await read_comprehensive_evaluation(
47+
db, user_id, comprehensive_evaluation_id
48+
)
49+
50+
if not db_comprehensive_evaluation:
51+
raise HTTPException(status_code=404, detail="종합평가 정보를 찾을 수 없습니다.")
52+
53+
return await update_comprehensive_evaluation(
54+
db, user_id, comprehensive_evaluation_id, comprehensive_evaluation
55+
)
56+
57+
58+
async def delete_comprehensive_evaluation_service(
59+
db: AsyncSession, user_id: UUID, comprehensive_evaluation_id: UUID
60+
) -> bool:
61+
db_comprehensive_evaluation = await read_comprehensive_evaluation(
62+
db, user_id, comprehensive_evaluation_id
63+
)
64+
if not db_comprehensive_evaluation:
65+
raise HTTPException(status_code=404, detail="종합평가 정보를 찾을 수 없습니다.")
66+
67+
return await delete_comprehensive_evaluation(
68+
db, user_id, comprehensive_evaluation_id
69+
)

app/utils/to_snake_case.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import re
2+
3+
4+
def camel_to_snake(text: str) -> str:
5+
"""camelCase를 snake_case로 변환합니다."""
6+
7+
s1 = re.sub("(.)([A-Z][a-z]+)", r"\1_\2", text)
8+
9+
return re.sub("([a-z0-9])([A-Z])", r"\1_\2", s1).lower()

0 commit comments

Comments
 (0)