forked from IsaacGemal/wikitok
-
Notifications
You must be signed in to change notification settings - Fork 0
Introduction
Hsiehting Lin edited this page Jul 3, 2026
·
1 revision
Hematok 是把 ASH Image Bank 的血液學/病理學影像,做成 TikTok 式垂直捲動的學習介面。UI fork 自 WikiTok,改寫為讀取靜態 feed(feed.json),影像位元組由 Cloudflare R2 供應。
- 垂直 snap-scroll 無限捲動,共 6,973 筆紀錄 / 7,950 張影像
- 單擊隱藏介面元素;全螢幕雙指縮放檢視影像細節
- Details sheet 顯示完整 metadata;其中 134 個 reference case 帶有完整臨床描述
- 多影像的 reference case 以卡片內畫廊左右滑動
- 語意推薦:依「喜歡」的影像找出相似影像(like-based recommendations),「不喜歡」可反向調整
- PWA:可安裝、Service Worker 自動更新
- Owner 登入:站長的 like / dislike / read 紀錄存到伺服器端,跨裝置同步並影響推薦
瀏覽器
├─ Cloudflare Pages(hematok) React 前端,載入 public/feed.json
├─ R2(hematok-img,公開自訂網域) 影像位元組,URL = ${VITE_IMG_BASE}/<key>
├─ Worker(hematok-rec-api) /recommend 語意推薦(Vectorize + Workers AI)
└─ Pages Functions(/api/*) owner 登入與伺服器端互動紀錄(KV)
- like / dislike 存在
localStorage;已讀(seen)存在記憶體 +localStorage的readImages - 推薦呼叫公開、無狀態的
hematok-rec-api.hsieh-ting-lin.workers.dev/recommend
- 瀏覽器改走同源的
hematok.pages.dev/api/*(Pages Functions):-
GET /api/me— 目前身分 -
GET /api/state— 從 KV 取回{ liked[], disliked[], read[] } -
POST /api/events— 記錄 like / unlike / dislike / undislike / read / unread -
POST /api/merge— 登入時把 localStorage 歷史 union 進 KV -
GET /api/login— Access 登入 trampoline(email 路徑用)
-
- 狀態存 Cloudflare KV,key 為
u:<email>(binding 名STATE) - 推薦邏輯不變:登入後客戶端一樣呼叫公開
/recommend,只是 liked/disliked/seen 改由伺服器 hydrate
-
Cloudflare Access email 登入(設計上的最終方案,「方向 A」) — 由 Access 注入
Cf-Access-Jwt-Assertion,函式讀取 email claim 比對 allow-list。Access 閘門尚未建立(見 Tech-Debt)。 -
Owner bearer token(現行可用) — header 的 Login 輸入 token,以
Authorization: Bearer <token>送出,與 Pages secretOWNER_TOKEN做 constant-time 比對。
目前唯一允許的使用者是 hsieh.ting.lin@gmail.com。
frontend/ React + Vite + Tailwind 前端
public/feed.json 前端載入的 feed(由 prep/build_feed.py 產生)
functions/api/ Pages Functions(me/state/events/merge/login)
pages-lib/ 共用後端邏輯(gate.ts 認證)
worker/ hematok-rec-api 推薦 Worker
prep/
build_feed.py index.jsonl → frontend/public/feed.json(含 refcase 描述)
build_embeddings.py 建立 Vectorize 的向量索引
upload_r2.sh rclone 上傳器 → R2(讀取 ../.env)
docs/plans/ 設計文件(見 [[Plan]])
plan-for-deploy-r2.md 部署 runbook
mock-data/ smoke test 用的小型 schema 鏡像(非真實資料)
feed.json 裡的 image key 必須等於 R2 的 object key:
來源檔案(~/ash-image-bank/data/) |
R2 object key |
|---|---|
collection/<id>/<id>.jpg |
collection/<id>/<id>.jpg |
atlas/<id>/<id>.jpg |
atlas/<id>/<id>.jpg |
reference-cases/<id>/images/<imgid>.jpg |
reference-cases/<id>/images/<imgid>.jpg |
若重新爬取後目錄結構改變,必須同時修改 prep/build_feed.py 的 keys_for()、重新產生 feed.json,並調整 rclone 上傳來源,讓兩邊 key 保持一致。
影像與 metadata © American Society of Hematology 及原始貢獻者。UI fork 自 WikiTok。