Giao diện
Mô hình dữ liệu
Lược đồ nằm trong apps/api/migrations, chạy theo thứ tự tên file.
Migration
| File | Nội dung |
|---|---|
0001_init.sql | Từ điển dùng chung và các thực thể Giai đoạn 1 |
0002_graph.sql | Thực thể Giai đoạn 2 và bảng cạnh tổng quát |
0003_search.sql | search_docs và bảng ảo FTS5 |
Bảng Giai đoạn 1
provinces ──┐
├──< schools ──< school_subjects >── subjects
subjects ───┘ │
├──< admissions
├──< exams >── subjects
├──< teachers
├──< school_activities
└──< competition_schools >── competitions >── subjectsschools — hồ sơ trường: slug, name, short_name, alt_names (các tên gọi khác, phân tách bằng |), type, province_id, grades, founded_year, website, summary, verification.
admissions — một dòng cho mỗi (trường, năm, khối lớp, phương thức), có ràng buộc duy nhất trên tổ hợp đó. Chứa places, applicants, cutoff_score, exam_structure, weighting, source_url.
exams — đề thi; topics là danh sách chuyên đề phân tách bằng |.
competitions — kỳ thi và olympic, level nhận truong | tinh | quoc-gia | quoc-te.
teachers, school_activities — hồ sơ giáo viên và dòng hoạt động của trường.
Bảng Giai đoạn 2 (đã tạo, chưa có giao diện)
universities, organizations, people, alumni_records, opportunities.
Ngoài ra có bảng cạnh tổng quát cho những quan hệ chưa cần bảng riêng:
sql
edges (from_type, from_id, relation, to_type, to_id, meta)Các quan hệ dự kiến mô hình hoá: Person → studied_at → School, Person → graduated_from → University, School → participates_in → Competition, Alumni → mentors → Student, University → recruits_from → School, Center → prepares_for → Exam.
Quy ước
- Ngày tháng luôn là chuỗi ISO
YYYY-MM-DD, so sánh trực tiếp bằng>=trong SQL. - Danh sách ngắn (tên gọi khác, chuyên đề) lưu chuỗi phân tách bằng
|thay vì bảng phụ, vì chúng chỉ dùng để hiển thị chứ không dùng để lọc. verificationcó ràng buộcCHECKtrên mọi bảng thực thể.idcố định trong seed để mỗi lần nạp lại cho ra cùng khoá — tiện so sánh giữa các lần chạy.
Sinh dữ liệu mẫu
seed/data.mjs là nguồn duy nhất. scripts/build-seed.mjs sinh ra seed/seed.sql và seed/search.sql. Bộ sinh số ngẫu nhiên là một LCG gieo bằng chuỗi (không dùng Math.random) nên kết quả tất định: chạy lại cho ra đúng số liệu cũ.
bash
pnpm db:build-seed # sinh lại SQL
pnpm db:reset:local # xoá state, migrate, nạp lại