From 6319386a2fec8d837d3374cd7375b743154bf416 Mon Sep 17 00:00:00 2001 From: virtus Date: Mon, 11 May 2026 15:28:00 +0700 Subject: [PATCH] docs: Revise architecture and contract documentation, clarify mobile API behavior, and update import flow details --- ARCHITECTURE.md | 4 ++-- CONTRACT.md | 1 + CROSS_REPO_ENDPOINT_MATRIX.md | 11 +++------ FLOWS.md | 2 +- README.md | 23 ++++++++----------- .../novel/providers/novels_provider.dart | 2 +- 6 files changed, 18 insertions(+), 25 deletions(-) diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 25d1910..e035d0e 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -26,8 +26,8 @@ Tai lieu nay mo ta vai tro `reader-app` trong he sinh thai doc truyen gom web + ## Environment va ket noi -- Local API mac dinh: `http://10.0.2.2:8000` (Android emulator). -- Script `scripts/flutter_run_with_env.sh` la cach chuan de chay local. +- Khong co `--dart-define`: Android native mac dinh toi `https://reader-api.fevirtus.dev`; cac platform khac `http://localhost:8000` (`lib/core/config/app_config.dart`). +- Dev local Android emulator: dat `BASE_URL=http://10.0.2.2:8000` trong `.env.mobile` va chay qua `scripts/flutter_run_with_env.sh`. - `BASE_URL`, `GOOGLE_SERVER_CLIENT_ID`, `GOOGLE_CLIENT_ID` duoc truyen qua `--dart-define`. ## Definition of Done (Mobile) diff --git a/CONTRACT.md b/CONTRACT.md index ec3812c..8366f3e 100644 --- a/CONTRACT.md +++ b/CONTRACT.md @@ -32,6 +32,7 @@ Tai lieu contract chung cho `reader`, `reader-app`, `reader-api`. - `409`: xung dot du lieu. - `422`: payload format dung JSON nhung khong dat rule nghiep vu. - `500`: loi he thong. +- `410`: (du tru) tai nguyen da go bo hoac khong con ho tro. ## Pagination Convention diff --git a/CROSS_REPO_ENDPOINT_MATRIX.md b/CROSS_REPO_ENDPOINT_MATRIX.md index a36721b..a04806a 100644 --- a/CROSS_REPO_ENDPOINT_MATRIX.md +++ b/CROSS_REPO_ENDPOINT_MATRIX.md @@ -26,17 +26,12 @@ Legend: | Comment | `GET/POST /api/truyen/{id}/comments` | Y | Y | Y | | | Rating | `POST /api/truyen/{id}/rate` | Y | Y | N | Mobile chua thay rating flow | | Search | `GET /api/truyen/suggest` | Y | Y | N | Mobile search suggest can bo sung | -| Import | `GET /api/import/assets/search` | Y | Y | N | Web MOD-only flow | -| Import | `GET /api/import/assets/{id}/preview-metadata` | Y | Y | N | Web MOD-only flow | -| Import | `POST /api/import/assets/{id}/ai-suggest` | Y | Y | N | Web MOD-only flow | -| Import | `POST /api/import/assets/{id}/review` | Y | Y | N | Web MOD-only flow | -| Import | `POST /api/import/assets/{id}/parse-preview` | Y | Y | N | Web MOD-only flow | -| Import | `POST /api/import/assets/{id}/start-import` | Y | Y | N | Web MOD-only flow | -| Import | `GET /api/import/sessions/{sessionId}` | Y | Y | N | Web MOD-only flow | +| Import | `POST /api/import/uploads/preview` | Y | Y | N | Upload EPUB multipart (preview) | +| Import | `POST /api/mod/epub`, `POST /api/mod/epub/ai-suggest` | Y | Y | N | Luong `/mod/import` | +| Import | `GET/POST/PUT/DELETE /api/mod/the-loai` | Y | Y | N | MOD quan ly the loai trong wizard | ## Priority gaps de dong bo tiep 1. Mobile: `user/settings`, `recommendations`, `rate`, `suggest`. 2. Web/Mobile chapter-read strategy can unify (`chapters/{id}` vs `by-number`). 3. Chuan hoa error contract implementation theo `CONTRACT.md`. -4. Import EPUB is intentionally out of mobile scope. diff --git a/FLOWS.md b/FLOWS.md index 6e013fc..13ff00a 100644 --- a/FLOWS.md +++ b/FLOWS.md @@ -49,4 +49,4 @@ Muc tieu: mobile follow cung business behavior voi web. ## Out of Scope (Current) -- EPUB import flow (`/api/import/*`) is MOD-only on web and not planned for mobile client. +- MOD EPUB import chi tren web (`/mod/import`: `/api/mod/epub`, `POST /api/import/uploads/preview`, …). Mobile khong co wizard import. diff --git a/README.md b/README.md index a0c4978..bdada2d 100644 --- a/README.md +++ b/README.md @@ -7,16 +7,11 @@ Flutter mobile app for reading novels, synced with the existing web platform. - Full end-user feature parity with the current web app. - Excludes all moderator/admin workflows. -## Planned Feature Set +## Implemented vs planned -- Google login and authenticated user session. -- Home feed, hot boards, and recommendations. -- Search with suggestions, genre, status, and sort filters. -- Novel detail with chapter list and series metadata. -- Reader with TOC, reading preferences, and progress sync. -- Bookshelf tabs: Dang doc, Danh dau, Da doc, De cu. -- Comments, ratings, and user recommendations. -- Native TTS and offline reading support. +Đã có trong code (theo `lib/features`): đăng nhập Google, home/browse, genres, tìm kiếm, chi tiết truyện + danh sách chương, reader (kèm TTS), bookshelf, bookmark/progress, bình luận, splash/settings. + +Còn thiếu hoặc mới dạng placeholder so với web: gợi ý tìm kiếm (`/api/truyen/suggest`), đánh giá truyện (`/api/truyen/{id}/rate`), đồng bộ settings và đề cử người dùng (`/api/user/settings`, `/api/user/recommendations`). Chi tiết parity xem `FEATURES.md` và `CROSS_REPO_ENDPOINT_MATRIX.md`. ## Architecture @@ -51,12 +46,14 @@ This script reads `.env.mobile` and automatically passes: - `GOOGLE_SERVER_CLIENT_ID` - optional `GOOGLE_CLIENT_ID` -Default `BASE_URL` behavior: +Default `BASE_URL` khi **không** truyền `--dart-define` (xem `lib/core/config/app_config.dart`): -- Android emulator: `http://10.0.2.2:8000` -- Others (iOS simulator, desktop, web): `http://localhost:8000` +- Android (native, không phải web build): `https://reader-api.fevirtus.dev` +- Các nền tảng khác (iOS, desktop, web build, v.v.): `http://localhost:8000` -If needed, you can still override explicitly: +Để dev local trên Android emulator, luôn set rõ qua `--dart-define` hoặc file `.env.mobile` + `scripts/flutter_run_with_env.sh`, ví dụ `http://10.0.2.2:8000`. + +Override trực tiếp: ```bash flutter run --dart-define=BASE_URL=http://localhost:8000 diff --git a/lib/features/novel/providers/novels_provider.dart b/lib/features/novel/providers/novels_provider.dart index 9aae778..4e4de0b 100644 --- a/lib/features/novel/providers/novels_provider.dart +++ b/lib/features/novel/providers/novels_provider.dart @@ -220,7 +220,7 @@ final chapterListProvider = try { return await fetchAllChapters(novelId); } catch (_) { - // Backend stores chapters by novel id in MongoDB; if route opened by slug, + // If route opened by slug/id mismatch, resolve canonical novel id and retry once. // first request can return empty list. Resolve canonical id and retry once. try { final novelRes = await client.dio.get('/api/novels/$novelId');