Sync — kênh đồng bộ BE ↔ FE ↔ Mobile
Nơi 3 bên (backend/, frontend/, mobile/) báo cho nhau mọi thay đổi hoặc vấn đề ảnh hưởng tới bên
khác, rồi theo dõi đến khi từng bên đã xử lý xong. Mỗi thay đổi hoặc vấn đề là 1 sync note (1 file
markdown). Mỗi bên nhận có trạng thái riêng trong note đó.
- Backlog từng bên vẫn ở chỗ cũ (
docs/tasks/**cho BE,plans/**cho FE). Sync note chỉ là lớp giao tiếp giữa các bên: nó trỏ tới task/PR quarefs, không thay thế backlog. - Việc gì đang chờ bên nào: xem INBOX.md (sinh tự động).
Cấu trúc
sync/
README.md # file này — giao thức
INBOX.md # sinh tự động: việc đang chờ của từng bên — KHÔNG sửa tay
_TEMPLATE.md # mẫu 1 sync note
scripts/sync.mjs # new | inbox | check | notify
_shared/ # thay đổi xuyên module: auth/refresh token, envelope {data}, format lỗi, pagination...
identity/ wework/ workflow/ request/
2026-09-24-be-workflow-task-patch-delete.md
Tên file = id = <YYYY-MM-DD>-<bên raise>-<slug>. Đặt theo ngày nên nhiều người tạo note song song trên
nhiều branch cũng không đụng số thứ tự.
Khi nào phải tạo sync note
Bắt buộc khi thay đổi của bạn làm bên khác phải làm gì đó hoặc phải biết:
- BE: thêm/sửa/xoá endpoint, DTO, mã lỗi, enum, quyền truy cập, hành vi nghiệp vụ mà client thấy được;
fix bug làm đổi response; deprecate một API. Khi sửa
*.controller.ts,*.dto.tshoặcprisma/schema.prismamà PR không kèm sync note, CI sẽ cảnh báo. Nếu thay đổi đó thật sự không ảnh hưởng client, ghi lý do trong PR description. - FE/Mobile: phát hiện bug hoặc hành vi lạ ở API (
bug-report), cần endpoint/field mới (featurevớitargets: { be: pending }), hoặc cần hỏi BE (question).
Không cần cho refactor nội bộ, test hay tài liệu không đổi contract.
Frontmatter
| Trường | Giá trị |
|---|---|
id |
trùng tên file (không có .md), không đổi sau khi tạo |
title |
tiêu đề ngắn |
module |
identity | wework | workflow | request | shared (→ thư mục _shared/) |
from |
bên raise: be | fe | mobile |
author |
người raise |
type |
feature | breaking | bugfix | deprecation | bug-report | question |
priority |
blocker | high | normal | low |
created |
YYYY-MM-DD |
refs |
task/PR liên quan, vd [WORKFLOW-018, WORKFLOW-FE-003, PR-47] |
targets |
map bên: trạng thái cho mỗi bên nhận (không gồm bên raise) |
Trạng thái của mỗi bên nhận
pending ──► acked ──► applied
│ │
└──► disputed ◄──┘ (phản biện → bên raise trả lời → bên nhận chuyển lại acked/applied/n/a)
└──► n/a (không ảnh hưởng bên mình — ghi lý do)
| Trạng thái | Nghĩa | Ai đặt |
|---|---|---|
pending |
chưa ai bên nhận đọc | bên raise, lúc tạo |
acked |
đã đọc, đồng ý, sẽ làm (ghi dự kiến task nào) | bên nhận |
applied |
đã làm xong ở phía mình (ghi PR/commit) | bên nhận |
disputed |
không đồng ý / cần làm rõ / phát hiện vấn đề ở thay đổi này | bên nhận |
n/a |
không liên quan tới bên mình (ghi lý do) | bên nhận |
Note đóng khi mọi bên nhận đều ở applied hoặc n/a. Note đã đóng vẫn giữ nguyên trong thư mục làm
lịch sử. Không xoá note.
Mobile: trong lúc mobile/ chưa có code (xem MOBILE_RULES.md), đặt mobile: n/a để không tích backlog
ảo. Khi mobile khởi động, bên mobile đọc Swagger hiện tại chứ không đọc lại các note cũ.
Quy trình
- Raise. Bên có thay đổi chạy:
Điền các mục trong file, rồi chạynode sync/scripts/sync.mjs new --module workflow --from be --to fe,mobile --type feature \ --slug workflow-task-patch-delete --title "Thêm PATCH/DELETE /workflow-tasks/:id" --refs "WORKFLOW-018"node sync/scripts/sync.mjs inbox. Commit note cùng PR của thay đổi. Mộtbug-reportkhông gắn với PR code nào thì mở PR riêng chỉ chứa note đó và merge sớm. - Nhận. Trước khi bắt đầu task trong project của mình, mỗi bên xem mục của mình trong
INBOX.md. Với mỗi note liên quan, đổitargets.<bên mình>và thêm 1 entry vào cuối mục "Thảo luận":### [FE] 2026-09-25 @handle — acked+ 1–3 dòng nội dung. - Phản biện. Đặt
disputedkèm lý do cụ thể trong "Thảo luận". Bên raise trả lời bằng entry mới, và nếu cần thì sửa phần nội dung/contract trong note. Không sửa entry của người khác. - Áp dụng. Làm xong thì đổi sang
appliedvà ghi PR/commit trong entry. - Sau mọi thay đổi trong
sync/, chạynode sync/scripts/sync.mjs inboxvà commit cảINBOX.md.
Tự động hoá
CI kiểm tra (
.github/workflows/sync-check.yml, chạy trên PR): chạysync.mjs check(frontmatter hợp lệ +INBOX.mdđã cập nhật). Nếu PR sửa contract BE mà không kèm sync note thì chỉ cảnh báo, không chặn merge.Telegram (
.github/workflows/sync-notify.yml, chạy khi push lênmain), gửi vào cùng group với các bot thông báo khác:- note mới → tag quản lý của các bên nhận để kiểm tra;
- một bên chuyển sang
disputed→ tag quản lý của bên raise để phản hồi; - note đóng (mọi bên
applied/n/a) → báo quản lý bên raise.
Người được tag khai báo cứng trong
envcủasync-notify.yml: BE →@Luan_DevOps, FE + Mobile →@esdridz. Đổi người quản lý thì sửa trực tiếp ở đó (nhiều người cách nhau bởi dấu cách). Workflow dùng lại secretTELEGRAM_BOT_TOKEN/TELEGRAM_CHAT_IDđã có. Thử trên máy mà không gửi thật:node sync/scripts/sync.mjs notify --before HEAD~1 --after HEAD --dry-run.Site HTML (
.github/workflows/sync-site.yml, chạy khi push lênmain): build toàn bộsync/thành HTML và deploy lên Cloudflare Pages, sau Cloudflare Access (chỉ thành viên GitHub orgLTBsoftware). Build thử và hướng dẫn thiết lập: tools/sync-site/README.md.