一場競賽的決賽,四十支隊伍要報到。要做到:
就這樣。沒有登入、沒有付款、沒有複雜流程。

但這個「單純」的需求有一個很嚴格的隱藏條件:它必須快。而我會知道這件事,是因為在這場決賽的前幾天,另一場活動的報到系統讓我學了一次。
決賽之前還有一場活動要報到。那一版我用 Google Apps Script 做——就是接在 Google 試算表後面的那個自動化工具,可以寫一段程式,讓試算表自己做事。
想法很直覺:報名名單本來就在試算表裡,報到紀錄也寫回試算表,一氣呵成。功能上完全可行,資料也正確。
但它慢。
慢的原因不難理解:每一次報到請求都要啟動、驗證、打開試算表、寫入、回傳。試算表本來就不是為了「每秒好幾次寫入」而設計的。
這裡我要先誠實講一件事:我沒有留下任何量測值。 沒有回應時間紀錄、沒有壓力測試,當時就是覺得「這個速度我不敢拿去現場用」,然後就動手換掉了。所以這篇不會出現任何秒數,我也沒辦法告訴你它到底慢多少。這是這篇最弱的一環,寫出來比藏起來好。
我能拿出來的證據只有檔案時間:Apps Script 那一版的程式檔停在 5 月 30 日下午,Firebase 版的報到頁是 5 月 31 日晚上——隔一天就換掉了。(這兩個資料夾都沒有進版本控制,所以時間只能以檔案的修改時間為準。)
報到現場是一個實體空間。參加者站在報到桌前面,掃了碼、輸入編號,然後等。
打個比方感受一下——這是比喻,不是我量到的數字:在後台看,「回應時間三秒」是一個很普通、甚至算不錯的數字。在現場,那是一個人站在你面前,你們兩個大眼瞪小眼三秒鐘,後面還排著二十個人。
慢個兩三秒,乘上人數,就是一條移動不了的隊伍。 系統的效能在這裡不是技術指標,是排隊長度。
Firebase 是 Google 的一套雲端服務,這裡用到的是它的資料庫。架構變成這樣:
參加者手機 ──掃 QR──▶ 報到頁(輸入編號,比對名單)
│ 寫入
▼
雲端資料庫
│ 即時監聽
▼
大螢幕播放頁 ──顯示「已報到」
關鍵差別在即時監聽:大螢幕那一頁不用每隔幾秒去問一次「有沒有新的報到?」,而是先跟資料庫說「這份資料有變動就通知我」,資料一寫進去,畫面就自己更新了。
這是這種資料庫被設計出來要解決的問題,不是硬拗出來的用法。決賽那套系統裡,大螢幕頁和後台頁各有兩處用了這個機制。
Day 3 我提過,選工具會先問「它原本是為了解決什麼問題而生的」。那條判準就是從這次來的:Apps Script 的本行是替試算表加自動化——排程、通知、資料整理,它做這些很好。用它撐現場的即時互動不是它的錯,是我一開始挑錯了。
所以幾天後做決賽的報到系統時,我直接從 Firebase 開始。不是因為我變厲害了,是因為上一場的錯誤還很新。
決賽版做了幾個決定:
一、四十支隊伍的名單寫死在網頁程式碼裡。
雲端資料庫只記錄「誰報到了」,名單本身不放雲端。理由是名單在活動當天不會變,放雲端會多一次讀取(多一次延遲),還要多管一份權限。能不動的東西就不要讓它動。
二、純靜態網頁,不用任何建置流程。
整個系統就是幾個網頁檔加上樣式和程式,不需要編譯、不需要自己架伺服器。這件事對行政單位很重要——明年換人接手,他不需要會任何開發工具,打開檔案就能改。
三、工作人員的入口網址刻意不好猜,而且不放在首頁。
工作人員控制台看得到報到狀況、可以手動處理,不該讓參加者隨便點進去。做法是用一個不好猜的網址,並且不從任何地方連過去。
這裡要誠實:這不是真正的安全機制。 網址被轉傳出去就沒用了。但對一場幾小時的活動來說,這個程度的保護跟它的成本是相稱的——要做真正的權限管控就得有登入,而登入表示活動當天多一個可能出錯的環節。
這種取捨在行政工作裡很常見:不是選最安全的做法,是選「風險和成本相稱」的做法,並且知道自己選的是什麼。
寫這篇的時候我回去翻那個換過代的專案,發現一件事。
那個資料夾裡,Apps Script 的程式檔還在。它裡面有一段程式寫著「有人打開網頁時,就把 index 這個檔案送出去」——而 index 這個檔案,早就被我改成 Firebase 版了。
也就是說:舊的入口還指著新的頁面,兩代的東西躺在同一個資料夾裡,誰都沒刪。 當時能跑,因為我自己知道哪個是現行版。
問題是我不會永遠記得。明年有人接手,打開這個資料夾,他看到一個「看起來是主程式」的檔案,和一個「看起來是首頁」的檔案,兩者在架構上根本不是同一代的東西。他要怎麼知道哪個才是活的?
這不是假想。我另外一個用 AI 生出來的活動網站,資料夾裡躺著三份首頁檔,我現在已經分不出哪一份是實際上線的那一版。
AI 讓「做一個新版本」變得很便宜,但它不會幫你刪舊的。 換代的成本從「重寫」變成「幾個小時」,於是我們換得很勤,殘骸也累積得很快。刪掉不用的檔案聽起來是小事,但對一個隨時可能換人的行政單位來說,「哪一份是現行版」這個問題答不出來,等於這套東西沒有人能接。
主要是把想法變成能跑的東西:頁面版型、即時監聽的程式、大螢幕的顯示效果。這些是有標準做法的東西,產出得很快,換代那一天之所以一天就換完,也是因為這樣。
它不知道的是「現場會發生什麼」——有人手機沒網路、有人編號輸錯、有人代替隊友報到、大螢幕的字要多大才看得到。這些是站過報到桌才會知道的事。
它也不會提醒你把上一代的檔案刪掉。
Day 18:停車位抽籤——一個要讓所有人服氣的程式,該怎麼寫。