Tran Manh Tuan

Dr.Well-B

Dr.Well-B là nền tảng thành viên dành cho bác sĩ, nha sĩ và sinh viên y khoa tại Nhật Bản, ra mắt công khai năm 2023. Thay vì giải một nghiệp vụ đơn lẻ, nền tảng gom nhiều dịch vụ vào một cổng: tài khoản chuyên môn có xác minh, quảng cáo theo hồ sơ, khảo sát, tuyển dụng và tìm việc, nội dung chuyên ngành và chương trình point thưởng — tất cả được đội vận hành điều khiển từ một trang quản trị riêng.

Tôi đảm nhận vai trò Tech Lead trong giai đoạn 2022–2024, đồng thời trực tiếp làm backend: định hướng kỹ thuật, thiết kế hệ thống và luồng dữ liệu, API Node.js / NestJS, Firestore, search, xử lý nền cùng các dịch vụ Google Cloud liên quan, review code, và phối hợp giữa phía Nhật Bản với team phát triển tại Việt Nam.

Vì sao đây là dự án hệ thống quản lý: mọi module cùng đọc một hồ sơ thành viên và cùng ghi vào một action log. Đổi cách chọn quảng cáo là đổi luôn point, báo cáo và file export phía sau — nên phần việc chính nằm ở workflow, luồng dữ liệu và khả năng kiểm soát của trang quản trị, không chỉ ở từng tính năng riêng lẻ.

Các module và người dùng

Hệ thống phục vụ hai nhóm. Thành viên — bác sĩ, nha sĩ, bác sĩ đang đào tạo, bác sĩ hành nghề độc lập và sinh viên y khoa — dùng Member Portal. Operator và admin dùng trang quản trị riêng để duyệt tài khoản, quản lý quảng cáo, supplier, survey, tin tuyển dụng và dữ liệu download.

Tổng quan các module của Dr.Well-BBác sĩ, nha sĩ, sinh viên y khoa và thành viên dùng Member Portal; operator và admin dùng trang quản trị. Member Portal dẫn tới tài khoản và hồ sơ, quảng cáo cá nhân hóa, survey động, tuyển dụng và job search, nội dung chuyên ngành. Trang quản trị quản lý tài khoản và hồ sơ, quảng cáo, survey, tuyển dụng và download/export. Quảng cáo và job sinh point/reward. Quảng cáo, survey, job và tài khoản cấp dữ liệu cho analytics/reporting. Point và survey sinh file download/export, và download/export gửi notification/email.

Bác sĩ / Nha sĩ / Sinh viên y khoa / Thành viên

Operator / Admin

Dr.Well-B Member Portal

Dr.Well-B Administration

Tài khoản & Hồ sơ

Quảng cáo cá nhân hóa

Survey động

Tuyển dụng / Job Search

Nội dung chuyên ngành

Point / Reward

Download / Export

Notification / Email

Analytics / Reporting

Sơ đồ vừa khung

Member Portal và trang quản trị dùng chung một bộ module. Hồ sơ thành viên và action log là thứ nối các module lại, thay vì mỗi tính năng chạy độc lập.

Vai trò của tôi

  • Định hướng kỹ thuật và chọn giải pháp cho từng chức năng lớn, đánh giá rủi ro kỹ thuật trước khi triển khai.
  • Thiết kế kiến trúc hệ thống và cách các module trao đổi dữ liệu.
  • Thiết kế và phát triển backend API bằng Node.js / NestJS.
  • Thiết kế dữ liệu Firestore, search trên Elasticsearch, xử lý nền và các dịch vụ cloud phía sau.
  • Review technical design và pull request, review bảo mật, hỗ trợ team xử lý các vấn đề kỹ thuật khó.
  • Xây dựng chiến lược unit test và automation test (Cypress) cho một hệ thống nhiều rule nghiệp vụ.
  • Hỗ trợ triển khai staging / production, theo dõi tiến độ kỹ thuật và rủi ro của các chức năng lớn.

Đăng ký thành viên có xác minh chuyên môn

Đăng ký ở đây là một workflow xác minh, không phải form email và mật khẩu. Nền tảng thu thập thông tin nghề nghiệp — chuyên khoa và chuyên ngành phụ, cơ sở công tác, khoa, chức vụ, năm tốt nghiệp, trường đại học, mã số sinh viên, số giấy phép hành nghề, thông tin đào tạo lâm sàng — cùng tài liệu xác minh như ảnh giấy phép, thẻ sinh viên, chứng chỉ đào tạo và CV.

