G-6.2:讀不了的檔案不再安靜消失——首頁當場說出來

服務 J-1 / S6「我丟進去的檔案,查得到」的考題 G-6.2:
「要嘛查得到,要嘛**當場被告知這種檔案還不支援**,不准安靜地略過。」
本次只做後半句(轉檔本體另有人閘,等 leo 裁「那段 Go 住哪裡」)。

## 真實現況比記載更糟
t16 寫的「PDF 被靜默略過」已不成立(t73 的轉檔層把 pdf/docx/xlsx/csv/pptx
都接上了,實測 2 頁中文 PDF 完整抽出)。**真正還在沉默的是別的東西**:
副檔名不在 allowedExt 的檔案在 scan.go 直接 `return nil`——
不進事件、不進 manifest、不進 status、不進畫面。
使用者丟一份 .doc 進去,從頭到尾一個字都沒有。

實測基線(真檔):丟 .pdf/.md/.doc/.key/.jpg 進資料夾,
`collector scan` 只吐出 pdf 與 md 兩個事件,另外三個檔沒留下任何痕跡。

## 改了什麼
- scan.go:白名單閘不再是死巷。像文件的(.doc/.xls/.ppt/.pages/.key/
  .numbers/.odt/.ods/.odp/.rtf/.epub/.wpd/.msg/.eml)逐檔留名;
  其餘(圖片/影音/程式碼)只計總數——**避免 Obsidian 附件庫炸出幾百行噪音**。
- 兩個新欄位標 `json:"-"`:collector-trigger schema 是
  additionalProperties:false,且 BuildSendablePayload 是淺拷貝
  ⇒ 有 tag 就會漏到雲端被擋。這是給本機使用者看的,不上 wire。
- direct.go → status.json → App 首頁一張卡:講檔名與格式(「舊版報告.doc
  (舊版 Word)」),並告訴他不用重丟、也給替代路(另存成 PDF/.docx)。
- 刻意不進 manifest、不走 CarryForwardActivity:每輪由檔案系統重算,
  不製造 t195 那種「跨輪欄位漏 carry 就靜默歸零」的債。

## 順手修掉一個會讓驗收失效的回歸
同綑的 arcrun-collector 一路自稱 `dev`:退役 fyne 版
(arcrun-tray/build-mac.sh:24,t150/t72)本來就有版本注入,
t194 換 Wails 時沒帶過來,Mac 與 Windows 兩邊都掉。
**幹活的是 collector**——它不報版本,就沒人能判斷修復有沒有到使用者手上。

## 實測
- go test ./... 135 過 0 敗(新增 10 條:scan 5+首頁文案 5)
- check-cis / check-render / check-tray 三閘全過;淺色深色都抓過畫面
- 從 **DMG 裡那支** collector 實跑:Info.plist 0.18.6、
  collector 回報 v0.18.6 (build 20260806-0101)、
  status.json 吐出 skipped_docs=[簡報.key, 舊版報告.doc]、other=1

⚠️ 未出貨:推 bundles repo 在 GitHub,要 leo 開 D20 閘。
DMG 已備妥 dist/Arcrun-v0.18.6.dmg。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-06 01:04:25 +08:00
parent f32e82bab5
commit 9cd0adab22
10 changed files with 486 additions and 16 deletions
+18
View File
@@ -45,8 +45,26 @@ type SyncStatus struct {
CloudCheckOK bool `json:"cloud_check_ok"` // /health 可達才為 true
// t104per-account 狀態(key = instanceHostOf(cypher_url)
AccountDetails map[string]AccountSyncStatus `json:"account_details,omitempty"`
// 🔴 G-6.2「不准安靜地略過」(2026-08-06):副檔名不在 allowedExt 的檔案,
// 以前在 scan.go 的白名單閘就 `return nil` 蒸發了——沒事件、沒紀錄、沒畫面。
// 使用者丟一份 .doc 進資料夾,得到的回應是**完全的沉默**。
// ⇒ 每輪把它們帶出來,讓 App 首頁講一句人話。
//
// ⚠️ 與 ExtractedOK 不同,**這三個欄位不進 CarryForwardActivity**
// 它們是每輪重走檔案系統算出來的「現況快照」,不是「本輪做了幾件事」的計數
//(後者才會在沒事做的那輪被歸零=db17f28 修的那個病)。
// 檔案還躺在資料夾裡,每輪都會被重新數到,所以原地重算就是對的。
SkippedDocs []SkippedFile `json:"skipped_docs,omitempty"` // 逐檔點名(已排序,上限 MaxSkippedListed
SkippedDocCount int `json:"skipped_doc_count"` // 文件類被略過的**總數**(可能大於清單長度)
SkippedOtherCount int `json:"skipped_other_count"` // 其餘非文件檔(圖片/影音/程式碼…)只給總數
}
// MaxSkippedListedstatus.json 裡最多逐檔列幾個。
// 超過的只反映在 SkippedDocCount,UI 說「…等 N 個」——避免整批舊 Office 檔
// 把狀態檔撐大,也避免畫面變成一面看不完的檔名牆。
const MaxSkippedListed = 20
// ExtractFail 記一筆萃取失敗(路徑+白話原因)。
type ExtractFail struct {
Path string `json:"path"`