Z User e99eae57e1 feat(LD): add LEAD feature — LDA0_0100 module + V11+V12 migration
Per skills/skill.md + ROADMAP.md mục 7 (Checklist module mới):
- SYSTEM_CODE=LD, SUBSYSTEM_CODE=A0, FUNCTION_ID=LDA0_0100
- Full module: LDA0_0100_pg.java + LDA0_0100_trx.java + LDA0_0100_mod.java + LDA0_0100.html + lead.js
- Migration V11__create_lead_table.sql: LD_LEAD table (15 cols + 5 index)
  - FK logic ASSIGNED_STAFF_ID → ST_STAFF (nullable)
  - FK logic CONVERTED_CLIENT_ID → CL_CLIENT (nullable, UQ — 1 lead = 1 client)
- Migration V12__seed_lead_data.sql: 3 SYS_FUNCTION (LD, LD_A0, LDA0_0100) + 2 SYS_ROLE_FUNCTION (R0002 ADMIN, R0003 STAFF)
- 11 API endpoints:
  - prompt (list + filter with JOIN staff + converted client)
  - get, create, update
  - changeStatus (NEW/CONTACTED/QUALIFIED/LOST; CONVERTED only via /convert)
  - assignStaff (validate staff exists + ACTIVE)
  - convert (transactional: SYS_USER + R0005 + CL_CLIENT + LD_LEAD update)
  - listStaff, listSources, stats (6 status counts + conversionRate + bySource)
  - delete (block if CONVERTED — history preservation)
- Business rules: 9 rules, status lifecycle NEW→CONTACTED→QUALIFIED→CONVERTED/LOST
- Lead does NOT create SYS_USER — only convert does (transactional)
- Block update/changeStatus/delete/convert for CONVERTED leads
- CONTACTED_AT set on changeStatus to CONTACTED, CONVERTED_AT set on convert (NOW())
- Documentation: docs/features/LEAD/LEAD.md + report_session_01.md
- ROADMAP.md updated: LEAD=DONE, next=CHAT

Bug fixed during testing: ST_STAFF table uses EMPLOYEE_CODE (not STAFF_CODE).
Fixed by aliasing EMPLOYEE_CODE AS staff_code in list/get/listStaff queries.

Smoke test 18/18 PASS: create lead → changeStatus NEW→CONTACTED→QUALIFIED →
convert (transactional: CL0003 + U0009 + HV_LEAD1, status=CONVERTED, CONVERTED_AT set) →
block update/changeStatus/delete/convert for CONVERTED →
stats (1 converted, conversionRate=100.0).

Build: mvn clean package -> target/drivemaster.jar
Run:   java -jar target/drivemaster.jar (NO Docker)
Flyway: V11+V12 applied OK, schema now at v12
2026-08-09 07:48:05 +00:00

DriveMaster — Hệ thống Quản lý và Đào tạo Lái xe

Project: DriveMaster v1.0 Stack: Java 21 + Spring Boot 3.3 + Embedded Tomcat + MySQL 8 + Flyway + Thymeleaf + Bootstrap 5 Architecture: Clean Architecture, module-based, Filter-based RBAC, DataSetRegistry (NO JPA) Run mode: mvn clean packagejava -jar target/drivemaster.jar (NO Docker, NO external Tomcat)


1. MỤC ĐÍCH

DriveMaster là hệ thống quản lý và đào tạo lái xe. Repository này chứa mã nguồn + documentation của dự án, được thiết kế để mọi AI/Agent hoặc Developer tiếp theo có thể tiếp nhận mà không cần đọc lịch sử hội thoại cũ.

Tài liệu điều phối chính: ROADMAP.mdBẮT BUỘC ĐỌC TRƯỚC KHI CODE.

Tài liệu convention: skills/skill.mdBẮT BUỘC TUÂN THỦ 100%, KHÔNG ĐƯỢC XÓA.


2. CẤU TRÚC PROJECT

DriveMaster/
│
├── ROADMAP.md                          ⭐ SOURCE OF TRUTH cấp project
├── README.md                           (file này)
├── pom.xml                             Maven build config
│
├── skills/
│   └── skill.md                        ⭐ Convention cốt lõi — KHÔNG XÓA
│
├── docs/
│   ├── architecture/                   architecture.md, security.md, database.md, deployment.md
│   ├── database/                       schema.md
│   └── features/
│       └── DM/                         DM system
│           ├── DM.md                   ⭐ SOURCE OF TRUTH của DM feature
│           └── report/                 Lịch sử phát triển DM
│               └── report_session_01.md
│
├── src/main/java/com/drivemaster/io/vn/
│   ├── DriveMasterApplication.java
│   ├── config/                         SecurityConfig, WebConfig
│   ├── common/                         DataSetRegistry, ApiResponse, PageResult
│   ├── security/                       SecurityContext
│   ├── filter/                         DriveMasterPermissionFilter
│   ├── exception/                      BusinessException, GlobalExceptionHandler
│   ├── controller/                     *_pg.java — chỉ mapping URL + trả HTML
│   │   ├── BaseController.java
│   │   └── DM/A0/DMA0_xxxx/
│   ├── api/                            *_trx.java (REST) + *_mod.java (business)
│   │   └── DM/A0/DMA0_xxxx/
│   └── service/                        MenuService, UploadService
│
├── src/main/resources/
│   ├── application.yml                 Config (DB, server, Thymeleaf, Flyway, upload)
│   ├── templates/
│   │   ├── common/layout.html          Navbar + Sidebar + Footer fragments
│   │   └── DM/A0/DMA0_xxxx/            7 trang HTML (DMA0_0001 → DMA0_0600)
│   ├── static/
│   │   ├── css/app.css                 Common CSS
│   │   └── js/                         app.js + 6 file JS theo feature
│   └── db/migration/                   Flyway V1, V2 (KHÔNG sửa)
│
└── uploads/                            Local file storage (mặc định)

