feat(console): 收件夾改裝=全部待辦分流台(Arcrun#9,kb-ingest SDD R7 消費端)

console 頁 7 從 Telegram 訊息清單改裝成三欄分流台:
- 資料源二合一:entry_type=todo(Logseq 萃取,Arcrun#8 ingest 線)+ entry_type=inbox
  (Telegram),/console/inbox-data → /console/triage-data(唯一消費者是本頁,一起改
  裝不留死端點;仍鎖 console session——待辦原文屬機敏)
- 三欄 80/15/5:ai=AI 會幫我搞定/collab=協作/leo=非我不可;owner_tier 缺席或看
  不懂(triage engine 還沒判)→ 歸 collab 欄+「未分流」徽章,不冒領 ai、不誤判 leo
- 各項顯示 text/project 徽章/source/marker;status:done 預設隱藏可切換
- per-project chips 過濾(全部/各 project/未分項),前端同包資料過濾零額外請求
- 手機直排沿 console 單檔薄殼;讀 KBDB 走既有 kbdbBase HTTP 慣例,不新增 binding

契約解析/分欄/計數=純函式 lib/console-triage-model.ts(比照 console-dashboard-model
模式,route 只做 IO),tests/console-triage-model.test.ts 11 測全綠(紅→綠驗證:抽掉
實作模組同測試即紅)。全套 vitest 98 passed,唯一失敗為 pre-existing executor
「不存在的零件」訊息斷言(main 同紅,與本 PR 無關)。

[總管-subagent]

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-08 22:44:54 +08:00
parent 2fa0974e1c
commit 5cd790c94a
5 changed files with 377 additions and 64 deletions
+13 -20
View File
@@ -68,6 +68,7 @@ import {
sortWaitingItems,
taipeiDayKey,
} from '../lib/console-dashboard-model';
import { buildTriageModel } from '../lib/console-triage-model';
import { TAIPEI_CLIENT_JS } from '../lib/taipei-time';
export const consoleDashboardRouter = new Hono<{ Bindings: Bindings }>();
@@ -454,30 +455,22 @@ consoleDashboardRouter.get('/console/settings-data', (c) => {
});
});
// GET /console/inbox-data — 收件匣清單Mira Console 頁 7)。**需 console session**Bearer):
// dashboard-data 只吐計數可免登入;這裡吐訊息原文(leo 丟給 Telegram bot 的指令內容)屬機敏,鎖登入
// 資料源同 dashboard-data 的 inbox entriesentry_type=inboxcontent JSON {"text","status","result"?}
consoleDashboardRouter.get('/console/inbox-data', async (c) => {
// GET /console/triage-data — 分流台資料Mira Console 頁 7Arcrun#9 收件夾改裝;原
// /console/inbox-data 的後繼——唯一消費者是 console 頁本身,一起改裝,不留死端點)
// **需 console session**Bearer):dashboard-data 只吐計數可免登入;這裡吐待辦/訊息原文屬機敏,鎖登入
// 資料源二合一(kb-ingest SDD R7):entry_type=todoLogseq 萃取,Arcrun#8 ingest 線)+
// entry_type=inboxTelegram)。契約解析/三欄分流/計數=純函式 lib/console-triage-model.ts。
consoleDashboardRouter.get('/console/triage-data', async (c) => {
const ok = await validateConsoleSession(c.env, c.req.header('authorization'));
if (!ok) return c.json({ error: '需要登入(console session' }, 401);
const tenant = c.env.CONSOLE_TENANT || 'leo';
const entries = await fetchEntries(c.env, tenant, 'inbox', 200);
const items = entries.map((e) => {
const j = parseJsonContent(e);
return {
id: e.id,
text: typeof j?.text === 'string' ? (j.text as string) : (e.content ?? ''),
status: j && j.status === 'done' ? 'done' : 'new',
result: typeof j?.result === 'string' ? (j.result as string) : '',
at: e.created_at,
};
});
return c.json({
items,
new_count: items.filter((i) => i.status !== 'done').length,
total: items.length,
});
const [todoEntries, inboxEntries] = await Promise.all([
fetchEntries(c.env, tenant, 'todo', 500),
fetchEntries(c.env, tenant, 'inbox', 200),
]);
const model = buildTriageModel(todoEntries, inboxEntries);
return c.json({ ...model, generated_at: new Date().toISOString() });
});
function renderDashboardHtml(): string {