重构表结构:合并 profiles→users,展平 API 响应,新增计数器字段

- models: 删除 Profile 模型,字段合并到 User;User 新增云朵/公开/收藏计数器;Cloud 新增 favorite_count
- schemas/serializers: 展平 UserOut/AuthOut/MeOut/AdminUserOut,移除嵌套 profile
- deps: user.profile.role→user.role,移除 selectinload profile
- auth/register: 注册时直接设置 user 字段,不再创建 Profile
- clouds: 创建/删除云朵时同步 user.cloud_count 计数器,状态变化时同步 public_cloud_count
- favorites: 点赞/取消时同步 cloud.favorite_count 计数器
- admin: 审批/隐藏/批量删时同步 public_cloud_count 计数器
- profiles/stats: 用计数器替代实时 COUNT 查询
- alembic: 新增 migration 合并 profiles 到 users,初始化 counters
This commit is contained in:
2026-07-28 23:48:57 +08:00
parent 118c5cbe96
commit e75833ee4b
14 changed files with 519 additions and 285 deletions
+6 -5
View File
@@ -5,7 +5,7 @@ from sqlalchemy.orm import selectinload
from app.config import settings
from app.database import SessionLocal
from app.models import CloudType, Profile, User
from app.models import CloudType, User
from app.security import hash_password, utc_now
@@ -36,20 +36,21 @@ async def seed() -> None:
if settings.admin_email and settings.admin_password:
email = settings.admin_email.strip().lower()
result = await db.execute(
select(User).options(selectinload(User.profile)).where(User.email == email)
select(User).where(User.email == email)
)
admin = result.scalar_one_or_none()
if admin:
admin.profile.role = "admin"
admin.profile.is_disabled = False
admin.role = "admin"
admin.is_disabled = False
admin.email_verified_at = admin.email_verified_at or utc_now()
else:
admin = User(
email=email,
password_hash=hash_password(settings.admin_password),
email_verified_at=utc_now(),
username=settings.admin_username,
role="admin",
)
admin.profile = Profile(username=settings.admin_username, role="admin")
db.add(admin)
await db.commit()