Thông tin xác minh được thì tài khoản được kích hoạt ngay. Không xác minh được thì hồ sơ chuyển sang quy trình duyệt của admin: thành viên được yêu cầu gửi thêm giấy tờ, admin kiểm tra, quyết định được ghi vào approval history, và hồ sơ bị khóa thao tác sau khi đã duyệt. Mỗi kết quả có email riêng.

Luồng đăng ký và xác minh tài khoản chuyên gia y tếNgười dùng bắt đầu đăng ký, nhập thông tin cá nhân, thông tin nghề nghiệp, giấy phép hoặc thông tin trường học, upload tài liệu xác minh rồi gửi đăng ký. Nếu thông tin xác minh được, hệ thống tạo và kích hoạt tài khoản thành viên rồi gửi email đăng ký thành công. Nếu không, hồ sơ chuyển sang quy trình kiểm tra bổ sung: yêu cầu gửi thêm giấy tờ, admin kiểm tra và approval. Được chấp thuận thì tài khoản được kích hoạt và Approval History được cập nhật; chưa được chấp thuận thì quay lại bước yêu cầu gửi thêm giấy tờ.

Có

Không

Có

Chưa

Người dùng bắt đầu đăng ký

Nhập thông tin cá nhân

Nhập thông tin nghề nghiệp

Nhập giấy phép / thông tin trường học

Upload tài liệu xác minh

Gửi đăng ký

Có thể xác minh thông tin?

Tạo / kích hoạt tài khoản thành viên

Gửi email đăng ký thành công

Chuyển sang quy trình kiểm tra bổ sung

Yêu cầu gửi thêm giấy tờ

Admin kiểm tra / Approval

Được chấp thuận?

Kích hoạt tài khoản

Cập nhật Approval History

Sơ đồ vừa khung

Xác minh tự động khi có thể, con người duyệt khi cần — và mọi quyết định đều có lịch sử.

Quảng cáo theo hồ sơ người dùng

Quảng cáo không phải banner hiển thị ngẫu nhiên. Mỗi quảng cáo mang luật phân phối riêng: khu vực hiển thị và kích thước banner, URL đích, banner hoặc text, tag, chuyên khoa và hội chuyên ngành mục tiêu, thời gian hiệu lực, giới hạn click, độ ưu tiên và trạng thái. Hệ thống lọc mọi quảng cáo đang chạy theo hồ sơ và lịch sử của từng thành viên, và hành vi của thành viên quay lại ảnh hưởng lần chọn sau — hide hoặc refresh một quảng cáo có thể loại nó khỏi danh sách candidate hoặc giảm priority với riêng người đó, còn tín hiệu quan tâm giữ các quảng cáo tương tự tiếp tục xuất hiện.

Ở trang quản trị, operator tạo, copy và lên lịch quảng cáo, đặt giới hạn và độ ưu tiên, quản lý supplier, và tải được danh sách thành viên khớp tag của từng quảng cáo.

Luồng lựa chọn quảng cáo theo hồ sơ người dùngAdmin tạo và publish quảng cáo, hệ thống lấy danh sách quảng cáo đang hoạt động rồi lọc qua bốn điều kiện: khớp chuyên khoa, society hoặc tag; còn trong thời gian hiệu lực; chưa vượt giới hạn click; người dùng chưa hide hoặc refresh quảng cáo đó. Quảng cáo trượt bất kỳ điều kiện nào bị loại hoặc giảm priority. Quảng cáo qua hết điều kiện được tính priority và mức phù hợp, sắp xếp candidate, chuẩn bị banner, text và URL, hiển thị, rồi ghi action log; action log quay lại làm đầu vào cho lần chọn tiếp theo.

Không

Có

Không

Có

Có

Không

Có

Không

Admin tạo / publish quảng cáo

Lấy danh sách quảng cáo đang hoạt động

Khớp chuyên khoa / society / tag?

Đang trong thời gian hiệu lực?

Đã vượt giới hạn click?

User đã hide / refresh quảng cáo?

Tính priority / mức phù hợp

Sắp xếp candidate

Chuẩn bị banner / text / URL

Hiển thị quảng cáo

Ghi action log

Loại hoặc giảm priority

Sơ đồ vừa khung

Bốn điều kiện quyết định một quảng cáo có được làm candidate hay không; chỉ sau đó mới xếp hạng. Action log khép vòng lặp.

Survey engine cấu hình động

