Skip to content

标签改造:词表所有权、多标签筛选、标签管理接口 - #112

Merged
DGuang21 merged 1 commit into
mainfrom
feat/tag-source
Sep 7, 2026
Merged

DGuang21 merged 1 commit into
mainfrom
feat/tag-source

Conversation

@wulujia

@wulujia wulujia commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

标签改造的公开后端部分。设计文档由 Luca 另发(HTML),这里只写改了什么和怎么测。

合并顺序

这个 PR 先合,私有仓 unnoo/slax_reader_backend 的 PR 把 submodule 指向这里的提交。

改了什么

  • sr_user_tagsourceauto / mine)和 last_used_atsr_user_bookmark_tagsourceuser / ai)。迁移用最后一条未软删的关联回填 last_used_at
  • 词表 getUserTags 只返回 display = true,SQL 里按我的标签优先、最近使用倒序。
  • AI 选词抽成 pickTagsForBookmarksrc/utils/tags.ts):只认词表里的词,我的标签在前,截 3 个。prompt 拆成“我的标签 / 备选标签”两段。AI 贴的关联写 source = 'ai',不动 last_used_at;AI 路径改成纯查询,不再有任何造词的口子。
  • 用户贴的关联写 source = 'user' 并刷新 last_used_at。文章里删标签改成软删(和 PowerSync 一致),孤儿自动标签隐藏,我的标签零篇也留着。
  • 新路由 POST /v1/tag/promote/v1/tag/demote/v1/tag/delete(前端早就在调 delete,之前是 404)。/v1/tag/update 和新路由都收 tag_uuid,给 local-first 用户用。GET /v1/tag/list?within=a,b 返回交集里的候选词带篇数。
  • GET /v1/bookmark/listtopic_ids=a,b(按 metadata.tags 的 jsonb 包含做交集,旧 topic_id 仍认)和 filter=untagged;列表项带 tags[](含 added_by)。add_tag / add_tagsbookmark_uid
  • 同步写路径:sync 建的标签算 mine,加关联算 user 并刷新时间;自动隐藏只对 auto 且限本用户。
  • 顺手修:createBookmarkTagupdate: {} 清不掉 is_deletedcreateUserTagsskipDuplicatesupdateUserTagDisplay 写死 true;add_tags 在关联全部已存在时报 500;标签页旧查询漏 deleted_at IS NULLorderBy
  • gen:di 重新生成后补上了 ContentOrchestrator 的注册,原生成物是旧的。

怎么测

本地:pnpm test -- run(14 条),pnpm lint。完整的仓库函数测试在私有仓的 PR 里(含真 Postgres 集成测试)。

beta 部署后用 curl:

curl -H "Authorization: Bearer $T" "$API/v1/tag/list"                        # 每项有 source / last_used_at,没有 display=false 的
curl -X POST ... /v1/tag/promote -d '{"tag_name":" 创业 "}'                  # 命中已有“创业”,返回 source=mine,id 不变
curl ... "/v1/bookmark/list?filter=topics&topic_ids=$A,$B&page=1&size=20"   # 每条都同时含 A、B,每条带 tags[]
curl ... "/v1/tag/list?within=$A,$B"                                         # 不含 A、B,每项带 count
curl ... "/v1/bookmark/list?filter=untagged"                                 # 全部 tags=[]
curl -X POST ... /v1/bookmark/add_tags -d '{"bookmark_uid":"...","tags":[{"id":..},{"name":"新词"}]}'

再存一篇新文章等 AI 打完标签:sr_user_bookmark_tag.source = 'ai',对应 sr_user_tag.last_used_at 没变。

没做的

  • metadata->'tags' 没有 GIN 索引,单用户量级靠 user_id 前缀索引够用,慢了再加。
  • CI 的 pnpm test 仍是 watch 模式,会挂住;改成 pnpm test -- run 的一行改动因为 token 没有 workflow 权限没推上来。
  • system_tag 列 2025-07 被主动删过一次,这次加的是词表所有权,AI 仍不能造词。当年删的原因请知道的同学在评论里说一下。

🤖 Generated with Claude Code

https://claude.ai/code/session_011QiL9KgdsseJDNAhSqwnCG

- sr_user_tag gains source ("auto" | "mine") and last_used_at; sr_user_bookmark_tag
  gains source ("user" | "ai"). Migration backfills last_used_at from live links.
- Vocabulary (listUserTags) now filters display=true and orders mine-first by
  recency; the AI picker (pickTagsForBookmark) keeps "mine" ahead and caps at 3.
- Prompt lists "my tags" before fallback tags.
- AI attachments write source=ai without touching last_used_at; user attachments
  write source=user and bump last_used_at. updateUserTagsDisplay no longer revives
  hidden tags on the AI path, so a deleted word stays deleted.
- New routes: /v1/tag/promote, /v1/tag/demote, /v1/tag/delete (the web already
  called delete; it was a 404). /v1/tag/update and the new routes accept tag_uuid
  for local-first clients. /v1/tag/list?within=a,b returns candidate tags with counts.
- /v1/bookmark/list accepts topic_ids=a,b (intersection via metadata.tags containment)
  and filter=untagged; list rows now carry tags[] with added_by.
- add_tag / add_tags accept bookmark_uid.
- deleteBookmarkTag is a soft delete, matching the PowerSync path. Orphaned auto
  tags are hidden; "mine" tags stay at zero links.
- Sync batch: created tags are "mine"; added links are "user" and bump recency;
  auto-hide only applies to auto tags and is scoped by user_id.
- Regenerated router and DI (the DI file also picks up ContentOrchestrator, which
  was missing from the generated file). CI test step runs vitest once instead of watch.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011QiL9KgdsseJDNAhSqwnCG
@wulujia
wulujia requested review from DGuang21 and Whyjsee September 4, 2026 15:13
@DGuang21
DGuang21 merged commit f42bed1 into main Sep 7, 2026
2 checks passed
@DGuang21
DGuang21 deleted the feat/tag-source branch September 7, 2026 08:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants