Files
sena_db_api_layer/VOCAB_GUIDE.md
silverpro89 2c7b4675a7 update
2026-01-26 20:23:08 +07:00

38 KiB
Raw Blame History

📚 VOCABULARY MANAGEMENT GUIDE

Tổng quan

Hệ thống Vocabulary quản lý từ vựng theo chương trình học, hỗ trợ nhiều dạng thức ngữ pháp, phát âm chuẩn xác, và tích hợp gamification.

🗂️ Cấu trúc Database

1. Bảng chính: vocab

Lưu trữ thông tin cơ bản của từ vựng.

Trường Kiểu Mô tả
vocab_id INTEGER ID tự động tăng
vocab_code STRING(50) Mã định danh duy nhất (ví dụ: "vocab-001-eat")
base_word STRING(100) Từ gốc
translation STRING(200) Bản dịch tiếng Việt
difficulty_score INTEGER Độ khó (1-10)
category STRING(100) Danh mục (ví dụ: "Action Verbs")
images JSON Mảng URL hình ảnh
tags JSON Mảng thẻ phân loại
syntax JSON Vai trò cú pháp (is_subject, is_verb, is_object, is_article, is_adv, verb_type, etc.)
semantics JSON Ràng buộc ngữ nghĩa (can_be_subject_type, can_take_object_type, can_modify, word_type)
constraints JSON Ràng buộc ngữ pháp (followed_by, match_subject, match_with, phonetic_rules)
is_active BOOLEAN Trạng thái hoạt động

2. Bảng phụ: vocab_mapping

Quản lý điểm xuất hiện của từ trong chương trình học.

Trường Kiểu Mô tả
mapping_id INTEGER ID tự động tăng
vocab_id INTEGER Tham chiếu đến vocab
book_id STRING(100) ID sách giáo trình
grade INTEGER Khối lớp
unit INTEGER Bài học
lesson INTEGER Tiết học
form_key STRING(50) Dạng từ sử dụng (v1, v_ing, v2, etc.)
context_note TEXT Ghi chú ngữ cảnh

3. Bảng phụ: vocab_form

Lưu trữ các biến thể ngữ pháp của từ.

Trường Kiểu Mô tả
form_id INTEGER ID tự động tăng
vocab_id INTEGER Tham chiếu đến vocab
form_key STRING(50) Khóa dạng từ (v1, v2, v3, v_ing, v_s_es, etc.)
text STRING(100) Từ thực tế (eat, eats, eating, ate)
phonetic STRING(100) Phiên âm IPA (ví dụ: /iːt/)
audio_url STRING(500) URL file phát âm
min_grade INTEGER Khối lớp tối thiểu để mở khóa
description TEXT Mô tả/ghi chú sử dụng

4. Bảng phụ: vocab_relation

Quản lý quan hệ ngữ nghĩa giữa các từ.

Trường Kiểu Mô tả
relation_id INTEGER ID tự động tăng
vocab_id INTEGER Tham chiếu đến vocab
relation_type ENUM Loại quan hệ: synonym, antonym, related
related_word STRING(100) Từ có quan hệ
related_vocab_id INTEGER Tham chiếu đến vocab liên quan (nếu có)

🔌 API Endpoints

1. Tạo từ vựng mới

POST /api/vocab

Request Body:

{
  "vocab_code": "vocab-001-eat",
  "base_word": "eat",
  "translation": "ăn",
  
  "attributes": {
    "difficulty_score": 1,
    "category": "Action Verbs",
    "images": [
      "https://cdn.sena.tech/img/eat-main.png",
      "https://cdn.sena.tech/img/eat-context.jpg"
    ],
    "tags": ["daily-routine", "verb"]
  },
  
  "mappings": [
    {
      "book_id": "global-success-1",
      "grade": 1,
      "unit": 2,
      "lesson": 3,
      "form_key": "v1"
    },
    {
      "book_id": "global-success-2",
      "grade": 2,
      "unit": 5,
      "lesson": 1,
      "form_key": "v_ing",
      "context_note": "Dạy thì tiếp diễn"
    }
  ],
  
  "forms": {
    "v1": {
      "text": "eat",
      "phonetic": "/iːt/",
      "audio": "https://cdn.sena.tech/audio/eat_v1.mp3",
      "min_grade": 1
    },
    "v_s_es": {
      "text": "eats",
      "phonetic": "/iːts/",
      "audio": "https://cdn.sena.tech/audio/eats_s.mp3",
      "min_grade": 2
    },
    "v_ing": {
      "text": "eating",
      "phonetic": "/ˈiː.tɪŋ/",
      "audio": "https://cdn.sena.tech/audio/eating_ing.mp3",
      "min_grade": 2
    },
    "v2": {
      "text": "ate",
      "phonetic": "/et/",
      "audio": "https://cdn.sena.tech/audio/ate_v2.mp3",
      "min_grade": 3
    }
  },
  
  "relations": {
    "synonyms": ["consume", "dine"],
    "antonyms": ["fast", "starve"]
  },
  
  "syntax": {
    "is_subject": false,
    "is_verb": true,
    "is_object": false,
    "is_be": false,
    "is_adj": false,
    "verb_type": "transitive"
  },
  
  "semantics": {
    "can_be_subject_type": ["human", "animal"],
    "can_take_object_type": ["food", "plant"],
    "word_type": "action"
  }
}

Response (201):

