Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,23 @@ jobs:
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new

- name: Copy Docker Compose file via SCP
uses: appleboy/scp-action@v0.1.7
with:
host: ${{ secrets.GCE_HOST }}
username: ${{ secrets.GCE_SSH_USER }}
key: ${{ secrets.GCE_SSH_KEY }}
source: "docker-compose.prod.yml"
target: "~/app-path"

- name: Deploy to GCE via SSH
uses: appleboy/ssh-action@v1.0.0
with:
host: ${{ secrets.GCE_HOST }}
username: ${{ secrets.GCE_SSH_USER }}
key: ${{ secrets.GCE_SSH_KEY }}
script: |
mkdir -p ~/app-path
cd ~/app-path

cat << 'EOF' > .env
Expand All @@ -70,7 +80,9 @@ jobs:

gcloud auth configure-docker ${{ env.ARTIFACT_REGISTRY }} --quiet

docker-compose -f docker-compose.prod.yml down
docker-compose -f docker-compose.prod.yml pull
docker-compose -f docker-compose.prod.yml run --rm -e MODE=prod fastapi alembic upgrade head
docker-compose -f docker-compose.prod.yml up -d
docker compose -f docker-compose.prod.yml down
docker compose -f docker-compose.prod.yml pull

docker compose -f docker-compose.prod.yml run --rm -e MODE=prod fastapi alembic upgrade head

docker compose -f docker-compose.prod.yml up -d
6 changes: 3 additions & 3 deletions api/v1/auth/auth_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@ async def sign_up(request: SignUpRequest, db: AsyncSession = Depends(get_db)):
print(info.values())

user_dto = UserCreateDTO(
**request.model_dump(exclude={"kakao_token"}),
**info
**{**request.model_dump(exclude={"kakao_token"}), **info}
)

user = await SignUpUseCase(db).execute(user_dto)
token_data = TokenUseCase.generate_tokens(user_id=user.id)
token_uc = TokenUseCase()
token_data = token_uc.generate_tokens(user_id=user.id)

return created(data=token_data, message="회원가입 성공")

Expand Down
5 changes: 5 additions & 0 deletions api/v1/test/test_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
from app.test.dto.request.create_dummy_data_request import CreateDummyDataRequest
#시험모드 문제 리스트 출력
from app.test.dto.response.get_certificates_exam_list_response import GetCertificatesExamListResponse
from app.test.usecase.test_usecase import get_exam_list_by_certificate_id_usecase
from app.test.usecase.exam_usecase import get_certificates_exam_list_usecase
from app.test.usecase.exam_usecase import create_exam_usecase
from app.test.usecase.exam_usecase import get_exam_info_usecase
Expand Down Expand Up @@ -171,6 +172,10 @@ async def get_questions_by_exam_id(
result = await get_questions_by_exam_id_usecase(exam_id, db)
return ok(data=[item.dict() for item in result], message="문제 목록 조회 성공")

@router.get("/list/{certificate_id}")
async def get_exam_list(certificate_id: int = Path(...), db: AsyncSession = Depends(get_db)):
return await get_exam_list_by_certificate_id_usecase(certificate_id, db)

@router.post("/dummy-data", summary="유형별 Dummy Data 생성 API")
async def create_dummy_data(
request: CreateDummyDataRequest, # ← 여기에 request 추가 필요!
Expand Down
4 changes: 2 additions & 2 deletions app/review/dto/response/review_note_list_response.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import List
from typing import List, Optional

from pydantic import BaseModel

Expand All @@ -7,5 +7,5 @@

class ReviewNoteListResponseDto(BaseModel):
category: List[str]
selected_category: str
selected_category: Optional[str] = None
exams: List[ExamItemInfo]
14 changes: 14 additions & 0 deletions app/test/dto/response/exam_response_dto.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from pydantic import BaseModel

class ExamResponseDTO(BaseModel):
id: int
name: str
year: int
month: int
trial: int | None
time: int
pass_rate: float | None
question_count: int

class Config:
from_attributes = True
35 changes: 33 additions & 2 deletions app/test/usecase/test_usecase.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import func
from sqlalchemy.future import select
from domain.test.entity.exam import Exam
from domain.test.entity.question import Question
from domain.user.entity.user import User
from app.utils.dto.success import ok
from sqlalchemy.ext.asyncio import AsyncSession
from app.test.dto.response.exam_response_dto import ExamResponseDTO
from domain.test.repository.test_repository import TestRepository
from exception.client_exception import NotFoundException
from app.utils.dto.success import created, ok

async def get_test_mode_usecase(
exam_id: int,
Expand Down Expand Up @@ -44,3 +47,31 @@ async def get_test_mode_usecase(
},
message="시험 조회 성공"
)

async def get_exam_list_by_certificate_id_usecase(certificate_id: int, db: AsyncSession):
repo = TestRepository(db)
exams = await repo.get_exams_by_certificate_id(certificate_id)

if not exams:
raise NotFoundException("해당 자격증에 대한 시험이 존재하지 않습니다.")

exam_list = []

for exam in exams:
stmt = select(func.count()).where(Question.exam_id == exam.id)
result = await db.execute(stmt)
question_count = result.scalar_one()

dto = ExamResponseDTO(
id=exam.id,
name=exam.name,
year=exam.year,
month=exam.month,
trial=exam.trial,
time=exam.time,
pass_rate=exam.pass_rate,
question_count=question_count
)
exam_list.append(dto.model_dump())

return ok(data={"exams": exam_list}, message="시험 리스트 조회 성공")
2 changes: 1 addition & 1 deletion domain/review/service/review_note_test_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ async def list_review_notes(

return ReviewNoteListResponseDto(
category = categories,
selected_category = selected,
selected_category = selected or "",
exams = exams
)

Expand Down
8 changes: 7 additions & 1 deletion domain/test/repository/test_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,11 @@ async def get_question_count_by_exam_id(self, exam_id: int) -> int:
)
return result.scalar()

async def get_exams_by_certificate_id(self, certificate_id: int) -> list[Exam]:
stmt = select(Exam).where(Exam.certificate_id == certificate_id)
result = await self.db.execute(stmt)
return result.scalars().all()

async def get_exams_by_certificate_ids(self, certificate_ids: list[int]) -> list[Exam]:
result = await self.db.execute(
select(Exam)
Expand All @@ -179,4 +184,5 @@ async def get_exam_by_id(self, exam_id: int) -> Exam | None:
result = await self.db.execute(
select(Exam).where(Exam.id == exam_id)
)
return result.scalars().first()
return result.scalars().first()

9 changes: 8 additions & 1 deletion domain/test/service/test_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,17 @@ async def check_user_submit(
if is_correct:
correct_count += 1

raw_list = question.option_explanations or []
option_explanations_dict: dict[str, str] = {
key: val
for item in raw_list
for key, val in item.items()
}

# 문제별 해설 DTO
info_list.append(AnswerInfoDto(
answer=question.answer,
option_explanations=question.option_explanations
option_explanations=option_explanations_dict
))

# 문제별 사용자 응답 기록
Expand Down
1 change: 0 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ boto3~=1.38.32
python-jose[cryptography]~=3.5.0
requests-oauthlib
requests~=2.32.3
starlette>=0.49.1

# test
pytest
Expand Down