Skip to content

Commit 4c75f0c

Browse files
committed
feat(cert): add season default study periods with fallback lookup
1 parent 20b39b8 commit 4c75f0c

2 files changed

Lines changed: 116 additions & 16 deletions

File tree

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"3": { "start": "2021-07-16", "end": "2021-10-08" },
3+
"4": { "start": "2022-03-07", "end": "2022-05-29" },
4+
"5": { "start": "2022-09-05", "end": "2022-11-27" },
5+
"6": { "start": "2023-03-15", "end": "2023-06-07" },
6+
"7": { "start": "2023-08-21", "end": "2023-11-12" },
7+
"8": { "start": "2024-03-03", "end": "2024-05-26" },
8+
"9": { "start": "2024-08-04", "end": "2024-10-27" },
9+
"10": { "start": "2025-03-02", "end": "2025-05-25" },
10+
"11": { "start": "2025-09-08", "end": "2025-11-30" }
11+
}

โ€Žcert/backend/src/utils/notion_client.pyโ€Ž

Lines changed: 105 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from datetime import datetime
2+
import json
23
import logging
34
import os
45
import aiohttp
@@ -43,8 +44,39 @@ def __init__(self):
4344
self._cache = {}
4445
self._cache_timestamps = {}
4546
self._projects_loaded = False # ์„œ๋ฒ„ ์‹œ์ž‘ ํ›„ ํ•œ ๋ฒˆ๋งŒ ๋กœ๋“œ
47+
self.default_periods = self._load_default_periods()
4648

4749
self._initialized = True
50+
51+
def _load_default_periods(self) -> Dict[str, Dict[str, str]]:
52+
"""์‹œ์ฆŒ๋ณ„ ๊ธฐ๋ณธ ๊ธฐ๊ฐ„ ์ •๋ณด ๋กœ๋“œ"""
53+
env_path = os.getenv("DEFAULT_PERIODS_FILE")
54+
default_file_path = env_path or os.path.join(
55+
os.path.dirname(__file__),
56+
"..",
57+
"..",
58+
"config",
59+
"default_periods.json",
60+
)
61+
try:
62+
with open(default_file_path, "r", encoding="utf-8") as f:
63+
return json.load(f)
64+
except FileNotFoundError:
65+
logger.warning(
66+
"๊ธฐ๋ณธ ๊ธฐ๊ฐ„ ํŒŒ์ผ์ด ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.",
67+
extra={"path": default_file_path},
68+
)
69+
except json.JSONDecodeError:
70+
logger.warning(
71+
"๊ธฐ๋ณธ ๊ธฐ๊ฐ„ ํŒŒ์ผ ํŒŒ์‹ฑ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.",
72+
extra={"path": default_file_path},
73+
)
74+
except Exception:
75+
logger.exception(
76+
"๊ธฐ๋ณธ ๊ธฐ๊ฐ„ ํŒŒ์ผ ๋กœ๋“œ ์ค‘ ์•Œ ์ˆ˜ ์—†๋Š” ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.",
77+
extra={"path": default_file_path},
78+
)
79+
return {}
4880

