chore(prep): shared groundwork for batch-3 (admin/golden/cache)
第三批(T12 后台/T13 黄金集/T14 检索缓存)协调提交: - kb:KbAssetService(登记/审核,tryon_ready 只能随 approved 打开)+ Asset 模型与 repo - retrieval:list_gaps 缺口看板查询 + invalidate_cache() 钩子(T14 背后实现真缓存) - 配置:ADMIN_TOKEN(空=后台 404)+ 检索缓存三参数 - pytest golden marker(默认跳过,CI 强制跑)+ Makefile golden + CI 防线 5c - 测试隔离修复:test_auth_sms 加 autouse 清 sms:* 键夹具(频控计数跨运行 累积会毒化后续运行——随机 IP 空间仅 254 且部分用例固定 device_id)
This commit is contained in:
+37
-1
@@ -15,7 +15,7 @@ from dataclasses import dataclass
|
||||
from sqlalchemy import ColumnElement, func, select, text
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from packages.shared.models import KbColor, KbEntity, KbRelation
|
||||
from packages.shared.models import KbAsset, KbColor, KbEntity, KbRelation
|
||||
|
||||
#: 递归遍历 SQL(1~3 跳)。``path`` 记录已经过的实体 id,``rels`` 与逐跳
|
||||
#: rel_type 平行——每行结果本身就是一条完整可解释路径,不需要在 Python
|
||||
@@ -166,3 +166,39 @@ async def list_colors(session: AsyncSession, *, season_code: str | None = None)
|
||||
def add_color(session: AsyncSession, color: KbColor) -> KbColor:
|
||||
session.add(color)
|
||||
return color
|
||||
|
||||
|
||||
async def get_asset(session: AsyncSession, asset_id: int) -> KbAsset | None:
|
||||
return await session.get(KbAsset, asset_id)
|
||||
|
||||
|
||||
async def list_assets(
|
||||
session: AsyncSession,
|
||||
*,
|
||||
entity_id: int | None = None,
|
||||
tryon_ready: bool | None = None,
|
||||
limit: int = 50,
|
||||
offset: int = 0,
|
||||
) -> tuple[list[KbAsset], int]:
|
||||
"""素材列表(含总数)。tryon_ready 过滤走 partial 索引。"""
|
||||
from sqlalchemy import func, select
|
||||
|
||||
conditions = []
|
||||
if entity_id is not None:
|
||||
conditions.append(KbAsset.entity_id == entity_id)
|
||||
if tryon_ready is not None:
|
||||
conditions.append(KbAsset.tryon_ready == tryon_ready)
|
||||
|
||||
base = select(KbAsset)
|
||||
if conditions:
|
||||
base = base.where(*conditions)
|
||||
total = (await session.execute(select(func.count()).select_from(base.subquery()))).scalar_one()
|
||||
rows = (
|
||||
await session.execute(base.order_by(KbAsset.asset_id.desc()).limit(limit).offset(offset))
|
||||
).scalars()
|
||||
return list(rows), int(total)
|
||||
|
||||
|
||||
def add_asset(session: AsyncSession, asset: KbAsset) -> KbAsset:
|
||||
session.add(asset)
|
||||
return asset
|
||||
|
||||
Reference in New Issue
Block a user