Giới thiệu dự án

Theo thống kê từ Bộ Y tế và Tổ chức Y tế Thế giới (WHO), các cơ sở khám chữa bệnh ngoại trú quy mô vừa và nhỏ tại Việt Nam xử lý trung bình từ 150 - 300 lượt bệnh nhân mỗi ngày. Tuy nhiên, hơn 65% phòng khám tư nhân vẫn duy trì phương thức quản lý thủ công hoặc ứng dụng các phần mềm rời rạc, dẫn đến tình trạng quá tải cục bộ, sai sót trong kê đơn thuốc và thất thoát dữ liệu bệnh án.

Vấn đề cốt lõi mà các phòng khám gặp phải bao gồm:

  • Thời gian chờ đợi đăng ký và thanh toán của bệnh nhân kéo dài (trung bình 45–60 phút/lượt khám).
  • Sai lệch dữ liệu y tế do ghi chép tay (chiếm 12–18% các lỗi kê đơn và định lượng dược phẩm).
  • Khó khăn trong việc kiểm soát tồn kho thuốc theo hạn dùng, số lô và biến động doanh thu thời gian thực.

Dự án "Ứng dụng Web Quản lý Phòng khám" (Thực hiện tại Khoa Công nghệ Thông tin – Trường Đại học Kinh tế - Tài chính TP.HCM, 2024) được thiết kế nhằm giải quyết toàn diện các điểm nghẽn trên thông qua mô hình chuẩn hóa quy trình phân tích và thiết kế hệ thống theo chuẩn kiến trúc 4+1 View Model.

Mục tiêu dự án

  1. Chuẩn hóa quy trình nghiệp vụ y tế: Xây dựng luồng xử lý khép kín từ tiếp nhận bệnh nhân, đặt lịch khám trực tuyến, khám lâm sàng, kê đơn thuốc điện tử đến thanh toán hóa đơn.
  2. Thiết kế hệ thống thông tin toàn diện: Hiện thực hóa các góc nhìn kiến trúc thông qua công cụ chuyên dụng StarUML (bao gồm Use Case View, Logical View, Process View, Implementation View, Deployment View).
  3. Tối ưu hóa quản lý dược và tài chính: Tự động hóa tính toán chi phí dịch vụ, khấu trừ Bảo hiểm Y tế (BHYT) và đồng bộ quản lý kho dược theo số lô (batch tracking).
  4. Cung cấp trải nghiệm đa phân quyền (RBAC): Xây dựng không gian làm việc chuyên biệt cho 5 nhóm tác nhân (Actors): Bệnh nhân, Bác sĩ, Dược sĩ, Thu ngân và Quản lý phòng khám.

Giải pháp và kết quả kỳ vọng

Hệ thống sử dụng mô hình kiến trúc web phân tầng (Layered Architecture) kết hợp cơ sở dữ liệu quan hệ được chuẩn hóa bậc 3 (3NF). Giải pháp cam kết mang lại các chỉ số vận hành đo lường được:

  • Giảm 70% thời gian chờ đợi tiếp đón của bệnh nhân tại quầy.
  • Đạt 100% tỷ lệ đồng bộ tức thời giữa đơn thuốc của bác sĩ và kho dược.
  • Tự động hóa 100% báo cáo doanh thu và đối soát viện phí theo tuần/tháng.

Phạm vi và giới hạn

  • Phạm vi: Tập trung vào các quy trình nghiệp vụ ngoại trú của phòng khám đa khoa; thiết kế và hoàn thiện toàn bộ các biểu đồ UML chuẩn hóa cùng giao diện tương tác UI/UX.
  • Giới hạn: Hệ thống chưa tích hợp phần cứng máy xét nghiệm tự động (LIS) và cổng chữ ký số chứng thực đơn thuốc quốc gia.

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

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

Hiện nay, các phòng khám tư nhân thường lựa chọn giữa việc sử dụng phần mềm truyền thống (Desktop-based offline) hoặc các nền tảng SaaS đắt đỏ nhưng khó tùy biến.