4981
async def verify_user_participation(
5082
self,
@@ -132,29 +164,86 @@ async def verify_user_participation(
132164
if user_role is None:
133165
raise NotEligibleError(f"์ˆ˜๋ฃŒ ๋ช…๋‹จ์— ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๐Ÿฅฒ\n๋””์Šค์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ์งˆ๋ฌธ๊ฒŒ์‹œํŒ์— ๋ฌธ์˜ํ•ด์ฃผ์„ธ์š”.")
134166

135-
period = project.get("properties", {}).get("๊ธฐ๊ฐ„", {}).get("date", {})
167+
study_status = properties.get("๋‹จ๊ณ„", {}).get("select", {})
168+
period_raw = project.get("properties", {}).get("๊ธฐ๊ฐ„", {}).get("date", {}) or {}
136169

137-
if not period:
170+
if not study_status:
138171
raise SystemError(
139-
"ํ”„๋กœ์ ํŠธ ๊ธฐ๊ฐ„ ์ •๋ณด๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. "
140-
"์Šคํ„ฐ๋”” ๋นŒ๋”์—๊ฒŒ ๋ฌธ์˜ํ•ด์ฃผ์„ธ์š”."
172+
"์Šคํ„ฐ๋””์˜ ์™„๋ฃŒ ์ •๋ณด๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.\n๋””์Šค์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ์งˆ๋ฌธ๊ฒŒ์‹œํŒ์— ๋ฌธ์˜ํ•ด์ฃผ์„ธ์š”."
141173
)
142174

143-
# ์ข…๋ฃŒ์ผ ๊ฒ€์ฆ
144-
if not period.get('end'):
145-
raise SystemError(
146-
"ํ”„๋กœ์ ํŠธ ์ข…๋ฃŒ์ผ ์ •๋ณด๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. "
147-
"์Šคํ„ฐ๋”” ๋นŒ๋”์—๊ฒŒ ๋ฌธ์˜ํ•ด์ฃผ์„ธ์š”."
175+
if study_status.get("name") != "์™„๋ฃŒ":
176+
raise NotEligibleError(
177+
"์ˆ˜๋ฃŒ์ฆ์€ ์Šคํ„ฐ๋””๊ฐ€ ์™„๋ฃŒ๋œ ์ดํ›„ ๋ฐœ๊ธ‰ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.\n๋””์Šค์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ์งˆ๋ฌธ๊ฒŒ์‹œํŒ์— ๋ฌธ์˜ํ•ด์ฃผ์„ธ์š”."
148178
)
149179

150-
end_date_str = period['end']
151-
end_date = datetime.strptime(end_date_str, "%Y-%m-%d").date()
152-
today = datetime.now().date()
180+
fallback_period = self.default_periods.get(str(season), {})
181+
raw_start = period_raw.get("start")
182+
raw_end = period_raw.get("end")
153183

154-
if today < end_date:
155-
raise NotEligibleError(
156-
f"์ˆ˜๋ฃŒ์ฆ์€ ์ˆ˜๋ฃŒ ํ›„ ๋ฐœ๊ธ‰ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค."
184+
# 1) ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์ดˆ๊ธฐํ™”
185+
period = {
186+
"start": fallback_period.get("start"),
187+
"end": fallback_period.get("end"),
188+
}
189+
190+
# 2) Notion ๊ฐ’์ด ์™„์ „ํ•˜๋ฉด ๋ฎ์–ด์“ฐ๊ธฐ
191+
if raw_start and raw_end:
192+
period["start"] = raw_start
193+
period["end"] = raw_end
194+
# 3) ํ•œ์ชฝ๋งŒ ์žˆ์„ ๋•Œ
195+
elif raw_start or raw_end:
196+
if fallback_period:
197+
logger.warning(
198+
"์Šคํ„ฐ๋”” ๊ธฐ๊ฐ„์ด ํ•œ์ชฝ๋งŒ ์žˆ์–ด ๊ธฐ๋ณธ ๊ธฐ๊ฐ„์œผ๋กœ ๋Œ€์ฒดํ•ฉ๋‹ˆ๋‹ค.",
199+
extra={
200+
"user_name": user_name,
201+
"season": season,
202+
"course_name": course_name,
203+
"project_id": project.get("id"),
204+
"raw_start": raw_start,
205+
"raw_end": raw_end,
206+
"fallback_start": period["start"],
207+
"fallback_end": period["end"],
208+
},
209+
)
210+
else:
211+
message = (
212+
"์Šคํ„ฐ๋”” ๊ธฐ๊ฐ„ ์ •๋ณด๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. "
213+
f"(season={season}, course={course_name}) "
214+
"config/default_periods.json์˜ ๊ธฐ๋ณธ ๊ธฐ๊ฐ„์„ ํ™•์ธํ•ด์ฃผ์„ธ์š”."
215+
)
216+
logger.error(
217+
message,
218+
extra={
219+
"user_name": user_name,
220+
"season": season,
221+
"course_name": course_name,
222+
"project_id": project.get("id"),
223+
"raw_start": raw_start,
224+
"raw_end": raw_end,
225+
"default_period_found": bool(fallback_period),
226+
},
227+
)
228+
raise SystemError(message)
229+
# 4) Notion ๊ฐ’๋„ ์—†๊ณ  ๊ธฐ๋ณธ๊ฐ’๋„ ์—†์Œ
230+
elif not period["start"] and not period["end"]:
231+
message = (
232+
"์Šคํ„ฐ๋”” ๊ธฐ๊ฐ„ ์ •๋ณด๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. "
233+
f"(season={season}, course={course_name}) "
234+
"config/default_periods.json์˜ ๊ธฐ๋ณธ ๊ธฐ๊ฐ„์„ ํ™•์ธํ•ด์ฃผ์„ธ์š”."
235+
)
236+
logger.error(
237+
message,
238+
extra={
239+
"user_name": user_name,
240+
"season": season,
241+
"course_name": course_name,
242+
"project_id": project.get("id"),
243+
"default_period_found": bool(fallback_period),
244+
},
157245
)
246+
raise SystemError(message)
158247

159248
logger.info(
160249
"์‚ฌ์šฉ์ž ๊ฒ€์ฆ ์„ฑ๊ณต",
@@ -183,7 +272,7 @@ async def verify_user_participation(
183272
"course_name": course_name,
184273
},
185274
)
186-
raise Exception("ํ•ด๋‹น ํ”„๋กœ์ ํŠธ๊ฐ€ ๊ฒ€์ƒ‰๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. \nDevFactory๋กœ ์—ฐ๋ฝ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค.")
275+
raise Exception("ํ•ด๋‹น ํ”„๋กœ์ ํŠธ๊ฐ€ ๊ฒ€์ƒ‰๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. \n๋””์Šค์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ์งˆ๋ฌธ๊ฒŒ์‹œํŒ์— ๋ฌธ์˜ํ•ด์ฃผ์„ธ์š”.")
187276
except Exception as e:
188277
raise e
189278

0 commit comments

Comments
ย (0)