fix(welfare): 消息提醒可重复领取并发重复发放修复 + review 清理
代码 review(本分支未提交 WIP)发现并修复: - 高: enable_notification 可重复领取的发放是无锁读-算-写,并发/连点会算出同一序号 双倍发钱。给 coin_transaction 加 (user_id,biz_type,ref_id) 部分唯一索引(仅 task_*), claim 撞唯一约束→IntegrityError 回滚兜底成 AlreadyClaimedError(409),不双发。 配套 alembic 迁移 coin_txn_task_ref_uq(挂 head=drop_force_onboarding)。 - 中: 加领取封顶 rewards.notification_max_claims(减半到底=1 后不再可领),挡通知一直关着 时无限刷 1 金币;列表领满后 claimed 置 True 供客户端隐藏。 - 中: _notification_grant_times 改只数 amount>0 流水,避免日后冲正/负向流水把次数算大。 - 低: 合并 ops_marquee._nickname 两个一字不差的重复分支。 - 文档: tasks-list / tasks-claim 补可重复领取/逐次减半/409 语义。 - 测试: 新增「领满到底→409 + claimed=True」用例;test_welfare 全绿(3 个 proxy 失败 为 pre-existing httpx mock 问题,与本次无关)。 注: review 标的「do_signin 未归一化老 cycle_day」经验算为非 bug(x%LEN+1 对越界值 本就周期正确,且与 get_status 预览公式恒等),未改。 含本分支签到7天改制/任务文案/膨胀金币等 WIP。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -13,6 +13,7 @@ from app.admin.audit import write_audit
|
||||
from app.admin.deps import AdminDb, get_client_ip, get_current_admin, require_role
|
||||
from app.admin.schemas.config import ConfigItemOut, ConfigUpdateRequest
|
||||
from app.core.config_schema import CONFIG_DEFS
|
||||
from app.core.rewards import SIGNIN_CYCLE_LEN
|
||||
from app.models.admin import AdminUser
|
||||
from app.repositories import app_config
|
||||
|
||||
@@ -34,8 +35,8 @@ def _validate(key: str, value: Any) -> None:
|
||||
raise ValueError("需为非空整数列表")
|
||||
if not all(isinstance(x, int) and not isinstance(x, bool) and x >= 0 for x in value):
|
||||
raise ValueError("列表元素需为非负整数")
|
||||
if key == "signin_rewards" and len(value) != 14:
|
||||
raise ValueError("签到档位必须正好 14 个(对应 14 天循环)")
|
||||
if key == "signin_rewards" and len(value) != SIGNIN_CYCLE_LEN:
|
||||
raise ValueError(f"签到档位必须正好 {SIGNIN_CYCLE_LEN} 个(对应 {SIGNIN_CYCLE_LEN} 天循环)")
|
||||
elif t == "dict_str_int":
|
||||
if not isinstance(value, dict) or not all(
|
||||
isinstance(k, str) and isinstance(v, int) and not isinstance(v, bool)
|
||||
|
||||
Reference in New Issue
Block a user