What to build
單一 PR 將散落各處的環境變數讀取統整為頂層 config.py 的 pydantic-settings Settings(即時單例,import 即驗證),部署設定自此「啟動時一次載入並驗證」。此票 block Normal-OJ/Normal-OJ#61(PR #341 將 rebase 其上)。
決策已定案如下:
- 頂層
config.py、settings = Settings() 即時單例;新依賴 pydantic-settings
- 行為凍結:所有欄位維持現行預設/Optional 語意;唯一啟動 raise 是現行
setup_smtp() 的 cross-field 規則(SMTP_SERVER 有設但 SMTP_NOREPLY 未設),搬進 model_validator 後 setup_smtp() 移除
- 搬遷清單:
MINIO_*(mongo/config.py,搬完刪檔)、MONGO_HOST(mongo/engine.py)、JWT_*(mongo/user.py)、TESTING/REDIS_*(mongo/utils.py)、SUBMISSION_TMP_DIR(mongo/submission.py)、SMTP_*(model/utils/smtp.py、app.py)
- 僅有的兩個刻意行為變更(PR 描述須明講):
SUBMISSION_TMP_DIR 預設值改 tempfile.mkdtemp()——現值 TemporaryDirectory(...).name 未留物件引用,GC 時目錄被刪;順修 noj-submisisons typo
FLASK_DEBUG 改名 DEBUG——外部已零設定點,唯一消費者是 mongo/utils.py 的 MinIO secure=
- 測試配套:runtime 改
os.environ 的測試(conftest、test_smtp、test_mongo_utils、test_target_sandbox)改用 monkeypatch.setattr(settings, ...)
- 不做:
JWT_SECRET 等安全 tightening(另議)
Acceptance criteria
Blocked by
None — can start immediately.
What to build
單一 PR 將散落各處的環境變數讀取統整為頂層
config.py的 pydantic-settingsSettings(即時單例,import 即驗證),部署設定自此「啟動時一次載入並驗證」。此票 block Normal-OJ/Normal-OJ#61(PR #341 將 rebase 其上)。決策已定案如下:
config.py、settings = Settings()即時單例;新依賴pydantic-settingssetup_smtp()的 cross-field 規則(SMTP_SERVER有設但SMTP_NOREPLY未設),搬進 model_validator 後setup_smtp()移除MINIO_*(mongo/config.py,搬完刪檔)、MONGO_HOST(mongo/engine.py)、JWT_*(mongo/user.py)、TESTING/REDIS_*(mongo/utils.py)、SUBMISSION_TMP_DIR(mongo/submission.py)、SMTP_*(model/utils/smtp.py、app.py)SUBMISSION_TMP_DIR預設值改tempfile.mkdtemp()——現值TemporaryDirectory(...).name未留物件引用,GC 時目錄被刪;順修noj-submisisonstypoFLASK_DEBUG改名DEBUG——外部已零設定點,唯一消費者是mongo/utils.py的 MinIOsecure=os.environ的測試(conftest、test_smtp、test_mongo_utils、test_target_sandbox)改用monkeypatch.setattr(settings, ...)JWT_SECRET等安全 tightening(另議)Acceptance criteria
config.settings;舊讀取點與mongo/config.py刪除poetry run pytest全綠、yapfdiff 乾淨SMTP_SERVER有設而SMTP_NOREPLY未設 → 啟動失敗;其餘缺省不擋啟動(與現行一致)Blocked by
None — can start immediately.