公告系統¶
本檔角色:公告的產品語意與內容規格權威。程式模組、生成物與查詢 API 見 程式架構/announcements.md;SEO 與離線快取的共用規則分別見 程式架構/seo.md 及 程式架構/pwa-offline.md。
1. 定位與信任邊界¶
Open4WD 公告是隨網站版本發布的公開靜態內容,不依賴 CMS、GitHub API、RSS、Ledger、 OrbitDB 或其他託管服務。來源位於主程式 repo,因此任何人皆可複製、驗證並隨前端部署。
- 公告只有單一分類;搜尋與導覽使用多個穩定 tag ID 及各語系 keywords。
public/不是存取控制邊界。草稿、 embargo、密鑰、個資或尚未公開的附件不得進入正式 公告目錄,也不得靠未來的publishedAt隱藏。- 公告內容不接受任意 HTML、CSS、script、iframe、inline event handler 或未知 block。
- 公告只提供資訊,不直接改變帳本、治理、費用、資產可用性或玩家權限;需要操作時只能 連到既有安全 route,真正權限仍由該功能自己的 guard 判定。
2. 公開位置與玩家流程¶
| 位置 | 顯示規則 | 目的 |
|---|---|---|
/ 公開首頁 |
所有有效置頂公告,再加最新 3 則未置頂公告;ID 去重 | 未登入也能看到重要公開消息 |
/announcements |
有效 published 公告列表、tag 與四語全文搜尋 | 完整瀏覽與篩選 |
/announcements/:id |
published、expired、retracted 歷史詳情皆可直接開啟 | 永久連結、修正與撤回紀錄 |
/home Race Bench |
只顯示仍有效的 important/critical;不遮蔽主比賽 CTA |
登入玩家的非阻斷提醒 |
expiresAt 只停止首頁、Race Bench 與一般列表曝光,不刪除詳情。retracted 不進一般列表,
但保留歷史頁與各語系撤回原因。初期沒有經核准的 dismissal 持久化規則,因此不得自行加
「已讀後永久隱藏」。正式來源可以是空目錄,空 catalog 是合法狀態,不建立示意公告。
3. 目錄與 ID¶
public/assets/announcements/
├── tags/
│ ├── zh-TW.json
│ ├── zh-CN.json
│ ├── en.json
│ └── ja.json
└── yyyyMMddNN/
├── manifest.json
├── zh-TW.json
├── zh-CN.json
├── en.json
├── ja.json
└── content 引用的圖片與附件
ID 為十位數 yyyyMMddNN:日期採 Asia/Taipei,流水號為 01–99。ID 發布後永久保留,
不得重用或重新命名;精確發布與更新時間由帶時區的 ISO 8601 timestamp 表示。
4. Manifest 與語系內容¶
manifest.json 是不可翻譯機器資料的唯一權威:
| 欄位 | 規則 |
|---|---|
schemaVersion |
初版固定 1 |
id |
必須等於資料夾名稱 |
status |
published 或 retracted |
publishedAt / updatedAt |
ISO timestamp;updated 不早於 published |
expiresAt |
ISO timestamp 或 null;不得早於 published |
pinned |
boolean |
priority |
normal、important、critical |
tags |
已登記的 lowercase ASCII kebab-case ID,檔內不重複 |
supersededBy |
較新且確實存在的公告 ID 或 null;整張關係圖不可循環 |
每則公告必須同時有 zh-TW、zh-CN、en、ja 四份 JSON,內容包括 locale、
title、summary、最多 32 個 keywords、最多 256 個 content blocks;retracted 另須
retractionNotice。標題、摘要、正文、圖片 alt/caption、附件 label/description 與 CTA
皆屬公告內容,不放 App 共用 i18n。tag 顯示名由四份 tag registry 翻譯,四語 key 集合必須
完全一致。
5. 結構化內容¶
允許的 block:heading(僅 H2/H3)、paragraph、list、quote、callout、image、
gallery、attachment、table、code、cta、divider。每個 block 必須有檔內唯一 ID;
四語可依文法調整順序與數量,不要求 block 一對一。
- title 是頁面唯一 H1;內容不得產生 H1。
image必須提供非空 alt,或明確decorative: true,兩者互斥;每語系最多一張role: cover。可選 layout 與 0–1 的 numeric focal point。attachment的 MIME、bytes、digest 與圖片尺寸由 generator 讀實檔補入,不手寫重複 inventory。table只接受純文字且有列欄上限;窄螢幕使用可鍵盤捲動的標示區域。code永遠以文字顯示、不執行;未知或損壞 block fail closed,不讓整個首頁失效。- CTA 站外只允許 HTTPS 且新分頁使用
noopener noreferrer;站內只接受明列 route,拒絕 traversal、protocol-relative、credentials、redirect-bearing query 與危險 scheme。
6. 圖片、附件與安全預算¶
引用只能是公告資料夾內的相對路徑;禁止 absolute path、..、percent encoding、反斜線、
URL query/fragment delimiter、symlink 與跨公告引用。副檔名、宣告 MIME 與 magic bytes 必須
一致;未被任一語系引用的額外檔案使 build 失敗。
允許 WebP、PNG、JPEG、保守 sanitize 後的 SVG、PDF、TXT、JSON;GLB 附件必須再通過既有 GLB 安全檢查。禁止 HTML、JavaScript、執行檔、未知 MIME、SVG active content、外部引用、 entity 與缺少合法 intrinsic dimensions 的圖片。
| 預算 | 上限 |
|---|---|
| 單張圖片 | 1.5 MiB |
| 單則所有圖片 | 5 MiB |
| 單一非圖片附件 | 10 MiB |
| 單則所有資源 | 25 MiB |
| 圖片寬/高 | 1–8192 px |
非圖片附件不進 precache,也不因開啟公告頁而自動下載。
7. 修正、取代與撤回¶
- 一般文字或附件修正保留 ID,更新
updatedAt;內容與資產 digest 使舊快取自然失效。 - 用新公告取代舊公告時,舊 manifest 設
supersededBy,舊詳情顯示後繼連結。 - 撤回時改為
retracted,四語補撤回說明。若附件本身違法或危險,可實際移除;詳情仍保留 最小撤回紀錄,不把缺附件當成正常下載。 - 公告不提供排程發布服務;部署中出現的內容視為已公開,發布時間與 commit/deploy 人工流程 必須一致。
8. SEO、離線與無障礙¶
- 列表與每則詳情提供 canonical、四語 hreflang;詳情提供 Article JSON-LD。retracted/expired 歷史頁仍可索引,retracted metadata 清楚標示撤回,不偽裝為最新消息。
- precache 包含 catalog、四語 tag registry、首頁最新少量 locale JSON 及其小型 cover;其他 詳情與小型資產讀取後進有容量上限的公告 runtime cache。大型 / 非圖片附件不自動快取。
- 「小型 cover」的獨立 precache 門檻為 512 KiB;超過門檻仍可在線顯示,但不隨安裝預載。
- Browser 逐則抓取帶內容 digest 的語系 JSON,Service Worker 與頁面載入器都要驗證原始 bytes 的 SHA-256 後才可快取 / 解析;SSR/SSG 才能使用 build-time 生成的正文模組。
- 離線詳情顯示「離線」與實際快取時間,不能把
publishedAt當快取時間;未快取內容顯示 可理解的 unavailable 狀態。 - priority/callout 不得只靠顏色;必須同時有文字或 SVG 形狀。所有流程驗證 320 px、200% 字級、鍵盤 focus、screen-reader 順序、圖片 alt 與 responsive table label。
9. 驗證閘¶
每次 build 先執行 generator 產生公告 catalog,再產生 SEO/PWA 清單;
check:announcements 可在本機或 PR check mode 驗證生成物與來源 byte-identical,但目前工具鏈
未把它宣稱為既有 CI job。測試至少涵蓋 schema、四語、tag、路徑越界 /symlink、MIME spoof、SVG active content、
GLB、安全連結、digest、未引用檔、預算、排序、supersession graph、空 catalog、SSR/SSG、
離線快取與鍵盤 / 行動版流程。