{
  "message": "Vocabulary created successfully",
  "data": {
    "id": "vocab-001-eat",
    "vocab_id": 1,
    "base_word": "eat",
    "translation": "ăn",
    "attributes": { ... },
    "mappings": [ ... ],
    "forms": { ... },
    "relations": { ... }
  }
}

2. Lấy danh sách từ vựng

GET /api/vocab

Query Parameters:

Tham số Mô tả Ví dụ
page Số trang (mặc định: 1) ?page=2
limit Số lượng/trang (mặc định: 20) ?limit=50
category Lọc theo danh mục ?category=Action Verbs
grade Lọc theo khối lớp ?grade=1
book_id Lọc theo sách ?book_id=global-success-1
difficulty_min Độ khó tối thiểu ?difficulty_min=1
difficulty_max Độ khó tối đa ?difficulty_max=5
search Tìm kiếm từ/nghĩa ?search=eat
include_relations Bao gồm synonyms/antonyms ?include_relations=true

Ví dụ:

GET /api/vocab?grade=1&category=Action Verbs&limit=10
GET /api/vocab?search=food&include_relations=true
GET /api/vocab?book_id=global-success-1&unit=2

Response (200):

{
  "message": "Vocabularies retrieved successfully",
  "data": [ ... ],
  "pagination": {
    "total": 150,
    "page": 1,
    "limit": 20,
    "totalPages": 8
  }
}

3. Lấy từ vựng theo ID hoặc Code

GET /api/vocab/:id

Ví dụ:

GET /api/vocab/1                    (Lấy theo vocab_id)
GET /api/vocab/vocab-001-eat        (Lấy theo vocab_code)

Response (200):

{
  "message": "Vocabulary retrieved successfully",
  "data": {
    "id": "vocab-001-eat",
    "vocab_id": 1,
    "base_word": "eat",
    "translation": "ăn",
    "attributes": {
      "difficulty_score": 1,
      "category": "Action Verbs",
      "images": [...],
      "tags": [...]
    },
    "mappings": [...],
    "forms": {...},
    "relations": {...}
  }
}

4. Lấy từ vựng theo chương trình học

GET /api/vocab/curriculum

Query Parameters:

Tham số Bắt buộc Mô tả
book_id Không* ID sách giáo trình
grade Không* Khối lớp
unit Không Bài học
lesson Không Tiết học

*Ít nhất book_id hoặc grade phải có.

Ví dụ:

GET /api/vocab/curriculum?grade=1&unit=2
GET /api/vocab/curriculum?book_id=global-success-1&grade=2&unit=5&lesson=1

Response (200):

{
  "message": "Vocabularies retrieved successfully",
  "data": [...],
  "count": 15
}

5. Cập nhật từ vựng

PUT /api/vocab/:id

Lưu ý:

  • Có thể cập nhật một phần hoặc toàn bộ
  • Khi cập nhật mappings, forms, hoặc relations, toàn bộ dữ liệu cũ sẽ được thay thế

Request Body (Partial Update):

{
  "translation": "ăn uống",
  "attributes": {
    "difficulty_score": 2,
    "tags": ["daily-routine", "verb", "food"]
  }
}

Request Body (Update Forms):

{
  "forms": {
    "v1": {
      "text": "eat",
      "phonetic": "/iːt/",
      "audio": "https://cdn.sena.tech/audio/eat_v1_updated.mp3",
      "min_grade": 1
    },
    "v2": {
      "text": "ate",
      "phonetic": "/eɪt/",
      "audio": "https://cdn.sena.tech/audio/ate_v2_updated.mp3",
      "min_grade": 3
    }
  }
}

Response (200):

{
  "message": "Vocabulary updated successfully",
  "data": { ... }
}

6. Xóa từ vựng (Soft Delete)

DELETE /api/vocab/:id

Ví dụ:

DELETE /api/vocab/1
DELETE /api/vocab/vocab-001-eat

Response (200):

{
  "message": "Vocabulary deleted successfully"
}

7. Thống kê từ vựng

GET /api/vocab/stats

Response (200):

{
  "message": "Vocabulary statistics retrieved successfully",
  "data": {
    "total": 500,
    "by_category": [
      { "category": "Action Verbs", "count": 120 },
      { "category": "Nouns", "count": 200 }
    ],
    "by_difficulty": [
      { "difficulty_score": 1, "count": 150 },
      { "difficulty_score": 2, "count": 100 }
    ],
    "by_grade": [
      { "grade": 1, "count": 80 },
      { "grade": 2, "count": 120 }
    ]
  }
}

📋 Quy tắc và Best Practices

1. Quy tắc đặt vocab_code

  • Format: vocab-{sequence}-{base_word}
  • Ví dụ: vocab-001-eat, vocab-002-run, vocab-150-beautiful
  • Phải unique trong toàn hệ thống

2. Quy tắc form_key

Sử dụng các key chuẩn sau:

Động từ (Verbs):

  • v1: Base form (eat)
  • v_s_es: Third person singular (eats)
  • v_ing: Present participle (eating)
  • v2: Past simple (ate)
  • v3: Past participle (eaten)

Danh từ (Nouns):

  • n_singular: Số ít (cat)
  • n_plural: Số nhiều (cats)

Tính từ (Adjectives):

  • adj_base: Dạng cơ bản (big)
  • adj_comparative: So sánh hơn (bigger)
  • adj_superlative: So sánh nhất (biggest)

