Menu
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Đang tải...

Bài 58 — Common JIRA Anti-patterns & Solutions

JIRA and Confluence for BA Bài 58/60

Mở đầu — vì sao bài này quan trọng

Sau 57 bài học, bạn đã biết cách tạo issue, viết JQL, dựng board, cấu hình workflow, làm tài liệu trong Confluence. Bạn đã có đủ "công cụ" trong tay. Nhưng có một sự thật phũ phàng mà ít khóa học nào nói thẳng: đa số các hệ thống JIRA "chết" không phải vì thiếu tính năng, mà vì bị dùng sai cách.

Một JIRA bị lạm dụng custom field, chồng chéo workflow, ngập trong ticket rác sẽ khiến cả team chậm lại thay vì nhanh hơn. Và trớ trêu thay, người gây ra phần lớn các "anti-pattern" này lại thường là... BA và PM — những người tạo ra cấu trúc, đặt ra quy ước, và yêu cầu thêm field. Bạn không cố tình làm hỏng, nhưng mỗi quyết định nhỏ ("thêm 1 field cho chắc", "tạo thêm 1 status cho rõ") tích lại thành một mớ bòng bong.

Anti-pattern là những "mẫu hành vi phản tác dụng" — thoạt nhìn có vẻ hợp lý, nhưng về lâu dài gây hại. Bài này không dạy bạn thêm tính năng mới. Bài này dạy bạn nhận diện cái sai, hiểu vì sao nó sai, và biết cách gỡ. Đây chính là khác biệt giữa một BA biết dùng JIRA và một BA làm chủ JIRA.

Khái niệm cốt lõi

Hãy đi qua những anti-pattern phổ biến nhất mà mình chứng kiến ở các team BA, đặc biệt trong môi trường công ty Việt Nam và outsourcing.

Anti-pattern 1: Over-customization (Tùy biến quá đà)

Triệu chứng: 100+ custom field, 20+ workflow khác nhau, 50+ status trên toàn instance. Mỗi project lại có một bộ field riêng. Khi tạo issue, người dùng phải cuộn qua một màn hình dài với hàng chục ô trống.

Vì sao sai: Mỗi custom field không miễn phí. Nó làm chậm màn hình tạo issue, làm rối JQL (vì có 3 field tên gần giống nhau), làm khó báo cáo (data nằm rải rác), và biến việc quản trị thành cơn ác mộng. Nguyên tắc vàng: mỗi field phải trả lời được câu hỏi "ai sẽ ĐỌC dữ liệu này, và để RA QUYẾT ĐỊNH gì?". Nếu không ai đọc, không ai quyết định dựa trên nó — field đó là rác.

Giải pháp: Field consolidation. Trước khi thêm field mới, hỏi: dữ liệu này đã có ở field khác chưa? Có thể dùng label hoặc component thay vì field riêng không? Định kỳ audit (rà soát) các field — Atlassian có công cụ thống kê field nào đang được dùng, field nào để trống 95% số issue.

Anti-pattern 2: Status Soup (Cháo status)

Triệu chứng: Workflow có những status như "In Progress", "In Development", "Developing", "Dev WIP", "Working" — bốn năm cái status nói cùng một chuyện. Hoặc status mô tả người ("With BA", "With Dev", "With QA", "With PM") thay vì mô tả trạng thái công việc.

Vì sao sai: Status nhiều thì board dài, report rối, và không ai thống nhất được "Done nghĩa là gì". Status nên phản ánh giai đoạn của công việc, không phải ai đang giữ ticket (cái đó đã có field Assignee).

Giải pháp: Gộp về 3–5 status cốt lõi cho mỗi workflow. Một workflow BA điển hình chỉ cần: To Do → In Progress → In Review → Done. Nếu cần biết "đang ở tay ai", dùng Assignee + một board column hợp lý.

Anti-pattern 3: JIRA như bãi rác (The Black Hole Backlog)

Triệu chứng: Backlog 2.000 ticket, ticket cũ nhất tạo từ 3 năm trước, không ai dám đụng vì "biết đâu sau này cần". Mỗi lần refinement phải scroll mỏi tay.

Vì sao sai: Backlog là danh sách việc bạn THỰC SỰ định làm, không phải nghĩa địa ý tưởng. Backlog phình to làm loãng tín hiệu, ẩn đi những việc quan trọng, và tạo cảm giác giả về khối lượng công việc.

