●●●~/happy-singing — zsh — 點歌資料流
HAPPY SINGING · 點歌資料流
客人在左、DJ 在右,中間是兩邊共用的那一份資料。線上寫的是「這一段傳的是什麼」;好幾個循環同時在跑。
■ 客人手機■ songs-order API■ 資料(PostgreSQL/R2)■ Netlify/上游■ 外部服務■ DJ 點播台──▸ 請求──▸ 回傳的資料──▸ 讀寫資料庫──▸ 客人帶著走的東西
第一段 · 只有查歌站 每家店都有,不用開通;歌單由上游往客人手機流
joysound 代查 API
外部 · Zeabur
日本機(JOYSOUND/DAM)
GET /api/search
DJ 代客點歌也打它
Cloudflare R2 · 曲庫桶
custom/<店>.json
rayying.json、kingsong.json …
客人直接 GET,快取 5 分~1 天
API · 曲庫同步
POST …/catalog-sync/trigger
POST …/catalog-sync/push
每天拉店家 Sheet
曲庫只有它能寫
上游 · 歌單來源
瑞影爬蟲 · 每週五
金嗓爬蟲 · 每月 2–4 號
店家 Google Sheet · 每天
跟有沒有人點歌無關
客人手機 · 查歌
曲庫 JSON 下載到手機
在手機上搜,不打 API
日本機才即時問 joysound
沒開點歌的店到此為止
Netlify · site-config
GET site-config 函式
外觀+曲庫清單 manifest
console 發布器寫的
最多等 1 秒,否則用上次的
歌單
寫 JSON
曲庫 JSON
即時結果
外觀+曲庫清單
想點歌:掃 QR
第二段 · 開通點歌站 客人和 DJ 透過同一份 song_requests 連在一起
Netlify
簽章代理
Netlify
後台簽章代理
客人手機 · 掃 QR 入座
開 /join/{publicCode}
POST /v1/guest/join
{publicCode, 裝置 id, 暱稱?}
收到 cookie,JS 讀不到
客人手機 · 點歌
POST …/guest/song-requests
歌號+catalogKey
+idempotencyKey(防重送)
回 201:排第幾
客人手機 · 看排隊
每 4 秒 GET /v1/guest/queue
帶 since=上次的游標
沒變就幾乎不傳東西
自己的歌:排第幾/已播
cookie 跟著走
記住單號
API · 入座
驗簽章 → 對到哪一家店
店家由伺服器判定
發 32 bytes token
回 Session+Set-Cookie
API · 收單
五道門:停點開關、
cookie、店家暫停、
服務期限、限流 20 首/分
過了才開一筆交易
API · 客人佇列
只回這桌的歌
queued/played+剩幾首
游標=queue version
沒變就回「沒變」
PostgreSQL
客人和 DJ 共用這一份
guest_devices
一台手機一列,存 token 雜湊
seat_sessions
queue version:一有變就 +1
song_requests
點的每一首歌=一列
客人 寫入 status = queued
客人 每 4 秒讀自己的
DJ 每 4 秒讀全部 queued
DJ 改成 played/rejected
兩邊從來不直接講話,
都是透過這一列。
每次寫入都記 audit_logs
API · DJ 佇列
GET /v1/staff/queue
回各桌 queued 清單
游標沒變=沒有新歌
API · 標記已播
POST …/mark-played
帶 expectedVersion
版本對不上就擋下
queue version +1
DJ 點播台 · 輪詢
每 4 秒問一次
分頁在前景才打
GET /staff-api/queue
cookie:__Host-order_staff
DJ 點播台 · 按已播
播完一首按一下
也可以退回 reject
或取消 cancel
看到新歌
publicCode
Set-Cookie
寫裝置
歌+cookie
201 queued
INSERT
每 4 秒 since=
排第幾/已播
讀自己的
讀全部
每 4 秒 since=
新歌清單
已播+版本
played
改狀態
歌單同步
每天/每週五/每月 2–4 號
自己的排程,跟店裡忙不忙無關
客人輪詢
每 4 秒 · GET /v1/guest/queue
每一台入座的手機各跑一個
DJ 輪詢
每 4 秒 · GET /v1/staff/queue
新歌最多晚 4 秒出現在點播台
有人按才發生
入座、點歌、已播 · POST
插進上面兩個循環之間
同時在跑的循環