Trạng từ (Adverbs):

  • adv_base: Dạng cơ bản (quickly)
  • adv_comparative: So sánh hơn (more quickly)
  • adv_superlative: So sánh nhất (most quickly)

3. Quy tắc min_grade

  • Xác định khối lớp tối thiểu để học sinh có thể truy cập dạng từ này
  • Ví dụ:
    • v1 (eat): min_grade = 1
    • v_ing (eating): min_grade = 2
    • v2 (ate): min_grade = 3

4. Quy tắc difficulty_score

Điểm Mô tả
1-2 Cơ bản - Từ vựng thường ngày
3-4 Trung bình - Từ vựng học thuật đơn giản
5-6 Nâng cao - Từ vựng học thuật phức tạp
7-8 Khó - Từ vựng chuyên ngành
9-10 Rất khó - Từ vựng hiếm/chuyên sâu

5. Quy tắc phát âm (Phonetic)

  • Sử dụng IPA (International Phonetic Alphabet)
  • Đặt trong dấu /.../
  • Ví dụ: /iːt/, /ˈiː.tɪŋ/, /eɪt/

6. Quy tắc Audio URL

  • Lưu trữ file âm thanh ở CDN
  • Format khuyến nghị: MP3, OGG
  • Naming convention: {base_word}_{form_key}.mp3
  • Ví dụ: eat_v1.mp3, eating_ing.mp3

7. Quy tắc syntax (Vai trò cú pháp)

Định nghĩa vai trò của từ trong câu để Grammar Engine có thể xây dựng câu đúng ngữ pháp.

Các trường:

  • is_subject (boolean): Từ có thể làm chủ ngữ không
  • is_verb (boolean): Từ có phải động từ không
  • is_object (boolean): Từ có thể làm tân ngữ không
  • is_be (boolean): Từ có phải động từ "to be" không
  • is_adj (boolean): Từ có phải tính từ không
  • verb_type (string): Loại động từ nếu is_verb = true
    • "transitive": Động từ ngoại động (cần tân ngữ) - eat, drink, read
    • "intransitive": Động từ nội động (không cần tân ngữ) - run, sleep, cry
    • "linking": Động từ liên kết - be, become, seem

Ví dụ:

// Động từ ngoại động "eat"
"syntax": {
  "is_subject": false,
  "is_verb": true,
  "is_object": false,
  "is_be": false,
  "is_adj": false,
  "verb_type": "transitive"
}

// Danh từ "apple"
"syntax": {
  "is_subject": true,
  "is_verb": false,
  "is_object": true,
  "is_be": false,
  "is_adj": false
}

// Tính từ "big"
"syntax": {
  "is_subject": false,
  "is_verb": false,
  "is_object": false,
  "is_be": false,
  "is_adj": true
}

8. Quy tắc semantics (Ràng buộc ngữ nghĩa)

Định nghĩa ràng buộc về mặt ngữ nghĩa để tạo câu có nghĩa logic.

Các trường:

  • can_be_subject_type (array): Loại chủ ngữ có thể đi với từ này (nếu từ là động từ)
  • can_take_object_type (array): Loại tân ngữ mà từ này có thể nhận (nếu từ là động từ)
  • word_type (string): Loại từ về mặt ngữ nghĩa

Các giá trị subject_typeobject_type:

  • "human": Con người (I, you, teacher, student)
  • "animal": Động vật (cat, dog, bird)
  • "object": Đồ vật vô sinh (table, chair, book)
  • "food": Thức ăn (apple, rice, bread)
  • "plant": Thực vật (tree, flower, grass)
  • "abstract": Khái niệm trừu tượng (love, idea, freedom)
  • "place": Địa điểm (school, home, park)
  • "time": Thời gian (morning, yesterday, hour)

Các giá trị word_type:

  • "action": Hành động (eat, run, jump)
  • "state": Trạng thái (be, seem, appear)
  • "entity": Thực thể (apple, cat, table)
  • "property": Tính chất (big, red, happy)
  • "concept": Khái niệm (love, freedom, idea)

Ví dụ:

// Động từ "eat" - chỉ con người/động vật ăn được thức ăn/thực vật
"semantics": {
  "can_be_subject_type": ["human", "animal"],
  "can_take_object_type": ["food", "plant"],
  "word_type": "action"
}

// Động từ "read" - con người đọc sách/văn bản
"semantics": {
  "can_be_subject_type": ["human"],
  "can_take_object_type": ["object", "abstract"],
  "word_type": "action"
}

// Danh từ "apple"
"semantics": {
  "word_type": "entity"
}

// Tính từ "happy"
"semantics": {
  "word_type": "property"
}

Tại sao cần semantics?

Grammar Engine sử dụng để tránh tạo câu vô nghĩa:

  • "The boy eats an apple" (human + food)
  • "The table eats an apple" (object + food - vô nghĩa!)
  • "The cat drinks water" (animal + food)
  • "The cat reads a book" (animal không thể read)

🔧 Hệ thống Function Words & Modifiers (Grammar Engine)

Để Grammar Engine có thể tạo câu tự nhiên và chính xác, cần bổ sung các từ chức năng và từ bổ nghĩa.

9. Quy tắc constraints (Ràng buộc ngữ pháp)

Định nghĩa các ràng buộc khi kết hợp từ với nhau.

Các trường:

  • followed_by (string): Loại âm phải theo sau (cho articles)
  • match_subject (object): Quy tắc khớp với chủ ngữ (cho động từ "be")
  • match_with (string): Khớp với loại từ nào
  • phonetic_rules (array): Quy tắc về phát âm

