diff --git a/apps/web/components/replay/weekly-replay-client.tsx b/apps/web/components/replay/weekly-replay-client.tsx index 34cb7b6..e8b65bd 100644 --- a/apps/web/components/replay/weekly-replay-client.tsx +++ b/apps/web/components/replay/weekly-replay-client.tsx @@ -101,6 +101,10 @@ export function WeeklyReplayClient() { ); } + const orderedDays = [...data.days].sort((left, right) => + right.marketDateLabel.localeCompare(left.marketDateLabel) + ); + return ( <>
@@ -132,7 +136,7 @@ export function WeeklyReplayClient() {
- {data.days.map((day) => ( + {orderedDays.map((day) => (
diff --git a/services/api/app/services/replay/weekly_replay.py b/services/api/app/services/replay/weekly_replay.py index 62253f6..2e3fe3d 100644 --- a/services/api/app/services/replay/weekly_replay.py +++ b/services/api/app/services/replay/weekly_replay.py @@ -96,6 +96,14 @@ def classify_theme_outcome(avg_leader_close_return_pct: float) -> str: return "부진" +def sort_day_items_latest_first(day_items: list[dict[str, object]]) -> list[dict[str, object]]: + return sorted( + day_items, + key=lambda item: str(item["marketDateLabel"]), + reverse=True, + ) + + class WeeklyReplayService: def __init__(self) -> None: self.reaction_engine = YahooMarketReactionEngine() @@ -199,11 +207,12 @@ async def build(self, session: AsyncSession, days: int = 7) -> dict[str, object] } ) + ordered_day_items = sort_day_items_latest_first(day_items) result = { "windowLabel": f"최근 {len(day_items)}거래일", "promptVersion": prompt_version, - "aggregate": self._aggregate(day_items), - "days": day_items, + "aggregate": self._aggregate(ordered_day_items), + "days": ordered_day_items, } _WEEKLY_REPLAY_CACHE[cache_key] = (now, result) return result diff --git a/services/api/tests/test_weekly_replay.py b/services/api/tests/test_weekly_replay.py index dae61cd..f37dab4 100644 --- a/services/api/tests/test_weekly_replay.py +++ b/services/api/tests/test_weekly_replay.py @@ -1,4 +1,8 @@ -from app.services.replay.weekly_replay import classify_theme_outcome, compute_stock_move +from app.services.replay.weekly_replay import ( + classify_theme_outcome, + compute_stock_move, + sort_day_items_latest_first, +) def test_compute_stock_move_uses_previous_close_as_base() -> None: @@ -14,3 +18,19 @@ def test_classify_theme_outcome_has_clear_bands() -> None: assert classify_theme_outcome(1.4) == "양호" assert classify_theme_outcome(0.2) == "보통" assert classify_theme_outcome(-1.8) == "부진" + + +def test_sort_day_items_latest_first_orders_descending_by_market_date() -> None: + ordered = sort_day_items_latest_first( + [ + {"marketDateLabel": "2026-04-07", "summary": "older"}, + {"marketDateLabel": "2026-04-09", "summary": "newest"}, + {"marketDateLabel": "2026-04-08", "summary": "middle"}, + ] + ) + + assert [item["marketDateLabel"] for item in ordered] == [ + "2026-04-09", + "2026-04-08", + "2026-04-07", + ]