3. ĐỌC THEO THỨ TỰ

Lần đầu tiếp nhận project:

  1. skills/skill.md — convention
  2. ROADMAP.md — trạng thái project
  3. docs/architecture/architecture.mdsecurity.mddatabase.mddeployment.md
  4. docs/features/DM/DM.md — feature cần làm
  5. docs/features/DM/report/report_session_01.md — report gần nhất
  6. Source code + DB migration liên quan

Khi làm feature mới:

  1. skills/skill.md
  2. ROADMAP.md
  3. docs/features/<FEATURE>/<FEATURE>.md (nếu tồn tại)
  4. Latest report của feature
  5. Source code
  6. DB migration liên quan

4. CHẠY PROJECT

Yêu cầu môi trường

  • Java 21+ (JDK, có javac)
  • Maven 3.9+
  • MySQL 8+ (hoặc dùng DB staging có sẵn)

Build & Run

# Build
mvn clean package -DskipTests

# Run (Embedded Tomcat ở port 8080)
java -jar target/drivemaster.jar

App tự động:

  1. Start Embedded Tomcat ở port 8080
  2. Connect MySQL (theo application.yml hoặc env var)
  3. Run Flyway migration
  4. Start DriveMaster

Truy cập

Mở browser: http://localhost:8080/login

Default credentials: admin / admin123 (SUPERADMIN — toàn quyền)

Production deployment

KHÔNG dùng Docker. Chạy trực tiếp:

DB_URL=jdbc:mysql://<prod-host>:3306/drivemaster \
DB_USER=<prod-user> \
DB_PASSWORD=<prod-pass> \
java -jar target/drivemaster.jar

Khuyến nghị: chạy dưới systemd / supervisord, đặt sau nginx reverse proxy.


5. CẤU HÌNH DATABASE

DB connection trong application.yml:

spring:
  datasource:
    url: ${DB_URL:jdbc:mysql://stag.mysql.devhub.io.vn:3306/drivemaster?...}
    username: ${DB_USER:admin}
    password: ${DB_PASSWORD:MatKhau123!}

Để đổi DB, set env var DB_URL, DB_USER, DB_PASSWORD — KHÔNG cần sửa code.


6. ARCHITECTURE HIGHLIGHTS

  • NO JPA / Repository / EntityManager / Hibernate / JdbcTemplate — chỉ dùng DataSetRegistry (raw JDBC wrapper).
  • Module structure: mỗi function = *_pg.java (controller HTML) + *_trx.java (REST API) + *_mod.java (business) + .html (Thymeleaf).
  • Filter-based RBAC: DriveMasterPermissionFilter check SYS_FUNCTIONROLE_USERROLE_FUNCTION. Controller/Mod KHÔNG kiểm tra quyền.
  • Menu dynamic: sidebar đọc từ SYS_FUNCTION (KHÔNG hardcode).
  • Unified JSON: {code, message, data, list, total} — per skills/skill.md.
  • Lowercase keys: DataSetRegistry.searchAndRetrieve() trả về Map với key LOWERCASE — JS frontend phải đọc lowercase.

7. FEATURE ĐÃ HOÀN THÀNH

SYSTEM Feature Function IDs Status
DM Hệ thống Quản trị (Admin) DMA0_0001, DMA0_0100, DMA0_0200, DMA0_0300, DMA0_0400, DMA0_0500, DMA0_0600 DONE

Xem chi tiết trong ROADMAP.md mục 4.


8. DOCUMENTATION MODEL

DriveMaster dùng mô hình 3 tầng tài liệu:

ROADMAP.md                  (project-level)
    ↓
docs/features/<F>/<F>.md    (feature-level current state)
    ↓
docs/features/<F>/report/   (feature-level history)

Quy tắc:

  • ROADMAP.md = bộ não toàn project
  • FEATURE.md = bộ nhớ dài hạn của feature (trạng thái hiện tại)
  • report/ = lịch sử phát triển của feature (session-by-session)
  • Ba thứ KHÔNG thay thế cho nhau
  • KHÔNG tạo work_reports/ hoặc reports/ ở root để chứa report chung

9. LICENSE

Proprietary — DriveMaster Project.


10. CONTACT

Đây là project được phát triển bởi AI Agent. Mọi thay đổi phải được ghi lại trong report của feature tương ứng.

S
Description
DriveMaster - He thong Quan ly va Dao tao Lai xe (Java Spring Boot + MySQL + Flyway, NO JPA, DataSetRegistry, Filter-based RBAC)
Readme
324 KiB
Languages
Java 50.7%
HTML 25.4%
JavaScript 22.9%
CSS 1%