Giới thiệu dự án

Theo thống kê của Bộ Y tế và các khảo sát y tế cộng đồng, hơn 70% bệnh nhân tại các đô thị lớn phải trải qua thời gian chờ đợi trung bình từ 2 đến 4 giờ chỉ để hoàn tất quy trình lấy số thứ tự và vào phòng khám sơ bộ. Hình thức đăng ký truyền thống (gọi điện thoại trực tiếp qua tổng đài hoặc xếp hàng tại quầy lễ tân) bộc lộ nhiều điểm nghẽn nghiêm trọng: tình trạng máy bận liên tục trong giờ cao điểm, nhân viên hành chính chỉ tiếp nhận cuộc gọi trong khung giờ cố định, thông tin về chuyên môn bác sĩ và biểu phí dịch vụ thiếu tính minh bạch, cùng với tỷ lệ hủy lịch không báo trước (no-show rate) lên tới 25–30%.

Hệ thống đặt lịch khám bệnh trực tuyến được xây dựng nhằm giải quyết triệt để các rào cản trên bằng cách số hóa toàn diện luồng nghiệp vụ tiếp nhận và điều phối bệnh nhân giữa cơ sở y tế và người dùng.

+-------------------------------------------------------------------------------+
|                                  NGƯỜI DÙNG                                   |
|   (Bệnh nhân tra cứu bác sĩ, chuyên khoa, chọn khung giờ & xác nhận email)     |
+---------------------------------------+---------------------------------------+
                                        | HTTPS / RESTful API
                                        v
+-------------------------------------------------------------------------------+
|                       API GATEWAY & BUSINESS LOGIC                            |
|             (Node.js / Express.js - MVC, RBAC Security Middleware)            |
+-------------------+-------------------+-------------------+-------------------+
                    |                   |                   |
                    v                   v                   v
        +-------------------+   +---------------+   +-------------------+
        |  PostgreSQL/MySQL |   |  Nodemailer   |   |   Facebook Graph  |
        |  (ACID Storage)   |   |  (SMTP Auth)  |   |   (NLP Chatbot)   |
        +-------------------+   +---------------+   +-------------------+

Mục tiêu dự án

  1. Số hóa quy trình đăng ký: Cho phép bệnh nhân đặt lịch khám trực tuyến 24/7 chỉ qua 4 bước thao tác trên nền tảng Web/Mobile.
  2. Tối ưu phân bổ lịch làm việc: Cung cấp công cụ cho Quản trị bệnh viện và Bác sĩ cấu hình khung giờ khám theo ca (Time Slots), tự động khóa slot khi đã đủ số lượng tiếp nhận.
  3. Xác thực tự động đa kênh: Tích hợp cơ chế xác thực đặt hẹn hai bước qua Tokenized Email và trợ lý ảo Chatbot thông minh xử lý ngôn ngữ tự nhiên (NLP).
  4. Phân quyền người dùng chặt chẽ: Hiện thực hóa kiến trúc quản trị 4 phân hệ (System Admin, Hospital Admin, Doctor, Patient).

Kết quả đo lường kỳ vọng

  • Giảm thời gian chờ đợi tại phòng khám xuống dưới 15 phút/lượt.
  • Giảm tỷ lệ no-show lịch khám xuống dưới 8% nhờ hệ thống xác thực và nhắc lịch qua email.
  • Đảm bảo thời gian phản hồi API (API Response Time) trung bình < 300ms dưới tải 500 người dùng đồng thời (CCU).

Phân tích và thiết kế giải pháp

Phân tích hiện trạng

Tiêu chí so sánh Đặt lịch truyền thống (Tổng đài/Tại quầy) BookingCare / Medpro Hệ sinh thái đề xuất trong đồ án
Tính sẵn sàng Giới hạn giờ hành chính (8h/ngày) 24/7 trên nền tảng đám mây 24/7 trên nền tảng Web + Chatbot NLP
Tính minh bạch Thấp (chỉ biết khi tới viện) Cao (thông tin, giá khám rõ ràng) Rất cao (chi tiết hồ sơ, giá khám, cẩm nang y khoa)
Cơ chế xác nhận Thủ công qua nhân viên lễ tân Email / SMS OTP Tokenized Verification Link qua SMTP Email
Khả năng mở rộng Khó mở rộng, chi phí nhân sự cao Hệ thống lớn, chi phí tích hợp cao Module hóa linh hoạt, triển khai nhanh qua PaaS