Giải pháp: Quy ước "backlog hygiene". Ticket nào không được động đến trong 6 tháng → đóng với resolution "Won't Do" (vẫn tìm lại được qua JQL khi cần). Đặt giới hạn mềm cho backlog.

Anti-pattern 4: Ticket mồ côi nội dung (Empty Tickets)

Triệu chứng: Story chỉ có tiêu đề "Login page", phần description trống, không acceptance criteria, không link tài liệu. Dev phải đi hỏi miệng.

Vì sao sai: Đây là lỗi đặc trưng của BA. Một ticket không đủ thông tin sẽ tạo ra hàng loạt cuộc trao đổi qua lại, mất context, và bug do hiểu nhầm yêu cầu.

Giải pháp: Bắt buộc "Definition of Ready" — ticket chỉ vào sprint khi có đủ description, acceptance criteria, và link sang Confluence (đúng tinh thần Bài 16 về liên kết JIRA–Confluence). Dùng issue template để chuẩn hóa.

Anti-pattern 5: Lạm dụng Sub-task và Epic sai cấp

Triệu chứng: Epic dùng để gom việc của một sprint thay vì một mục tiêu nghiệp vụ; sub-task tạo cho mọi thứ khiến board ngập sub-task; hoặc ngược lại, mọi thứ đều là Story phẳng lì không phân cấp.

Vì sao sai: Cấu trúc phân cấp sai làm hỏng báo cáo tiến độ và roadmap. Epic nên là một outcome nghiệp vụ (ví dụ "Thanh toán qua ví điện tử"), không phải một nhóm task ngẫu nhiên.

Giải pháp: Quy ước rõ ràng cho từng issue type (bám theo Bài 4). Epic = mục tiêu lớn nhiều sprint; Story = một mẩu giá trị giao được trong 1 sprint; Sub-task = bước kỹ thuật nhỏ trong 1 Story.

Anti-pattern 6: Báo cáo thủ công lặp đi lặp lại

Triệu chứng: BA mỗi sáng thứ Hai export Excel, copy số liệu, gửi mail status. Mất 2 tiếng mỗi tuần cho việc máy có thể làm.

Giải pháp: Dùng Dashboard + saved filter (Bài 10, Bài 35) và Automation (Bài 17) để hệ thống tự gửi report. Việc gì máy làm được, đừng làm tay.

Tình huống thực tế

Ví dụ 1 — Công ty fintech "VíNhanh" (TP.HCM): Cơn ác mộng 137 custom field

VíNhanh là một startup ví điện tử tăng trưởng nóng, từ 8 lên 60 người trong 18 tháng. Mỗi khi một team mới hoặc một quản lý mới gia nhập, họ lại yêu cầu admin "thêm cho em một field để track cái này". Không ai từ chối. Sau 18 tháng, instance JIRA của VíNhanh có 137 custom field, 14 workflow, và màn hình tạo Story dài tới mức phải cuộn ba lần.

Hậu quả cụ thể: chị Lan, BA trưởng, đo được rằng trung bình mỗi dev mất 40 giây chỉ để tạo một issue vì phải bỏ qua hàng chục field không liên quan. Với khoảng 200 issue/tuần, đó là hơn 2 giờ công bị đốt vô ích mỗi tuần chỉ riêng thao tác tạo ticket. Tệ hơn, có tới 4 field cùng tên kiểu "Priority": Priority gốc của JIRA, "Business Priority", "Mức ưu tiên", và "Độ ưu tiên KH" — không ai biết dùng cái nào, JQL viết ra cho kết quả lung tung.

Chị Lan tổ chức một đợt audit. Kết quả: 89 trong 137 field bị bỏ trống trên hơn 90% số issue. Đội đặt nguyên tắc mới: muốn thêm field phải nêu rõ ai đọc và quyết định gì. Họ gộp 4 field priority về 1, archive 89 field rác, và rút workflow từ 14 xuống 4. Sau 2 tháng, thời gian tạo issue giảm còn ~12 giây, và quan trọng hơn, report về độ ưu tiên cuối cùng cũng đáng tin.

Bài học: Việc nói "không" với một field tưởng vô hại lại là một trong những đóng góp giá trị nhất của BA. Sự đơn giản phải được bảo vệ chủ động, vì entropy luôn kéo hệ thống về phía phức tạp.

Ví dụ 2 — Công ty outsourcing "TechBridge" (Đà Nẵng): Backlog 2.300 ticket

