Skip to content

feat(tweet): add tweet search with /search page and BFF route - #19

Merged
Chilfish merged 10 commits into
mainfrom
feat/tweet-search
Aug 31, 2026
Merged

Chilfish merged 10 commits into
mainfrom
feat/tweet-search

Conversation

@Chilfish

Copy link
Copy Markdown
Owner

Summary

打通 Twitter/X 推文搜索链路(方案:docs/features/tweet/search.md):

  • rettiwt-api:TWEET_SEARCH 补入 AllowGuestAuthenticationGroup(此前 guest 池直接抛 RESOURCE_NOT_ALLOWED)
  • 数据层:parseSearchTimeline 纯函数 + fetchSearchTweets(池化 TWEET_SEARCH);q 原样透传 rawQuery → X 高级搜索语法可用(from: / until: / min_faves: 等),自动解包 TweetWithVisibilityResults
  • BFF:GET /api/tweet/search?q=&type=&cursor=&count= → { tweets: EnrichedTweet[], nextCursor }(分页形态同 /api/tweet/replies,元素格式同 /api/tweet/get)
  • 前端:/search 页面(InputGroup 搜索框 + 热门/最新 ToggleGroup + 高级搜索快捷插入面板 + cursor 加载更多)+ footer「推文搜索」内链;按 docs/ui-design/GENERAL.md / README.md 规范实现
  • 验证:AC-TWEET-009(离线解析回归)/ AC-TWEET-010(集成端点),fixture + 单测 13 例

Verification

  • bun run typecheck 通过
  • bun run lint 0 error
  • bun run test 294/294 通过
  • bun run verify/index.ts --exit-on-fail 301 passed + 5 skipped(需 TWEET_KEYS/INS_COOKIES 的集成项)
  • bun run build 通过
  • 相关文档已更新(feature doc / backlog / AC-tweet.md / dev log 2026-08-31)

Notes

  • 搜索结果在无 TWEET_KEYS 的 guest 模式下可能受限(X 对未登录搜索有限流),页面已区分「无结果」与「搜索失败」两种状态
  • 分支:feat/tweet-search(10 个原子提交)

- feature plan: docs/features/tweet/search.md (interface + 5-phase plan)
- backlog: 阶段二 add search task (in progress, feat/tweet-search)
- AC-tweet.md v1.1: AC-TWEET-009 offline parse regression, AC-TWEET-010
  integration endpoint returns EnrichedTweet[] (same shape as /api/tweet/get)
- dev log 2026-08-31: search integration kickoff
- /api/tweet/search returns { tweets, nextCursor } (shape aligned with
  /api/tweet/replies; tweet elements same as /api/tweet/get)
- AC-TWEET-010 updated: assert paginated payload shape
TWEET_SEARCH was missing from AllowGuestAuthenticationGroup, so key-less
pool instances threw RESOURCE_NOT_ALLOWED before the request was even sent.
Search now works for guest attempts (and stays key-based via TWEET_KEYS).
…Tweets)

- parseSearchTimeline: pure function over SearchTimeline instructions,
  keeps tweet- entries, drops cursors, unwraps TweetWithVisibilityResults
- fetchSearchTweets: pooled TWEET_SEARCH request; query passes through as
  rawQuery verbatim, so X advanced syntax (from:/until:/min_faves:/...) works
- returns { tweets, nextCursor } for cursor pagination
- searchTweetSchema: q (1..500) / type top|latest / cursor / count (1..50)
- loader aggregates fetchSearchTweets + enrichTweet, returns
  { tweets, nextCursor }; 400 on invalid params, structured 5xx on upstream
- register route under api/tweet prefix
- search form (controlled input) + 热门/最新 toggle + 高级搜索 panel with
  operator chips (from:/to:/#/min_faves:/min_retweets:/since:/until:/lang:/-)
- results rendered with MyTweet single-tweet pattern, deduped, load-more
  paginated via nextCursor
- friendlier empty/error states (no misleading tweet-not-found)
- footer More adds internal 推文搜索 link to /search
- fixture test/fixtures/search/search-tweets.json (2 tweets + ad + cursors)
- unit: parseSearchTimeline (extraction/order/cursor/robustness/visibility
  unwrap) + TweetFilter advanced-syntax verbatim passthrough
- unit: /api/tweet/search loader (400 on missing q, arg passthrough,
  upstream error)
- acceptance AC-TWEET-009 offline fixture regression
- integration AC-TWEET-010 endpoint shape (skipIf no keys/server) +
  api-client tweet.search
- feature doc: all phases done + iteration notes (advanced syntax
  passthrough, quick-input panel, visibility unwrap, empty-state fix)
- dev log 2026-08-31: implementation details + gate results
- backlog: mark search task complete
- InputGroup (magnifier addon + input + inline-end submit) replaces raw
  Field/Input composition
- ToggleGroup for 热门/最新 instead of hand-rolled outlined Buttons
- Collapsible panel for advanced operators; chips use Button size-xs
- Empty/EmptyHeader/EmptyMedia/EmptyTitle/EmptyDescription for empty and
  error states instead of bare text divs
- footer search icon size-3.5 per icon spec
- conforms to docs/ui-design/GENERAL.md + README.md (no raw <button>,
  no hardcoded colors, dark-mode tokens, cursor/focus handled by coss)
@vercel

vercel Bot commented Aug 31, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
anon-tweet Ready Ready Preview Aug 31, 2026 5:03am

@Chilfish
Chilfish merged commit fd2cd18 into main Aug 31, 2026
2 checks passed
@Chilfish
Chilfish deleted the feat/tweet-search branch August 31, 2026 05:19

This branch was successfully deployed

1 active deployment
Preview — 2df7b86d Deployed Aug 31, 2026 by vercel[bot]
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.

1 participant