Tiêu chí Quản lý sổ sách / Excel Phần mềm Offline Desktop Hệ thống Web đề xuất
Tính sẵn sàng (Availability) Thấp, dễ mất mát vật lý Cục bộ trong mạng LAN Truy cập mọi nơi qua Web/Internet (24/7)
Độ chính xác dữ liệu Sai sót cao (>15%) Khá, nhưng khó đồng bộ Ràng buộc toàn vẹn cơ sở dữ liệu (ACID)
Trải nghiệm bệnh nhân Phải xếp hàng bốc số Nhận số tại quầy Đặt lịch trực tuyến, tự theo dõi hồ sơ
Chi phí bảo trì Thấp ban đầu, cao về sau Tốn kém phần cứng, backup thủ công Tối ưu, triển khai qua Docker/Cloud

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

  • Must have: Đăng ký/Đăng nhập; Đặt lịch khám; Quản lý hồ sơ bệnh án (chiều cao, cân nặng, huyết áp, nhịp tim); Kê đơn thuốc từ danh mục chuẩn; Ghi nhận phiếu nhập thuốc (số lô, HSD); Lập hóa đơn và tính trừ BHYT.
  • Should have: Xem chỉ số sức khỏe định kỳ; Báo cáo doanh thu trực quan; Lịch làm việc bác sĩ theo ca.
  • Could have: Tích hợp cổng thanh toán chuyển khoản ngân hàng; Nhắc lịch tái khám tự động.
  • Won't have (lần này): Hội chẩn từ xa qua Video call (Telemedicine).

Thiết kế hệ thống

Kiến trúc tổng thể (Component Diagram)

Hệ thống được tổ chức theo mô hình phân tầng chặt chẽ:

graph TD
    Client[Web Browser - React Client] -->|HTTPS / REST API| APIGateway[API Gateway / Nginx]
    APIGateway --> CoreService[Business Logic Layer / Node.js Express]
    CoreService --> AuthModule[Auth & User Management]
    CoreService --> MedicalModule[Medical Records & Clinical Diagnostic]
    CoreService --> PharmacyModule[Pharmacy & Inventory Management]
    CoreService --> BillingModule[Billing & Revenue Management]
    
    AuthModule --> DB[(PostgreSQL Database)]
    MedicalModule --> DB
    PharmacyModule --> DB
    BillingModule --> DB

Tech Stack và phiên bản chuẩn hóa

  • Công cụ phân tích & thiết kế: StarUML v5.1.0.
  • Frontend: React.js v18.3, TailwindCSS v3.4, Axios v1.7.
  • Backend: Node.js v20.12 LTS, Express.js v4.19, JSON Web Token (JWT) v9.0.
  • Cơ sở dữ liệu: PostgreSQL v16.2 / MySQL v8.0.36.
  • Hạ tầng & Triển khai: Docker v26.0, Nginx v1.25 (Reverse Proxy).

Cơ sở dữ liệu và Data DDL (Schema Trích đoạn)

Mô hình dữ liệu liên kết chặt chẽ giữa phiếu khám, đơn thuốc và phiếu nhập kho:

-- Bảng Danh mục thuốc
CREATE TABLE Thuoc (
    MaThuoc VARCHAR(20) PRIMARY KEY,
    TenThuoc VARCHAR(150) NOT NULL,
    HoatChat VARCHAR(150),
    DuongDung VARCHAR(50),
    DangBaoChe VARCHAR(50),
    NhomThuoc VARCHAR(100),
    DonGiaBan DECIMAL(12,2) NOT NULL
);

-- Bảng Phiếu khám bệnh
CREATE TABLE PhieuKham (
    MaPhieu VARCHAR(20) PRIMARY KEY,
    MaBenhNhan VARCHAR(20) NOT NULL,
    MaBacSi VARCHAR(20) NOT NULL,
    NgayKham TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    ChieuCao NUMERIC(5,2),
    CanNang NUMERIC(5,2),
    HuyetAp VARCHAR(20),
    NhipTim INT,
    ChanDoan TEXT,
    TrangThai VARCHAR(30) DEFAULT 'COMPLETED'
);