Admin dựng survey không cần code: tên, mô tả, ghi chú, số response tối thiểu và tối đa, trạng thái publish và quảng cáo liên kết, rồi thêm câu hỏi với loại câu hỏi, required hoặc optional, danh sách answer và free input. Các câu hỏi có thể phụ thuộc nhau — "câu 1 chọn A thì bật câu 2" — tạo ra nhánh điều kiện, sub-question và embedded question. Thành viên nhận một form thay đổi theo câu trả lời, và trong một số luồng, câu trả lời sửa lại sẽ ghi đè bản cũ thay vì tạo submission trùng lặp.

Luồng survey động từ cấu hình tới reportingAdmin tạo survey, cấu hình metadata, thêm câu hỏi, chọn loại câu hỏi, cấu hình required hoặc free input, cấu hình quan hệ giữa các câu hỏi rồi publish. Thành viên mở survey và trả lời; nếu một answer kích hoạt câu hỏi phụ thì câu hỏi phụ được hiển thị hoặc enable trước khi tiếp tục, nếu không thì tiếp tục ngay. Cuối cùng thành viên submit, hệ thống lưu survey result và dữ liệu đi tiếp vào reporting, download và analytics.

Có

Không

Admin tạo Survey

Cấu hình metadata

Thêm câu hỏi

Chọn loại câu hỏi

Cấu hình Required / Free Input

Cấu hình quan hệ giữa câu hỏi

Publish Survey

Thành viên mở Survey

Trả lời câu hỏi

Answer có kích hoạt câu hỏi phụ?

Hiển thị / Enable câu hỏi phụ

Tiếp tục Survey

Submit

Lưu Survey Result

Reporting / Download / Analytics

Sơ đồ vừa khung

Form là dữ liệu, không phải code: quan hệ giữa các câu hỏi quyết định, ngay lúc trả lời, thành viên thấy câu nào.

Point thưởng tính từ action log

Point không được tính ngay trong request phát sinh ra nó. Các hành động hợp lệ — click quảng cáo, thao tác với job, các booking được cấu hình — được ghi vào action log, phần còn lại do batch xử lý. Batch hằng ngày đọc log chưa xử lý, kiểm tra điều kiện, tra số point tương ứng, áp dụng rule (nhiều click vào cùng một quảng cáo hoặc job trong cùng ngày chỉ tính một lần; point có giới hạn theo tháng), tạo point distribution plan rồi đánh dấu log đã xử lý. Batch đầu tháng tổng hợp point và số profile thành kết quả phân phối và file báo cáo. Thành viên đổi point qua một ứng dụng point đối tác.

Luồng tính point và reward bằng action log và batchClick quảng cáo, thao tác với job và các booking hoặc action hợp lệ đều được ghi vào action logs. Daily batch đọc action logs và kiểm tra rule, trùng lặp và giới hạn; kết quả vừa tạo point distribution plan vừa đánh dấu log đã xử lý. Monthly batch tổng hợp point distribution plan thành monthly distribution result, từ đó tạo file và report.

Click Advertisement

Job Action

Booking / Action hợp lệ

Action Logs

Daily Batch

Kiểm tra rule / duplicate / giới hạn

Point Distribution Plan

Đánh dấu log đã xử lý

Monthly Batch

Monthly Distribution Result

Tạo file / Report

Sơ đồ vừa khung

Ghi event log trước, tính toán hằng ngày, rồi tổng hợp hằng tháng. Hành động của người dùng kết thúc ngay; rule nghiệp vụ chạy sau.

Export bất đồng bộ và thông báo

Kết quả survey, export toàn bộ doctor profile, file CSV và ZIP có thể mất nhiều thời gian hơn một request nên có. Chúng chạy nền trên Cloud Tasks và Cloud Functions; file được lưu vào Cloud Storage, và Firebase Cloud Messaging báo cho admin khi file sẵn sàng — trang quản trị xin quyền thông báo chính cho việc này. Lịch sử download lưu lại các lần export trước.

Email nghiệp vụ bao phủ phần còn lại của vòng đời: đăng ký thành công, xác minh giấy phép thành công, không thể xác minh, yêu cầu bổ sung giấy tờ, thông báo sự cố và vận hành.

Luồng xử lý download bất đồng bộAdmin yêu cầu export qua backend API. Backend giao việc cho background task hoặc batch; task đọc Firestore và dữ liệu nghiệp vụ, tạo file CSV hoặc ZIP, lưu file vào Cloud Storage. Khi file sẵn sàng, Firebase Cloud Messaging gửi thông báo hoàn tất, nên admin không phải giữ màn hình chờ request dài.

Admin yêu cầu Export

Backend API

Background Task / Batch

Firestore / Dữ liệu nghiệp vụ

CSV / ZIP