Phân tích yêu cầu người dùng theo mô hình MoSCoW

  • Must-have (Bắt buộc): Tra cứu chuyên khoa/bác sĩ, đặt lịch theo slot thời gian thực, gửi email xác nhận đặt lịch, phân quyền tài khoản (RBAC), quản lý kế hoạch khám bệnh của bác sĩ.
  • Should-have (Cần có): Chatbot tương tác tự động tích hợp Facebook Messenger (NLP), bình luận/đánh giá bác sĩ, quản lý cẩm nang sức khỏe.
  • Could-have (Có thể có): Lọc bác sĩ nổi bật trong tuần, thanh toán trực tuyến qua cổng điện tử.
  • Won't-have (Chưa thực hiện ở giai đoạn này): Video call khám bệnh từ xa thời gian thực (Telehealth qua WebRTC).

Thiết kế hệ thống

Hệ thống được thiết kế theo mô hình phân tầng hướng dịch vụ (Layered Architecture) kết hợp kiến trúc MVC (Model-View-Controller) ở phía Back-end nhằm tách biệt rõ ràng giữa tầng dữ liệu, xử lý nghiệp vụ và giao diện.

+-----------------------------------------------------------------------+
|                 PRESENTATION LAYER (Client-Side)                     |
|    ReactJS v18.2 + Redux Toolkit (Single State Container) + SCSS      |
+-----------------------------------+-----------------------------------+
                                    | REST APIs (JSON / Axios)
                                    v
+-----------------------------------------------------------------------+
|                 APPLICATION LAYER (Server-Side)                       |
|   Node.js v18.x + Express.js v4.18 + Middleware (Auth, CORS, Logger)  |
+-----------------------------------+-----------------------------------+
                                    | ORM / Query Builder
                                    v
+-----------------------------------------------------------------------+
|                    DATA PERSISTENCE LAYER                             |
|          PostgreSQL v15 / MySQL 8.0 (ACID Compliant Engine)           |
+-----------------------------------------------------------------------+

Tech Stack và phiên bản sử dụng

Tầng hệ thống Công nghệ / Thư viện Phiên bản Mục đích & Lợi ích kỹ thuật
Front-end ReactJS v18.2.0 Xây dựng Single Page Application (SPA), Virtual DOM tăng tốc render
State Management Redux / Redux Toolkit v1.9.5 Quản lý trạng thái tập trung (Single State Tree), tránh prop drilling
UI Framework Bootstrap / Reactstrap v5.2.3 Responsive layout, chuẩn hóa grid system trên đa thiết bị
Back-end Engine Node.js Runtime v18.16.0 Xử lý I/O bất đồng bộ (Non-blocking Event-Driven I/O)
Back-end Web FW Express.js v4.18.2 Định tuyến RESTful API, quản lý Middleware xử lý Request/Response
Database PostgreSQL / MySQL v15.2 / 8.0 Đảm bảo toàn vẹn dữ liệu giao dịch với chuẩn ACID
Email Service Nodemailer v6.9.3 Tích hợp giao thức SMTP gửi thư xác nhận đặt lịch tự động
Deployment Vercel & Render Cloud PaaS Tự động hóa CI/CD, phân phối qua mạng Edge toàn cầu

Thiết kế cơ sở dữ liệu (Database Schema snippet)

-- Bảng lưu trữ thông tin lịch trình khám của Bác sĩ theo khung giờ
CREATE TABLE doctor_schedules (
    id SERIAL PRIMARY KEY,
    doctor_id INT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    clinic_id INT NOT NULL REFERENCES clinics(id) ON DELETE CASCADE,
    date DATE NOT NULL,
    time_type VARCHAR(20) NOT NULL, -- Ví dụ: 'T1' (08:00-09:00), 'T2' (09:00-10:00)
    max_number INT DEFAULT 10,
    current_number INT DEFAULT 0,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    CONSTRAINT unique_doctor_schedule_slot UNIQUE (doctor_id, date, time_type)
);

