Skip to content

feat: 首頁議題排序加入公民/志願者角色切換,最新排序改用最新活動日期(#77) - #78

Merged
Link1515 merged 3 commits into
mainfrom
feat/issue-77-home-sorting
Aug 29, 2026
Merged

feat: 首頁議題排序加入公民/志願者角色切換,最新排序改用最新活動日期(#77)#78
Link1515 merged 3 commits into
mainfrom
feat/issue-77-home-sorting

Conversation

@bestian

@bestian bestian commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

摘要

解 GitHub issue #77——首頁新增「角色」切換(公民/志願者,預設公民);公民不顯示「素材收集中」議題;志願者顯示全部且「素材收集中」固定排最前(第一階排序,階內套用使用者選的排序);「最新」排序改以最新活動日期為準(素材/意見投稿、說明頁更動),不再用議題建立日期。

實作重點

  • src/lib/homeSorting.ts(新):純函式 filterByRolesortByOrderfilterAndSortHomeIssues,SSR 安全;last_activity_at 為 NULL 時 fallback 到 created_at
  • migration migrations/0011_issue_last_activity.sqlct_issues 新增 last_activity_at DATETIME 欄位並回填(三類子內容 abuse_flagged IN (0,1)MAX(created_at);無子內容者維持 NULL;abuse_flagged = 3 一併回填)。採欄位版是因為 updateLatestBriefing() 是原地 UPDATE,子表 MAX(created_at) 抓不到說明頁更動
  • src/db/queries.ts:新增 touchIssueActivity() helper,四個寫入路徑(createMaterialcreateOpinioncreateBriefingupdateLatestBriefing)同步維護欄位。隱藏投稿(moderation-hidden,abuse_flagged = 3)不算活動——touch 只在非隱藏投稿呼叫,與 migration 回填及公開查詢 IN (0,1) 口徑一致;updateLatestBriefing() 無條件 touch(其 UPDATE 本就只觸及 abuse_flagged IN (0,1) 的列);skipStatusTransition 只影響狀態轉換,不影響口徑判斷。讀取層以 COALESCE(last_activity_at, created_at) fallback;listIssuesWithAuthor() 管理端同步補欄位;公開欄位維持列舉、無 SELECT *
  • src/views/Home.vueviewerRole ref(預設 citizen)+角色切換鈕群
  • i18n:idx_role_labelidx_role_citizenidx_role_volunteer,zh-TW/en 雙檔同步

⚠️ Migration 狀態

0011_issue_last_activity.sql 尚未套用至遠端 D1(本機已套用並驗證:sqlite_master 只新增 ct_ 前綴業務表、回填值與子內容 MAX(created_at) 一致)。merge 前需取得授權套用遠端,且順序必須:先套 migration、再 deploy(否則每次素材/意見/說明頁投稿會 runtime error no such column: last_activity_at)。

驗證

  • vp check --no-fmt --no-lint 零錯誤(63 files)
  • vp test 15 檔 / 91 測試全過(含 src/tests/homeSorting.test.ts 18 個:四個寫入路徑落表+欄位更新、moderation-hidden 不更新、NULL fallback)
  • vp run build 成功

Closes #77

- listIssues() 以子查詢計算 last_activity_at(素材/意見/說明頁 abuse_flagged IN (0,1) 的最新 created_at,無則 fallback 到 created_at)
- 抽出 src/lib/homeSorting.ts 純函式:citizen 過濾 collecting;volunteer 顯示全部且 collecting 固定排最前
- newest 排序改以 last_activity_at 為準
- Home.vue 新增角色切換鈕(樣式比照排序鈕,token 不硬寫顏色)
- i18n zh-TW/en 同步新增 idx_role_label/citizen/volunteer
- 新增 src/tests/homeSorting.test.ts(node:sqlite 跑真實 SQL + 純函式測試)
- migration 0011:ct_issues 新增可 NULL 的 last_activity_at,回填三類子內容
  (abuse_flagged IN (0,1))的最新 created_at;無子內容則維持 NULL(尚無活動),
  不回填 created_at(僅套用本機,未動遠端)
- 寫入路徑:createMaterial/createOpinion/createBriefing/updateLatestBriefing
  統一經 touchIssueActivity() 更新欄位;moderation-hidden 投稿也算活動,
  不受 skipStatusTransition 影響
- 讀取路徑:listIssues 改用 COALESCE(last_activity_at, created_at) 欄位版,
  捨棄 COALESCE 子查詢(抓不到 updateLatestBriefing 的原地更新);
  listIssuesWithAuthor 同步補上同欄位
- homeSorting newest 排序對 NULL 做 created_at fallback
- 測試:seed 加入 last_activity_at 欄位;新增四個寫入路徑測試與
  NULL fallback 測試(node:sqlite 真資料庫驗證)
- createMaterial/createOpinion/createBriefing 只在非 moderationHidden
  投稿時呼叫 touchIssueActivity(),與 migration 0011 回填
  (abuse_flagged IN (0, 1))及公開查詢 material_count/opinion_count
  口徑一致
- updateLatestBriefing 維持無條件 touch:getLatestBriefing() 已過濾
  IN (0, 1),UPDATE 本來就只觸及非隱藏列(補註解說明)
- touchIssueActivity() docstring 改為說明隱藏投稿不算活動
- 測試補強:create* 三函式新增 INSERT 落表斷言;moderationHidden
  投稿不更新 last_activity_at;順帶修復 createOpinion 遺失的
  await .run()(INSERT 未執行)
@bestian
bestian requested a review from Link1515 August 29, 2026 00:35
@Link1515
Link1515 merged commit 7d557b5 into main Aug 29, 2026
1 check passed
@Link1515
Link1515 deleted the feat/issue-77-home-sorting branch August 29, 2026 01:36
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