10. Mạo từ (Articles: a, an, the)

Mạo từ cần logic về phát âm để Engine tự động chọn đúng.

Cấu trúc mạo từ bất định "a":

{
  "vocab_code": "vocab-art-01",
  "base_word": "a",
  "translation": "một (mạo từ bất định)",
  "attributes": {
    "difficulty_score": 1,
    "category": "Articles",
    "tags": ["article", "function-word", "grammar"]
  },
  "forms": {
    "base": {
      "text": "a",
      "phonetic": "/ə/",
      "audio": "https://cdn.sena.tech/audio/a.mp3",
      "min_grade": 1
    }
  },
  "syntax": {
    "is_article": true,
    "article_type": "indefinite",
    "priority": 1
  },
  "constraints": {
    "followed_by": "consonant_sound"
  }
}

Cấu trúc mạo từ bất định "an":

{
  "vocab_code": "vocab-art-02",
  "base_word": "an",
  "translation": "một (mạo từ bất định - trước nguyên âm)",
  "attributes": {
    "difficulty_score": 1,
    "category": "Articles",
    "tags": ["article", "function-word", "grammar"]
  },
  "forms": {
    "base": {
      "text": "an",
      "phonetic": "/ən/",
      "audio": "https://cdn.sena.tech/audio/an.mp3",
      "min_grade": 1
    }
  },
  "syntax": {
    "is_article": true,
    "article_type": "indefinite",
    "priority": 1
  },
  "constraints": {
    "followed_by": "vowel_sound"
  }
}

Cấu trúc mạo từ xác định "the":

{
  "vocab_code": "vocab-art-03",
  "base_word": "the",
  "translation": "cái, con (mạo từ xác định)",
  "attributes": {
    "difficulty_score": 1,
    "category": "Articles",
    "tags": ["article", "function-word", "grammar"]
  },
  "forms": {
    "base_consonant": {
      "text": "the",
      "phonetic": "/ðə/",
      "audio": "https://cdn.sena.tech/audio/the_consonant.mp3",
      "min_grade": 1,
      "description": "Phát âm trước phụ âm"
    },
    "base_vowel": {
      "text": "the",
      "phonetic": "/ðiː/",
      "audio": "https://cdn.sena.tech/audio/the_vowel.mp3",
      "min_grade": 1,
      "description": "Phát âm trước nguyên âm"
    }
  },
  "syntax": {
    "is_article": true,
    "article_type": "definite",
    "priority": 1
  },
  "constraints": {
    "followed_by": "any"
  }
}

Logic Engine cho Articles:

Khi Engine chọn từ "apple" (/ˈæp.əl/ - bắt đầu bằng nguyên âm):

  1. Quét trường phonetic của "apple"
  2. Phát hiện âm đầu là /æ/ (nguyên âm)
  3. Loại bỏ "a" (vì followed_by: "consonant_sound")
  4. Chọn "an" (vì followed_by: "vowel_sound")
  5. Kết quả: "an apple"

11. Trạng từ (Adverbs)

Trạng từ cần biết nó bổ nghĩa cho gì và vị trí trong câu.

Trạng từ chỉ cách thức (Manner) - "quickly":

{
  "vocab_code": "vocab-adv-01",
  "base_word": "quickly",
  "translation": "nhanh chóng, một cách nhanh",
  "attributes": {
    "difficulty_score": 2,
    "category": "Adverbs",
    "tags": ["adverb", "manner", "modifier"]
  },
  "forms": {
    "base": {
      "text": "quickly",
      "phonetic": "/ˈkwɪk.li/",
      "audio": "https://cdn.sena.tech/audio/quickly.mp3",
      "min_grade": 2
    }
  },
  "syntax": {
    "is_adv": true,
    "adv_type": "manner",
    "position": "after_verb"
  },
  "semantics": {
    "can_modify": ["action_verb"],
    "cannot_modify": ["stative_verb", "be_verb"],
    "word_type": "property"
  },
  "constraints": {
    "match_with": "dynamic_verb"
  }
}

Trạng từ chỉ tần suất (Frequency) - "often":

{
  "vocab_code": "vocab-adv-02",
  "base_word": "often",
  "translation": "thường xuyên",
  "attributes": {
    "difficulty_score": 2,
    "category": "Adverbs",
    "tags": ["adverb", "frequency", "modifier"]
  },
  "forms": {
    "base": {
      "text": "often",
      "phonetic": "/ˈɒf.ən/",
      "audio": "https://cdn.sena.tech/audio/often.mp3",
      "min_grade": 2
    }
  },
  "syntax": {
    "is_adv": true,
    "adv_type": "frequency",
    "position": "before_main_verb"
  },
  "semantics": {
    "can_modify": ["verb"],
    "word_type": "property"
  },
  "constraints": {
    "position_rules": ["before_verb", "after_be", "between_auxiliary_main"]
  }
}

Trạng từ chỉ mức độ (Degree) - "very":

