Dựng một nền tảng CRM multi-tenant từ con số không: chuyện nghề 20 tháng
Tháng 01/2025 mình được giao init một sản phẩm, lần đầu tiên trong nghề, là một nền tảng CRM multi-tenant mà lúc nhận thì repo còn trống trơn. Gần một năm đầu nó sống ở chế độ đi demo cho nhiều khách thuộc nhiều ngành, rồi tới gần cuối 2025 thì chốt được khách ngành y tế và chuyển sang delivery thật. Hai mươi tháng sau nó là 18 microservice trên ABP Framework / .NET 9 và 13 Angular library, của một team đã lớn lên tới 25 người. Bài này không phải bài kỹ thuật mà là chuyện nghề kể theo thứ tự thời gian, trong đó có cái màn hình export bị quên phân quyền, có hai tuần làm Angular xong phải revert, có ba tháng giữa năm mình được chuyển sang dự án loyalty khác nên không commit dòng nào, và có một lần migration nhàm chán tới mức chẳng ai để ý là nó đã xảy ra. Trong bài cũng có đoạn về kiến trúc EAV cho phép khách tự cấu hình trường dữ liệu trên portal, kèm mấy tháng mình vật lộn với performance của nó và của bộ dynamic filter nằm trên nó, đoạn kể quãng mình lần đầu làm mentor cho bốn bạn intern, và đoạn kể cách mình viết code đổi dần từ gõ tay sang dùng ChatGPT, rồi Cursor, rồi Claude.
Ngày 14 tháng 1 năm 2025, mình mở một cái repo trống trơn mà trong đầu chẳng có gì ngoài mấy câu hỏi rất tầm thường, kiểu đặt tên solution là gì, thư mục nào để đâu, database thì chia bảng thế nào.
Trước đó mình toàn nhận những codebase đã chạy sẵn rồi, công việc chỉ là đọc, sửa và thêm màn hình, nên lần này thấy khác hẳn: không có gì để bắt chước, mà cái gì mình gõ ra thì sau này người khác lại cứ thế làm theo. Nghe kể thì oai, chứ lúc ngồi trước cái repo trống ấy mình hơi ngợp thật.
Commit hôm đó của mình chỉ có một dòng, Init - Databases, projects, và cũng chẳng có gì long trọng cả.
Hai mươi tháng sau, cái repo ấy có 18 microservice với 29.607 commit của 25 người. Mình vẫn còn ở đó, và thỉnh thoảng vẫn mở git log --reverse ra xem lại mấy dòng đầu.
git log --reverse --format="%h %ad %an %s" --date=short | head -5
Bài này mình viết để vài năm nữa đọc lại. Vì sản phẩm là của công ty nên tên riêng mình ẩn hết, từ tên sản phẩm, tên repo, tên khách hàng cho tới tên mấy library nội bộ, còn tech stack thì để nguyên vì đó là phần kể được.
