Files
eryao/.trellis/workspace/zl-q/journal-1.md
T
2026-04-15 18:19:25 +08:00

446 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Journal - zl-q (Part 1)
> AI development session journal
> Started: 2026-04-10
---
## Session 1: 实现站内通知系统
**Date**: 2026-04-10
**Task**: 实现站内通知系统
### Summary
(Add summary)
### Main Changes
## 完成内容
| 模块 | 描述 |
|------|------|
| 协议文档 | `docs/protocols/notification/notification-inbox-protocol.md``http-error-codes.md` 新增 `NOTIFICATION_NOT_FOUND` |
| 数据库迁移 | `notifications` + `user_notifications` 两张表, RLS 策略, 索引 |
| 后端 ORM | `Notification(TimestampMixin, SoftDeleteMixin, Base)` + `UserNotification(TimestampMixin, Base)` |
| 后端 API | schema/repository/service/router 全套, 4 个端点 (列表/未读数/单条已读/全部已读) |
| 后端测试 | 19 个单元测试覆盖: 列表权限隔离, 未读数统计, 幂等已读, 越权拒绝, 撤销/删除过滤, payload 解析 |
| Flutter models | `NotificationPayload` sealed class (none/open_route/open_url) + `NotificationItem` + `NotificationListResult` |
| Flutter API | `NotificationApi` (list/unreadCount/markRead/markAllRead) |
| Flutter Repository | 抽象接口 + `NotificationRepositoryImpl` |
| Flutter Bloc | `NotificationBloc` (ChangeNotifier) 含 Realtime 事件处理 |
| Flutter UI | `NotificationCenterScreen` + `NotificationListItem` + 首页 badge 集成 |
| Flutter 测试 | 14 个测试: payload 解析 6 个 + bloc 状态管理 8 个 |
## 验收标准对照
- [x] 能为指定用户写入一条站内通知 (ORM + migration 就绪)
- [x] 用户能看到自己的通知列表 (GET /notifications)
- [x] 用户点击通知后可标记为已读 (PATCH /notifications/{id}/read)
- [x] "全部已读"后未读数归零 (PATCH /notifications/mark-all-read)
- [x] 用户 A 不能读取或修改用户 B 的通知 (service 层 user_id 来自 JWT, 测试覆盖)
- [x] 已读接口重复调用不会报错 (幂等实现, 测试覆盖)
- [x] 首页 badge 会随未读数自动更新 (NotificationBloc + ListenableBuilder)
- [x] 撤销或统一删除主通知后, 用户侧列表不再展示 (repository 过滤 status+deleted_at)
### Git Commits
| Hash | Message |
|------|---------|
| `3f3d613` | (see git log) |
### Testing
- [OK] (Add test results)
### Status
[OK] **Completed**
### Next Steps
- None - task complete
## Session 2: 静态通知同步 + 积分审计 bug 修复
**Date**: 2026-04-10
**Task**: 静态通知同步 + 积分审计 bug 修复
### Summary
(Add summary)
### Main Changes
## 完成内容
| 功能 | 说明 |
|------|------|
| 静态通知 Pydantic Schema | `static_schema.py` — 含 `deleted` 字段支持显式软删除 |
| 静态通知同步逻辑 | `static_sync.py` — 创建、更新、撤销、软删除、prune、reconcile-targets |
| CLI 命令 | `sync-notifications` 支持 `--path/--source-key/--dry-run/--prune/--reconcile-targets` |
| 数据库迁移 | 新增 `source/source_key/source_version/content_hash` 字段 |
| 示例通知 | `welcome_points.yaml` |
| 触发脚本 | `infra/scripts/register-notifications.sh` |
| 协议文档 | `static-notification-sync-protocol.md` |
| Bug 修复 | `AuditLedgerMetadata` 未序列化直接写 JSONB → `.model_dump(mode="json")` |
| 单测 | 28 passed`test_static_notification_sync.py``test_notification_service.py` |
| 冒烟验证 | 注册→通知→未读数→reconcile-targets→prune 全链路通过 |
**未完成**:
- `notification_updated` Realtime 事件链路
- Flutter 端通知中心页面、badge、Realtime 订阅
**新增文件**:
- `backend/src/core/config/notification/__init__.py`
- `backend/src/core/config/notification/static_schema.py`
- `backend/src/core/config/notification/static_sync.py`
- `backend/src/core/config/static/notification/notifications/welcome_points.yaml`
- `backend/alembic/versions/20260411_0005_add_notification_static_sync_fields.py`
- `backend/tests/unit/test_static_notification_sync.py`
- `docs/protocols/notification/static-notification-sync-protocol.md`
- `infra/scripts/register-notifications.sh`
**修改文件**:
- `backend/src/core/runtime/cli.py`
- `backend/src/models/notification.py`
- `backend/src/v1/points/repository.py`
- `docs/plans/static-notification-sync-plan.md`
### Git Commits
| Hash | Message |
|------|---------|
| `3f3d613` | (see git log) |
### Testing
- [OK] (Add test results)
### Status
[OK] **Completed**
### Next Steps
- None - task complete
## Session 3: 积分重注册余额恢复验证
**Date**: 2026-04-13
**Task**: 积分重注册余额恢复验证
### Summary
完成 register_bonus_claims 快照方案的本地迁移与集成测试验证,确认删除账号后重注册可恢复删除前积分余额。
### Main Changes
| Feature | Description |
|---------|-------------|
| DB Migration | 通过 `dev-migrate.sh migrate` 应用 `20260413_0004_register_bonus_claims_snapshot`,新增 `first_user_id_snapshot``balance_snapshot`,移除 `first_user_id`。 |
| Restore Logic | 注册流程优先读取 `balance_snapshot` 恢复余额;删除账号前写入当前余额快照。 |
| Integration Tests | 新增未消费删号重注册恢复场景,并更新已有消费后删号重注册断言。 |
**Updated Files**:
- `backend/alembic/versions/20260413_0004_register_bonus_claims_snapshot.py`
- `backend/src/models/register_bonus_claims.py`
- `backend/src/v1/points/repository.py`
- `backend/src/v1/points/service.py`
- `backend/src/v1/users/service.py`
- `backend/tests/integration/test_register_run_delete_reregister.py`
- `backend/tests/unit/test_points_service_audit.py`
- `docs/protocols/common/user-points-chat-data-protocol.md`
**Verification**:
- `uv run pytest backend/tests/unit/test_points_service_audit.py` -> 5 passed
- `uv run pytest backend/tests/integration/test_register_run_delete_reregister.py` -> 2 passed
- Supabase MCP 查询确认 `register_bonus_claims.balance_snapshot` 已写入并与测试行为一致。
### Git Commits
(No commits - planning session)
### Testing
- [OK] (Add test results)
### Status
[OK] **Completed**
### Next Steps
- None - task complete
## Session 4: 绑定积分重注册余额恢复提交
**Date**: 2026-04-13
**Task**: 绑定积分重注册余额恢复提交
### Summary
将删除账号后重注册积分余额恢复 feature 的代码提交与 session 记录绑定。
### Main Changes
| Item | Details |
|------|---------|
| Feature Commit | `c55be6d` |
| Scope | register_bonus_claims 快照字段、删号前余额快照、重注册余额恢复、相关测试与协议更新 |
**Validation**:
- pre-commit hooks passed during commit
- integration: `backend/tests/integration/test_register_run_delete_reregister.py` passed (`2 passed`)
### Git Commits
| Hash | Message |
|------|---------|
| `c55be6d` | (see git log) |
### Testing
- [OK] (Add test results)
### Status
[OK] **Completed**
### Next Steps
- None - task complete
## Session 5: feat: 邀请码显示功能 - 后端API + 前端对接
**Date**: 2026-04-13
**Task**: feat: 邀请码显示功能 - 后端API + 前端对接
### Summary
(Add summary)
### Main Changes
## Backend 新增 (src/v1/invite/)
| 文件 | 描述 |
|------|------|
| schemas.py | `MyInviteCodeResponse` (code, used_count) |
| repository.py | `InviteCodeRepository.get_by_owner_id()` |
| service.py | `InviteCodeService.get_my_invite_code()` |
| dependencies.py | 依赖注入 |
| router.py | `GET /api/v1/invite/me` |
修改: `src/v1/router.py` - 注册 invite_router
## Frontend 新增/修改 (apps/lib/features/settings/)
新增:
- `data/models/my_invite_code.dart` - `MyInviteCode` 数据模型
- `data/apis/invite_api.dart` - API 调用
- `data/repositories/invite_repository.dart` - Repository 封装
修改:
- `invite_screen.dart` - 移除 mock 数据,改为调用真实 API,增加 loading/error 状态
- `settings_screen.dart` - 接收 `InviteRepository` 参数
- `home_screen.dart` - 创建并传递 `InviteRepository` 实例
**验证**: ruff check ✅ / flutter analyze ✅
### Git Commits
(No commits - planning session)
### Testing
- [OK] (Add test results)
### Status
[OK] **Completed**
### Next Steps
- None - task complete
## Session 6: 修复追问链路与上限判定
**Date**: 2026-04-13
**Task**: 修复追问链路与上限判定
### Summary
定位并修复 follow_up 上下文解析报错;将追问上限改为基于 assistant 回复数;补充单测与集成测试并通过。
### Main Changes
| 项目 | 说明 |
|------|------|
| 追问报错根因 | `worker-agent.log``AgentChatMessageMetadata` 校验失败,原因是历史 metadata 存在 snake_case 字段与 alias 契约不一致 |
| 结构修复 | `divination` 相关模型启用 `populate_by_name=True`,允许 snake_case/alias 一致解析;用户消息缓存写入统一 `by_alias=True` |
| 上限逻辑 | 会话运行上限由按 user 消息数改为按 assistant 消息数统计 |
| 回归测试 | 新增 `backend/tests/unit/test_runtime_context_messages.py` 覆盖 snake_case metadata 场景 |
| 集成测试 | 新增 `backend/tests/integration/test_follow_up_flow.py`,验证 chat->follow_up 成功、assistant=2 后再次 follow_up 返回 409 |
**验证结果**:
- `uv run ruff check`(相关文件)通过
- `uv run pytest backend/tests/unit/test_runtime_context_messages.py backend/tests/unit/test_runtime_models_worker_output.py backend/tests/unit/test_history_message_schema.py` 通过
- `./infra/scripts/app.sh restart` 后,`uv run pytest backend/tests/integration/test_follow_up_flow.py` 通过
### Git Commits
(No commits - planning session)
### Testing
- [OK] (Add test results)
### Status
[OK] **Completed**
### Next Steps
- None - task complete
## Session 7: 六爻算法修复 + Prompt架构重构 + i18n输出规则
**Date**: 2026-04-15
**Task**: 六爻算法修复 + Prompt架构重构 + i18n输出规则
### Summary
(Add summary)
### Main Changes
## 概述
本次会话完成了六爻核心算法的全面审计修复、prompt架构重构清理、以及多语言输出规则适配。
### 算法修复 (P0/P1)
| 问题 | 修复内容 |
|------|----------|
| P0-1 空亡判断 | 改为仅从日柱计算,年月空亡仅标注不断事 |
| P0-2 暗动逻辑 | 重写为静爻+旺相+日冲三条件 |
| P1-1 月破 | 独立标注 |
| P1-2 动不为空/旺不为空 | 补充判断 |
| P1-3 三合局 | 新增判断逻辑 |
| P1-4 反吟伏吟 | 新增判断逻辑 |
| P1-5 日辰十二长生 | 新增字段 `riChenZhangSheng` |
| P1-6 回头生克 | 新增判断逻辑 |
### Prompt架构重构
- **删除 `_build_env_section`**:不再向prompt泄露用户上下文(user_context、timezone、client_time等)
- **简化语言判断**:删除 `if is_chinese` 分支,`_LANGUAGE_LABELS` 已覆盖全部语言映射
- **安全规则改为六爻专属**:只回答六爻占卜相关问题,拒绝无关提问
- **`_WORKER_OUTPUT_RULES` 多语言适配**zh-CN/zh-Hant/en 三版本,按 `ai_language` 分发
- **`_WORKER_ROLE_PLAYING` 始终中文**:保证六爻专业性不受语言切换影响
- **`sign_level` 枚举统一**:所有语言版本强制使用简体中文枚举值(上上签/中上签/中下签/下下签),前端负责显示映射
- **`worker_rules.py` 独立文件**管理多语言规则
### 清理死代码
- 删除 `UserPreferences`/`RuntimePromptContext` 及全部辅助函数
- 删除 runner 中 `runtime_client_time` 参数链路
- 删除 `SystemAgentRuntimeConfig.extra_context`
- 删除 `sections.py``env` section marker
- 删除 `AgentPromptRegistry` 死代码
- runner 中 `ai_language``user_context.settings.preferences` 提取传入prompt
### 安全规则
- `AGENTS.md` 添加 Git Safety 规则(禁止未经批准的破坏性git操作)
- `.opencode/opencode.json` 添加高危git命令审批配置
### 测试
- 新增 22 个六爻算法单元测试
- 重写 7 个 prompt 测试适配新签名
- 全部 85 个单元测试通过
**修改文件 (14)**:
- `backend/src/core/divination/derivation.py`
- `backend/src/schemas/domain/divination.py`
- `apps/lib/features/divination/data/models/divination_backend_models.dart`
- `backend/src/core/agentscope/prompts/system_prompt.py`
- `backend/src/core/agentscope/prompts/agent_prompt.py`
- `backend/src/core/agentscope/prompts/worker_rules.py` (新)
- `backend/src/core/agentscope/prompts/sections.py`
- `backend/src/core/agentscope/prompts/user_prompt.py`
- `backend/src/core/agentscope/runtime/runner.py`
- `backend/tests/unit/test_agentscope_prompts.py`
- `backend/tests/unit/test_divination_derivation.py` (新)
- `docs/plans/liuyao-algorithm-audit.md`
- `AGENTS.md`
- `.opencode/opencode.json`
### Git Commits
| Hash | Message |
|------|---------|
| `9598d16` | (see git log) |
| `be68681` | (see git log) |
### Testing
- [OK] (Add test results)
### Status
[OK] **Completed**
### Next Steps
- None - task complete
## Session 8: Session deletion anonymization for iOS compliance
**Date**: 2026-04-15
**Task**: Session deletion anonymization for iOS compliance
### Summary
Replace soft-delete with anonymize + hard-delete. Add anonymous_session_snapshots table for analytics. Remove points_ledger.biz_id FK constraint for snapshot-style reference.
### Main Changes
### Git Commits
| Hash | Message |
|------|---------|
| `c2b726e` | (see git log) |
### Testing
- [OK] (Add test results)
### Status
[OK] **Completed**
### Next Steps
- None - task complete