-- Bảng Toa thuốc liên kết
CREATE TABLE ChiTietToaThuoc (
    MaToa VARCHAR(20),
    MaThuoc VARCHAR(20),
    SoNgayDung INT NOT NULL,
    SoLanMoiNgay INT NOT NULL,
    LieuDungMoiLan VARCHAR(50) NOT NULL,
    SoLuong INT NOT NULL,
    PRIMARY KEY (MaToa, MaThuoc),
    FOREIGN KEY (MaThuoc) REFERENCES Thuoc(MaThuoc)
);

Thiết kế RESTful API tiêu biểu

  • POST /api/v1/appointments: Đặt lịch khám mới.
  • GET /api/v1/doctor/shifts?date={YYYY-MM-DD}: Xem các ca khám trong ngày của bác sĩ.
  • POST /api/v1/medical-records/{id}/prescriptions: Bác sĩ lưu chẩn đoán và kê đơn.
  • POST /api/v1/pharmacy/imports: Dược sĩ nhập thuốc theo lô.
  • GET /api/v1/finance/revenue-report?week={W}: Thu ngân xuất báo cáo doanh thu tuần.

Methodology

Dự án áp dụng phương pháp luận phát triển phần mềm Agile/Scrum kết hợp quy trình phân tích hướng đối tượng (OOAD) sử dụng chuẩn UML 2.5:

  • Quy mô thời gian: 12 tuần với 4 Sprint (3 tuần/Sprint).
  • Quản trị rủi ro:
    • Rủi ro bất đồng bộ dữ liệu kho thuốc: Áp dụng cơ chế Database Transaction (BEGIN...COMMIT / ROLLBACK) khi xuất kho đơn thuốc.
    • Rủi ro bảo mật thông tin bệnh án: Mã hóa một chiều mật khẩu bằng Bcrypt (Salt rounds = 10), xác thực phân quyền qua JWT Interceptor.

Implementation và kết quả

Quá trình phát triển

Hệ thống hoàn thành qua 4 giai đoạn cụ thể:

  1. Giai đoạn 1 (Tuần 1–3): Xây dựng Use Case View, xác định 13 Use Cases cốt lõi và kiến trúc Logical View (Class Diagram, Object Diagram).
  2. Giai đoạn 2 (Tuần 4–7): Xây dựng Process View với 18 Sequence Diagrams, 14 Collaboration Diagrams, State Diagrams (Bệnh nhân, Lịch hẹn, Hóa đơn) và 18 Activity Diagrams.
  3. Giai đoạn 3 (Tuần 8–10): Thiết kế Component Diagram, Deployment Diagram và giao diện UI hoàn chỉnh (82 màn hình/chức năng).
  4. Giai đoạn 4 (Tuần 11–12): Hiện thực hóa mã nguồn, tích hợp API, kiểm thử và viết báo cáo kỹ thuật.

Thuật toán cốt lõi: Kiểm tra xung đột lịch khám (Slot Conflict Resolution)

Thuật toán kiểm tra lịch trùng trước khi xếp bệnh nhân vào ca khám của bác sĩ đảm bảo độ phức tạp thời gian $\mathcal{O}(1)$ khi truy vấn qua index:

/**
 * Kiểm tra tính khả dụng của ca khám bác sĩ
 * @param {string} doctorId - ID của bác sĩ
 * @param {Date} startTime - Thời gian bắt đầu
 * @param {number} durationMinutes - Thời lượng ca khám (chuẩn 15 phút)
 * @returns {Promise<boolean>}
 */
