AFF Manager: sơ đồ chức năng

Hệ thống quản lý công việc, phòng ban và nghỉ phép · theo đặc tả phiên bản 08/11/2026

Tổng quan hệ thống

Ba module dùng chung một hệ thống tài khoản. Mỗi tài khoản có hai lớp quyền độc lập: quyền App và quyền Phòng ban/Nghỉ phép.

flowchart LR
  AUTH["Tài khoản và đăng nhập
Email + mật khẩu, SSO Google,
2FA bắt buộc cho Admin và HR"] AUTH --> M1 AUTH --> M2 AUTH --> M3 subgraph M1["Module 1: Quản lý App"] direction TB T["Team"] --> P["Dự án App"] P --> TK["Task updates"] P --> H["Lịch sử thay đổi"] T --> R["Weekly Recap"] P --> MV["Trang Member"] end subgraph M2["Module 2: Phòng ban"] direction TB D["Phòng ban"] --> E["Hồ sơ nhân viên"] end subgraph M3["Module 3: Nghỉ phép"] direction TB LR["Đơn nghỉ phép"] --> AP["Duyệt"] AP --> BAL["Số ngày phép năm"] BAL --> SUM["Tổng hợp tháng + Excel"] end M1 -. "thông báo" .-> DC["Discord
(webhook)"] M2 --- M3
Ngoài phạm vi giai đoạn 1Chấm công, tính lương, ngân sách ads, API Google Play Console, app mobile native.
Quy tắc chungKhông tự đăng ký. Nhân viên nghỉ việc chuyển sang Inactive, không xóa. Giao diện tiếng Việt, ngày dd/MM/yyyy, múi giờ Asia/Ho_Chi_Minh.

Vai trò và quyền

Hai lớp quyền tách nhau. Backend phải kiểm tra quyền ở mọi API, không chỉ ẩn nút trên giao diện.

flowchart TB
  U(("Một tài khoản"))
  U --> L1["Lớp 1: Quyền module App"]
  U --> L2["Lớp 2: Quyền Phòng ban / Nghỉ phép"]
  L1 --> A1["Admin
(không chia cấp)"] L1 --> A2["PO · MO · Dev · Tester · Designer
mỗi vai trò có Leader hoặc Member"] A2 --> TL["Mỗi Team có đúng 1 Team Leader"] L2 --> B1["Admin"] L2 --> B2["HR"] L2 --> B3["Department Leader"] L2 --> B4["Member"]
Hành độngAi được làm
Tạo tài khoảnAdmin; HR cho tài khoản nhân viên
Quản lý Team, cấu hình hệ thốngAdmin
Tạo / sửa dự án trong TeamPO và Team Leader
Đổi trạng thái TesterChỉ Tester. Admin được ghi đè khi khẩn cấp, bắt buộc nhập lý do
Tạo và đăng Weekly RecapAdmin và PO
Duyệt nghỉ phépLeader phòng ban hoặc HR (Leader không tự duyệt đơn của mình)
Xem dữ liệu cá nhân nhân viênAdmin, HR, Leader phòng ban đó

Vòng đời dự án App

Dự án đi từ Research tới Release. Stop, Pending và Unpublish là các nhánh rẽ.

stateDiagram-v2
  direction LR
  [*] --> Research
  Research --> Design
  Design --> Develop
  Develop --> Interview
  Interview --> Release
  Release --> Unpublish
  Research --> Pending
  Design --> Pending
  Develop --> Pending
  Pending --> Develop
  Research --> Stop
  Design --> Stop
  Develop --> Stop
  Unpublish --> [*]
  Stop --> [*]
  
Cần xác nhậnĐặc tả chỉ liệt kê 8 trạng thái, không ghi rõ chuyển đổi nào được phép. Các mũi tên Pending/Stop trong hình là suy đoán hợp lý, cần chốt với PO.
Thông tin chính của dự ánTeam, tên app (≤30 ký tự), mã app dạng AB123_name (duy nhất), link Google Play, loại (New App / Reskin), trạng thái ads, người phụ trách, ngày Design và Dev, trạng thái Tester, tài liệu, webhook Discord riêng.
Danh sách dự ánBảng trên desktop, thẻ trên mobile. Ngày kết thúc Dev/Design quá hạn tô đỏ. Bộ lọc nằm trên URL, mặc định lọc theo tháng tạo hiện tại.
Lịch sử thay đổiChỉ ghi thêm, không sửa được. Lưu ai, đổi gì, lúc nào, giữ tối thiểu 2 năm.

Vòng đời Task update

Mỗi task thuộc một dự án, có loại (Bug, Feature, Ads, Store listing, Other), mức ưu tiên, người làm, ngày bắt đầu/kết thúc và số ngày làm việc (thứ 2 đến thứ 6).

stateDiagram-v2
  direction LR
  [*] --> ToDo
  ToDo --> InProgress
  InProgress --> Testing
  Testing --> Done
  Testing --> InProgress: lỗi, làm lại
  ToDo --> Cancelled
  InProgress --> Cancelled
  Done --> [*]
  Cancelled --> [*]
  

Tự động gia hạn task

Khi chèn task mới vào lịch của người đang làm task khác, task đang làm bị đẩy ngày kết thúc lùi đúng bằng số ngày công của task chèn vào.

sequenceDiagram
  participant PO as PO / Leader
  participant SYS as Hệ thống
  participant A as Task A (đang làm)
  participant DEV as Dev
  participant DC as Discord
  PO->>SYS: Tạo Task B (3 ngày công) cho Dev
  SYS->>A: Phát hiện Task B chèn vào lịch của A
  SYS->>A: Lùi ngày kết thúc +3 ngày công
  SYS->>SYS: Ghi audit, kiểm tra tiếp các task phía sau (dây chuyền)
  SYS->>DC: Thông báo task mới
  SYS-->>DEV: Hiển thị lịch mới
  Note over PO,SYS: Nếu Task B bị hủy, ngày của Task A được hoàn lại
  
Task nhiều người làmChỉ lùi ngày khi tất cả người được giao đều bị ảnh hưởng.

Weekly Recap

Mỗi Team một bản mỗi tuần (thứ 2 đến thứ 6), do Admin hoặc PO viết.

flowchart LR
  A["Tạo bản nháp
cho Team + tuần"] --> B["Soạn nội dung
@mention, #task, chip dự án"] B -->|"tự lưu mỗi 10 giây"| B B --> C["Đăng (Publish)"] C --> D["Gửi Discord
qua webhook của Team"]

Thông báo Discord

Gửi qua hàng đợi, thử lại tối đa 3 lần, Admin xem được log. URL webhook được mã hóa.

flowchart LR
  E1["Đổi trạng thái Tester
(bắt buộc)"] --> Q E2["Tạo task
(bắt buộc)"] --> Q E3["Đăng Weekly Recap
(bắt buộc)"] --> Q E4["Đổi trạng thái task / dự án
(tùy chọn)"] -.-> Q Q["Hàng đợi
thử lại tối đa 3 lần"] --> W{"Dự án có
webhook riêng?"} W -->|"có"| W1["Webhook dự án"] W -->|"không"| W2["Webhook mặc định của Admin"] W1 --> L["Log thông báo
(Admin xem)"] W2 --> L

Quy trình nghỉ phép

Chỉ cần một người duyệt. Đơn đã duyệt hoặc từ chối thì bị khóa.

flowchart TB
  S["Nhân viên gửi đơn
(giờ bắt đầu, giờ kết thúc, tính ra ngày công)"] --> PD["Chờ duyệt"] PD -->|"sửa hoặc hủy được"| PD PD --> AP{"Leader phòng ban hoặc HR
(Leader không tự duyệt đơn mình)"} AP -->|"duyệt"| OK["Đã duyệt (khóa)"] AP -->|"từ chối"| NO["Từ chối (khóa)"] OK --> BAL{"Còn đủ phép năm?"} BAL -->|"đủ"| PAID["Trừ vào phép năm
(nghỉ có lương)"] BAL -->|"thiếu"| UNP["Phần vượt tính nghỉ không lương"] OK -->|"hủy trước ngày bắt đầu"| RS["Hoàn lại số ngày phép"] OK -.->|"mở lại: chỉ HR hoặc Admin + lý do"| PD NO -.->|"mở lại: chỉ HR hoặc Admin + lý do"| PD PAID --> SUM["Tổng hợp tháng
đơn nghỉ qua 2 tháng được tách theo tháng"] UNP --> SUM SUM --> X["Xuất Excel"]
Còn để mởSố giờ làm chuẩn mỗi ngày, số ngày phép năm mặc định, và phép dư có chuyển sang năm sau không (mặc định: không).

Mô hình dữ liệu

Các bảng chính và quan hệ. Bảng lịch sử dự án và audit log chỉ ghi thêm.

erDiagram
  USERS ||--|| EMPLOYEES : "là"
  DEPARTMENTS ||--o{ EMPLOYEES : "có"
  USERS ||--o{ USER_ROLES : "có quyền"
  TEAMS ||--o{ TEAM_MEMBERS : "gồm"
  USERS ||--o{ TEAM_MEMBERS : "thuộc"
  TEAMS ||--o{ PROJECTS : "sở hữu"
  PROJECTS ||--o{ PROJECT_ASSIGNEES : "giao cho"
  PROJECTS ||--o{ PROJECT_LINKS : "có"
  PROJECTS ||--o{ TASKS : "gồm"
  PROJECTS ||--o{ PROJECT_HISTORY : "ghi lại"
  TASKS ||--o{ TASK_EXTENSIONS : "bị gia hạn"
  TEAMS ||--o{ WEEKLY_RECAPS : "có"
  WEEKLY_RECAPS ||--o{ RECAP_MENTIONS : "nhắc"
  WEEKLY_RECAPS ||--o{ RECAP_TASK_LINKS : "nhúng"
  EMPLOYEES ||--o{ LEAVE_REQUESTS : "gửi"
  EMPLOYEES ||--o{ LEAVE_BALANCES : "có"
  LEAVE_BALANCES ||--o{ BALANCE_ADJUSTMENTS : "điều chỉnh"
  
Bảng bổ trợholidays, audit_logs, notification_logs.
Công nghệ đề xuấtNext.js hoặc React, Laravel hoặc NestJS, PostgreSQL, Redis. VPS hoặc AWS, Docker, CI/CD từ nhánh main, đặt sau Cloudflare.

Lộ trình 4 giai đoạn

Tổng khoảng 7 đến 10 tuần.

Giai đoạn 1 · 1-2 tuần

Nền tảng

  • Đăng nhập, phân quyền, 2FA
  • Triển khai
  • Khung giao diện responsive
Giai đoạn 2 · 3-4 tuần

Quản lý App

  • Team, dự án, task
  • Tự gia hạn task
  • Trang Member, Weekly Recap
  • Lịch sử thay đổi, Discord
Giai đoạn 3 · 2-3 tuần

Phòng ban và nghỉ phép

  • Hồ sơ nhân viên
  • Đơn và duyệt nghỉ phép
  • Phép năm, tổng hợp tháng, Excel
Giai đoạn 4 · 1 tuần

Hoàn thiện

  • Audit log, backup
  • Kiểm thử bảo mật
  • Nhập dữ liệu, hướng dẫn sử dụng