fix(auth): 登录目录就绪幂等化与并发控制

- employee/settings/user_session_metrics 的 ensure_*_ready 改为按 bind 缓存 + 锁,
  避免每次登录重复建表与并发场景下的竞态
- auth 登录链路先查员工再降级触发目录就绪,并吞掉查询期 SQLAlchemy 异常
- 默认管理员账号由 superadmin 迁移为 admin,兼容历史账号回填
- 补充登录降级与设置持久化相关测试
This commit is contained in:
caoxiaozhu
2026-06-18 22:11:53 +08:00
parent 59ba76c74a
commit 3f17619e0c
7 changed files with 155 additions and 19 deletions

View File

@@ -2,6 +2,7 @@ from __future__ import annotations
from collections import Counter
from datetime import UTC, date, datetime
import threading
from typing import Any
from sqlalchemy import select
@@ -81,11 +82,31 @@ def prepare_employee_directory() -> None:
class EmployeeService:
_directory_ready_lock = threading.Lock()
_directory_ready_keys: set[tuple[str, int]] = set()
def __init__(self, db: Session) -> None:
self.db = db
self.repository = EmployeeRepository(db)
@staticmethod
def _bind_cache_key(db: Session) -> tuple[str, int]:
bind = db.get_bind()
return (bind.url.render_as_string(hide_password=True), id(bind.pool))
def ensure_directory_ready(self) -> None:
cache_key = self._bind_cache_key(self.db)
if cache_key in self._directory_ready_keys:
return
with self._directory_ready_lock:
if cache_key in self._directory_ready_keys:
return
self._ensure_directory_ready_uncached()
self._directory_ready_keys.add(cache_key)
def _ensure_directory_ready_uncached(self) -> None:
try:
Base.metadata.create_all(bind=self.db.get_bind())
ensure_employee_schema(self.db)