sync/README.md · Xem trên GitHub

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 qua refs, 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.ts hoặc prisma/schema.prisma mà 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 (feature với targets: { 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

  1. Raise. Bên có thay đổi chạy:
    node 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"
    
    Điền các mục trong file, rồi chạy node sync/scripts/sync.mjs inbox. Commit note cùng PR của thay đổi. Một bug-report không gắn với PR code nào thì mở PR riêng chỉ chứa note đó và merge sớm.
  2. 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, đổi targets.<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.
  3. Phản biện. Đặt disputed kè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.
  4. Áp dụng. Làm xong thì đổi sang applied và ghi PR/commit trong entry.
  5. Sau mọi thay đổi trong sync/, chạy node sync/scripts/sync.mjs inbox và commit cả INBOX.md.

Tự động hoá

  • CI kiểm tra (.github/workflows/sync-check.yml, chạy trên PR): chạy sync.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ên main), 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 env của sync-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 secret TELEGRAM_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ên main): build toàn bộ sync/ thành HTML và deploy lên Cloudflare Pages, sau Cloudflare Access (chỉ thành viên GitHub org LTBsoftware). Build thử và hướng dẫn thiết lập: tools/sync-site/README.md.