Bỏ qua để đến nội dung

Phòng ban (Departments)

Danh sách phòng ban dạng card: tên, mô tả, số thành viên, tenure trung bình và trưởng phòng

Trang Phòng ban hiển thị mỗi department dưới dạng 1 card, không phải cây lồng nhau — dù schema có parent_department_id để tự tham chiếu, UI hiện tại render phẳng theo danh sách. Mỗi card có:

Tên + mô tả

name, description, cùng màu/icon tuỳ chỉnh cho card (color, icon).

2 chỉ số

member_count (số nhân viên) và avg_tenure_months (thâm niên trung bình) — hai số này do backend tính sẵn khi trả list, không phải field lưu trong hr_departments.

Người đứng đầu (Head)

Avatar + tên head, click vào để mở thẳng hồ sơ nhân viên đó (/hr/employees/:id). Nếu chưa gán head, hiển thị “chưa có”.

Menu ⋮

Sửa hoặc xoá department. Xoá một department còn thành viên sẽ bị chặn (lỗi DEPT_HAS_MEMBERS) — phải chuyển hết nhân viên sang phòng khác trước.

Nút Tạo phòng ban (yêu cầu quyền hr:create) mở modal dùng field-registry (FormRoot + useHrFieldRegistry(['hr_departments'])), chỉ hiện đúng 5 field:

name, code, description, head_person_id, parent_department_id

name là bắt buộc; các field còn lại tuỳ chọn. head_person_id/parent_department_id là dropdown M2O — chọn từ danh sách hr_people/hr_departments hiện có.

Không có thao tác “thêm thành viên” trên trang Departments. Field department_id nằm trên hr_people, nên việc gán/đổi phòng ban của một người luôn thực hiện từ phía hồ sơ nhân viên (form Employee) — xem Nhân viên (Employees). Trang Departments chỉ đọc ngược để đếm member_count và hiển thị head.

Department làm head → mở khoá quyền duyệt nghỉ phép theo phòng

Phần tiêu đề “Department làm head → mở khoá quyền duyệt nghỉ phép theo phòng”

Theo PERMISSIONS.md, policy Dept Manager có action leave.approve.dept — chỉ duyệt được leave request của nhân viên thuộc phòng ban mà họ đứng đầu. Cơ chế resolve:

  1. Tìm hr_people record của user hiện tại qua hr_people.user_id.
  2. Tìm các hr_departmentshead_person_id = person đó.
  3. Mọi GET /peopleGET /leave/requests tự động lọc theo các phòng ban tìm được ở bước 2.