{
  "vocab_code": "vocab-adv-03",
  "base_word": "very",
  "translation": "rất",
  "attributes": {
    "difficulty_score": 1,
    "category": "Adverbs",
    "tags": ["adverb", "degree", "modifier"]
  },
  "forms": {
    "base": {
      "text": "very",
      "phonetic": "/ˈver.i/",
      "audio": "https://cdn.sena.tech/audio/very.mp3",
      "min_grade": 1
    }
  },
  "syntax": {
    "is_adv": true,
    "adv_type": "degree",
    "position": "before_adj_adv"
  },
  "semantics": {
    "can_modify": ["adjective", "adverb"],
    "cannot_modify": ["verb", "noun"],
    "word_type": "property"
  },
  "constraints": {
    "match_with": "gradable_adjective"
  }
}

12. Đại từ (Pronouns)

Đại từ nhân xưng chủ ngữ:

{
  "vocab_code": "vocab-pron-01",
  "base_word": "I",
  "translation": "tôi",
  "attributes": {
    "difficulty_score": 1,
    "category": "Pronouns",
    "tags": ["pronoun", "personal", "subject"]
  },
  "forms": {
    "subject": {
      "text": "I",
      "phonetic": "/aɪ/",
      "audio": "https://cdn.sena.tech/audio/I.mp3",
      "min_grade": 1
    },
    "object": {
      "text": "me",
      "phonetic": "/miː/",
      "audio": "https://cdn.sena.tech/audio/me.mp3",
      "min_grade": 1
    }
  },
  "syntax": {
    "is_subject": true,
    "is_pronoun": true,
    "pronoun_type": "personal",
    "person": "first",
    "number": "singular"
  },
  "semantics": {
    "person_type": "1st",
    "word_type": "entity"
  },
  "constraints": {
    "match_subject": {
      "I": "am",
      "you": "are",
      "he/she/it": "is"
    }
  }
}

13. Giới từ (Prepositions)

{
  "vocab_code": "vocab-prep-01",
  "base_word": "in",
  "translation": "trong, ở trong",
  "attributes": {
    "difficulty_score": 1,
    "category": "Prepositions",
    "tags": ["preposition", "location", "function-word"]
  },
  "forms": {
    "base": {
      "text": "in",
      "phonetic": "/ɪn/",
      "audio": "https://cdn.sena.tech/audio/in.mp3",
      "min_grade": 1
    }
  },
  "syntax": {
    "is_preposition": true,
    "prep_type": "location",
    "position": "before_noun"
  },
  "semantics": {
    "can_take_object_type": ["place", "object", "abstract"],
    "word_type": "relation"
  }
}

14. Bảng tổng hợp Syntax Roles

Role Key Loại từ Ví dụ Thuộc tính quan trọng
is_subject Chủ ngữ I, Dog, Teacher person_type (1st, 2nd, 3rd), number
is_be Động từ Be am, is, are match_subject (I -> am)
is_verb Động từ run, eat, play verb_type (transitive/intransitive)
is_object Tân ngữ ball, apple, milk is_countable (đếm được hay không)
is_article Mạo từ a, an, the constraints.followed_by (vowel/consonant)
is_adv Trạng từ quickly, slowly adv_type, position, can_modify
is_adj Tính từ beautiful, big position (before_noun/after_be)
is_pronoun Đại từ I, you, he, she person, number, pronoun_type
is_preposition Giới từ in, on, at prep_type, can_take_object_type

15. Pattern Logic cho Grammar Engine

Ví dụ: Present Continuous với Adverb

// "The cat is eating an apple quickly"
{
  "pattern_name": "Present_Continuous_Adv",
  "structure": {
    "pattern_logic": [
      {
        "slot": "{art_s}",
        "role": "is_article",
        "target": "{S}",
        "auto_select": true  // Engine tự chọn a/an/the dựa vào phonetic
      },
      {
        "slot": "{S}",
        "role": "is_subject",
        "semantic": ["animal", "human", "object"]
      },
      {
        "slot": "{be}",
        "role": "is_be",
        "match_constraint": "subject_agreement"  // Khớp với chủ ngữ
      },
      {
        "slot": "{V}",
        "role": "is_verb",
        "form": "v_ing",
        "verb_type": "transitive"
      },
      {
        "slot": "{art_o}",
        "role": "is_article",
        "target": "{O}",
        "auto_select": true
      },
      {
        "slot": "{O}",
        "role": "is_object",
        "semantic_match": "{V}.can_take_object_type"  // Object phải khớp với verb
      },
      {
        "slot": "{Adv}",
        "role": "is_adv",
        "adv_type": "manner",
        "match_with": "{V}",
        "optional": true  // Trạng từ là tùy chọn
      }
    ]
  }
}

Ví dụ: Simple Present với Frequency Adverb

// "I often eat apples"
{
  "pattern_name": "Simple_Present_Freq",
  "structure": {
    "pattern_logic": [
      {
        "slot": "{S}",
        "role": "is_pronoun",
        "person": "first"
      },
      {
        "slot": "{Adv_freq}",
        "role": "is_adv",
        "adv_type": "frequency",
        "position": "before_main_verb"
      },
      {
        "slot": "{V}",
        "role": "is_verb",
        "form": "v1",  // Base form với I/you/we/they
        "verb_type": "transitive"
      },
      {
        "slot": "{O}",
        "role": "is_object",
        "form": "n_plural",  // Số nhiều không cần article
        "semantic_match": "{V}.can_take_object_type"
      }
    ]
  }
}

🎯 Use Cases phổ biến

Case 1: Thêm từ vựng mới cho bài học

POST /api/vocab

