md2link

API Data Gaps

DraftMay 26, 2026

API Data Gaps

So sánh data API trả về vs data các screen cần hiển thị — Cập nhật: 2026-05-26


Tổng quan

Mức độ Số lượng
Đủ data 5 flow
Thiếu field 3
Data absent (UX) 1

Đủ data (Không cần thay đổi)

Flow API Ghi chú
FreeTalk conversation POST /conversations, POST /conversations/{id}/messages (SSE) Trả đủ: content, ttsAudioUrl, grammarCorrection, suggestedResponse, newVocab
Scenario list GET /cms/lessons?page=1&pageSize=100 Trả đủ: documentId, title, level, cardPreview.mediaUrl
Lesson detail GET /cms/lessons/{documentId} Trả đủ: title, content.dialogues, targetWords
Word error detection POST /learning/word-error Trả đủ: wrongWords, totalWords, errorCount
Lesson plan generation POST /learning/lesson-plan Trả đủ: title, level, content.dialogues, targetWords

Thiếu data (Cần server bổ sung)

GAP-1: grammarCorrection thiếu explanation

  • API endpoint: POST /conversations/{id}/messages — SSE event stream_end
  • API trả: { "wrong": "...", "correct": "..." }
  • Screen cần: { "wrong": "...", "correct": "...", "explanation": "..." }
  • Ảnh hưởng: AISpeakingResultScreen — mục Grammar Corrections hiển thị explanation luôn trống
  • Code liên quan: AISpeakingViewModel.kt:414 hardcode explanation = ""
  • Đề xuất server: Thêm field explanation vào grammarCorrection trong SSE stream_end:
    {
      "grammarCorrection": {
        "wrong": "I wants to order",
        "correct": "I want to order",
        "explanation": "'want' không chia 's' với chủ ngữ 'I'"
      }
    }

GAP-2: newVocab thiếu definition, meanings, examples, relatedWords

  • API endpoint: POST /conversations/{id}/messages — SSE event stream_end
  • API trả: { "word": "iced", "pos": "adj", "ipa": "/aɪst/" }
  • Screen cần: word, pos, ipa + definition, meanings, examples, relatedWords
  • Ảnh hưởng:
    • VocabScreen — từ vựng từ FreeTalk chỉ có tên + phiên âm, không có nghĩa
    • FlashcardScreen / FlashcardDetailScreen — flashcard thiếu nội dung học
  • Code liên quan: VocabRepositoryImpl.saveVocabFromFreeTalk() — save với definition = ""
  • Đề xuất server: Mở rộng newVocab trong SSE stream_end:
    {
      "newVocab": [
        {
          "word": "iced",
          "pos": "adj",
          "ipa": "/aɪst/",
          "definition": "made very cold",
          "meanings": ["làm lạnh", "ướp đá"],
          "examples": ["I'd like an iced coffee.", "Iced tea is refreshing."],
          "relatedWords": ["frozen", "chilled"]
        }
      ]
    }

GAP-3: CMS targetWords chỉ là comma-separated string

  • API endpoint: GET /cms/lessons/{documentId}, POST /learning/lesson-plan
  • API trả: "targetWords": "coffee, iced, medium, sugar, pay"
  • Screen cần: Mỗi từ cần word, pronunciation, type, definition, meanings, examples, relatedWords
  • Ảnh hưởng:
    • RoleplayResultScreen — vocab words chỉ hiển thị tên từ, các field còn lại trống
    • VocabScreen — từ vựng từ Roleplay thiếu tất cả metadata
  • Code liên quan: RoleplayApiServiceImpl.parseTargetWords() — chỉ parse ra word, còn lại empty
  • Đề xuất server: Đổi targetWords từ string sang array of objects:
    {
      "targetWords": [
        {
          "word": "coffee",
          "pos": "noun",
          "ipa": "/ˈkɒfi/",
          "definition": "a hot drink made from coffee beans"
        }
      ]
    }
    Hoặc giữ nguyên targetWords string và thêm API riêng: GET /learning/vocab/enrich?words=coffee,iced,medium

Data absent (UX impact)

GAP-4: cardPreview có thể absent trên nhiều lessons

  • API endpoint: GET /cms/lessons?page=1&pageSize=100
  • Vấn đề: API doc ghi rõ "cardPreview is only present on lessons that have a thumbnail configured in CMS — it may be absent on many items"
  • Ảnh hưởng: AIRoleplayScreen — nhiều scenario hiển thị cùng 1 ảnh mặc định img_scenario_cover_1
  • Hiện tại: Đã xử lý fallback trong ScenarioCard với AsyncImage error/placeholder
  • Đề xuất: CMS team upload thumbnail cho tất cả lessons, hoặc server tự generate thumbnail

Tổng kết ưu tiên

Ưu tiên GAP Lý do
Cao GAP-2: newVocab thiếu metadata Ảnh hưởng trực tiếp VocabScreen + FlashcardScreen — core feature của app
Cao GAP-3: targetWords chỉ là string Ảnh hưởng RoleplayResult + VocabScreen — từ vựng là feature chính
Trung bình GAP-1: grammarCorrection thiếu explanation AISpeakingResult hiện được nhưng thiếu context giải thích
Thấp GAP-4: cardPreview absent Đã có fallback, chỉ ảnh hưởng UX