NUK 區域網路匿名投票 — Windows 主機／Android 平板操作說明
開發測試版 v3.1.2-dev｜2026-10-13

適用情境
========
筆記型電腦 A 執行投票服務及主持畫面。21 台或更多 Android 平板，
以 01、02、03…編號，透過同一區域網路使用瀏覽器投票。
主機先建立會議，再顯示加入 QR。平板掃描 QR、選擇設備編號，
經主持人核對配對碼並核准後取得會議資料及投票資格。

開發／測試階段可使用有外部網路的區域網路；程式在使用時不依賴
外部服務。最終部署使用沒有外部網路的設備及獨立區域網路。
一般操作採 HTTP。正式隔離環境須由現場管理者控制設備和網路；
若需要防止區域網路封包被讀取，請配置後述的本機 HTTPS。

一、部署前準備
==============
1. 在可上網的準備用電腦取得完整 LAN 發行包，複製到 USB 隨身碟。
   在筆記型電腦 A 解壓縮至例如 C:\NUK-LAN-Vote。
   應包含 Start-LAN.cmd、lan-server.mjs、lan-store.mjs、dist 網頁資料夾及
   runtime\node.exe。若取得的是原始碼而非完整包，需先準備
   Node.js 22 或更新的 LTS Windows 版本；Windows x64 電腦使用
   x64 版本。可在連網電腦下載官方安裝檔或 Windows ZIP，離線搬移。
   ZIP 中的 node.exe 可放在應用程式的 runtime 資料夾。
   官方下載：[Node.js Windows 下載](https://nodejs.org/en/download)
   最終設備不需要下載套件、登入雲端或連上外部網站。

2. 應用程式放在主機本機磁碟，不要以 OneDrive 同步資料夾作為
   正式投票資料存放處。啟動器固定將資料放在目前 Windows 使用者的
   %LOCALAPPDATA%\NUK-LAN-Vote，通常是
   C:\Users\使用者名稱\AppData\Local\NUK-LAN-Vote。
   以同一 Windows 帳號操作，才能持續使用同一份資料。

3. 最終部署準備獨立路由器／Wi-Fi AP，WAN 不接外部網路。
   主機與全部平板都連接這個區域網路。建議主機以網路線連接路由器，
   並在路由器為主機預留固定 DHCP 位址，例如 192.168.50.10。
   使用能承載實際平板數量的 AP，關閉用戶端隔離／AP isolation，
   不使用無法存取主機的訪客 Wi-Fi。平板如提示 Wi-Fi 無網際網路，
   選擇繼續連線；不要改用其他 Wi-Fi 或行動數據路徑。
   開發階段可讓這個網路有 WAN，但投票資料仍只存於主機本機。

4. 確認主機、Android 瀏覽器及 QR 掃描功能已在離線前準備完成。
   最終設備的應用程式、QR 程式、樣式及字型均由主機本機提供。
   QR 是「開啟主機網址」，不會自動連接 Wi-Fi；先連同一 Wi-Fi 再掃描。

二、第一次允許區域網路連線
==========================
只有主持主機需要開放投票服務的 TCP 8080 連入。
將使用的受控區域網路設為 Windows「私人網路」。不要關閉防火牆。
由管理員在 PowerShell 執行一次下列規則；先將程式路徑改成實際位置：

  New-NetFirewallRule -Name 'NUK-LAN-Vote-8080' -DisplayName 'NUK LAN Vote (Private local subnet)' -Direction Inbound -Action Allow -Profile Private -Protocol TCP -LocalPort 8080 -RemoteAddress LocalSubnet -Program 'C:\NUK-LAN-Vote\runtime\node.exe'

此規則限私人網路、同一子網路、指定程式及 8080 埠。若使用已安裝的
Node.js，程式路徑必須改成該 node.exe 的實際完整路徑。
更換安裝位置、程式路徑或服務埠後，也要更新對應規則。
不要在 Windows 提示視窗中另外新增允許所有公用網路的寬鬆規則。
啟動器本身不修改防火牆，也不需要以管理員身分執行。
參考：[Microsoft 防火牆規則參數](https://learn.microsoft.com/en-us/powershell/module/netsecurity/new-netfirewallrule)

三、每次會議操作
================
1. 主機接上電源，關閉會議期間的睡眠／自動休眠；確認主機與平板
   在同一網路。雙擊 Start-LAN.cmd，保持服務視窗開啟。
   等待服務顯示已啟動，在筆記型電腦 A 開啟：

     http://127.0.0.1:8080/host

   主持頁僅接受主機本機連線。平板不能使用這個 127.0.0.1 網址，
   也不能從區域網路開啟主持功能。

2. 服務會選擇主機的私人 IPv4 位址。若沒有適用位址，或同時偵測到
   多個位址（例如 Ethernet、Wi-Fi、VPN），會停止並要求指定。
   查明平板所連網路上的主機 IPv4，再於應用程式資料夾的終端機執行：

     Start-LAN.cmd --public-url http://192.168.50.10:8080

   上面的 IP 僅為範例。主機更換 IP 後，重新啟動服務並重新掃描新 QR。
   主機本機主持網址仍為 http://127.0.0.1:8080/host。

3. 在主持頁設定會議名稱及平板數量，按「建立本次會議」。預設 21 台；
   應用程式可設定
   最多 500 個設備編號，這是資料設定上限，不是實機容量保證。
   會議建立後，在「讓平板加入會議」顯示加入 QR 給平板掃描。
   新會議會取代目前會議；必須先關閉全部舊議題，並保存需要保留的
   舊會議資料。未開放的草稿按「取消議題」後「確認取消議題」。
   需要下一場會議時，先停止服務備份，再重新啟動，按「準備下一場會議」，
   填寫新名稱／平板數量並「取代目前會議並建立」，全部平板重新配對。

4. 各平板使用相機掃描同一 QR，在瀏覽器輸入自己的設備編號，例如 01，
   按「申請加入」。
   平板顯示隨機配對碼。主持人核對設備與畫面上的配對碼，再於主持頁
   按「允許加入」核准該設備；只核准實際看過的正確配對碼。
   配對碼不符或設備編號有誤，先按「拒絕」再請正確設備重新申請。
   同一設備編號不能同時核准兩台平板，防止重複占用席位。
   這些設備編號只供連線、配對及投票資格管理使用，不是選票署名。
   主持頁「已配對」表示已核准登記；各平板的「已連接主機」表示
   該瀏覽器目前成功與主機通訊。

5. 在主持頁「新增議題」填寫名稱、說明，並「設定可投票的平板」，
   按「加入議程」。表決選項固定為同意／不同意。
   必須先核准名單中的全部平板，再按「開放投票」。同一時間只開啟一個議題。
   已核准平板會更新會議及議題資料；名單外設備無法對該議題投票。

6. 使用者在平板選擇同意或不同意；不同意必須填寫理由（最多 500 字）。
   按「確認表決內容」檢查後「確認送出」，確認「選票已收錄」及收據。
   如網路暫時中斷，保留原瀏覽器頁面，恢復連線後以原選票重試。
   按「重新確認收錄」會沿用原提交識別碼重試，只記一票。
   連線中斷本身不代表已送出成功。
   不要為了解決等待畫面而清除瀏覽器資料或任意換設備編號。

7. 主持人按「結束投票」，核對總票數後按「結束投票並公開結果」，
   主機及平板才顯示同意、不同意、未投票數及不同意理由。
   主持頁不顯示每台設備是否已投票，
   不提供「設備編號對應答案」或逐台投票進度。
   依序開啟下一議題，完成後關閉全部議題。

8. 要結束服務，先確認全部議題已關閉，再於服務視窗按 Ctrl+C。
   正常停止後可關閉視窗。不要在投票期間直接斷電或休眠。

四、資料保存、備份與更新
======================
服務將目前會議保存在資料資料夾內的 current.json；以原子方式寫入。
重新啟動同一資料資料夾，可恢復目前會議、配對、資格及已接受選票。
瀏覽器的成功回覆代表主機已接受並保存該票。仍須使用可靠的本機磁碟，
防止磁碟故障、資料夾被刪除或非正常斷電造成的風險。

此版只保存目前會議，不提供歷年會議資料庫。建立新會議會取代舊會議。
如需保留舊會議，先關閉議題及停止服務，再將整個資料資料夾複製至
受控的離線備份媒體；保留日期及會議名稱，勿覆蓋唯一備份。
如需恢復備份，先停止服務、另外保留目前資料，再以備份替換資料目錄。
備份包含配對及投票資料，只有授權的現場管理者應能存取。

更新時先正常停止並備份。只更換應用程式資料夾中的程式／網頁／runtime，
保留 %LOCALAPPDATA%\NUK-LAN-Vote。不要將空白資料覆蓋到原資料資料夾。
大版本更新前應先以備份副本驗證相容性；確認可讀取才用於正式會議。

五、匿名範圍與本機 HTTPS
========================
選票的答案及理由不附設備編號或提交時間；設備授權與選票內容分開。
主持頁顯示連線及配對資訊，投票只提供整體統計，不顯示個人答案。
這是應用程式資料及畫面層面的匿名，並非密碼學匿名投票協定。
主機、瀏覽器、作業系統及現場管理者仍須受到信任；自行填入可辨識
身份的理由文字也可能洩露身份。

HTTP 不加密。能觀察區域網路封包的人仍可能讀取或關聯投票請求。
有外部網路的開發環境應只使用測試票，不當作正式匿名投票環境。
最終隔離網路可減少外部接觸，但不等於傳輸加密或抵抗內部攻擊。

若部署需要加密，可自行準備本機受信任的伺服器憑證及私鑰，使用：

  Start-LAN.cmd --public-url https://192.168.50.10:8080 --tls-cert C:\NUK-Certs\server.crt --tls-key C:\NUK-Certs\server.key

憑證必須涵蓋實際主機 LAN IP，以及主持頁使用的 127.0.0.1。
所有 Android 平板及主機瀏覽器應預先信任發證的本機 CA。
主持網址改為 https://127.0.0.1:8080/host。
不要以忽略憑證警告作為正式部署方式；私鑰只保存在受控主機。
HTTPS 仍不改變前述的匿名範圍。

六、現場驗收與常見狀況
======================
正式啟用前，在實際 Windows 筆電、AP 及 21 台以上 Android 平板驗收：
  - 拔除最終網路的 WAN，全部平板仍可掃描、配對、更新議題及投票。
  - 01 至 21 同時操作，主持人核對全部配對；重複設備編號被拒絕。
  - 每個議題資格名單正確，名單外設備不能投票。
  - 同時送票、短暫斷線、原票重試，總票數不多記也不遺失。
  - 關閉議題後不能新投票；主機重啟後已接受的票及設定仍保留。
  - 平板不能進入主持頁，主持畫面不呈現個別設備的投票進度或答案。
  - QR 大小、Android 掃描行為及現場 Wi-Fi 覆蓋範圍符合實際使用。
自動化模擬驗證不能替代這項實機驗收；500 個編號不是效能承諾。

平板無法連線：先確認與主機同網路、IP 正確、服務視窗仍開啟，
再檢查私人網路防火牆規則與 AP 用戶端隔離。不要用關閉防火牆排除。
掃 QR 後畫面不對：確認掃描的是本次會議、主機目前 IP 的加入 QR。
編號已被占用：使用原平板的原瀏覽器；待核准申請可由主持人拒絕再登記。
已核准平板若清除 Cookie、改瀏覽器或換機，此版無法在原會議重新指派
該編號。先保留並結束目前會議，再建立新會議重新配對；不要冒用其他編號。
服務報埠已被使用：先查明既有服務；不要重複啟動兩份投票服務。
服務拒絕讀取資料：保留原資料及錯誤訊息，從備份副本檢查，
不要直接刪除 current.json 以重新啟動。
主機重啟後看不到會議：確認使用相同 Windows 帳號和資料路徑。

技術啟動方式（不使用啟動器時）
==============================
  runtime\node.exe lan-server.mjs --port 8080 --public-url http://192.168.50.10:8080 --data-dir "%LOCALAPPDATA%\NUK-LAN-Vote"

舊有 cPanel／雲端發行檔與此 LAN 版本分開。隔離設備使用這個 LAN
啟動器及 dist 中的 LAN 網頁，不以舊有雲端網址作為平板入口。