{
  "vocab_code": "vocab-150-run",
  "base_word": "run",
  "translation": "chạy",
  "attributes": {
    "difficulty_score": 1,
    "category": "Action Verbs",
    "images": ["https://cdn.sena.tech/img/run.png"],
    "tags": ["sport", "verb", "movement"]
  },
  "mappings": [
    {
      "book_id": "global-success-1",
      "grade": 1,
      "unit": 4,
      "lesson": 2,
      "form_key": "v1"
    }
  ],
  "forms": {
    "v1": {
      "text": "run",
      "phonetic": "/rʌn/",
      "audio": "https://cdn.sena.tech/audio/run_v1.mp3",
      "min_grade": 1
    },
    "v_s_es": {
      "text": "runs",
      "phonetic": "/rʌnz/",
      "audio": "https://cdn.sena.tech/audio/runs_s.mp3",
      "min_grade": 2
    }
  },
  "relations": {
    "synonyms": ["jog", "sprint"],
    "antonyms": ["walk", "stop"]
  },
  "syntax": {
    "is_subject": false,
    "is_verb": true,
    "is_object": false,
    "is_be": false,
    "is_adj": false,
    "verb_type": "intransitive"
  },
  "semantics": {
    "can_be_subject_type": ["human", "animal"],
    "can_take_object_type": [],
    "word_type": "action"
  }
}

Case 2: Thêm danh từ với semantic constraints

POST /api/vocab

{
  "vocab_code": "vocab-200-apple",
  "base_word": "apple",
  "translation": "quả táo",
  "attributes": {
    "difficulty_score": 1,
    "category": "Nouns",
    "images": ["https://cdn.sena.tech/img/apple.png"],
    "tags": ["food", "fruit", "noun"]
  },
  "mappings": [
    {
      "book_id": "global-success-1",
      "grade": 1,
      "unit": 3,
      "lesson": 1,
      "form_key": "n_singular"
    }
  ],
  "forms": {
    "n_singular": {
      "text": "apple",
      "phonetic": "/ˈæp.əl/",
      "audio": "https://cdn.sena.tech/audio/apple_singular.mp3",
      "min_grade": 1
    },
    "n_plural": {
      "text": "apples",
      "phonetic": "/ˈæp.əlz/",
      "audio": "https://cdn.sena.tech/audio/apples_plural.mp3",
      "min_grade": 1
    }
  },
  "syntax": {
    "is_subject": true,
    "is_verb": false,
    "is_object": true,
    "is_be": false,
    "is_adj": false
  },
  "semantics": {
    "word_type": "entity"
  }
}

Case 3: Lấy tất cả từ vựng cho Grade 1, Unit 2

GET /api/vocab/curriculum?grade=1&unit=2

Case 4: Tìm kiếm từ vựng có liên quan đến "food"

GET /api/vocab?search=food&include_relations=true

Case 5: Cập nhật bản dịch và thêm tag mới

PUT /api/vocab/vocab-001-eat

{
  "translation": "ăn, dùng bữa",
  "attributes": {
    "tags": ["daily-routine", "verb", "food", "health"]
  }
}

Case 6: Cập nhật syntax và semantics

PUT /api/vocab/vocab-001-eat

{
  "syntax": {
    "is_subject": false,
    "is_verb": true,
    "is_object": false,
    "is_be": false,
    "is_adj": false,
    "verb_type": "transitive"
  },
  "semantics": {
    "can_be_subject_type": ["human", "animal"],
    "can_take_object_type": ["food", "plant"],
    "word_type": "action"
  }
}

Case 8: Thêm mạo từ "a" với phonetic constraints

POST /api/vocab

{
  "vocab_code": "vocab-art-01",
  "base_word": "a",
  "translation": "một (mạo từ bất định)",
  "attributes": {
    "difficulty_score": 1,
    "category": "Articles",
    "tags": ["article", "function-word", "grammar"]
  },
  "forms": {
    "base": {
      "text": "a",
      "phonetic": "/ə/",
      "audio": "https://cdn.sena.tech/audio/a.mp3",
      "min_grade": 1
    }
  },
  "syntax": {
    "is_article": true,
    "article_type": "indefinite",
    "priority": 1
  },
  "constraints": {
    "followed_by": "consonant_sound"
  }
}

Case 9: Thêm trạng từ với modifier constraints

POST /api/vocab

{
  "vocab_code": "vocab-adv-01",
  "base_word": "quickly",
  "translation": "nhanh chóng",
  "attributes": {
    "difficulty_score": 2,
    "category": "Adverbs",
    "tags": ["adverb", "manner", "modifier"]
  },
  "forms": {
    "base": {
      "text": "quickly",
      "phonetic": "/ˈkwɪk.li/",
      "audio": "https://cdn.sena.tech/audio/quickly.mp3",
      "min_grade": 2
    }
  },
  "syntax": {
    "is_adv": true,
    "adv_type": "manner",
    "position": "after_verb"
  },
  "semantics": {
    "can_modify": ["action_verb"],
    "cannot_modify": ["stative_verb", "be_verb"],
    "word_type": "property"
  },
  "constraints": {
    "match_with": "dynamic_verb"
  }
}

Case 10: Thêm đại từ với subject agreement

POST /api/vocab

