Orientation cho AI agent / dev mới. Đọc file này → hiểu repo, biết đọc tiếp ở đâu.
Static-first movie catalog (chuyên phim) theo CDN-as-database + edge video proxy. Đọc 100% file tĩnh trên CDN (không server); ghi bằng job ephemeral (không server); byte phim nặng qua proxy edge khi host cần CORS/Range.
Fork chuyên hoá từ nghyane/staticat — bỏ truyện (comic), giữ VIDEO, thêm lớp proxy làm tâm điểm.
WRITE (ephemeral) STORE READ (static) STREAM (edge)
GitHub Actions cron ──ghi──► R2 (data + token) ───► Cloudflare CDN ──► gd/src ─► proxy /p/*
transcode/sub/pack Drive/B2/R2 (video) Cache Rules r2/b2 ─► thẳng
- Write ⟂ Read — gặp nhau CHỈ qua file tĩnh R2. Crawler là bộ ghi; sập thì site đọc vẫn sống.
- Data ⟂ Blob — R2 giữ data + token trỏ blob (
gd:/r2:/b2:/src:). Byte phim ở host khác. Đổi host = đổi resolver, data y nguyên. - Mutable ⟂ Immutable — CHỈ pointer nhỏ (
head.json,feed/latest/0,search/head) tươi (SWR). Mọi payload*.v{rev}immutable, cache vĩnh viễn. - Direct ⟂ Proxied —
r2/b2phát thẳng custom domain;gd/srcqua proxy/p/<token>(Range/CORS/confirm/hide). Data/v1/*.jsonKHÔNG bao giờ qua proxy.
spec/contract.yaml— data contract machine-readable (entities, paths, fields, TTL, examples). CHÍNH XÁC ở đây.spec/proxy.yaml— hợp đồng lớp proxy (endpoint, behavior, resolver, deploy/test).contract/contract.ts— mirror TS của contract.yaml (types + path builders + token codec +resolveBlob). Lệch → contract.yaml thắng.spec/cache-rules.yaml— chính sách cache deployable.
| Bạn muốn… | Đọc |
|---|---|
| Hiểu tổng thể, vì sao thiết kế vậy | docs/architecture.md |
| Lớp proxy video (Range/CORS/HLS) | docs/proxy.md + spec/proxy.yaml + proxy/ |
| Schema chính xác 1 file/entity + path + TTL | spec/contract.yaml |
| Dùng trong code (types/path/token/resolve) | contract/contract.ts |
| Cách crawl→transcode→ghi (thứ tự an toàn, cron) | docs/ingestion.md |
| Lớp dynamic (watch-progress sync + comment) | spec/dynamic.yaml |
| Cấu hình cache CDN | spec/cache-rules.yaml |
| Quickstart cho người | README.md |
- Mọi path dưới
/v1. Đổi schema phá vỡ → ra/v2, bumpCONTRACT_VERSION; client cũ không vỡ. - Đơn vị: title (phim) → parts (tập).
kind = movie | series. - Payload part discriminated theo
kind:video-mp4|video-hls(KHÔNG còn comic). - Phụ đề rời
SubtitleTrack[](.vtt/.srt) đa ngôn ngữ. - List view (feed/search) denormalized → 1 fetch là render được card.
- Ghi: immutable TRƯỚC, pointer SAU; idempotent (hash-based).
- Proxy chỉ
gd/src;r2/b2phát thẳng → endpoint trả 400 nếu nhận r2/b2.
Pha 0 (spec + proxy + ingest) xong: proxy/ (Worker/Pages Fn), ingest/ (Bun + ffmpeg) + .github/workflows/ingest.yml. TODO: frontend Astro (repo riêng, import contract.ts), crawler thật (kế thừa Source).