TechBridge nhận một dự án bảo trì dài hạn cho khách Nhật. Sau 3 năm, backlog của project phình lên 2.300 issue, trong đó nhiều ticket tạo từ thời nhân sự đã nghỉ việc. Mỗi buổi backlog refinement (Bài 11) biến thành cực hình: team scroll mãi không hết, gặp những ticket mô tả mơ hồ kiểu "fix cái bug hôm qua khách báo" mà không ai còn nhớ là bug gì.

Anh Dũng, BA của dự án, chạy một JQL đơn giản: project = TB AND updated <= -180d AND status != Done. Kết quả trả về 1.640 ticket — tức hơn 70% backlog là "xác chết" không ai động tới nửa năm. Anh export ra, gửi cho khách review một tuần, rồi bulk-close (Bài 40) toàn bộ với resolution "Won't Do". Lưu ý quan trọng: anh không xóa, chỉ đóng — nếu sau này khách cần, vẫn tìm lại được bằng JQL.

Sau đợt dọn dẹp, backlog "sống" chỉ còn ~660 ticket. Refinement nhanh hơn hẳn, và team thiết lập một automation rule tự gắn label "stale" cho ticket không cập nhật quá 90 ngày để cảnh báo sớm.

Bài học: Backlog không phải kho lưu trữ vĩnh viễn. "Đóng" khác "xóa" — bạn vẫn giữ được lịch sử mà không để rác làm loãng tín hiệu công việc thật.

Ví dụ 3 — Công ty SaaS "EduCloud" (Hà Nội): Status soup khiến report vô nghĩa

EduCloud có 3 squad, mỗi squad tự định nghĩa workflow riêng. Squad A có status "In Dev", squad B có "Developing", squad C có "WIP-Dev". Khi giám đốc sản phẩm muốn một báo cáo tổng "có bao nhiêu việc đang code trên toàn công ty", BA không thể viết nổi một JQL gọn vì status nằm rải rác dưới ba cái tên khác nhau. Tệ hơn, có những status mô tả người giữ ticket: "With QA", "With Client", "With BA" — khiến một ticket nhảy qua lại giữa các status này tới 7 lần, làm hỏng hoàn toàn metric cycle time.

Chị Hương, BA lead, đề xuất một workflow chuẩn dùng chung: To Do → In Progress → In Review → Done, cộng thêm một status "Blocked" duy nhất. Phần "đang ở tay ai" được chuyển sang dùng Assignee và board column. Sau khi chuẩn hóa, JQL tổng status = "In Progress" cho con số chính xác trên toàn công ty, và cycle time đo được trở nên có ý nghĩa lần đầu tiên.

Bài học: Status mô tả giai đoạn công việc, không mô tả người đang giữ. Thống nhất workflow giữa các team là điều kiện tiên quyết để có báo cáo so sánh được.

Hướng dẫn từng bước

Đây là quy trình audit và "giải độc" một instance JIRA mà bạn có thể áp dụng:

  • Khảo sát hiện trạng custom field. Vào Settings → Issues → Custom fields. Sắp xếp theo số lượng issue đang dùng. Lập danh sách field bị trống trên hơn 90% issue — đây là ứng viên để archive.
  • Đếm và phân loại status. Liệt kê toàn bộ status đang tồn tại. Nhóm những status đồng nghĩa lại với nhau (mọi biến thể của "đang làm" về một nhóm). Đánh dấu các status mô tả người thay vì giai đoạn.
  • Chạy JQL đo "độ chết" của backlog. Dùng project = XXX AND updated <= -180d AND resolution = Unresolved. Con số này cho biết bao nhiêu phần trăm backlog là rác.
  • Kiểm tra chất lượng nội dung ticket. Lấy mẫu 20 ticket gần nhất, đếm xem bao nhiêu có đủ description + acceptance criteria. Nếu dưới 70%, bạn có vấn đề về Definition of Ready.
  • Họp thống nhất quy ước. Trình bày dữ liệu audit cho team. Quyết định cùng nhau: bộ field tối thiểu, workflow chuẩn, định nghĩa Done, ngưỡng dọn backlog. Ghi lại thành tài liệu chuẩn trong Confluence.
  • Thực thi gọn gàng. Archive field rác, gộp status (cẩn thận test workflow trước trên project nháp), bulk-close ticket chết với resolution rõ ràng (không xóa).
  • Thiết lập "phòng bệnh" tự động. Tạo automation rule gắn label "stale" cho ticket cũ; tạo dashboard theo dõi số field, số status, kích thước backlog theo thời gian để phát hiện entropy quay lại.
  • Định kỳ tái audit. Đặt lịch quý: cứ mỗi 3 tháng rà lại một lần. Anti-pattern không biến mất vĩnh viễn — nó tích tụ lại nếu không ai canh.