{
  "vocab_code": "vocab-pron-01",
  "base_word": "I",
  "translation": "tôi",
  "attributes": {
    "difficulty_score": 1,
    "category": "Pronouns",
    "tags": ["pronoun", "personal", "subject"]
  },
  "forms": {
    "subject": {
      "text": "I",
      "phonetic": "/aɪ/",
      "audio": "https://cdn.sena.tech/audio/I.mp3",
      "min_grade": 1
    },
    "object": {
      "text": "me",
      "phonetic": "/miː/",
      "audio": "https://cdn.sena.tech/audio/me.mp3",
      "min_grade": 1
    }
  },
  "syntax": {
    "is_subject": true,
    "is_pronoun": true,
    "pronoun_type": "personal",
    "person": "first",
    "number": "singular"
  },
  "semantics": {
    "person_type": "1st",
    "word_type": "entity"
  },
  "constraints": {
    "match_subject": {
      "I": "am",
      "you": "are",
      "he/she/it": "is"
    }
  }
}

Case 11: Thêm động từ "be" với subject matching

POST /api/vocab

{
  "vocab_code": "vocab-be-01",
  "base_word": "be",
  "translation": "là, thì",
  "attributes": {
    "difficulty_score": 1,
    "category": "Verbs",
    "tags": ["verb", "be-verb", "linking-verb"]
  },
  "forms": {
    "base": {
      "text": "be",
      "phonetic": "/biː/",
      "audio": "https://cdn.sena.tech/audio/be.mp3",
      "min_grade": 1
    },
    "am": {
      "text": "am",
      "phonetic": "/æm/",
      "audio": "https://cdn.sena.tech/audio/am.mp3",
      "min_grade": 1,
      "description": "Dùng với 'I'"
    },
    "is": {
      "text": "is",
      "phonetic": "/ɪz/",
      "audio": "https://cdn.sena.tech/audio/is.mp3",
      "min_grade": 1,
      "description": "Dùng với he/she/it"
    },
    "are": {
      "text": "are",
      "phonetic": "/ɑːr/",
      "audio": "https://cdn.sena.tech/audio/are.mp3",
      "min_grade": 1,
      "description": "Dùng với you/we/they"
    }
  },
  "syntax": {
    "is_verb": true,
    "is_be": true,
    "verb_type": "linking"
  },
  "constraints": {
    "match_subject": {
      "I": "am",
      "he": "is",
      "she": "is",
      "it": "is",
      "you": "are",
      "we": "are",
      "they": "are"
    }
  }
}

Case 12: Lấy tất cả articles cho Grammar Engine

GET /api/vocab?category=Articles

Case 13: Lấy tất cả adverbs có thể bổ nghĩa cho action verbs

# Filter trong application logic dựa trên semantics.can_modify
GET /api/vocab?category=Adverbs&include_relations=true

Case 14: Cập nhật constraints cho từ hiện có

PUT /api/vocab/vocab-001-eat

{
  "constraints": {
    "requires_object": true,
    "cannot_be_passive": false,
    "semantic_object_types": ["food", "plant"]
  }
}

⚠️ Lưu ý quan trọng

1. Transaction Safety

  • Tất cả các thao tác tạo/cập nhật đều sử dụng transaction
  • Nếu bất kỳ phần nào thất bại, toàn bộ thao tác sẽ rollback

2. Cascade Delete

  • Khi xóa vocab, các bản ghi liên quan trong vocab_mapping, vocab_form, và vocab_relation cũng tự động xóa
  • Sử dụng soft delete để có thể khôi phục

3. Indexing

  • Các trường vocab_code, base_word, category đã được index
  • Tìm kiếm theo các trường này sẽ nhanh hơn

4. Validation

  • vocab_code phải unique
  • base_wordtranslation là bắt buộc
  • form_key trong vocab_form phải unique cho mỗi vocab_id

🔍 Troubleshooting

Lỗi: "vocab_code already exists"

  • Kiểm tra xem code đã tồn tại chưa
  • Sử dụng code khác hoặc xem lại vocab hiện có

Lỗi: "At least book_id or grade is required"

  • Khi dùng endpoint /curriculum, phải cung cấp ít nhất book_id hoặc grade

Lỗi: "Vocabulary not found"

  • Kiểm tra ID hoặc code có đúng không
  • Kiểm tra từ vựng có bị soft delete (is_active = false) không

📊 Database Migration

Để tạo các bảng trong database, chạy lệnh:

npm run sync-database

Hoặc sử dụng script đồng bộ:

const { syncDatabase } = require('./models');

// Development only - force sync
await syncDatabase({ force: true });

// Production - alter existing tables
await syncDatabase({ alter: true });

🚀 Testing với Swagger

Truy cập: http://localhost:3000/api-docs

Tìm section Vocabulary để test các endpoint.


🎮 Grammar Engine Integration Summary

Quy trình tạo câu tự động

Bước 1: Chọn Pattern

// Engine chọn pattern "Present_Continuous_Adv"
pattern = "The {art_s} {S} {be} {V_ing} {art_o} {O} {Adv}"

Bước 2: Chọn từ theo Roles và Constraints

// 1. Chọn Subject (animal)
S = "cat" (syntax.is_subject=true, semantics.word_type="entity")

// 2. Auto-select Article cho Subject
// Engine đọc phonetic của "cat" = /kæt/ (bắt đầu phụ âm)
art_s = "the" (constraints.followed_by="any")

// 3. Match Be verb với Subject
// "cat" là số ít, ngôi 3 -> is
be = "is" (constraints.match_subject["it"]="is")

// 4. Chọn Verb (transitive)
V = "eat" (syntax.is_verb=true, verb_type="transitive", form="v_ing")

