架構與工作流程說明書
給研究、編輯與工程夥伴的共同手冊:網站怎麼組成、介面怎麼設計、資料怎麼查證、更新怎麼上傳,以及出問題時怎麼回復。
01產品定位與邊界
這個網站是什麼、不是什麼
提供可查證的移工安置制度與機構研究索引,回答「誰設立、誰承接、誰出錢、誰監督」。它不是即時庇護所名錄,也不是緊急轉介入口。
- 區分一般臨時安置、人口販運庇護、駐台代表處安置、婦幼特殊安置與仲介住宿,不虛構全國總數。
- 歷史安置紀錄不等於現在仍在營運或持有政府契約。
- 不收集個資、不提供上傳、不公開受庇護者非公開位置。
02系統架構
靜態頁面+邊緣函式+鍵值儲存
| 檔案 | 角色 |
|---|---|
site/index.html | 主網站。HTML、CSS、JS、圖示與插圖全部內嵌,一次請求就能完整顯示。 |
site/docs.html | 本說明書,共用同一套設計代號與友善模式設定。 |
site/_headers | Cloudflare 安全標頭(CSP、HSTS、X-Frame-Options 等)與快取規則。 |
site/version.json | 部署時自動寫入的版本與更新時間。 |
functions/api/visit.js | 獨立訪客統計 API。 |
wrangler.toml | Pages 專案名稱、輸出資料夾、KV 綁定。 |
deploy.ps1/deploy.bat | 一鍵更新上傳;preview.bat 用於本機預覽(含統計函式)。 |
03前端模組
單頁分頁式應用,切換不重新載入
以 #/db 這類網址切換六個分頁;支援上一頁/下一頁、舊版錨點自動轉址;有 View Transitions 時用淡入轉場。
深色模式與友善模式;設定存於 wen8604.a11y.v1,與 wen8604 網站群共用;head 內先套用避免閃爍。
關鍵字(120ms 防抖)、類型篩選膠囊、證據狀態下拉、卡片展開、CSV 匯出(含公式注入防護)。
所有文章段落可收合,展開/收合有高度動畫,每區提供「全部展開/全部收合」。
每個瀏覽工作階段只計一次;失敗或本機開啟時整塊隱藏,不顯示 0。
讀取 <meta name="build-time">,以台灣時間顯示在首頁與頁尾,由部署腳本自動改寫。
04介面設計系統
配色、字體、三種裝置版型、深色與友善模式
配色(依 wen8604 設計規範 v1.0)
內文對比 ≥ 4.5:1;金色只用於深色底或當底色配黑字。插圖顏色全部以 CSS 變數控制,深色模式自動轉為夜景(月亮、星星、窗戶亮燈)。
三種裝置版型
底部五格分頁列(拇指可及),「更多」以底部抽屜開啟;設定面板也從下方滑出;表格改為卡片式。
頂部列下方加一排可橫向滑動的分頁膠囊,目前分頁自動置中;卡片兩欄。
頂部分頁列帶滑動指示器;卡片三欄;時間軸右側固定地圖說明。
友善模式細部設定
| 項目 | 選項 | 效果 |
|---|---|---|
| 友善模式總開關 | 開/關 | 字級 ×1.25、行距寬鬆、按鈕 ≥ 48px、連結底線、強化焦點框(可再個別微調) |
| 外觀主題 | 淺色/深色/跟隨系統 | 頂部也有一鍵切換按鈕 |
| 文字大小 | 標準/大/特大/超大 | 100%/112.5%/125%/150%,全站以 rem 等比放大 |
| 行距 | 標準/寬鬆/加寬 | 1.75/1.9/2.1 |
| 高對比 | 開/關 | 底 #10212C、字 #E8F1F5(14.4:1)、連結 #F2B544 |
| 減少動態 | 開/關 | 關閉轉場、插圖漂浮與收合動畫;也自動遵循系統設定 |
| 加寬字距 | 開/關 | 字距 +0.06em |
| 連結加底線/強化焦點框 | 開/關 | 不靠顏色辨識連結;鍵盤焦點加粗並加光暈 |
05載入速度策略
為什麼這麼快
- 單一 HTML 檔,零外部字型與零外部腳本;使用系統內建的思源黑體/微軟正黑體。
- 圖示改為內嵌 SVG sprite(
<symbol>+<use>),插圖為向量,不需載入任何圖片。 - 分頁切換只切換顯示,不重新請求;資料卡片用 DocumentFragment 式建立,搜尋加防抖。
- 訪客統計延後到瀏覽器閒置時才呼叫(requestIdleCallback),不影響首屏。
- Cloudflare 自動 Brotli 壓縮、HTTP/3 與全球節點;HTML 每次重新驗證,確保更新立即生效。
- 上線後以 Lighthouse 量測:目標 LCP < 1.5 秒、CLS < 0.05、效能分數 ≥ 95。
06訪客統計與更新時間
Cloudflare Functions+KV,獨立計算、不追蹤個人
- 頁面載入後閒置時:若是本工作階段第一次造訪送
POST /api/visit,之後只送GET讀取。 - 邊緣函式判斷:排除爬蟲、無頭瀏覽器與 Cloudflare 判定的機器人;拒絕跨網域 POST。
- 去重:以「IP+瀏覽器+日期+鹽」做 SHA-256,存 48 小時後自動刪除;同一人同一天只算一次。
- 累加:
total與d:YYYY-MM-DD兩個計數器各加一,回傳累計與今日人次。 - 顯示:頁尾「累計造訪 N 人次・今日 n」;若 API 失敗或數字為 0,整塊隱藏。
KV 為最終一致性儲存,極短時間內大量同時造訪可能少算幾筆;研究網站流量下影響可忽略。若未來需要精確到每一筆,可改用 D1(SQL 原子遞增)或 Durable Objects。
更新時間:每次執行 deploy.ps1 會把當下時間寫入兩個頁面的 build-time 與 version.json,並在 deploy-log.txt 記一筆。
07資料模型
下一版建議拆成獨立 JSON
{
"id": "organization-001",
"name": "組織名稱",
"category": "government | shelter | education",
"shelter_contract_status": "documented | unverified",
"description": "已查得服務與限制",
"source_ids": ["S01"],
"reference_year": 2022,
"last_verified_at": "2026-10-27",
"operating_status": "unknown",
"reviewer": "待指派",
"revision_notes": "需取得正式函覆"
}
同一團體可有多種服務類型;正式資料庫應以多對多關聯表(organizations、services、facilities、contracts、grants、evidence、revisions)處理。設施與法人分開,避免重複計算。
08內容採證工作流程
從提案到勘誤的八個步驟
- 提案:建立待查問題,明確統計期間與定義。
- 取證:法規、標案、審計報告、官方年報優先;保存網址、發布日、擷取日。
- 分級:官方直接證實/歷史有據/尚待驗證/已更正/已撤回。
- 核對:高風險資訊至少兩位編輯交叉覆核;涉及機構聲譽須給予回應機會。
- 去重:依法人識別碼、設施識別碼、契約案號與年度比對。
- 審核:法規適用、統計單位、推論限制、個資遮蔽、中性用詞與來源連結。
- 發布:更新資料陣列 → 執行
deploy.ps1,自動記錄更新時間與摘要。 - 勘誤:公布錯誤位置、來源與更正日期;不默默改寫重要結論。
09更新上傳流程(Cloudflare)
第一次設定與日常更新
第一次設定(約 5 分鐘)
- 安裝 Node.js LTS(nodejs.org)。
- 雙擊
deploy.bat。第一次會開啟瀏覽器,請登入 Cloudflare 並按「Allow」授權。 - 腳本會自動建立 KV「VISITS」、填入
wrangler.toml、建立 Pages 專案migrant-shelter-research並上傳。 - 完成後網址為
https://migrant-shelter-research.pages.dev;可在 Cloudflare 後台 Pages → 自訂網域 綁定自己的網域。
日常更新
# 1. 修改 site\index.html 內的 ORGS/SOURCES 等資料陣列或文字
# 2. 本機預覽(含統計 API)
preview.bat # 開啟 http://localhost:8788
# 3. 上傳(可附更新說明)
.\deploy.ps1 -Message "新增 2026 年勞動部安置名冊"
回復上一版
Cloudflare 後台 → Workers & Pages → 本專案 → 部署 → 找到上一個成功版本 →「Rollback to this deployment」,數秒內生效,訪客統計不受影響。
部署只需要 Cloudflare 帳號授權,不需要在檔案裡寫任何密碼或 API 金鑰。若改由 CI 自動部署,請把 CLOUDFLARE_API_TOKEN 設為 CI 的祕密變數(權限只給 Pages 編輯與 Workers KV 編輯)。
10安全與隱私
威脅模型與對策
| 潛在問題 | 目前對策 | 後續強化 |
|---|---|---|
| XSS 注入 | 動態資料一律以 textContent/DOM 節點建立 | 將 JS/CSS 拆出檔案,CSP 移除 'unsafe-inline' |
| 供應鏈 | 零外部套件、零 CDN | 若引入套件需鎖版本並掃描 |
| 點擊劫持、嗅探 | _headers:X-Frame-Options DENY、nosniff、frame-ancestors 'none' | — |
| 傳輸安全 | Cloudflare 全站 HTTPS+HSTS | 網域加入 HSTS preload |
| 統計灌水 | 排除機器人、拒絕跨網域 POST、每人每日一次 | 開啟 Cloudflare Bot Fight Mode/Turnstile |
| 個資 | 不存 IP,只存 48 小時的加鹽雜湊;無 Cookie | 設定 VISIT_SALT 祕密變數 |
| 惡意 CSV 公式 | 以 = + - @ 開頭的欄位前加單引號 | 匯出自動化測試 |
| 誹謗/不當推論 | 未證實一律標「待查」,不作犯罪指控 | 法務與事實查核審閱、申訴管道 |
11驗收清單
v2.0 完成項目與待辦
- 六分頁單頁應用、滑順切換、舊網址相容
- 手機底部列/平板滑動分頁/桌機分頁指示器
- 重新繪製的主視覺插圖、分頁插圖與 45 個圖示,深色模式夜景
- 文章與說明全面可收合,含全部展開/收合
- 深色模式+友善模式 8 項細部設定,跨站共用設定
- 網站更新時間自動寫入、獨立訪客統計(排除機器人)
- Cloudflare 安全標頭、一鍵部署、本機預覽
- 全台政府安置名冊與委託契約逐筆去重
- 機構狀態正式函覆、印尼據點精確開設日期
- 真機 WCAG 2.2 AA 稽核與螢幕閱讀器實測
- 公開勘誤紀錄頁與資料版本差異
12下一版路線與維護角色
優先順序與分工
| 優先 | 項目 |
|---|---|
| P0 | 來源連結自動檢查(排程 Worker)、法規與數據證據綁定、對外勘誤流程 |
| P1 | 資料拆為獨立 JSON、版本管理、公開 CSV/JSON API |
| P2 | 政府標案與補助資料交叉索引、分年度趨勢圖、雙語(中/印尼文)介面 |
| P3 | 需身分驗證的內容管理後台(Cloudflare Access 保護、操作稽核、備份) |
角色:資料研究員收集來源;主編審核推論與措辭;法務/資安審查敏感內容;工程師管理程式、部署、備份與監測。任何人都不應在缺乏原始資料時自行更改數字或指控機構。