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

1578 lines
38 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 📚 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:
```json
{
"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):
```json
{
"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):
```json
{
"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):
```json
{
"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):
```json
{
"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):
```json
{
"translation": "ăn uống",
"attributes": {
"difficulty_score": 2,
"tags": ["daily-routine", "verb", "food"]
}
}
```
#### Request Body (Update Forms):
```json
{
"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):
```json
{
"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):
```json
{
"message": "Vocabulary deleted successfully"
}
```
---
### 7. Thống kê từ vựng
**GET** `/api/vocab/stats`
#### Response (200):
```json
{
"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ụ:**
```json
// Độ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_type` và `object_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ụ:**
```json
// Độ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":**
```json
{
"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":**
```json
{
"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":**
```json
{
"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":**
```json
{
"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":**
```json
{
"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":**
```json
{
"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ữ:**
```json
{
"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)
```json
{
"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**
```javascript
// "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**
```javascript
// "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
```bash
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
```bash
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
```bash
GET /api/vocab/curriculum?grade=1&unit=2
```
### Case 4: Tìm kiếm từ vựng có liên quan đến "food"
```bash
GET /api/vocab?search=food&include_relations=true
```
### Case 5: Cập nhật bản dịch và thêm tag mới
```bash
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
```bash
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
```bash
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
```bash
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
```bash
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
```bash
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
```bash
GET /api/vocab?category=Articles
```
### Case 13: Lấy tất cả adverbs có thể bổ nghĩa cho action verbs
```bash
# 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ó
```bash
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_word``translation` 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:
```bash
npm run sync-database
```
Hoặc sử dụng script đồng bộ:
```javascript
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**
```javascript
// 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**
```javascript
// 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**
```sql
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"**
```sql
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**
```sql
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**
```sql
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
```javascript
// 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
- **IPA Chart**: https://www.internationalphoneticalphabet.org/
- **Cambridge Dictionary**: Nguồn phát âm chuẩn
- **Forvo**: Phát âm bởi người bản xứ
### Grammar Resources
- **English Grammar Rules**: https://www.englishgrammar.org/
- **Parts of Speech**: https://www.grammarly.com/blog/parts-of-speech/
- **Verb Types**: Transitive, Intransitive, Linking verbs
### 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