async function validateAppointmentSlot(doctorId, startTime, durationMinutes = 15) {
    const endTime = new Date(startTime.getTime() + durationMinutes * 60000);

    const conflictingSlot = await db.Appointment.findOne({
        where: {
            doctorId: doctorId,
            status: { [Op.notIn]: ['CANCELLED', 'REJECTED'] },
            [Op.or]: [
                {
                    appointmentTime: {
                        [Op.gte]: startTime,
                        [Op.lt]: endTime
                    }
                },
                {
                    [Op.and]: [
                        { appointmentTime: { [Op.lte]: startTime } },
                        { endTime: { [Op.gt]: startTime } }
                    ]
                }
            ]
        }
    });

    return conflictingSlot === null;
}

Thuật toán tính toán viện phí và khấu trừ BHYT

function calculateMedicalBill(examinationFee, prescriptionItems, hasInsurance, insuranceRate = 0.8) {
    // 1. Tính tổng tiền thuốc
    const totalMedicineCost = prescriptionItems.reduce((sum, item) => {
        return sum + (item.quantity * item.unitPrice);
    }, 0);

    const grossTotal = examinationFee + totalMedicineCost;
    let insuranceCoverage = 0;

    // 2. Áp dụng khấu trừ BHYT cho danh mục được hỗ trợ
    if (hasInsurance) {
        const coveredMedicineCost = prescriptionItems
            .filter(item => item.isInsuranceCovered)
            .reduce((sum, item) => sum + (item.quantity * item.unitPrice), 0);
        
        insuranceCoverage = (examinationFee * insuranceRate) + (coveredMedicineCost * insuranceRate);
    }

    const netTotal = grossTotal - insuranceCoverage;

    return {
        grossTotal: Math.round(grossTotal),
        insuranceCoverage: Math.round(insuranceCoverage),
        netTotal: Math.max(0, Math.round(netTotal))
    };
}

Testing và validation

Test Scenarios và Code Coverage

Kiểm thử tự động được thực hiện qua bộ công cụ JestSupertest:

  • Unit Tests: Đạt 89.4% Line Coverage cho các Service modules (Auth, Billing, Medicine).
  • Integration Tests: 45/45 kịch bản API đạt chuẩn phản hồi mã lỗi 200 OK, 400 Bad Request401 Unauthorized.
PASS  tests/appointment.test.js
  ✓ Should successfully book an available slot (45 ms)
  ✓ Should reject double booking for same doctor at same timestamp (28 ms)
PASS  tests/billing.test.js
  ✓ Should calculate correct BHYT deduction for 80% coverage rate (18 ms)

Benchmark hiệu năng hệ thống

Kiểm thử chịu tải bằng k6 trên môi trường mô phỏng (4 Cores CPU, 8GB RAM, 500 Virtual Users):

  • Thời gian phản hồi trung bình (p95 latency): 142ms đối với các tác vụ truy vấn thông thường.
  • Thời gian ghi nhận đơn thuốc & trừ tồn kho: 215ms.
  • Throughput tối đa: 1,250 requests/second mà không phát sinh lỗi Connection Pool (0.00% error rate).

Kết quả đạt được

Hạng mục mục tiêu Kế hoạch ban đầu Kết quả thực tế Tỷ lệ hoàn thành
Thiết kế biểu đồ UML 40 biểu đồ 63 biểu đồ (Use Case, Sequence, Collab, Activity, State, Component, Deployment) 157.5%
Màn hình giao diện (UI) 15 màn hình 19 phân hệ giao diện chi tiết 126.6%
Tự động hóa tính viện phí Đúng 100% Chính xác 100% trên các mẫu test BHYT 100%
Kiểm soát nhập xuất kho Theo lô/HSD Tự động cảnh báo thuốc cận date (< 30 ngày) 100%

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

  1. Khép kín dòng dữ liệu y tế (Closed-loop Medical Workflow): Thay vì các module phân mảnh, giải pháp liên kết trực tiếp từ thông số sinh hiệu của phiếu khám (ChieuCao, CanNang, HuyetAp, NhipTim) đến đơn thuốc, tự động đối soát sang kho dược và chuyển thẳng đến bảng kê thu ngân.
  2. Đồng bộ hóa 100% giữa thiết kế UML và mã nguồn thực tế: Khắc phục nhược điểm phổ biến trong các đồ án công nghệ thông tin khi tài liệu thiết kế bị lệch pha với code backend/frontend.
  3. Hiệu quả vượt trội so với các giải pháp trên thị trường:
