Code · Những thứ đang làm, đang hỏng, đang sửa — kiến trúc, vài dòng hay ho, và những con bug.

Khi developer quyết định business mà không hỏi business

Đây là một trong những anti-pattern nguy hiểm nhất trong công ty phần mềm — và nó nguy hiểm chính xác vì nó trông rất giống người có năng lực đang làm việc.

Hai nửa nhịp cầu mực vươn từ hai bờ nhưng hụt nhau, một chấm đỏ chu sa nằm giữa khe trống
Hai nhịp cầu xây từ hai phía, không gặp nhau ở giữa — chấm đỏ rơi đúng vào chỗ đáng lẽ phải nối.

Đây là một trong những anti-pattern nguy hiểm nhất trong công ty phần mềm — và nó nguy hiểm chính xác vì nó trông rất giống người có năng lực đang làm việc.

Tôi không nói về developer tệ. Tôi nói về developer giỏi — người biết tool mới, đọc blog kỹ thuật, bám xu hướng, và có đủ tự tin để triển khai những thứ họ nghĩ là đúng. Đây chính xác là loại người có thể phá vỡ một tổ chức mà không ai nhận ra cho đến khi quá muộn.


Bắt đầu từ một quyết định nhỏ

Hãy thử với một ví dụ thực tế. Một hệ thống cần authentication. Developer đọc về một auth library mới — Better Auth, chẳng hạn. Tài liệu tốt, cộng đồng dùng đông, API design đẹp. Developer triển khai trong vài nốt nhạc.

Vấn đề: Better Auth được thiết kế cho user-facing authentication — người dùng thật, có session, có browser. Nhưng hệ thống cũng cần machine-to-machine auth — server A nói chuyện với server B, không có người dùng nào ở giữa, không có browser, không có session.

Hai bài toán này khác nhau hoàn toàn ở thiết kế và luồng hoạt động. Dùng user auth cho M2M auth không phải là “ứng biến sáng tạo” — đó là sự lạm dụng, và nó tạo ra một lỗ hổng bảo mật (security gap) mà sau này phải sửa.

Ai sẽ phát hiện ra điều này? Không phải người bên kinh doanh(business) — họ không rành kỹ thuật. Cũng khó là một developer khác: nhiều khi chỉ có một người làm, hoặc kiểu văn hóa mà một ngày đẹp trời CTO quăng cho bạn một file .md do AI viết, đọc chẳng ai hiểu, kèm yêu cầu triển khai ngay. Không có ai review chéo. Chỉ đến khi có sự cố — hoặc khi có ai đủ rảnh để audit kỹ — mới lộ ra.


Sự leo thang của vấn đề: từ library đến kiến trúc

Một quyết định nhỏ không phá được hệ thống. Nhưng vấn đề tích lũy.

Cùng một hệ thống: developer thấy Keycloak — một identity provider cấp doanh nghiệp, đã được kiểm chứng, đầy đủ tính năng. Quyết định: triển khai Keycloak cho hệ thống.

Câu hỏi cần hỏi trước khi triển khai: Hệ thống có bao nhiêu loại user? Reseller account quản lý thế nào? Tenant isolation cần ở tầng nào? Có cần SSO không?

Những câu hỏi này không phải kỹ thuật — chúng là câu hỏi nghiệp vụ kinh doanh (business question). Và nếu không hỏi chúng trước khi deploy, bạn đang xây một tòa nhà trên nền móng do chính mình phỏng đoán.

Một tòa tháp mực vẽ vững phía trên, nhưng nền móng tan thành những nét đứt mờ ở dưới
Xây vững phía trên một nền móng chỉ là phỏng đoán — phần kỹ thuật trông chắc chắn, phần giả định bên dưới thì không ai kiểm.

Keycloak được deploy. Rồi mới phát hiện: reseller account có thiết kế đặc biệt mà Keycloak không lo cho bạn. Thế là phải dựng một giải pháp tạm. Giải pháp tạm tạo ra nợ kỹ thuật (tech debt). Nợ kỹ thuật tích lũy. Và không ai còn nhớ tại sao cái giải pháp tạm đó tồn tại — vì người quyết định không ghi lại một dòng nào về lý do nghiệp vụ (business reason), họ chỉ ghi lại phần kỹ thuật đã làm (technical implementation).


Vấn đề thứ ba: open source và license

Đây là loại rủi ro mà developer ít nghĩ đến nhất, vì nó không phải rủi ro kỹ thuật.

Developer tìm được một open source tool ngon — miễn phí, đầy đủ tính năng, cộng đồng đông. Đưa thẳng vào sản phẩm thương mại. License review? Không có trong checklist.

