V12.1 Curriculum Sync: curriculum metadata, lesson release, progress và student resources sync Web ↔ Desktop. Teacher-only guides, answer keys và draft chưa publish không vào Offline Pack.
V12.1 · Hybrid Cloud + Desktop

Một hệ thống, hai cách mở — dữ liệu phải là một

Web và bản cài trên máy dùng cùng API, cùng quyền và cùng cloud database. Desktop chỉ giữ cache/offline queue; khi có mạng, mọi thay đổi đi qua Sync Engine rồi mới trở thành dữ liệu chính thức trên server.

Đang online
🌐

Web App

HTTPS + IndexedDB cache. Luôn ưu tiên server, có thể giữ draft/note nhẹ khi mất mạng.

☁️

Cloud Core

PostgreSQL + Storage + Realtime + Auth. Đây là nguồn sự thật duy nhất cho toàn bộ tổ chức.

💻

Desktop App

Cùng frontend, đóng gói bằng Tauri. SQLite cache + file cache + Outbox để làm việc khi offline.

Trạng thái đồng bộ thiết bị

Những chỉ số này phải có trên cả web và desktop để người dùng luôn biết dữ liệu đã lên cloud chưa.

Kết nốiOnline
Thay đổi chờ0
Lần sync cuốiVừa xong
Offline pack284 MB2 khóa đã tải
App version9.0.0Đã cập nhật

Ma trận đồng bộ toàn bộ tính năng

Không phải chức năng nào cũng nên cho “offline rồi tự ghi đè”; các phần nhạy cảm cần policy khác nhau.

Tính năngWeb onlineDesktop onlineDesktop offlineKhi có mạng lạiQuy tắc xung đột
Tài khoản / vai trò / quyềnĐầy đủĐầy đủDùng quyền đã cacheRefresh token + quyền mớiServer luôn thắng; role bị thu hồi phải khóa local ngay khi sync.
Lịch lớp / giáo viên / dạy thayTạo & xác nhậnTạo & xác nhậnChỉ lưu nhápServer chạy conflict check rồi mới publishHard conflict không auto-merge
Điểm danhRealtimeRealtimeĐược nhậpSync từng học viênMerge theo record học viên; nếu 2 GV sửa cùng một người thì hiện conflict.
Đăng thông báo / note lớpĐăng ngayĐăng ngayQueueĐăng theo thứ tự OutboxPost mới là append-only; edit dùng version.
Tạo bài tập / testĐầy đủĐầy đủDraft đượcUpload file → kiểm tra → publishKhông publish offline nếu có deadline/lịch cần kiểm tra.
Làm test onlineAutosaveAutosaveNếu test đã tảiGửi attempt + answersFinal submit bất biến theo attempt ID; không để answer key nhạy cảm trong cache.
Nộp bài file / PDF / Word / ExcelUploadUploadQueue fileResumable upload + checksumChỉ hiện “Đã nộp” sau server ACK; trước đó là “Chờ đồng bộ”.
Bài luyện nói / audioUploadRecord + uploadRecord localResume upload khi onlineGiữ file local tới khi server xác nhận hash + storage object.
Chấm điểm / feedbackĐầy đủĐầy đủDraft feedbackOptimistic-lock publishNếu bài đã được GV khác chấm, bắt buộc chọn bản nào giữ.
Sổ tay / từ vựng / ngữ phápĐầy đủĐầy đủĐầy đủDelta sync từng itemItem UUID riêng; sửa khác trường thì merge, cùng trường thì hỏi người dùng.
Chat / comment / reactionRealtimeRealtimeQueue gửiSend theo client_message_idIdempotent; không gửi trùng khi retry.
Tài liệu đã tải vềBrowser cacheFile cacheXem offlineKiểm tra version/hashFile mới tạo version mới; không ghi đè file đang mở.
Khóa học hết hạn / archiveServerServerRead-only cacheNhận trạng thái mớiServer authoritative; local tự khóa khi nhận trạng thái ended/archived.

Demo Outbox — thao tác khi mất mạng

Thử tắt mạng rồi tạo các thay đổi. Khi online lại, Sync Engine đẩy từng mutation và kiểm tra quyền/xung đột.

Tạo thay đổi

Nhật ký Sync Engine

Luồng dữ liệu chuẩn

Frontend web và desktop tuyệt đối không tự coi local database là nguồn chính.

Web / Desktop UITạo mutation có UUID
Sync Engine + APIAuth · idempotency · conflict check · permissions
Cloud PostgreSQLCommit + change event + storage metadata
Chiều ngược lại: Realtime/Broadcast hoặc delta-pull theo sync cursor cập nhật Web IndexedDB và Desktop SQLite.

Offline Pack

Người dùng chọn khóa cần mang theo. Không tải toàn bộ dữ liệu doanh nghiệp về máy.

IELTS Speaking B1 · Offline Pack
Lịch 30 ngày · slide/PDF · audio · note đã ghim · bài tập mở · test cho phép offline. Không tải private admin data hay answer key nhạy cảm.
Ước tính 142 MB

Smart Conflict Resolution

Sync tốt không chỉ “retry”; phải giúp người dùng hiểu bản nào mới hơn và tránh ghi đè im lặng.

1 conflict demo
ConflictLịch dạy

Desktop draft khác với lịch Cloud mới.

Desktop: Group B · 18:30–19:30 · tạo 16:20 offline.
Cloud: Cô Hà đã được gán IELTS B1 · 18:00–19:30 · cập nhật 16:27.

Không có nút “ghi đè Cloud” vì đây là hard schedule conflict.
Prefetch thông minhWi‑Fi

Tải trước thứ học viên sắp cần.

Ưu tiên tài liệu của 3 buổi tới + assignment đang mở + audio đã ghim; không tải toàn bộ kho tài nguyên.

Giảm dung lượng, nhưng người học vẫn có đủ nội dung cho 7 ngày tiếp theo.

8 quy tắc tôi đề nghị khóa cứng trong sản phẩm

1. Cloud là source of truthSQLite/IndexedDB chỉ cache, không phải database thứ hai.
2. Mọi mutation có client_mutation_idRetry bao nhiêu lần cũng không tạo bài/nộp file trùng.
3. Lịch xung đột phải kiểm tra serverOffline chỉ draft; không tự xác nhận teacher slot.
4. File dùng checksum + resumable uploadMất mạng giữa 90% không phải upload lại từ đầu.
5. Hiển thị trạng thái thật“Đã lưu trên máy” khác “Đã đồng bộ lên cloud”.
6. Logout phải purge cache theo userTránh người sau mở máy đọc dữ liệu lớp trước.
7. Private data mặc định không offlineAdmin secrets, private teacher notes và dữ liệu nhạy cảm chỉ cache khi thật cần.
8. App update tách khỏi data syncDesktop auto-update code; Sync Engine cập nhật dữ liệu. Hai việc không được lẫn nhau.