diff --git a/backend/app/core/config.py b/backend/app/core/config.py index 00586af..6149f8c 100644 --- a/backend/app/core/config.py +++ b/backend/app/core/config.py @@ -1,5 +1,6 @@ """核心配置 — Pydantic Settings 自动从 .env 读取""" import json +from pydantic import model_validator from pydantic_settings import BaseSettings @@ -26,6 +27,17 @@ class Settings(BaseSettings): except (json.JSONDecodeError, TypeError): return ["http://localhost:1420", "tauri://localhost"] + @model_validator(mode="after") + def _validate_production_secret(self): + """生产环境强制校验:SECRET_KEY 禁止使用默认值""" + if not self.DEBUG and self.SECRET_KEY == "change-me-in-production": + raise ValueError( + "生产环境 (DEBUG=False) 禁止使用默认 SECRET_KEY。" + "请在 .env 中设置 SECRET_KEY 为至少 32 字符的随机值。" + "示例: python -c \"import secrets; print(secrets.token_urlsafe(32))\"" + ) + return self + class Config: env_file = ".env" extra = "ignore" diff --git a/backend/app/services/dashboard_service.py b/backend/app/services/dashboard_service.py index 6f24ebe..793b051 100644 --- a/backend/app/services/dashboard_service.py +++ b/backend/app/services/dashboard_service.py @@ -17,7 +17,7 @@ class DashboardStats(BaseModel): async def get_dashboard_stats(db: AsyncSession) -> DashboardStats: from app.models.product import Product - from app.models.task import Task + from app.models.task import Task, TASK_STATUS_PENDING, TASK_STATUS_WIP, TASK_STATUS_COMPLETED p_total = await db.scalar(select(func.count(Product.id))) p_pending = await db.scalar(select(func.count(Product.id)).where(Product.status == "pending")) @@ -25,9 +25,9 @@ async def get_dashboard_stats(db: AsyncSession) -> DashboardStats: p_done = await db.scalar(select(func.count(Product.id)).where(Product.status == "completed")) t_total = await db.scalar(select(func.count(Task.id))) - t_pending = await db.scalar(select(func.count(Task.id)).where(Task.status == "pending")) - t_progress = await db.scalar(select(func.count(Task.id)).where(Task.status == "in_progress")) - t_done = await db.scalar(select(func.count(Task.id)).where(Task.status == "completed")) + t_pending = await db.scalar(select(func.count(Task.id)).where(Task.status == TASK_STATUS_PENDING)) + t_progress = await db.scalar(select(func.count(Task.id)).where(Task.status == TASK_STATUS_WIP)) + t_done = await db.scalar(select(func.count(Task.id)).where(Task.status == TASK_STATUS_COMPLETED)) return DashboardStats( products_total=p_total or 0,