Skip to content

Commit e715b2e

Browse files
swa07016Gukhee Jo
andauthored
[NL-75] : 로또 결과 확인 API (#21)
* feat: 로또 결과 확인 API * fix: black 적용 및 is_finished 변수 반환 --------- Co-authored-by: Gukhee Jo <[email protected]>
1 parent afc4537 commit e715b2e

File tree

6 files changed

+267
-39
lines changed

6 files changed

+267
-39
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
"""add is_read, read_at field to lotto recommendation table
2+
3+
Revision ID: 578233fccdf8
4+
Revises: 926bb28822d1
5+
Create Date: 2025-08-18 00:37:25.201315
6+
7+
"""
8+
from typing import Sequence, Union
9+
10+
from alembic import op
11+
import sqlalchemy as sa
12+
13+
14+
# revision identifiers, used by Alembic.
15+
revision: str = '578233fccdf8'
16+
down_revision: Union[str, Sequence[str], None] = '926bb28822d1'
17+
branch_labels: Union[str, Sequence[str], None] = None
18+
depends_on: Union[str, Sequence[str], None] = None
19+
20+
21+
def upgrade() -> None:
22+
"""Upgrade schema."""
23+
# ### commands auto generated by Alembic - please adjust! ###
24+
op.add_column('lotto_recommendations', sa.Column('is_read', sa.Boolean(), nullable=False))
25+
op.add_column('lotto_recommendations', sa.Column('read_at', sa.DateTime(), nullable=True))
26+
# ### end Alembic commands ###
27+
28+
29+
def downgrade() -> None:
30+
"""Downgrade schema."""
31+
# ### commands auto generated by Alembic - please adjust! ###
32+
op.drop_column('lotto_recommendations', 'read_at')
33+
op.drop_column('lotto_recommendations', 'is_read')
34+
# ### end Alembic commands ###

src/lotto/entities/models.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from sqlalchemy import (
22
Column,
33
Integer,
4+
Boolean,
45
Date,
56
CheckConstraint,
67
BigInteger,
@@ -55,5 +56,8 @@ class LottoRecommendations(Base):
5556
user_id = Column(String(255), ForeignKey("users.id"), nullable=False)
5657
round = Column(Integer, nullable=False)
5758
content = Column(JSON, nullable=False)
59+
is_read = Column(Boolean, nullable=False, default=False)
60+
read_at = Column(DateTime, nullable=True)
5861

5962
user = relationship("User", back_populates="lotto_recommendations")
63+

src/lotto/entities/schemas.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,21 +84,38 @@ def normalize_element(cls, v):
8484
"금(金)": FiveElements.METAL,
8585
"수(水)": FiveElements.WATER,
8686
}
87-
87+
8888
normalized = element_mapping.get(v)
8989
if normalized is not None:
9090
return normalized
91-
91+
9292
return v
9393

9494

9595
class LottoRecommendation(CommonBase):
9696
user_id: str
9797
round: int
9898
content: Optional[LottoRecommendationContent] = None
99+
is_finished: bool = False
99100

100101

101102
class LottoRecommendationCreate(CommonBase):
102103
user_id: str
103104
round: int
104105
content: LottoRecommendationContent
106+
107+
108+
class LottoResultCheckResponse(CommonBase):
109+
user_id: str
110+
round: int
111+
112+
# 추가된 필드들
113+
draw_numbers: List[int] # 해당 회차 당첨 메인 번호 6개 (원본 순서)
114+
bonus_number: int # 해당 회차 보너스 번호
115+
recommended_numbers: List[int] # 추천받은 번호 6개 (원본 순서)
116+
117+
matched_count: int
118+
matched_numbers: List[int] # 교집합(오름차순)
119+
has_bonus: bool
120+
rank: Optional[int] # 1~5, 낙첨이면 None
121+
prize_amount: Optional[int] # 원 단위, 알 수 없으면 None

src/lotto/repository.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from typing import List, Optional, Tuple
33

44
from fastapi import Depends
5-
from sqlalchemy import select, desc, asc
5+
from sqlalchemy import select, update, desc, asc
66
from sqlalchemy.ext.asyncio import AsyncSession
77

88
from src.common.dependencies import get_db_session
@@ -194,3 +194,26 @@ async def get_excluded_numbers(self, limit: int = 2) -> List[int]:
194194
)
195195
result = await self.session.execute(query)
196196
return [row[0] for row in result.fetchall()]
197+
198+
async def get_recommendation_by_user_and_round(
199+
self, user_id: str, round: int
200+
) -> Optional[LottoRecommendations]:
201+
query = (
202+
select(LottoRecommendations)
203+
.where(
204+
LottoRecommendations.user_id == user_id,
205+
LottoRecommendations.round == round,
206+
)
207+
.limit(1)
208+
)
209+
result = await self.session.execute(query)
210+
return result.scalar_one_or_none()
211+
212+
async def mark_recommendation_read(self, recommendation_id: int, read_at: datetime) -> None:
213+
"""추천 레코드를 읽음 처리합니다."""
214+
stmt = (
215+
update(LottoRecommendations)
216+
.where(LottoRecommendations.id == recommendation_id)
217+
.values(is_read=True, read_at=read_at)
218+
)
219+
await self.session.execute(stmt)

0 commit comments

Comments
 (0)