// 5. Chọn Object phù hợp với Verb
// eat.semantics.can_take_object_type = ["food", "plant"]
O = "apple" (semantics.word_type="entity", category="food")

// 6. Auto-select Article cho Object
// "apple" phonetic = /ˈæp.əl/ (bắt đầu nguyên âm)
art_o = "an" (constraints.followed_by="vowel_sound")

// 7. Chọn Adverb phù hợp với Verb
// quickly.semantics.can_modify = ["action_verb"]
// eat là action_verb -> match!
Adv = "quickly" (syntax.is_adv=true, adv_type="manner")

Kết quả:

"The cat is eating an apple quickly"

Kiểm tra tính hợp lệ

Semantic Check:

  • cat (animal) CAN eat (can_be_subject_type includes "animal")
  • eat CAN take apple (can_take_object_type includes "food")
  • quickly CAN modify eat (can_modify includes "action_verb")

Syntax Check:

  • "the" before consonant sound /k/
  • "an" before vowel sound /æ/
  • "is" matches with singular third person (cat)
  • "quickly" in correct position (after_verb)

Database Query Examples cho Grammar Engine

Query 1: Lấy tất cả từ có thể làm chủ ngữ động vật

SELECT * FROM vocab 
WHERE JSON_EXTRACT(syntax, '$.is_subject') = true
AND JSON_CONTAINS(semantics, '"animal"', '$.word_type');

Query 2: Lấy động từ transitive có thể nhận object loại "food"

SELECT * FROM vocab 
WHERE JSON_EXTRACT(syntax, '$.is_verb') = true
AND JSON_EXTRACT(syntax, '$.verb_type') = 'transitive'
AND JSON_CONTAINS(semantics, '"food"', '$.can_take_object_type');

Query 3: Lấy mạo từ cho từ bắt đầu bằng nguyên âm

SELECT * FROM vocab 
WHERE JSON_EXTRACT(syntax, '$.is_article') = true
AND JSON_EXTRACT(constraints, '$.followed_by') = 'vowel_sound';

Query 4: Lấy trạng từ có thể bổ nghĩa cho action verb

SELECT * FROM vocab 
WHERE JSON_EXTRACT(syntax, '$.is_adv') = true
AND JSON_CONTAINS(semantics, '"action_verb"', '$.can_modify');

Ví dụ hoàn chỉnh: Tạo 10 câu tự động

// Pseudo code cho Grammar Engine
async function generateSentences(pattern, count = 10) {
  const sentences = [];
  
  for (let i = 0; i < count; i++) {
    // 1. Lấy Subject candidates
    const subjects = await Vocab.findAll({
      where: sequelize.literal("JSON_EXTRACT(syntax, '$.is_subject') = true")
    });
    const S = randomPick(subjects);
    
    // 2. Auto-select Article cho Subject
    const firstSound = getFirstPhoneme(S.forms.base.phonetic);
    const art_s = await selectArticle(firstSound);
    
    // 3. Match Be verb
    const be = await matchBeVerb(S);
    
    // 4. Lấy Verb candidates (transitive only)
    const verbs = await Vocab.findAll({
      where: sequelize.literal(`
        JSON_EXTRACT(syntax, '$.is_verb') = true 
        AND JSON_EXTRACT(syntax, '$.verb_type') = 'transitive'
      `)
    });
    const V = randomPick(verbs);
    
    // 5. Lấy Object phù hợp với Verb
    const objectTypes = V.semantics.can_take_object_type;
    const objects = await Vocab.findAll({
      where: sequelize.literal(`
        JSON_EXTRACT(syntax, '$.is_object') = true
        AND JSON_EXTRACT(semantics, '$.word_type') IN (${objectTypes})
      `)
    });
    const O = randomPick(objects);
    
    // 6. Auto-select Article cho Object
    const objFirstSound = getFirstPhoneme(O.forms.base.phonetic);
    const art_o = await selectArticle(objFirstSound);
    
    // 7. Lấy Adverb phù hợp
    const adverbs = await Vocab.findAll({
      where: sequelize.literal(`
        JSON_EXTRACT(syntax, '$.is_adv') = true
        AND JSON_CONTAINS(semantics, '"action_verb"', '$.can_modify')
      `)
    });
    const Adv = randomPick(adverbs);
    
    // 8. Construct sentence
    sentences.push(
      `${art_s.base_word} ${S.base_word} ${be.form} ${V.forms.v_ing.text} ${art_o.base_word} ${O.base_word} ${Adv.base_word}`
    );
  }
  
  return sentences;
}

// Output:
// [
//   "The cat is eating an apple quickly",
//   "A dog is drinking the water slowly",
//   "The boy is reading a book carefully",
//   ...
// ]

📞 Hỗ trợ

Nếu cần hỗ trợ, liên hệ team development hoặc tham khảo tài liệu API đầy đủ tại Swagger UI.


📚 Tài liệu tham khảo

Phonetic Resources

Grammar Resources

Best Practices

  1. Consistency: Luôn sử dụng cùng một convention cho vocab_code
  2. Completeness: Điền đầy đủ syntax, semantics, constraints cho mỗi từ
  3. Accuracy: Kiểm tra kỹ phonetic transcription
  4. Testing: Test Grammar Engine với nhiều combinations
  5. Documentation: Ghi chú rõ ràng cho từng trường đặc biệt

Version: 2.0.0 (Grammar Engine Ready)
Last Updated: January 26, 2026
Maintainer: SENA Development Team