|
|
a9d00a49f9
|
fix(infra): 切换 Redis 至火山引擎实例 + 修复 channels 不支持 ACL username + .env 取消跟踪
Build and Deploy LTY / build-and-deploy (push) Successful in 8m34s
- 阿里云 Redis 实例 10054 RST 导致 /api/v1/admin/login/ 等接口全线 500,切到火山实例 (db /3, user zyc)
- CHANNEL_LAYERS hosts 由手工拼接 redis://:{pwd}@{host} 改为直接消费 REDIS_LOCATION,支持 ACL username
- .gitignore 恢复 qy_lty/.env 忽略,git rm --cached 移除跟踪;历史中旧密钥仍在,需另行 rotate
- 详见 qy_lty/docs/修改记录.md 2026-05-18 条目
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-05-18 13:48:14 +08:00 |
|
|
|
cc8ffee168
|
docs(affinity-P2): 修改记录与任务清单同步 P2 完成状态
Build and Deploy LTY / build-and-deploy (push) Successful in 8m15s
- qy_lty/docs/修改记录.md 顶部追加 P2 阶段条目:service 层 6 模块 + admin API 7 视图的详细产出物清单 + 跨项目联动注意事项
- docs/好感度系统-开发任务清单.md:
- P2-01 ~ P2-12 状态从 ⬜ 改为 ✅,每条补充实际产出物路径与验证标准
- 变更记录加 P2 完成条目,记录 6 项 smoke test 全 PASS 与下一步 P3 指引
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-05-14 09:36:20 +08:00 |
|
|
|
7c79b72544
|
feat(affinity-P2): admin API — Rule/Level CRUD + Setting + Logs + Stats + Devices + Adjust (P2-06~P2-12)
新增 admin 管理端完整 API,挂载在 /api/v1/admin/affinity/ 路径下:
- serializers.py:9 个序列化器
- AffinityRuleSerializer / AffinityLevelSerializer / AffinitySettingSerializer
含跨字段 validate(min/max 关系、区间重叠、衰减区间、companion_time 字段必填等)
- AffinityLogSerializer 只读 + 关联字段展开(user_username/device_code/rule_name)
- UserDeviceAffinitySerializer 含 device_code/mac/status/level_name
- AffinityAdjust + AffinityAdjustBatch 用 Serializer 而非 ModelSerializer
- permissions.py 中 IsAdminUserStaff 复用,所有 view 默认 RedisTokenAuthentication + IsAdminUserStaff
- views.py:7 个视图
- AffinityRuleAdminViewSet (P2-06):ModelViewSet + 软删 (is_deleted+is_enabled=False) + restore action;?include_deleted=true 返回全集
- AffinityLevelAdminViewSet (P2-07):同上软删;serializer 跨字段校验区间重叠
- AffinitySettingView (P2-08):APIView 单例 GET/PUT/PATCH;pk=1 硬约束
- AffinityLogListView (P2-09):过滤 user_id/device_id/rule_key/source/date_from/date_to;分页 page_size 上限 200;select_related 防 N+1
- AffinityStatsView (P2-10):avg/max/top_count/active_7d/total_devices/today_interactions/today_change_sum/rule_freq_top/level_distribution;全部基于 UserDevice.active 聚合;今日按 AffinitySetting.timezone 取 local date
- UserAffinityDevicesView (P2-11):?user_id= 必传 + 404 校验;?include_unbound=true 含历史;默认仅 is_bound=True
- AffinityAdjustView + AffinityAdjustBatchView (P2-12):委托 AffinityService.admin_adjust;批量遍历 UserDevice.active 逐台调用,返回 per-device 结果数组
- urls.py:DRF DefaultRouter 注册 rules/levels CRUD + 5 个独立 path 挂 settings/logs/stats/devices/adjust*
- admin_urls.py:引入 include 并新增 path('affinity/', include('userapp.affinity.urls'))
Django check 通过,6 URL reverse 全部解析正确:
/api/v1/admin/affinity/settings/
/api/v1/admin/affinity/logs/
/api/v1/admin/affinity/stats/
/api/v1/admin/affinity/devices/
/api/v1/admin/affinity/adjust/
/api/v1/admin/affinity/adjust-batch/
旧的 /api/user/affinity-rules/ 与 /affinity-levels/ 暂保留兼容,前端切到 admin 后即可清理。
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-05-14 09:36:11 +08:00 |
|
|
|
f26e78c545
|
feat(affinity-P2): service 层落地 — 唯一写入入口 + Redis 计数器 + 等级映射 + 跨级奖励 + WS 推送 (P2-01~P2-05)
新增 6 个模块,把好感度变化的全部副作用收敛到一个调用入口:
- counters.py (P2-02):Redis 三类计数器
- affinity💿{device_id}:{rule_key} 冷却
- affinity:daily:{device_id}:{rule_key}:{YYYYMMDD} 单规则日上限
- affinity:daily:{device_id}:_global:{YYYYMMDD} 全局正向日上限
- 自然日按 AffinitySetting.timezone (Asia/Shanghai 默认) 通过 zoneinfo 计算
- cache.add + cache.incr 实现 set-if-not-exists + atomic-incr 语义,TTL 48h
- event_id 60s 去重防客户端重复上报
- levels.py (P2-03):等级映射
- map_value_to_level / update_device_level / progress_to_next_level
- update_device_level 仅 level 变化时 save(update_fields=['affinity_level'])
- ws.py (P2-05):WebSocket 推送 helper
- 3 类事件 affinity_update / level_up / level_down
- asgiref.async_to_sync 包装 channel_layer.group_send
- 推送故障 fire-and-forget 仅日志记录,不阻塞主流程
- rewards.py (P2-04):跨级奖励发放(A3 方案 B)
- grant_levels(user_device, from_level, to_level) 逐级独立事务
- UserLevelRewardGrant 唯一约束保证幂等(决策 11:衰减回升不补发)
- _dispatch_reward_to_external_systems 是 STUB,P3/P4 接虚拟货币/道具 app 时实现
- services.py (P2-01):AffinityService 主入口
- apply(user_id, device_id, rule_key, source, event_id, metadata, operator_admin_id, reason)
- 10 步流水线 [event_id 去重 → 取规则 → 冷却 → 取 UserDevice.active → 计算 + single_cap 钳位 → 规则日上限 → 全局日上限 → 原子写库 → Redis 累加 → 奖励 → WS 推送]
- admin_adjust 绕过 rule 与冷却,但走 [0, max_affinity] 钳位 + log + 等级缓存 + 奖励 + WS
- 返回 ApplyResult dataclass 含 ApplyOutcome 枚举(applied / noop_no_rule / noop_cooldown / noop_*_daily_cap / noop_event_duplicate / noop_value_boundary / error)
- permissions.py:IsAdminUserStaff 复用 IsAuthenticated + is_staff 检查
Smoke test 6 项全 PASS:no_rule / chat applied / event_id 去重 / 冷却拦截 / admin_adjust / max_affinity 钳位。
AffinityLog 写库 / UserLevelRewardGrant 幂等 / level 缓存更新 均经事务原子保证。
设计依据:docs/好感度系统功能与规则设计.md §4.3 触发流程 + §6 等级规则 + §9 数据契约。
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-05-14 09:35:53 +08:00 |
|
|
|
f66e2dfc86
|
docs(affinity-P1): 归档代码审查报告与修复报告
P1 审查阶段产物补落库(深度审查 + 修复同步过程中漏 commit):
- docs/REVIEW-affinity-P1.md — gsd-code-reviewer 输出,18 项 finding(3 Critical / 9 Warning / 6 Info),含 Cross-Module 调用链分析与 Cross-App FK 一致性表
- docs/REVIEW-affinity-P1-FIX-REPORT.md — gsd-code-fixer 输出,17 FIXED + 1 PARTIAL (WR-008) + 0 SKIPPED 状态明细,对应 4 个修复 commit A/B/C/D 索引
两份报告与 P1 fix commits (33b302c / 9a87f5e / 2a28aa8 / 61e8374) 配套阅读,为 P2 service 层依赖的设计决策 / DB 约束 / 软删语义提供溯源依据。
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-05-14 09:35:31 +08:00 |
|
|
|
61e8374e6a
|
fix(affinity-P1): WR-002~WR-009 + IN-001~IN-006 综合改进收尾
WR-002 UserLevelRewardGrant.device on_delete CASCADE → SET_NULL,加 device_snapshot_id,
unique 改为 partial(device 非空时唯一),与 AffinityLog.device SET_NULL 对齐
WR-003 AffinityLog 删除 3 个低价值索引(user/rule_key/source -created_at 复合)
WR-004 event_id 改为 null=True,partial unique 用 isnull=False;RunPython '' → NULL
WR-005 seed 加 companion_30min 默认规则
WR-006 description 显式 default='';DEFAULT_LEVELS 全部补 description
WR-007 seed_affinity 每条 spec 独立事务,部分失败可重跑
WR-008 ParadiseUser.favorability 字段保留 + UserInfoSerializer 移除暴露 + [DEPRECATED] 标记
WR-009(见 Commit B:AffinityLevel.clean + save full_clean 多层兜底)
IN-001 5 个弃用字段 help_text 加 [DEPRECATED — 计划于 P2 完成后删除]
IN-002 DEFAULT_RULES/LEVELS/SETTING 抽到 userapp/affinity/defaults.py
IN-003 AffinitySetting.daily_cap RenameField → global_daily_cap(区分 AffinityRule.daily_cap)
IN-004 AffinityLog.__str__ 用 pk or 'new' 兜底 None
IN-005(见 Commit A:is_active → is_bound 改名)
IN-006(见 Commit C:0006 print 前缀改为 [migration 0006_...])
迁移 0009 手工修正:daily_cap 改名用 RenameField(保留数据),不是 Remove+Add;
event_id '' → NULL 数据兜底;UserLevelRewardGrant on_delete + conditional unique 重建。
详见 docs/REVIEW-affinity-P1.md WR-* / IN-* 与 FIX-REPORT.md。
|
2026-05-13 10:18:47 +08:00 |
|
|
|
2a28aa8b28
|
fix(affinity-P1): CR-003 修正 0006 数据迁移幂等性
旧 forward 用 target.favorability == 10 判断"未迁移",10 既是初始值也是衰减
常见值,重跑会覆盖合法数据;backward 用 != 10 反向判断会丢衰减回 10 的数据。
改用 AffinityLog source='data_migration' 标记做幂等:
- forward 写入新值时同步写一条 audit log,metadata 含原 ParadiseUser 值
- backward 遍历 audit log 反向恢复并删除标记,保证 forward/backward 可循环
同步:AffinityLog.SOURCE_CHOICES 追加 'data_migration' + 0008 AlterField 迁移
更新 Python 端 choices 校验。
option B 选择:直接重写 0006(dev 已跑过但 migrate_count=0 等于未动数据,
django_migrations 表已记录完成不会再跑)。生产部署前需确认 prod 未跑过 0006,
否则需 fake-reverse 流程,详见迁移文件 docstring 与 FIX-REPORT。
详见 docs/REVIEW-affinity-P1.md CR-003。
|
2026-05-13 10:13:31 +08:00 |
|
|
|
9a87f5e2b5
|
fix(affinity-P1): CR-002 + WR-001 加 Affinity 模型 DB CHECK 约束 + 单例硬约束
AffinityRule / AffinityLevel / AffinitySetting 三表共 13 条 CheckConstraint
覆盖 min ≤ max / 各类 cap > 0 / cooldown ≥ 0 / companion_time 配套字段必填 /
decay 区间合法 / initial ≤ max 等不变量。
AffinitySetting 加 pk=1 单例硬约束(CR-002 + WR-001 联动)+ save() 强制 pk=1,
形成事实单例防御并发首次插入重复行。
模型 clean() 提供 Python 级兜底(给 DRF / admin 友好错误信息);
AffinityLevel.save() 自动 full_clean 触发跨行区间不重叠校验(为 WR-009 铺路)。
详见 docs/REVIEW-affinity-P1.md CR-002 / WR-001。
|
2026-05-13 10:12:01 +08:00 |
|
|
|
33b302c773
|
fix(affinity-P1): CR-001 + IN-005 修复 UserDevice 软删语义 + is_bound 改名
UserDevice.is_active 改名为 is_bound(消除与 Device.is_active 的命名冲突),
新增 ActiveUserDeviceManager(active manager),4 处控制权解析调用点
(MAC 登录、bind_status、绑定校验、RTC token、绑定 endpoint)切换到
UserDevice.active.filter(...),避免 P2 软删后旧绑定者被签发 user-token、
WS 分组路由错误、RTC 房间归属错乱等安全 / 越权风险。
base_manager_name='objects' 保证 admin 默认 queryset 不受 active 过滤影响。
详见 docs/REVIEW-affinity-P1.md CR-001 / IN-005。
|
2026-05-13 10:10:14 +08:00 |
|
|
|
c0db8560c9
|
docs(03-03): 完成「Milestone v1.0 收尾」plan
Build and Deploy LTY / build-and-deploy (push) Successful in 9m39s
- 03-03-SUMMARY.md 落地:Phase 3 收尾 plan + Milestone v1.0 收尾态确认(5 条 ROADMAP success criteria + 11 条需求 100% 交付)
- STATE.md:milestone status → completed,progress 100%(3/3 phase + 7/7 plan),决策段补 Plan 03-03 落地详情,会话连续性 + 下一步行动切到候选下一周期 milestone
- ROADMAP.md:Phase 3 ✅ Complete(3/3 plan),Milestones 段 v1.0 ✅ 100% 交付
- REQUIREMENTS.md:CRED-FE-04 + CRED-FE-05 已勾选完成(Plan 03-02 已落地),更新条目记录 Plan 03-03 落地
Plan 级整体双重验证 4 段全过:
- A 段 tsc 反向断言:整体 67 条存量错误(与 Phase 1+2 持平)+ 反向断言对 3 个改动文件(layout.tsx / credential-slot-dialog.tsx / page.tsx)0 行命中
- B 段 grep specifics 全表:13 条 specifics + 2 条 Layout Toaster + 2 条反向防回归全部命中
- C 段 lockfile diff:4 个 manifest+lockfile 工作区 0 行 diff + Phase 3 全程(069c01d → HEAD)累计 0 行 diff
- D 段 lint:沿用 Phase 1+2 跳过判定(项目无 .eslintrc* / eslint-config-next)
3 处 Rule 3 环境兼容偏差(PowerShell ExecutionPolicy → npx.cmd / 正则 \l 警告 → [\\/] 字符类 / lockfile diff 锚点 HEAD~3 → 7065d73^ 更精确)已记入 SUMMARY,结论与 PLAN 期望一致
Milestone v1.0「通用凭据槽位前端集成」100% 交付:3/3 phase + 7/7 plan + 11/11 需求(CRED-01~06 后端 + CRED-FE-01~05 前端)+ 5/5 ROADMAP success criteria 全部确认通过
CLAUDE.md L70-94 修改记录强制规则闭环:Phase 1 / Phase 2 / Phase 3 三条 [2026-05-08] 条目按时间倒序排列在 docs/修改记录.md 顶部
|
2026-05-08 12:47:43 +08:00 |
|
|
|
892b0b10da
|
docs(03-03): docs/修改记录.md 顶部追加 Phase 3 条目
- 在 L26 注释之后、L28 Phase 2 条目之前插入 [2026-05-08] Phase 3 完整条目
- 条目按 CLAUDE.md L72-82 4 字段格式(文件路径 / 修改类型 / 修改内容 / 修改原因)+ 跨项目联动 + 服务端联动
- 列出 3 个改动文件(app/layout.tsx + components/ai-model/credential-slot-dialog.tsx + app/ai-model/page.tsx)
- 修改原因段显式说明 access_token 强制输入语义的业务权衡 + 候选下一周期 milestone 锚点(识别脱敏掩码保留旧值)
- 跨项目联动 + 服务端联动字段使用 CONTEXT.md / 上下文锁定的中文文本
- 覆盖 CRED-FE-04 + CRED-FE-05
- CLAUDE.md L70-94 修改记录强制规则闭环
|
2026-05-08 12:40:16 +08:00 |
|
|
|
89cd768765
|
docs(03-02): 完成「编辑对话框组件落地 + 页面接入」plan
- 新建 .planning/phases/03-dialog-feedback/03-02-SUMMARY.md(Plan 03-02 收尾归档)
- 更新 STATE.md:Phase 3 进度 1/3 → 2/3(67%),milestone 进度 71% → 86%(6/7 plan)
- 更新 ROADMAP.md:Plan 03-02 标记完成(commits d719891 + 7872840)
- 更新 REQUIREMENTS.md:CRED-FE-04 + CRED-FE-05 切到 ✅ Done
- 业务功能完整闭环(CredentialSlotDialog 191 行 RHF+Zod+Sonner+handleApiError + page 接入);等待 Plan 03-03 收尾(修改记录追加 + plan 级双重验证)
|
2026-05-08 12:36:56 +08:00 |
|
|
|
7872840db7
|
feat(03-02): /ai-model 页面接入 CredentialSlotDialog 组件
- 删除 L9-15 Dialog 系列命名导入(占位 Dialog 删后 page 不再直接使用 Dialog primitive)
- 新增 import { CredentialSlotDialog } from "@/components/ai-model/credential-slot-dialog"
- 删除 L473-485 占位 Dialog(含「对话框真实内容由 Phase 3 落地」字面量)
- 替换为 <CredentialSlotDialog open onOpenChange />,复用既有 isCredentialDialogOpen state
- 保留 mounted && hasPermission("credential-slot") 守卫 + Button 入口(Phase 2 已落地)
- CRED-FE-04 + CRED-FE-05 端到端串联,Milestone v1.0 收尾就绪
|
2026-05-08 12:32:29 +08:00 |
|
|
|
d719891754
|
feat(03-02): 新建 CredentialSlotDialog 组件 (RHF + Zod + Sonner + handleApiError)
- 新增 components/ai-model/credential-slot-dialog.tsx(kebab-case,191 行)
- RHF + Zod schema:appId / accessToken 强制非空(CONTEXT D-提交逻辑 锁定)
- 打开时 useEffect 调 getCredentialSlot 拉数据 + reset 表单(accessToken 永远空串)
- placeholder 用 slot.accessTokenMasked(仅视觉提示,不回填脱敏掩码)
- 提交成功 toast.success + 自动关闭;失败 toast.error + 对话框保持打开 + 表单值不丢
- 错误经 handleApiError(lib/api/error-handler.ts,不走 barrel)映射为中文
- 落地 CRED-FE-04 + CRED-FE-05 主体
|
2026-05-08 12:31:59 +08:00 |
|
|
|
28bc2a7251
|
docs(03-01): 完成「RootLayout 挂载 Sonner Toaster」plan
- 新增 .planning/phases/03-dialog-feedback/03-01-SUMMARY.md(plan 完成总结)
- STATE.md 更新:Phase 3 进度 1/3,milestone 整体 71%(5/7 plan)
- ROADMAP.md 更新:Plan 03-01 标记完成(commit 7065d73),Phase 3 进度 1/3
- REQUIREMENTS.md 更新:CRED-FE-05 反馈通道前置打通(完整闭环依赖 03-02)
任务原子提交:feat 7065d73(app/layout.tsx)
|
2026-05-08 12:29:49 +08:00 |
|
|
|
7065d73666
|
feat(03-01): 在 RootLayout 挂载 Sonner Toaster
- app/layout.tsx 新增 import { Toaster } from '@/components/ui/sonner'
- <body> 内 {children} 之后渲染 <Toaster />
- 修复仓库 9 处 toast 调用静默失败的 pre-existing dead code 问题
- Phase 3 业务功能 (toast 反馈) 的硬前置
|
2026-05-08 12:25:59 +08:00 |
|
|
|
069c01d3ae
|
docs(03): STATE 切到 Phase 3 Ready to execute(3 plans,Milestone v1.0 收尾)
|
2026-05-08 12:24:42 +08:00 |
|
|
|
b27be2508f
|
docs(03): qy-lty-admin Phase 3 PLAN ×3(03-01 Toaster 挂载 / 03-02 对话框组件 + page 替换 / 03-03 修改记录 + 双重验证),plan-checker 一遍过
|
2026-05-08 12:24:41 +08:00 |
|
|
|
1068c77075
|
docs(03): 据 researcher 实测修正 CONTEXT.md(Sonner Toaster 未挂载关键 bug + kebab-case 命名 + 直接 import sonner toast + 显式 import handleApiError)
|
2026-05-08 12:13:36 +08:00 |
|
|
|
c21a16af5c
|
docs(phase-3): 调研 Phase 3 编辑对话框 + 提交反馈
|
2026-05-08 12:12:33 +08:00 |
|
|
|
814f49372b
|
docs(03): qy-lty-admin Phase 3 CONTEXT.md(编辑对话框 + 反馈 PRD 快速通道,--skip-ui,含留空保留旧值无法实现的权衡说明)
|
2026-05-08 12:05:49 +08:00 |
|
|
|
3945ab646e
|
docs(02): qy-lty-admin Phase 2 VERIFICATION(11/11 must-haves PASSED)
|
2026-05-08 11:59:48 +08:00 |
|
|
|
cf1a777033
|
docs(02-02): 完成 Phase 2 Plan 02-02(修改记录追加 + plan 级双重验证)
- 新增 .planning/phases/02-rbac-ai/02-02-SUMMARY.md(含 7 字段条目结构记录 + 4 大类验证结果汇总 + 偏离 PLAN 记录)
- 更新 STATE.md:Phase 2 由 进行中 切到 已交付(5/5 plan);milestone 进度 67%;下一步 /gsd-plan-phase 3
- 更新 ROADMAP.md:Phase 2 行 ✅ Complete;02-02-PLAN.md 行勾选;Plans Complete 列 2/2
- 更新 REQUIREMENTS.md:尾部追加 Plan 02-02 落地会话日志
- Phase 2 5 条 success criteria 全部确认通过;CRED-FE-02 + CRED-FE-03 闭环
- 验证 A:tsc 整体 67 条存量错误 + 反向断言 0 条指向本 phase 改动文件
- 验证 B:14 条 grep 全命中(11 specifics + 4 反向断言;原 PLAN awk 在 Windows Bash 失败 → 替换为 sed 行号区间方案)
- 验证 C:4 个 manifest+lockfile 工作区 + HEAD~1 比较均 0 行 diff
- 验证 D:next lint 因项目无 .eslintrc* 跳过沿用 Phase 1 判定
|
2026-05-08 11:56:26 +08:00 |
|
|
|
2be1f1d505
|
docs(02-02): docs/修改记录.md 顶部追加 Phase 2 条目
- 在 line 26 锚点注释之后、Phase 1 条目之前插入 [2026-05-08] Phase 2 条目
- 完整 7 字段结构:元信息行(配套服务端 Phase + 覆盖前端需求 CRED-FE-02/03)+ 文件路径 + 修改类型 + 修改内容 + 修改原因 + 跨项目联动 + 服务端联动
- 跨项目联动字段逐字与 02-CONTEXT.md 锁定一致(无新跨项目契约 / 后端 46d72b8 互引仍有效 / Phase 3 再评估)
- 纯追加 +32 行,0 删除,line 1-26 头部完全不变
- Phase 1 及更早历史条目逐字未动
|
2026-05-08 11:50:13 +08:00 |
|
|
|
15e725a32f
|
docs(02-01): 完成 Phase 2 Plan 02-01(RBAC 扩展 + /ai-model 凭据槽位入口)
- 新增 .planning/phases/02-rbac-ai/02-01-SUMMARY.md(含 frontmatter / 任务详情 / 验证结果 / Self-Check PASSED)
- STATE.md:进度 50% → 75%,已完成 plan 2 → 3,Phase 2 状态切到 In progress(1/2 plan)
- ROADMAP.md:Phase 2 Plans Complete 0/2 → 1/2,状态 Not started → In progress;Plan 02-01 勾选完成
- REQUIREMENTS.md:CRED-FE-02 + CRED-FE-03 状态切到 ✅ Done,Active 段两条 unchecked → checked
|
2026-05-08 11:47:59 +08:00 |
|
|
|
0bcaa398cc
|
feat(02-01): /ai-model 页面新增凭据槽位入口 Button + 占位 Dialog
- 文件转为 Client Component(line 1 加 'use client')
- 新增 import:useState/useEffect (react)、Dialog 子组件 5 个、KeyRound (lucide-react)、hasPermission (@/lib/permissions)
- 函数体顶部加 mounted 守卫 + isCredentialDialogOpen 两个 useState(复用 sidebar.tsx 同模式避免 SSR 水合警告)
- DashboardHeader children 改为 flex 容器,包含原「添加新模型」+ 新增「凭据槽位」(variant=outline)
- 凭据槽位 Button 由 mounted && hasPermission('credential-slot') 收敛,未授权角色 DOM 中完全不存在
- </Tabs> 之后插入 controlled mode 占位 Dialog,DialogTitle「通用凭据槽位」+ DialogDescription 提示由 Phase 3 落地
- Tabs / TabsContent / Card 等所有原有内容(line 18-441)逐字未动
|
2026-05-08 11:44:07 +08:00 |
|
|
|
d60dd897c7
|
feat(02-01): 扩展 RBAC 矩阵增加 credential-slot 模块
- PermissionModule union 末尾追加 'credential-slot' 字面量(共 14 项)
- 超级管理员 / AI模型管理员 两角色数组末尾追加 'credential-slot'
- 顶部权限矩阵注释表新增「凭据槽位」行
- 其他 4 角色(内容管理员/卡牌管理员/查看者/管理员)数组逐字不变
- getModuleFromPath 不动(凭据槽位是 /ai-model 子能力,无独立路由)
|
2026-05-08 11:43:14 +08:00 |
|
|
|
3097f15f6c
|
docs(02): qy-lty-admin STATE 切到 Phase 2 Ready to execute
|
2026-05-08 11:41:45 +08:00 |
|
|
|
d4a404eb1b
|
docs(02): qy-lty-admin Phase 2 PLAN ×2(02-01 RBAC + 入口控件 / 02-02 修改记录 + 类型检查),plan-checker 一遍过
|
2026-05-08 11:41:45 +08:00 |
|
|
|
d396249aef
|
docs(02): qy-lty-admin Phase 2 RESEARCH(permissions.ts 矩阵 + ai-model/page.tsx 插入点 + KeyRound 首引)
|
2026-05-08 11:41:45 +08:00 |
|
|
|
c62b9c50d8
|
docs(02): qy-lty-admin Phase 2 CONTEXT.md(RBAC + 入口控件 PRD 快速通道,--skip-ui)
|
2026-05-08 11:24:31 +08:00 |
|
|
|
ba9782313f
|
docs(01-02): 完成 Phase 1 Plan 01-02『修改记录追加 + 双重验证』收尾
- 新增 .planning/phases/01-credential-slot-api/01-02-SUMMARY.md(Plan 01-02 执行总结)
- Task 1:docs/修改记录.md 顶部追加 [2026-05-08] Phase 1 条目(commit c1743a3)
- Task 2:npx tsc --noEmit 在新增/修改文件零类型错误(67 条存量错误与本 phase 无关,记录为信息债);
npm run lint 因项目无 ESLint 配置(next lint 进入交互式 prompt)—
按 PLAN 自动 verify 规则判定通过(不指向新增/修改文件);
临时探针 lib/api/__phase1_probe__.ts 验证 barrel 入口可解析后已删除
- 偏差:项目 ESLint 基础设施缺失(pre-existing),按用户硬约束不动 lockfile 不修复,
留给 PERM-06 候选 #3 跟踪
- 更新 STATE.md:Phase 1 状态切到 ✅ 已交付(2/2 plan,进度 100%);
下一步行动 = /gsd-plan-phase 2 启动 Phase 2「RBAC 收敛 + AI 模型页入口」
- 更新 ROADMAP.md:Phase 1 ✅ Complete(2026-05-08);Plan 01-02 勾选 [x]
- 更新 REQUIREMENTS.md Traceability:CRED-FE-01 标注 Plan 01-02 commit c1743a3 + Phase 1 已封盘
Self-check: PASSED(文件、commit、探针删除、关键字命中、lockfile 零漂移 全部 ✓)
|
2026-05-08 11:15:47 +08:00 |
|
|
|
c1743a3369
|
docs(01-02): 修改记录顶部追加 Phase 1 凭据槽位 API 客户端条目
- docs/修改记录.md 顶部插入 [2026-05-08] Phase 1(前端)凭据槽位 API 客户端
- 含『配套服务端 Phase』『覆盖前端需求 CRED-FE-01』前置元数据
- 跨项目联动字段:无 — 后端 commit 46d72b8 已建立互引;Phase 1 不引入新跨项目代码契约
- 现有 [2026-05-07] Phase 2 条目内容不变、位置后移
- 关键字命中:CRED-FE-01 / 46d72b8 / accessTokenMasked / accessToken / lib/api/credential-slot.ts / lib/api/index.ts / /v1/admin/credential-slot/ / 无需再次互引
|
2026-05-08 11:09:06 +08:00 |
|
|
|
ce0df098be
|
docs(01-01): 完成 Phase 1 Plan 01-01「凭据槽位 API 客户端」收尾
- 新增 01-01-SUMMARY.md:记录 Task 1/2 commits、关键串命中、字节产物对比、Self-Check PASSED
- STATE.md:当前位置切到 'Plan 01-01 完成 / 01-02 待执行',进度 50%(Phase 1 内部 1/2 plan),新增 Plan 执行记录表 + 2026-05-08 关键决策
- ROADMAP.md:Phase 1 进度 0/2 → 1/2,状态 Not started → In Progress
- REQUIREMENTS.md:CRED-FE-01 Active 段已勾选 [x];Traceability 状态切到 ✅ Done(commits a0d0b9c + c072bbe)
Plan 01-01 父仓库 commits:a0d0b9c (lib/api/credential-slot.ts) + c072bbe (lib/api/index.ts)
|
2026-05-08 11:06:42 +08:00 |
|
|
|
c072bbec8c
|
feat(01-01): lib/api/index.ts 末尾追加凭据槽位具名 re-export
- 在 handleApiError 之后追加 7 行具名 re-export 块
- 暴露 4 个公共符号:getCredentialSlot / updateCredentialSlot / CredentialSlot / CredentialSlotUpdatePayload
- 路径相对 './credential-slot',与现有 export * from './card' 等风格在同文件混用合法
- 现有 export */usersApi/rolesApi/handleApiError 完全不变
|
2026-05-08 11:03:08 +08:00 |
|
|
|
a0d0b9c1ad
|
feat(01-01): 新建 lib/api/credential-slot.ts 凭据槽位 API 客户端
- 类型 CredentialSlot { appId, accessTokenMasked, updatedAt }(脱敏掩码语义命名)
- 类型 CredentialSlotUpdatePayload { appId, accessToken }(明文语义命名)
- 内部接口 BackendCredentialSlot(snake_case,不导出)
- adapter mapBackendCredentialSlot 把 snake → camel
- getCredentialSlot() 走 apiClient.get '/v1/admin/credential-slot/'
- updateCredentialSlot(payload) 走 apiClient.put '/v1/admin/credential-slot/',body 仅 { app_id, access_token } 不带 updated_at
- GET / PUT 各含一次 response.data?.data || response.data 双保险解包
- 1:1 复刻 lib/api/ai-models.ts 风格
|
2026-05-08 11:02:35 +08:00 |
|
|
|
7d7fc2867d
|
docs(01): qy-lty-admin STATE.md 切到 Phase 1 Ready to execute
|
2026-05-08 11:00:37 +08:00 |
|
|
|
6e74e74263
|
docs(01): qy-lty-admin Phase 1 PLAN ×2(01-01 lib/api/credential-slot.ts / 01-02 修改记录 + 双重验证),plan-checker 一遍过
|
2026-05-08 11:00:35 +08:00 |
|
|
|
a3d71f4d08
|
docs(01): qy-lty-admin Phase 1 RESEARCH.md(拦截器不解包 + ai-models.ts 1:1 模板 + npm run lint 仅 ESLint)
|
2026-05-08 11:00:32 +08:00 |
|
|
|
c012b56573
|
docs(01): 据 researcher 实测修正 CONTEXT.md(拦截器不解包 + npm run lint 仅 ESLint + PUT body 不带 updated_at)
|
2026-05-08 10:51:27 +08:00 |
|
|
|
9aa29877e9
|
docs(01): qy-lty-admin Phase 1 CONTEXT.md(API 客户端 PRD 快速通道)
|
2026-05-08 10:44:06 +08:00 |
|
|
|
9965d0bcf0
|
docs(03-02): 完成 Phase 3 Plan 03-02 + Milestone v1.0 收尾
- 03-02-SUMMARY.md 新建: AccessTokenMaskFilter + LOGGING + 修改记录条目落地, 9 truth × 32 项断言全 PASS, 2 处 Rule 1 auto-fix bug 文档化
- STATE.md 更新: 进度 100%, Phase 3 标记 Complete, Milestone v1.0 收尾, 决策日志补 [Plan 03-02] 7 条
- ROADMAP.md 更新: Milestone v1.0 标 ✅ 完结, Phase 3 / Plan 03-01+03-02 全部 ✓
- REQUIREMENTS.md 更新: CRED-06 标记 Done, traceability 表 Phase 3 行 Done, 覆盖率 6/6 全 Done
Milestone v1.0「通用凭据槽位 (APP ID + Access Token)」CRED-01 至 CRED-06 全部交付完成。
|
2026-05-08 10:36:17 +08:00 |
|
|
|
db4d5cf89d
|
docs(03-02): docs/修改记录.md 顶部追加 Phase 3 条目 (CRED-05 + CRED-06)
- 5 处文件改动汇总: aiapp/views.py + qy_lty/urls.py + common/logging/__init__.py + common/logging/filters.py + qy_lty/settings.py
- 修改类型: 新增
- 修改内容: 客户端 GET 接口明文返回 + AccessTokenMaskFilter 4 正则脱敏 + LOGGING 注册
- 修改原因: Milestone v1.0 收尾 phase, 客户端读取 + 日志防御性兜底
- 跨项目联动: 无 — 客户端给 Unity (LTY_Project / LTY_App_Project_URP) 用, 那两个 repo 各自维护; qy-lty-admin 不消费此接口
- qy-lty-admin/docs/修改记录.md mtime 验证未变, 不写互引
|
2026-05-08 10:30:14 +08:00 |
|
|
|
7a9e511132
|
test(03-02): Phase 3 端到端验收报告 (CRED-05 + CRED-06)
- 9 truth × 32 项独立断言全 PASS, FAIL = 0
- T1-T5: 客户端 GET 5 项 (user/admin token + 401 + swagger schema)
- T6: filter 4 种正则形态 (JSON/Pyrepr/Query/Fallback)
- T7: 不误伤 Authorization / Bearer 字段
- T8: admin PUT roundtrip + admin GET 脱敏 + client GET 明文
- T9: 端到端 logger.info 真打印 console 输出脱敏
- T_FINAL: DB 探针态还原 (probe_app/probe_secret_xxxx)
- 临时脚本均已删除 (_phase3_01_verify / _phase3_02_unit_test / _phase3_02_verify / _phase3_02_settings_check)
|
2026-05-08 10:28:26 +08:00 |
|
|
|
35eb11091f
|
feat(03-02): qy_lty/settings.py LOGGING 注册 access_token_mask filter
- 新增 LOGGING.filters 段,用 dictConfig 工厂语法 "()" 引用 AccessTokenMaskFilter
- LOGGING.handlers.aliyun 与 LOGGING.handlers.console 各加 filters: ['access_token_mask']
- loggers 段 5 条 logger 完全未动 (django / django.request / aiapp / common / userapp)
- Django setup() 不报 ValueError;端到端 logger.info('access_token=...') 输出脱敏 (***...ABCD)
|
2026-05-08 10:26:13 +08:00 |
|
|
|
891a5ead7c
|
feat(03-02): 新建 common/logging/ 包 + AccessTokenMaskFilter
- common/logging/__init__.py 空文件 (package marker)
- common/logging/filters.py 含 AccessTokenMaskFilter(logging.Filter)
- 4 个正则模式:JSON / Python dict repr / URL query / 等号或冒号兜底
- 调 common.utils.mask_token 替换捕获组,保留末 4 位明文
- 兼容 logger.info('...%s...', value) tuple args 形态
- 不误伤 Authorization header / Bearer 字段(field-name 锚点)
- filter() 永远 return True 不丢弃 record
|
2026-05-08 10:25:01 +08:00 |
|
|
|
a58980fd73
|
docs(03-01): 完成 Phase 3 Plan 01 — CRED-05 客户端 GET 接口落地
- 新增 03-01-SUMMARY.md:4.5 min × 3 task / 2 commit / 2 修改文件 / 6 truth × 15 断言全 PASS
- STATE.md 切到 Phase 3 In Progress(5/6 plan complete,83%),决策段累积 5 条 [Plan 03-01] 决策
- ROADMAP.md 更新 Phase 3 进度(1/2 plan complete)
- REQUIREMENTS.md 标记 CRED-05 → Done
- 3 处 deviations 全 auto-fixed(Rule 1 docstring 字面量误报 / Rule 3 Windows shell 行级 REPL / Rule 3 GBK 编码);plan acceptance criteria 全部达成
Hand-off to Plan 03-02:DB 探针态保持 / _phase3_01_verify.py 留仓库根待删除 / 不写 docs/修改记录.md(由 03-02 Task 4 一并写)
|
2026-05-08 10:20:13 +08:00 |
|
|
|
50dcf1c8e2
|
feat(03-01): 在 qy_lty/urls.py 注册 /api/credential-slot/ 路由
- imports 段追加 from aiapp.views import CredentialSlotClientView
- api_urlpatterns 列表在 common/upload/ 与 v1/admin/ 之间插入新路由
path('credential-slot/', CredentialSlotClientView.as_view(), name='client_credential_slot')
- 最终 URL: /api/credential-slot/(顶层 api_urlpatterns,非任何 sub-include)
- resolve('/api/credential-slot/') 返回 CredentialSlotClientView,反向解析返回 /api/credential-slot/
- python manage.py check 通过(仅遗留 staticfiles.W004 与本 plan 无关)
CRED-05 落地步骤 2/3
|
2026-05-08 10:14:04 +08:00 |
|
|
|
5269a08118
|
feat(03-01): 在 aiapp/views.py 末尾追加 CredentialSlotClientView 类
- 新增 _credential_slot_client_data_schema:客户端响应 schema,access_token description 标注「明文」
- 新增 CredentialSlotClientView(APIView):仅 GET,user/admin token 鉴权(RedisTokenAuthentication + IsAuthenticated)
- 关键差异(vs Phase 2 admin view):不调 _ensure_admin / 不调 _build_response_data / 不调 mask_token / 不含 def put
- 直接 success_response(data=serializer.data) 明文返回,供手机/设备端实际调用第三方服务
- imports 段未变(Phase 2 已就位 CredentialSlot/CredentialSlotSerializer/RedisTokenAuthentication 等)
CRED-05 落地步骤 1/3
|
2026-05-08 10:13:07 +08:00 |
|
|
|
ad9580dd11
|
docs(03): STATE.md 切到 Phase 3 Ready to execute
|
2026-05-08 10:10:11 +08:00 |
|