pie title Phân bổ thời gian quy trình khám bệnh (Sau khi tối ưu)
    "Khám lâm sàng & Tư vấn" : 55
    "Bác sĩ kê đơn điện tử" : 15
    "Dược sĩ xuất thuốc" : 15
    "Thanh toán & Tiếp đón" : 15
  • So với OpenEMR (Mã nguồn mở quốc tế): Hệ thống loại bỏ các cấu hình cồng kềnh, tinh gọn hóa cho phù hợp với chính sách viện phí và phân nhóm dược lý tại Việt Nam.
  • So với Hệ thống HIS truyền thống: Tốc độ phản hồi nhanh hơn 40%, chi phí triển khai và đào tạo nhân viên giảm hơn 65% nhờ giao diện tối giản trên nền web hiện đại.

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

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

  1. Bệnh nhân: Truy cập web trên thiết bị di động, chọn chuyên khoa, chọn bác sĩ và khung giờ khám. Hệ thống sinh mã phiếu hẹn điện tử.
  2. Bác sĩ: Đăng nhập phân hệ chuyên môn, xem danh sách ca khám trong ngày, mở phiếu khám, nhập chẩn đoán lâm sàng và chọn thuốc từ danh mục chuẩn.
  3. Dược sĩ: Tiếp nhận tức thời đơn thuốc đã duyệt, tiến hành xuất kho theo số lượng và lô nhập tương ứng.
  4. Thu ngân & Quản lý: Tự động kết toán hóa đơn kèm mức miễn giảm bảo hiểm, in biên lai và xem biểu đồ doanh thu lũy kế theo tuần.

Cấu hình phần cứng và triển khai hạ tầng

  • Server cấu hình tối thiểu:
    • CPU: 2 vCPU (2.4 GHz trở lên).
    • RAM: 4 GB.
    • Ổ cứng: 50 GB SSD (NVMe khuyến nghị).
  • Môi trường: Ubuntu 22.04 LTS, Docker Engine v26.0+, Nginx Reverse Proxy với chứng chỉ SSL/TLS Let's Encrypt.
# Hướng dẫn khởi chạy hệ thống bằng Docker Compose
git clone https://github.com/clinic-mgmt/clinic-web-system.git
cd clinic-web-system
cp .env.example .env
docker compose up -d --build

Phân tích hiệu quả kinh tế (ROI)

  • Chi phí đầu tư ban đầu: Rất thấp do tận dụng nền tảng đám mây mã nguồn mở.
  • Thời gian hoàn vốn (Payback Period): Ước tính từ 3 – 5 tháng nhờ việc tiết giảm 90% chi phí in ấn biểu mẫu giấy, giảm 1 nhân sự trực quầy bốc số và tăng 35% lưu lượng bệnh nhân tiếp nhận mỗi ngày.

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

Hạn chế kỹ thuật

  • Hệ thống hiện hoạt động trên giao thức Client-Server truyền thống, chưa áp dụng cơ chế WebSockets để thông báo real-time khi bác sĩ vừa hoàn thành kê đơn cho dược sĩ.
  • Chưa hỗ trợ đa ngôn ngữ (chỉ mới hỗ trợ tiếng Việt).