Lỗi thường gặp & mẹo

  • Xóa thay vì đóng: Đừng bao giờ xóa ticket cũ. Hãy đóng với resolution như "Won't Do". Xóa là mất lịch sử vĩnh viễn; đóng vẫn truy vết được.
  • Gộp status mà quên test workflow: Khi gỡ bỏ một status, các transition và automation gắn với nó có thể vỡ. Luôn thử trên project nháp trước, kiểm tra mọi rule và board column.
  • Audit một mình rồi áp đặt: Anti-pattern thường sinh ra từ nhu cầu thật của ai đó. Nếu bạn xóa field mà không hỏi, sẽ có người mất dữ liệu họ đang dùng. Luôn khảo sát trước khi cắt.
  • "Thêm cho chắc": Tâm lý sợ thiếu khiến người ta thêm field/status "phòng khi cần". Mẹo: mặc định là không thêm. Chỉ thêm khi chứng minh được ai đọc và quyết định gì. Bạn luôn có thể thêm sau, nhưng gỡ ra thì khó hơn nhiều.
  • Nhầm component/label với custom field: Rất nhiều nhu cầu phân loại có thể giải quyết bằng label (linh hoạt) hoặc component (có cơ cấu) mà không cần field mới. Cân nhắc hai lựa chọn này trước.
  • Bỏ qua "phòng bệnh": Dọn một lần rồi để đó, 6 tháng sau lại như cũ. Bí quyết bền vững là tự động hóa cảnh báo và đặt lịch audit định kỳ.
  • Để mỗi team tự do hoàn toàn: Tự chủ là tốt, nhưng không có một bộ chuẩn tối thiểu chung thì không bao giờ có báo cáo tổng so sánh được. Cân bằng giữa linh hoạt cục bộ và chuẩn hóa toàn cục.

Bài tập thực hành

  • Audit nhanh: Trên một instance JIRA bạn có quyền truy cập (hoặc bản dùng thử miễn phí), chạy JQL updated <= -180d AND resolution = Unresolved và ghi lại tỷ lệ phần trăm so với tổng backlog. Bạn đang ở mức "khỏe" hay "báo động"?
  • Diệt status soup: Liệt kê toàn bộ status của một project. Tự nhóm chúng về tối đa 5 status cốt lõi và viết bảng ánh xạ (status cũ → status mới). Đánh dấu status nào đang mô tả "người" thay vì "giai đoạn".
  • Định nghĩa quy tắc field: Viết ra một "field admission policy" gồm 3 câu hỏi mà bất kỳ field mới nào cũng phải vượt qua trước khi được tạo. Áp thử lên 5 field hiện có của một project và xem có bao nhiêu field "trượt".
  • Soạn Definition of Ready: Viết một checklist DoR gồm 4–5 mục cho ticket Story của team bạn, kèm một issue template tương ứng.
  • Tình huống: Giả sử bạn là BA mới nhận một instance có 90 custom field và backlog 1.500 ticket. Hãy viết kế hoạch 4 tuần để giải độc nó, nêu rõ tuần nào làm gì và cách bạn thuyết phục team đồng thuận.

Tóm tắt

Anti-pattern trong JIRA hiếm khi đến từ ác ý — chúng đến từ những quyết định nhỏ, hợp lý trong khoảnh khắc, tích tụ thành sự phức tạp giết chết hiệu quả. Sáu anti-pattern lớn nhất bạn cần nhận diện là: over-customization (quá nhiều field), status soup (status trùng lặp hoặc mô tả người), backlog hố đen (rác chất đống), ticket rỗng nội dung, phân cấp Epic/Sub-task sai, và báo cáo thủ công lặp lại.

Vai trò của BA không chỉ là tạo cấu trúc, mà còn là người gác cổng cho sự đơn giản. Mỗi lần bạn nói "không" với một field thừa, gộp một status trùng, đóng một ticket chết, bạn đang trả lại tốc độ cho cả team. Hãy nhớ ba nguyên tắc cốt lõi: field phải có người đọc và ra quyết định; status mô tả giai đoạn chứ không mô tả người; và "đóng" luôn an toàn hơn "xóa". Cuối cùng, giải độc không phải việc làm một lần — hãy tự động hóa cảnh báo và đặt lịch audit định kỳ, vì entropy luôn quay lại nếu không ai canh giữ.