Cloud Storage

Firebase Cloud Messaging

Thông báo hoàn tất

Sơ đồ vừa khung

Admin yêu cầu một lần và được báo khi file đã có, thay vì giữ màn hình chờ một request dài.

Tìm việc trên Elasticsearch

Member Portal có khu vực tuyển dụng và tìm việc, lọc theo từ khóa, hình thức làm việc và tỉnh thành. Tìm kiếm, lọc và sắp xếp chạy trên index Elasticsearch thay vì Firestore, và hành vi tìm kiếm, click được ghi log để tính point, tracking và analytics.

Kiến trúc mức high-level

Các ứng dụng Angular xác thực qua Firebase Authentication và gọi backend Node.js / NestJS. Firestore giữ dữ liệu nghiệp vụ, Cloud Storage giữ file, Elasticsearch phục vụ search, còn Cloud Run, Cloud Functions và Cloud Tasks gánh phần xử lý nền. BigQuery phục vụ tổng hợp dữ liệu và reporting, Cloud Logging gom log, Firebase Cloud Messaging gửi thông báo.

Kiến trúc kỹ thuật mức high-level của Dr.Well-BNgười dùng và admin dùng các ứng dụng web Angular. Frontend xác thực qua Firebase Authentication và gọi backend Node.js / NestJS. Backend làm việc với Firestore, Cloud Storage, Elasticsearch và Cloud Run. Cloud Run đẩy việc vào Cloud Tasks, gửi thông báo qua Firebase Cloud Messaging, ghi dữ liệu sang BigQuery và log vào Cloud Logging. Cloud Tasks và Cloud Functions ghi vào Firestore; Firestore đổ dữ liệu sang BigQuery; Cloud Functions cũng ghi log vào Cloud Logging. Đây là các thành phần chính trong tài liệu dự án, không phải bản sao 1:1 của sơ đồ production nội bộ.

Người dùng

Admin

Angular Web Applications

Firebase Authentication

Node.js / NestJS Backend

Firestore

Cloud Storage

Elasticsearch

Cloud Run

Cloud Functions

Cloud Tasks

Firebase Cloud Messaging

BigQuery

Cloud Logging

Sơ đồ vừa khung

Các thành phần chính xuất hiện trong tài liệu dự án. Đây không phải bản sao 1:1 của sơ đồ production nội bộ.

Luồng dữ liệu giữa các module

Luồng dữ liệu tổng quát giữa các moduleProfile người dùng là đầu vào cho quảng cáo, survey và job. User actions được ghi thành action logs; quảng cáo và job cũng ghi vào action logs, còn survey đổ dữ liệu trực tiếp vào analytics / BigQuery. Action logs nuôi point engine và analytics. Job dùng search. Point engine và analytics cùng tạo export và report. Module nội dung đứng riêng, không tham gia các luồng dữ liệu này.

Profile

User Actions

Ads

Survey

Job

Content

Action Logs

Point Engine

Search

Analytics / BigQuery

Export / Report

Sơ đồ vừa khung

Hồ sơ đi vào quảng cáo, survey và job; hành động đi vào log; log và dữ liệu survey đi tiếp vào point, analytics và export.

Dự án bao phủ những gì

Bài toán của một hệ thống quản lý lớnThể hiện trong Dr.Well-B
Workflow nghiệp vụ có phê duyệtXác minh giấy phép, admin approval, approval history, khóa hồ sơ sau duyệt
Rule do operator cấu hình, không cần codeSurvey engine với quan hệ câu hỏi; luật phân phối quảng cáo
Cá nhân hóaChọn quảng cáo theo chuyên khoa, society, tag, thời gian, giới hạn và hành vi
Xử lý sự kiện và batchAction log, batch point hằng ngày, rồi tổng hợp và file hằng tháng
Tác vụ chạy lâuExport nền trên Cloud Tasks / Cloud Functions, thông báo qua FCM
Search quy mô lớnIndex và sorting trên Elasticsearch, tách khỏi Firestore
Báo cáoTổng hợp trên BigQuery, export CSV/ZIP, lịch sử download
Giữ nhiều rule không bị hồi quyAutomation test Cypress cho nhiều service, survey và trình duyệt mobile

Các sơ đồ được dựng lại ở mức thành phần từ tài liệu thiết kế của dự án. Chúng lược bỏ URL nội bộ, định danh hệ thống, source code độc quyền và dữ liệu của khách hàng; ảnh chụp dùng tài khoản test và dữ liệu demo, các tên nội bộ đã được làm mờ.

Ảnh 1 trên 5