Nhiều giấy phép open source có điều khoản hạn chế dùng cho mục đích thương mại. AGPL chẳng hạn: bất kỳ sản phẩm nào dùng hoặc liên kết tới nó đều có thể bị yêu cầu công bố toàn bộ source code của chính mình. Với SaaS thì định nghĩa “phân phối” (distribute) còn đang tranh cãi, nhưng rủi ro pháp lý là thật.

Developer không phải luật sư. Nhưng developer đang quyết định triển khai một tool mà không đẩy câu hỏi này lên người có thể đánh giá rủi ro. Đó là một quyết định kinh doanh — được đưa ra mà không ai trong tổ chức biết nó đang được đưa ra.


Tại sao điều này xảy ra

Không phải vì developer thiếu ý thức. Thường là vì:

Không có người để hỏi. Product owner thì không rõ ràng. Các bên liên quan (stakeholder) thì không quan tâm. Hỏi thì không ai trả lời trong thời gian hợp lý. Developer đành tự quyết cho xong — một phản xạ hợp lý trong môi trường thiếu kết nối.

Được khen vì “tự lo được”. Tổ chức đề cao người ít cần hỏi. “Tự giải quyết được” trông như năng lực, nhưng thực ra đang nuôi dưỡng sự rối loạn (dysfunction) của tổ chức về sau.

Tự tin mà không có thông tin cần thiết để ra quyết định. Developer giỏi kỹ thuật (hoặc tự nghĩ mình giỏi) thường rất tự tin. Tự tin đúng chỗ là tài sản. Tự tin sai chỗ — ra quyết định kinh doanh mà không có business context — là rủi ro.

Người giỏi kỹ thuật nhất trong phòng không phải lúc nào cũng là người hiểu kinh doanh nhất — và hai thứ đó không thay thế được cho nhau.


Hệ quả cộng dồn

Mỗi quyết định đơn lẻ đều có thể sửa. Nhưng khi khuôn mẫu (pattern) này kéo dài đủ lâu, hậu quả cộng dồn:

Hệ thống quản lý kho (inventory) được xây song song với hệ thống bán hàng (order), cùng một công ty, nhưng không có lấy một buổi ngồi lại làm rõ “ai quản lý gì, và dữ liệu chảy qua lại ra sao”. Hai hệ thống cùng có entity “sản phẩm” — nhưng schema khác nhau, định dạng SKU khác nhau, mô hình quan hệ (relationship model) khác nhau.

Hai con dấu khắc cùng một ký tự nhưng hình dáng và kích thước khác nhau, đặt cạnh nhau
Cùng một 'sản phẩm', hai con dấu khác nhau — hai hệ thống dùng chung cái tên nhưng không chung một hình.

Sau này muốn tích hợp, phải viết một lớp dịch (translation layer). Lớp dịch đó là nợ kỹ thuật. Mà nợ kỹ thuật thì có giá.

Quan trọng hơn: khi một AI agent cần suy luận trên cả hai hệ thống, nó cần context đầy đủ từ cả hai bên — mà lúc đó nó không biết dữ liệu bên nào mới là thật. Và hiển nhiên, nhân viên vận hành cũng chẳng rõ. Data silo không phải vấn đề của tương lai — nó là vấn đề đang được tạo ra ngay hôm nay, bởi những quyết định đưa ra mà không ai nói chuyện với nhau.


Giải pháp không phải là ít developer hơn

Điều tôi muốn nói không phải là developer không nên được quyền quyết định kỹ thuật. Họ nên — đó là công việc của họ.

Điều tôi muốn nói là: có một ranh giới giữa quyết định kỹ thuậtquyết định nghiệp vụ vận hành được thể hiện dưới dạng kỹ thuật. Khi triển khai một auth library — đó là kỹ thuật. Khi chọn auth model mà không hỏi về reseller account structure — đó là một quyết định kinh doanh, đưa ra mà không có chút thông tin nào về chính nghiệp vụ đó.

Ranh giới đó đòi hỏi tổ chức phải có người giữ nó, chịu trách nhiệm về nó. Product owner thật sự, không phải danh nghĩa. Stakeholder phản hồi được, không phải biến mất sau 1 đoạn chat nhóm hoặc email. Và cần có quy trình để developer biết: câu hỏi nào tự quyết được, câu hỏi nào cần hỏi người khác.

Nếu tổ chức không có những thứ đó — developer sẽ tự lấp đầy khoảng trống. Không phải vì họ muốn kiểm soát, mà vì công việc cần tiếp tục.

Và thứ tổ chức nhận lại là một hệ thống phản ánh quyết định của một người — thay vì sự hiểu biết tập thể của cả tổ chức.

落款
chưa đóng

Con dấu đọc

Đọc tới cuối rồi ngồi lại một nhịp — con dấu sẽ tự đóng. Không điểm, không streak; chỉ một vết mực cho riêng bạn.