1578 lines
38 KiB
Markdown
1578 lines
38 KiB
Markdown
# 📚 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` và `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
|
||
|