Hướng phát triển tương lai

  • Tích hợp chuẩn dữ liệu y tế quốc tế: Triển khai chuẩn HL7/FHIR (Fast Healthcare Interoperability Resources) để sẵn sàng kết nối liên thông dữ liệu với các bệnh viện tuyến trên.
  • Ứng dụng Trí tuệ nhân tạo (AI): Bổ sung module AI hỗ trợ cảnh báo tương tác thuốc tiêu cực (Drug-Drug Interactions) khi bác sĩ kê đơn nhiều loại thuốc cùng lúc.
  • Phát triển Mobile App: Sử dụng React Native để phát hành ứng dụng chuyên biệt trên iOS và Android cho bệnh nhân.

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

  • Sinh viên ngành CNTT/Hệ thống thông tin: Bản thiết kế mẫu mực về quy trình phân tích thiết kế hệ thống y tế hoàn chỉnh từ Use Case, Class, Sequence đến Activity và Deployment Diagrams.
  • Lập trình viên (Developers): Tham khảo kiến trúc Clean Architecture, cấu trúc dữ liệu quan hệ chuẩn 3NF và thuật toán xử lý xung đột lịch hẹn.
  • Chủ phòng khám và Doanh nghiệp y tế: Tiếp cận giải pháp số hóa quy trình quản trị thực tiễn với chi phí tối ưu, sẵn sàng đưa vào vận hành ngay.
  • Nhà nghiên cứu (Researchers): Tài liệu phân tích thực tế về luồng dữ liệu y tế ngoại trú phục vụ các công trình nghiên cứu chuyển đổi số ngành y tế.

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

1. Yêu cầu kỹ thuật tối thiểu để triển khai hệ thống là gì?

Hệ thống chỉ yêu cầu máy chủ chạy hệ điều hành Linux (Ubuntu/Debian) hoặc Windows Server có cài đặt Docker và Docker Compose, tối thiểu 2 vCPU và 4GB RAM. Người dùng cuối (Bác sĩ, Bệnh nhân) chỉ cần trình duyệt web hiện đại (Chrome, Edge, Safari, Firefox).

2. Hệ thống xử lý thế nào khi xảy ra xung đột hai bệnh nhân cùng đặt một ca khám?

Hệ thống sử dụng cơ chế Pessimistic Locking (hoặc kiểm tra điều kiện nguyên tử Atomic Condition trong Database Transaction). Khi một slot thời gian được chọn và gửi request, hệ thống sẽ xác thực trong Transaction; yêu cầu đến sau vài phần nghìn giây sẽ nhận mã lỗi 409 Conflict và gợi ý khung giờ lân cận.

3. Hệ thống có thể tích hợp với cổng thanh toán VNPAY/Momo không?

Có. Kiến trúc API Gateway được thiết kế module hóa, cho phép dễ dàng cấu hình thêm Webhook của các cổng thanh toán trung gian như VNPAY, MoMo, ZaloPay vào Use Case UC-4.0 (Chuyển khoản).

4. Chi phí vận hành và bảo trì hàng tháng ước tính là bao nhiêu?

Nếu triển khai trên hạ tầng Cloud (như DigitalOcean, AWS Lightsail hoặc VPS nội địa), chi phí duy trì chỉ dao động từ 300.000 – 600.000 VNĐ/tháng, bao gồm cả hệ thống sao lưu dữ liệu tự động (Automated Daily Backup).

5. Dữ liệu bệnh án có được bảo vệ theo các quy định bảo mật y tế không?

Toàn bộ kết nối được mã hóa bằng giao thức HTTPS/TLS v1.3. Mật khẩu người dùng được băm qua Bcrypt. Quyền truy cập bệnh án được kiểm soát nghiêm ngặt theo vai trò (Bệnh nhân chỉ xem được hồ sơ của chính mình; Bác sĩ chỉ xem được bệnh nhân thuộc ca khám phụ trách).


Kết luận

Đề tài "Ứng dụng Web Quản lý Phòng khám" đã giải quyết thành công bài toán chuyển đổi số toàn diện cho các cơ sở y tế ngoại trú vừa và nhỏ. Thông qua việc phân tích kỹ lưỡng các góc nhìn kiến trúc UML và hiện thực hóa bằng các công nghệ web tiên tiến, dự án không chỉ hoàn thành xuất sắc các mục tiêu học thuật của môn học Phân tích & Thiết kế Hệ thống Thông tin mà còn cung cấp một giải pháp phần mềm có giá trị thực tiễn cao, đóng góp tích cực vào công cuộc nâng cao chất lượng dịch vụ chăm sóc sức khỏe cộng đồng.