IMMI-Case- 是澳洲移民法庭案例的下載、管理與分析平台。從 AustLII 抓取 9 個法院 / 仲裁庭(149,016 筆案件,2000–2026)。提供全文搜尋、法官排行榜、視覺化分析,以及 LLM Council 智能摘要。 主要使用者是自助申請的移民申請人——非法律專業人士,在壓力情境下使用。
IMMI-Case- is a platform for downloading, managing, and analyzing Australian immigration tribunal cases. It scrapes 9 courts/tribunals from AustLII (149,016 cases, 2000–2026), offering full-text search, judge leaderboards, visual analytics, and LLM Council intelligent summaries. Primary users are self-represented immigration applicants — non-lawyers using the platform under high-stress conditions.
品牌定位:權威 · 精準 · 學術。美學方向:「法律典籍」(暖米白 + 深海軍藍 + 琥珀金)。
Brand positioning: Authoritative · Precise · Academic. Aesthetic: "Legal Codex" (warm off-white + deep navy + amber gold).
根本原因:LATERAL unnest 在 149K 行上展開法官陣列,執行 3 次全表掃描。加索引 7.3x → 再加 Cache API TTL=600s → 合計 383x。
Root cause: LATERAL unnest expanding the judges array over 149K rows, causing 3 full-table scans. Adding an index yielded 7.3x; adding Cache API TTL=600s combined to 383x total.
vite.config.ts manualChunks 從 object 改為 arrow function。i18next + react-i18next + 2x locale JSON(115 KB)拆成獨立 lazy chunk。
Changed vite.config.ts manualChunks from object to arrow function. i18next + react-i18next + 2× locale JSON (115 KB) split into an independent lazy chunk.
wrangler.toml 加 cron trigger,scheduled() 執行 SELECT 1 保持 Worker isolate + Hyperdrive TCP 連線池存活,消除冷啟動。
Added cron trigger to wrangler.toml; scheduled() runs SELECT 1 to keep Worker isolate + Hyperdrive TCP connection pool alive, eliminating cold starts.
success-rate 冷啟動 8.9s(LATERAL unnest judges 欄位),visa-families 5.5s。四個端點加 Cache API,納入 cron 預熱。
success-rate cold start 8.9s (LATERAL unnest on judges column), visa-families 5.5s. All four endpoints given Cache API and included in cron pre-warming.
三個 concept 分析端點,LATERAL unnest legal_concepts 欄位,其中 concept-cooccurrence 冷啟動 13.0s。全部加 Cache API TTL=600s,URL key 含 limit/min_count 參數。
Three concept-analysis endpoints using LATERAL unnest on legal_concepts; concept-cooccurrence cold start was 13.0s. All given Cache API TTL=600s with URL keys including limit/min_count params.
judge-compare 冷啟動 6.6s(平行 LATERAL unnest 最多 4 法官)、taxonomy/countries 4.3s(GROUP BY country_of_origin 149K 行)。
judge-compare cold start 6.6s (parallel LATERAL unnest for up to 4 judges); taxonomy/countries 4.3s (GROUP BY country_of_origin over 149K rows).
Wave 5 部署後全部端點顯示冷啟動。根本原因:cron 只預熱 4 個端點,curl 打到不同 CF PoP。scheduled() 擴展至 8 個 handler,覆蓋所有高影響分析頁。
After Wave 5 deploy, all endpoints showed cold starts. Root cause: cron only warmed 4 endpoints while curls hit different CF PoPs. Expanded scheduled() to 8 handlers, covering all high-impact analytics pages.
Telegram Widget → Worker HMAC 驗證 → AuthNonce DO replay 防護 → DB upsert user → HS256 JWT(5min access + 7d refresh cookie)→ Supabase RLS 透過 SET LOCAL request.jwt.claims 實現多租戶隔離。
Telegram Widget → Worker HMAC verify → AuthNonce DO replay protection → DB upsert user → HS256 JWT (5min access + 7d refresh cookie) → Supabase RLS multi-tenant isolation via SET LOCAL request.jwt.claims.
每個認證 DB 查詢發出 JSON 結構化日誌(kid、tenant_id、user_id、query_ms、ok)。4 個 schema mismatch 修正。Sidebar + Topbar 接入 auth state。
Every authenticated DB query emits JSON structured logs (kid, tenant_id, user_id, query_ms, ok). 4 schema mismatches fixed. Sidebar + Topbar wired to auth state.
tests/integration/rls_isolation.sql(跨租戶查詢驗證)、test_revoke_member.py(成員移除閉環,高風險 race condition 修正)、tests/k6/auth-latency.js(auth 端點壓力測試,thresholds:p95<800ms)。
tests/integration/rls_isolation.sql (cross-tenant query validation), test_revoke_member.py (member-removal closed-loop with high-risk race condition fix), tests/k6/auth-latency.js (auth endpoint load test, thresholds: p95<800ms).
caches.default.put() 只填充請求落地的那個 PoP。Cron 預熱也只預熱「cron 執行的 PoP」(通常是澳洲)。非 APAC 用戶第一次請求仍是冷的——這不是 bug,是 HTTP CDN 的設計。澳洲使用者(Sydney/Melbourne PoP)享有穩定的暖路徑。
Cloudflare maintains independent Cache API storage across ~300 PoPs. caches.default.put() only populates the PoP where the request lands. Cron pre-warming also only warms the PoP where cron runs (typically Australia). Non-APAC users still get a cold first request — this is not a bug, it is HTTP CDN by design. Australian users (Sydney/Melbourne PoP) enjoy a reliably warm path.
const sql = postgres(...) 放在函數外都會導致「Cannot perform I/O on behalf of a different request」錯誤。Hyperdrive 管理 TCP 連線池,Worker 只傳 connectionString。
Workers I/O context is bound to a single request lifecycle. Any const sql = postgres(...) placed outside a function will cause "Cannot perform I/O on behalf of a different request" errors. Hyperdrive manages the TCP connection pool; the Worker only passes connectionString.
set_config('request.jwt.claims', '...', true)。true = transaction-local,隨 transaction 結束消失。若設 false(session-local),Hyperdrive 連線池重用時前一個用戶的 claims 會洩漏給下一個請求——跨租戶資料洩漏。
set_config('request.jwt.claims', '...', true). true = transaction-local, disappears when the transaction ends. Setting false (session-local) causes the previous user's claims to leak into the next request when Hyperdrive reuses a connection — cross-tenant data leak.
_cache.match(),命中直接 return cached。Hyperdrive 連線池在 Cache API 命中的請求中完全不被觸及。這降低了 DB 負載和連線使用,是 Cache API 成本收益的核心。
Every cached handler first calls _cache.match() and on a hit directly return cached. The Hyperdrive connection pool is never touched in Cache API-hit requests. This reduces DB load and connection usage — it is the core value of Cache API.
idFromName("flask-v15") 定位容器。改名 = 新實例(冷狀態)。只有刻意重置時才改(例如強制取得新 container image)。目前版本 v15,見 workers/proxy.js:2475。
Durable Objects use idFromName("flask-v15") to locate the container. Renaming = new instance (cold state). Only rename intentionally (e.g., to force a new container image). Current version v15, see workers/proxy.js:2475.
buildCasesWhere() 對 tag 參數回傳 null,Worker 檢測到 null 就 fallthrough 到 FlaskBackend DO。Pipe-delimited 陣列邏輯只在 Python 端有。新增 Worker handler 時無需處理 tag 過濾。
buildCasesWhere() returns null for the tag parameter; the Worker detects null and falls through to FlaskBackend DO. Pipe-delimited array logic only exists on the Python side. New Worker handlers do not need to handle tag filtering.
refresh_sessions(jti, user_id, expires_at, revoked_at) 表,refresh token 加 jti claim,AuthNonce DO 或 DB 驗證 jti 未撤銷。
Create a refresh_sessions(jti, user_id, expires_at, revoked_at) table, add jti claim to refresh tokens, and validate jti is not revoked via AuthNonce DO or DB.
根據近期動態與未閉環事項推斷。非指令,而是「動能指向哪裡」的描述。 Inferred from recent activity and open items. Not directives — a description of "where the momentum points."