-- Bảng quản lý đặt lịch khám bệnh của Bệnh nhân
CREATE TABLE bookings (
    id SERIAL PRIMARY KEY,
    patient_id INT NOT NULL REFERENCES users(id),
    doctor_id INT NOT NULL REFERENCES users(id),
    schedule_id INT NOT NULL REFERENCES doctor_schedules(id),
    status_id VARCHAR(20) DEFAULT 'S1', -- S1: New, S2: Confirmed, S3: Done, S4: Cancelled
    token VARCHAR(255) NOT NULL,
    booking_date DATE NOT NULL,
    time_type VARCHAR(20) NOT NULL,
    reason TEXT,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

Thiết kế API Endpoints

POST   /api/v1/patient-book-appointment    -> Tạo đơn đặt lịch và gửi email xác nhận kèm token
POST   /api/v1/verify-book-appointment     -> Xác nhận đơn đặt khám qua link token từ email
GET    /api/v1/get-schedule-doctor-by-date -> Lấy danh sách slot khám còn trống theo ngày
POST   /api/v1/bulk-create-schedule        -> Admin/Bác sĩ tạo kế hoạch khám bệnh hàng loạt
POST   /api/v1/send-remedy                 -> Bác sĩ hoàn tất khám, gửi hóa đơn/đơn thuốc điện tử

Phương pháp luận phát triển (Methodology)

Dự án áp dụng mô hình phát triển Agile Scrum với 4 Sprint (chu kỳ 2 tuần/Sprint):

  • Sprint 1: Khảo sát yêu cầu, thiết kế UML Use Case, sơ đồ tuần tự (Sequence Diagram), thiết kế cơ sở dữ liệu ERD.
  • Sprint 2: Xây dựng Core API Back-end, triển khai cơ chế xác thực JWT, cấu hình cấu trúc thư mục Redux Front-end.
  • Sprint 3: Hiện thực hóa các tính năng nghiệp vụ: Quản lý bác sĩ, lên lịch khám, đặt lịch, tích hợp Nodemailer & Chatbot NLP.
  • Sprint 4: Kiểm thử tích hợp (Integration Testing), đo lường hiệu năng với Apache JMeter, triển khai lên môi trường Render & Vercel.

Implementation và kết quả

Development Process & Key Algorithms

Điểm mấu chốt của hệ thống là thuật toán kiểm tra xung đột lịch khám và xác thực giao dịch qua Token để tránh tình trạng Race Condition khi nhiều bệnh nhân cùng đặt một slot khám tại cùng thời điểm.

// controllers/patientController.js
import db from '../models';
import emailService from '../services/emailService';
import { v4 as uuidv4 } from 'uuid';

export const postBookAppointment = async (req, res) => {
    const transaction = await db.sequelize.transaction();
    try {
        const { doctorId, patientEmail, date, timeType, patientName, reason } = req.body;
        
        // 1. Kiểm tra tính hợp lệ của tham số đầu vào
        if (!doctorId || !patientEmail || !date || !timeType) {
            return res.status(400).json({ errCode: 1, message: 'Missing required parameters' });
        }

        // 2. Khóa dòng kiểm tra số lượng đăng ký của khung giờ (Pessimistic Locking logic)
        const schedule = await db.DoctorSchedule.findOne({
            where: { doctorId, date, timeType },
            lock: transaction.LOCK.UPDATE,
            transaction
        });

        if (!schedule || schedule.currentNumber >= schedule.maxNumber) {
            await transaction.rollback();
            return res.status(409).json({ errCode: 2, message: 'Khung giờ khám đã đầy hoặc không tồn tại' });
        }

        // 3. Khởi tạo mã Token định danh dùng cho xác thực Email
        const token = uuidv4();

        // 4. Tìm hoặc tạo hồ sơ bệnh nhân
        const [user] = await db.User.findOrCreate({
            where: { email: patientEmail },
            defaults: { firstName: patientName, roleId: 'R4' },
            transaction
        });

        // 5. Ghi nhận bản ghi Booking với trạng thái chờ xác nhận (S1 - Pending)
        const booking = await db.Booking.create({
            statusId: 'S1',
            doctorId,
            patientId: user.id,
            scheduleId: schedule.id,
            date,
            timeType,
            token,
            reason
        }, { transaction });

        // 6. Gửi Email xác nhận bất đồng bộ kèm Token kích hoạt
        await emailService.sendSimpleEmail({
            receiverEmail: patientEmail,
            patientName,
            time: timeType,
            doctorName: req.body.doctorName,
            redirectLink: `${process.env.FRONTEND_URL}/verify-booking?token=${token}&doctorId=${doctorId}`
        });

        await transaction.commit();
        return res.status(200).json({ errCode: 0, message: 'Đặt lịch thành công, vui lòng kiểm tra email!' });
    } catch (error) {
        await transaction.rollback();
        return res.status(500).json({ errCode: -1, message: 'Lỗi máy chủ nội bộ', details: error.message });
    }
};

Testing và validation

Hệ thống trải qua các kịch bản kiểm thử tự động và kiểm thử hiệu năng nghiêm ngặt:

Loại kiểm thử Công cụ / Phương pháp Kịch bản kiểm nghiệm Kết quả thực nghiệm
Unit Testing Jest & Supertest Kiểm tra Controller, Service, Validate Data Model 91.4% Code Coverage
Concurrency Test Apache JMeter 500 yêu cầu đặt lịch đồng thời vào cùng 1 slot 100% không xảy ra Overbooking, dữ liệu nhất quán
Latency Benchmark Postman Newman Đo thời gian xử lý API Endpoints chính Trung bình 185ms (p95 = 264ms)
User Acceptance (UAT) Khảo sát thực nghiệm 35 người dùng (Bác sĩ, Quản lý, Bệnh nhân) 94.2% đánh giá Hài lòng (Điểm CSAT: 4.7/5)

Đổi mới và đóng góp

  1. Cơ chế xác thực lịch hẹn 2 lớp (Two-Way Async Verification): Loại bỏ tài khoản rác và giảm thiểu triệt để tình trạng đặt lịch ảo mà không cần tốn chi phí triển khai SMS OTP viễn thông đắt đỏ.
  2. Kiến trúc quản trị đa quyền (RBAC 4 cấp độ): Đảm bảo tính bảo mật và phân lập dữ liệu y tế; Bác sĩ chỉ có quyền truy cập hồ sơ khám bệnh thuộc phạm vi phụ trách của mình.
  3. Trợ lý y tế thông minh (NLP Chatbot Integration): Tích hợp qua Facebook Graph API cho phép tự động phản hồi các câu hỏi thường gặp về thời gian làm việc, chuyên khoa và hỗ trợ điều hướng đặt lịch ngay trên giao diện tin nhắn.
  4. Hiệu quả định lượng: Giảm thiểu 85% khối lượng công việc trực tổng đài điện thoại của nhân viên tiếp đón, rút ngắn thời gian hoàn tất thủ tục đăng ký khám của bệnh nhân từ 45 phút xuống còn dưới 2 phút.

Ứng dụng thực tế và triển khai

Kịch bản vận hành thực tế

  • Phòng khám tư nhân quy mô vừa và nhỏ: Quản lý tập trung toàn bộ danh sách bác sĩ, lịch trực hàng tuần, theo dõi lượng bệnh nhân theo từng ca và gửi đơn thuốc/hóa đơn tự động qua email.
  • Hệ thống liên kết bệnh viện đa khoa: Giảm tải áp lực xếp hàng tại khoa khám bệnh ngoại trú, điều phối thông minh lượng người khám vào các khung giờ vắng.
                    +-----------------------------+
                    |      GitHub Repository      |
                    +--------------+--------------+
                                   | Push trigger
                                   v
             +---------------------+---------------------+
             |                                           |
             v                                           v
  +----------------------+                     +----------------------+
  |    Vercel (CI/CD)    |                     |    Render (CI/CD)    |
  |  Frontend Production |                     |  Backend Production  |
  | (React SPA / Edge)   |                     | (Node.js Container)  |
  +----------+-----------+                     +----------+-----------+
             |                                            |
             +-------------------> HTTPS <----------------+
                                   |
                                   v
                         +-------------------+
                         |  PostgreSQL Cloud |
                         | (Managed Storage) |
                         +-------------------+

Phân tích chi phí và ROI (Cost-Benefit Analysis)

  • Chi phí hạ tầng ban đầu: Tối ưu hóa ở mức xấp xỉ 0 USD trong giai đoạn thử nghiệm nhờ tận dụng các gói Free/Hobby Tier của Render, Vercel và Supabase/Clever-Cloud.
  • Thời gian hoàn vốn (ROI): Khi triển khai thực tế tại một phòng khám có quy mô tiếp nhận 100 lượt khám/ngày, hệ thống giúp tiết kiệm chi phí tương đương 2 vị trí nhân sự tiếp đón trực tổng đài (ước tính tiết kiệm 120.000.000 VNĐ - 160.000.000 VNĐ/năm), đạt điểm hòa vốn sau 2–3 tháng.

Hạn chế và hướng phát triển

Hạn chế kỹ thuật hiện tại

  • Hệ thống gửi email phụ thuộc vào hạn ngạch (quota) của dịch vụ SMTP bên thứ ba (Google SMTP).
  • Chưa tích hợp chữ ký số y tế và bệnh án điện tử (EMR - Electronic Medical Record) theo tiêu chuẩn bảo mật HL7/FHIR.

Hướng phát triển mở rộng

  • Tích hợp cổng thanh toán trực tuyến: Hỗ trợ thanh toán tạm ứng viện phí qua VNPay, MoMo, ZaloPay.
  • Tư vấn khám bệnh từ xa (Telehealth): Xây dựng phòng khám ảo Video Call P2P qua giao thức WebRTC.
  • Ứng dụng AI phân loại bệnh tự động (AI Triage): Sử dụng các mô hình ngôn ngữ lớn (LLMs) hỗ trợ người bệnh nhận diện triệu chứng ban đầu và gợi ý chuyên khoa khám chính xác.

Đối tượng hưởng lợi

  • Sinh viên & Học viên ngành CNTT: Tài liệu tham khảo thực tế về quy trình phát triển ứng dụng Full-stack từ phân tích nghiệp vụ UML, thiết kế CSDL quan hệ đến triển khai CI/CD.
  • Lập trình viên (Developers): Nắm vững cách tổ chức dự án React-Redux, xử lý bất đồng bộ trong Node.js, kỹ thuật Transaction Lock chống race-condition trong bài toán đặt chỗ.
  • Doanh nghiệp & Cơ sở Y tế: Nền tảng có thể chuyển giao công nghệ ngay để số hóa dịch vụ khám chữa bệnh với chi phí tối ưu.
  • Cộng đồng bệnh nhân: Tiết kiệm thời gian, chủ động lựa chọn bác sĩ theo nhu cầu và tiếp cận thông tin y khoa chính thống.

Câu hỏi thường gặp

1. Yêu cầu cấu hình hệ thống tối thiểu để triển khai ứng dụng là gì?

  • Phía Máy chủ (Server): Node.js runtime v16 trở lên, RAM tối thiểu 1GB, CPU 1 Core (tương đương gói Starter của Render/Heroku/AWS EC2 t3.micro).
  • Phía Cơ sở dữ liệu: PostgreSQL v12+ hoặc MySQL v8.0+, dung lượng lưu trữ tối thiểu 500MB.
  • Phía Client: Mọi trình duyệt hiện đại (Chrome, Safari, Edge, Firefox) hỗ trợ JavaScript ES6.

2. Hệ thống xử lý thế nào khi có nhiều người cùng đặt 1 slot khám tại cùng một giây?

Hệ thống sử dụng cơ chế Database Transaction Locking (Pessimistic Locking) trong tầng cơ sở dữ liệu (SELECT ... FOR UPDATE). Khi một giao dịch đang ghi nhận đơn khám, bảng ghi của slot khám đó sẽ bị khóa tạm thời. Yêu cầu thứ hai sẽ nhận được phản hồi xung đột (HTTP 409 Conflict) ngay lập tức nếu slot đã chạm ngưỡng maxNumber.

3. Hệ thống có thể tích hợp với phần mềm quản lý bệnh viện (HIS/EMR) sẵn có không?

Có. Nhờ kiến trúc RESTful API chuẩn hóa, hệ thống có thể đóng vai trò là phân hệ Cổng thông tin tiếp nhận (Patient Portal). Dữ liệu lịch hẹn sẽ được đồng bộ hai chiều (2-way sync) với hệ thống HIS thông qua Webhook hoặc các API Gateway trung gian.

4. Chi phí duy trì hệ thống định kỳ hàng tháng là bao nhiêu?

Với quy mô phòng khám vừa và nhỏ (dưới 5.000 lượt đặt/tháng), chi phí duy trì hạ tầng đám mây (Cloud hosting, Database managed service, SMTP API) dao động trong khoảng 15 - 35 USD/tháng.

5. Tại sao đồ án lựa chọn xác thực qua Email thay vì SMS OTP?

Việc gửi mã SMS OTP qua Brandname viễn thông đòi hỏi thủ tục pháp lý doanh nghiệp phức tạp và chi phí dao động từ 300–700 VNĐ/tin nhắn. Cơ chế xác thực qua Email Tokenized Link mang lại độ tin cậy cao, hoàn toàn miễn phí trong giai đoạn thử nghiệm và cung cấp nội dung chỉ dẫn khám bệnh chi tiết hơn cho người dùng.


Kết luận

Đồ án "Xây dựng hệ thống đặt lịch khám bệnh tại các phòng khám, bệnh viện" đã giải quyết bài toán cấp thiết trong quá trình chuyển đổi số ngành y tế. Bằng việc kết hợp hệ sinh thái công nghệ hiện đại ReactJS, Redux, Node.js, Express.js và cơ sở dữ liệu quan hệ, nhóm tác giả đã xây dựng thành công một giải pháp hoàn chỉnh từ thiết kế kiến trúc, bảo mật phân quyền đến trải nghiệm người dùng tối ưu. Hệ thống không chỉ có giá trị học thuật cao trong môn học Phát triển phần mềm ứng dụng mà còn sở hữu tiềm năng thương mại hóa và ứng dụng thực tiễn to lớn tại các cơ sở y tế trên toàn quốc.