1. 12:10 13/08/2026
CHUỖI THỰC HÀNH: CHATBOT AI HỎI ĐÁP ĐẤT ĐAI — PHP 8.x + MySQL 9.x
Lưu ý trách nhiệm: đây là phần mềm cung cấp thông tin tham khảo từ kho tài liệu đã được quản trị viên phê duyệt; không phải tư vấn pháp lý, không xác nhận quyền sử dụng đất, không thay thế hồ sơ/cơ quan có thẩm quyền. Không yêu cầu người dùng gửi CCCD, số sổ, ảnh giấy tờ, tọa độ chính xác hay dữ liệu cá nhân vào ô chat. Khi trả lời có ảnh hưởng quyền/lợi ích cụ thể, chatbot phải hướng người dùng kiểm tra văn bản gốc và liên hệ cơ quan có thẩm quyền hoặc chuyên gia pháp lý.
# 01/10 — Bắt đầu đúng trước khi viết mã
Mục tiêu của chuỗi là làm một website chatbot PHP 8.x + MySQL 9.x trả lời câu hỏi phổ biến về đất đai **dựa trên kho tri thức do chính đơn vị của bạn duyệt**. Người mới có thể copy từng tệp, chạy ở máy local, sau đó đưa lên máy chủ. Chatbot không được “tự nhớ luật” rồi trả lời như kết luận pháp lý: mỗi câu trả lời cần gắn nguồn tham khảo đã tìm được; không có nguồn phù hợp thì từ chối an toàn và gợi ý nơi tra cứu.
## Kết quả sau bài 10
- Trang web `/` có hộp chat, danh sách nguồn và cảnh báo phạm vi.
- API `POST /api/chat` có CSRF, giới hạn tốc độ, request ID và thông báo lỗi không lộ stack trace.
- MySQL lưu kho tài liệu, đoạn trích, phiên chat, lịch sử tối thiểu và audit log.
- Lớp AI tách riêng, mặc định chạy `AI_FAKE_MODE=true`; chỉ khi tự cấu hình môi trường mới gọi nhà cung cấp AI.
- Câu trả lời chỉ dùng đoạn tài liệu đã truy xuất (RAG đơn giản); nội dung tài liệu cũng không được phép thay đổi quy tắc hệ thống.
## Yêu cầu tối thiểu
- PHP 8.1+ (khuyến nghị PHP 8.2 hoặc 8.3), các extension: `pdo_mysql`, `curl`, `mbstring`, `json`, `openssl`.
- MySQL 9.x, InnoDB, `utf8mb4`. Mã trong chuỗi cũng tương thích phần lớn MySQL 8.x.
- Web server Apache/Nginx trỏ **DocumentRoot vào thư mục `public/`**, không trỏ vào thư mục gốc dự án.
- Một nguồn AI có API tương thích mẫu Chat Completions. Không cần khóa thật ở giai đoạn đầu vì dự án có chế độ mô phỏng.
## Kiến trúc được dùng
```text
Trình duyệt
-> public/index.php (router + CSRF + JSON)
-> app/ChatService.php (kiểm tra đầu vào, rate limit, RAG, lưu lịch sử)
-> app/KnowledgeService.php (MySQL FULLTEXT, tài liệu đã duyệt)
-> app/AiClient.php (adapter gọi AI hoặc fake mode)
-> MySQL 9.x
```
Nguyên tắc quan trọng là **AI không có quyền truy cập trực tiếp vào database**, không chạy SQL do người dùng gõ, không đọc tệp tùy ý, không gọi công cụ bên ngoài. PHP chỉ gửi cho AI câu hỏi đã giới hạn và vài đoạn ngữ cảnh được lấy bằng prepared statement.
## Tạo cây thư mục
Tạo đúng cấu trúc sau (tên thư mục có thể đổi, nhưng các đường dẫn trong bài sẽ theo tên này):
```text
land-ai-chatbot/
├── .env # chỉ ở máy chủ, tuyệt đối không commit
├── .env.example # mẫu an toàn để chia sẻ
├── .gitignore
├── database/
│ └── schema.sql
├── app/
│ ├── Bootstrap.php
│ ├── Config.php
│ ├── Database.php
│ ├── Http.php
│ ├── Csrf.php
│ ├── SecurityHeaders.php
│ ├── KnowledgeService.php
│ ├── AiClient.php
│ └── ChatService.php
├── cli/
│ ├── check.php
│ ├── import_knowledge.php
│ └── knowledge.sample.json
├── public/ # CHỈ thư mục này được public qua web
│ ├── index.php
│ └── assets/
│ ├── chat.css
│ └── chat.js
└── views/
└── chat.php
```
Tạo một repository Git rồi thêm `.gitignore` ngay từ đầu:
```gitignore
/.env
/vendor/
/storage/
*.log
.DS_Store
```
## Phạm vi câu trả lời nên có và không nên có
Nên hỗ trợ: giải thích thuật ngữ, hướng dẫn quy trình ở mức tổng quát, danh sách giấy tờ **tham khảo theo nguồn đã duyệt**, cách tìm cơ quan tiếp nhận, nhắc kiểm tra hiệu lực của văn bản.
Không nên hỗ trợ: kết luận “mảnh đất chắc chắn hợp lệ”, tính tiền nghĩa vụ cụ thể, tư vấn chiến lược tranh chấp, suy đoán ranh giới/quy hoạch, xử lý ảnh giấy tờ hoặc định danh cá nhân. Khi gặp nhóm này, câu trả lời phải nói rõ giới hạn và chuyển hướng an toàn.
## Quy ước dữ liệu
Mỗi tài liệu phải có: tiêu đề, URL nguồn, đơn vị sở hữu/duyệt, ngày kiểm tra, trạng thái `published`. Chỉ tài liệu `published` mới được truy xuất. Không nhập bản scan không rõ nguồn hay văn bản đã hết hiệu lực nhưng chưa ghi chú.
Sang bài 02, ta tạo database và các bảng. Chưa cần cài API hay có khóa AI.