[{"data":1,"prerenderedAt":610},["ShallowReactive",2],{"content-\u002Fplugins\u002Faio-epub-translate\u002Faio-epub-quality":3,"children-\u002Fplugins\u002Faio-epub-translate\u002Faio-epub-quality":609},{"id":4,"title":5,"author":6,"body":7,"budget_tier":6,"build_tags":6,"created":6,"description":600,"document_type":601,"extension":602,"game":6,"install":36,"investment_tier":6,"league":6,"meta":603,"navigation":604,"patch":6,"path":605,"plugin":24,"profit_per_hour":6,"ratings":6,"seo":606,"skills_count":6,"status":6,"stem":607,"strategy_tier":6,"tags":6,"updated":6,"version":6,"weight":6,"__hash__":608},"content\u002Fplugins\u002Faio-epub-translate\u002Faio-epub-quality.md","aio-epub-quality",null,{"type":8,"value":9,"toc":586},"minimark",[10,37,42,45,60,65,75,79,84,90,94,181,185,190,200,208,223,229,301,310,420,424,430,436,440,446,450,510,514,566],[11,12,13],"blockquote",{},[14,15,16,17,25,26,25,30,33,34],"p",{},"From plugin ",[18,19,21],"a",{"href":20},"\u002Fplugins\u002Faio-epub-translate",[22,23,24],"strong",{},"aio-epub-translate"," · ",[27,28,29],"code",{},"v4.0.0",[22,31,32],{},"Install:"," ",[27,35,36],{},"\u002Fplugin install aio-epub-translate@aiocean-plugins",[38,39,41],"h1",{"id":40},"epub-quality-translation-quality-report","EPUB Quality — Translation Quality Report",[14,43,44],{},"Check translation quality across a book or specific chapter to find issues.",[11,46,47],{},[14,48,49,52,53,55,56,59],{},[22,50,51],{},"Khi nào dùng",": Sau khi dịch xong bằng ",[27,54,24],{},", chạy quality check trước khi xuất bằng ",[27,57,58],{},"aio-epub-export",".",[61,62,64],"h2",{"id":63},"api-setup","API Setup",[66,67,73],"pre",{"className":68,"code":70,"language":71,"meta":72},[69],"language-python","import json, urllib.request, os\n\nBASE = \"https:\u002F\u002Fread-api.aiocean.dev\u002FListBooks.v1.BookService\"\nKEY = os.environ.get(\"AIO_EPUB_API_KEY\", \"duocnv\")\n\ndef api(method, body):\n    data = json.dumps(body).encode('utf-8')\n    req = urllib.request.Request(f\"{BASE}\u002F{method}\", data=data, headers={\n        \"Content-Type\": \"application\u002Fjson\",\n        \"X-License-Key\": KEY\n    })\n    with urllib.request.urlopen(req) as resp:\n        return json.loads(resp.read())\n","python","",[27,74,70],{"__ignoreMap":72},[61,76,78],{"id":77},"workflow","Workflow",[80,81,83],"h3",{"id":82},"_1-run-quality-report","1. Run Quality Report",[66,85,88],{"className":86,"code":87,"language":71,"meta":72},[69],"# Check a specific chapter\nreport = api(\"GetTranslationQualityReport\", {\n    \"bookId\": BOOK_ID,\n    \"filePath\": FILE_PATH  # leave empty to check entire book\n})\n\nprint(f\"Quality Score: {report['qualityScore']:.1f}%\")\nprint(f\"Total Items: {report['totalItems']}\")\nprint(f\"Issues Found: {report['issuesCount']}\")\n\nfor issue in report.get(\"issues\", []):\n    print(f\"\\n  [{issue['issueType']}] {issue['contentId'][:12]}\")\n    print(f\"  Detail: {issue['detail']}\")\n    if issue.get(\"originalText\"):\n        print(f\"  Original: {issue['originalText'][:100]}\")\n    if issue.get(\"translatedText\"):\n        print(f\"  Translated: {issue['translatedText'][:100]}\")\n",[27,89,87],{"__ignoreMap":72},[80,91,93],{"id":92},"_2-issue-types","2. Issue Types",[95,96,97,113],"table",{},[98,99,100],"thead",{},[101,102,103,107,110],"tr",{},[104,105,106],"th",{},"Type",[104,108,109],{},"Meaning",[104,111,112],{},"Action",[114,115,116,130,143,156,168],"tbody",{},[101,117,118,124,127],{},[119,120,121],"td",{},[27,122,123],{},"mixed_language",[119,125,126],{},">50% words still in English",[119,128,129],{},"Re-translate",[101,131,132,137,140],{},[119,133,134],{},[27,135,136],{},"empty_translation",[119,138,139],{},"Translation element is empty",[119,141,142],{},"Translate",[101,144,145,150,153],{},[119,146,147],{},[27,148,149],{},"too_short",[119,151,152],{},"Translation \u003C30% of original length",[119,154,155],{},"Review & re-translate",[101,157,158,163,166],{},[119,159,160],{},[27,161,162],{},"untranslated",[119,164,165],{},"Translation identical to original",[119,167,129],{},[101,169,170,175,178],{},[119,171,172],{},[27,173,174],{},"missing_translation_element",[119,176,177],{},"ID referenced but element missing",[119,179,180],{},"Re-mark or re-translate",[80,182,184],{"id":183},"_2b-literary-quality-evaluation-đánh-giá-văn-học-sâu","2b. Literary Quality Evaluation (Đánh giá văn học sâu)",[11,186,187],{},[14,188,189],{},"Dùng khi mechanical score cao (>90%) nhưng bản dịch \"nghe như dịch máy\" hoặc \"đọc không tự nhiên\".",[14,191,192,195,196,199],{},[22,193,194],{},"Nạp kiến thức đánh giá"," — resolve path đến references của ",[27,197,198],{},"aio-epub-vn-style",":",[66,201,206],{"className":202,"code":204,"language":205,"meta":72},[203],"language-bash","REFS=\"${CLAUDE_PLUGIN_ROOT}\u002Fskills\u002Faio-epub-vn-style\u002Freferences\"\necho \"$REFS\"\n","bash",[27,207,204],{"__ignoreMap":72},[14,209,210,211,214,215,218,219,222],{},"Dùng Read tool đọc ",[27,212,213],{},"$REFS\u002Fquality-rubric.md"," (khung đánh giá MQM\u002FATA) và ",[27,216,217],{},"$REFS\u002Fcommon-errors.md"," (6 loại lỗi phải tránh). Đọc thêm ",[27,220,221],{},"$REFS\u002Fword-choice.md"," nếu cần tra đại từ.",[14,224,225,228],{},[22,226,227],{},"Tiêu chí đánh giá"," (MQM + Tín-Đạt-Nhã):",[95,230,231,244],{},[98,232,233],{},[101,234,235,238,241],{},[104,236,237],{},"Tiêu chí",[104,239,240],{},"Trọng số",[104,242,243],{},"Kiểm tra",[114,245,246,257,268,279,290],{},[101,247,248,251,254],{},[119,249,250],{},"Accuracy (Tín)",[119,252,253],{},"35%",[119,255,256],{},"Đúng nghĩa, không thêm bớt",[101,258,259,262,265],{},[119,260,261],{},"Fluency (Đạt)",[119,263,264],{},"25%",[119,266,267],{},"Không calque, không bị động thừa, Topic-Comment",[101,269,270,273,276],{},[119,271,272],{},"Style (Nhã)",[119,274,275],{},"20%",[119,277,278],{},"Giọng văn tác giả, từ láy, nhịp điệu",[101,280,281,284,287],{},[119,282,283],{},"Cultural fit",[119,285,286],{},"12%",[119,288,289],{},"Thành ngữ, Hán-Việt\u002Fthuần Việt phù hợp",[101,291,292,295,298],{},[119,293,294],{},"Consistency",[119,296,297],{},"8%",[119,299,300],{},"Đại từ, thuật ngữ xuyên chương",[14,302,303,306,307,309],{},[22,304,305],{},"Red flags — dấu hiệu chất lượng kém"," (chi tiết trong ",[27,308,213],{},"):",[95,311,312,325],{},[98,313,314],{},[101,315,316,319,322],{},[104,317,318],{},"Red Flag",[104,320,321],{},"Pattern",[104,323,324],{},"Mức",[114,326,327,338,358,368,378,389,399,409],{},[101,328,329,332,335],{},[119,330,331],{},"Calque thành ngữ",[119,333,334],{},"\"phá băng\", \"con voi trong phòng\"",[119,336,337],{},"Critical",[101,339,340,343,355],{},[119,341,342],{},"Calque bị động",[119,344,345,346,350,351,354],{},"\"bị ",[347,348,349],"span",{},"verb"," bởi ",[347,352,353],{},"agent","\"",[119,356,357],{},"Major",[101,359,360,363,366],{},[119,361,362],{},"Calque copula",[119,364,365],{},"\"Nó là quan trọng để...\"",[119,367,357],{},[101,369,370,373,376],{},[119,371,372],{},"Đại từ không nhất quán",[119,374,375],{},"\"anh\u002Fem\" → \"anh\u002Fcô\" giữa cảnh",[119,377,357],{},[101,379,380,383,386],{},[119,381,382],{},"Thiếu tiểu từ tình thái",[119,384,385],{},"Đối thoại không có nhé, nhỉ, ơi, mà",[119,387,388],{},"Minor–Major",[101,390,391,394,397],{},[119,392,393],{},"Câu dài >30 từ không tách",[119,395,396],{},"Giữ nguyên cấu trúc Anh",[119,398,388],{},[101,400,401,404,407],{},[119,402,403],{},"Danh từ hóa quá mức",[119,405,406],{},"Chuỗi \"sự + verb\"",[119,408,388],{},[101,410,411,414,417],{},[119,412,413],{},"Cụm sáo rỗng dịch thuật",[119,415,416],{},"\"Nói một cách khác\", \"Sự thật là...\"",[119,418,419],{},"Minor",[80,421,423],{"id":422},"_3-re-translate-bad-items","3. Re-translate Bad Items",[14,425,426,427,429],{},"For chapters with issues, use ",[27,428,24],{}," to re-translate:",[66,431,434],{"className":432,"code":433,"language":71,"meta":72},[69],"# Get the problematic items\npage = api(\"GetPageJson\", {\n    \"bookId\": BOOK_ID,\n    \"filePath\": FILE_PATH,\n    \"size\": 0,\n    \"offset\": 0\n})\n\n# Filter only items with quality issues\nissue_ids = {issue[\"contentId\"] for issue in report.get(\"issues\", [])}\nbad_items = [item for item in page[\"contents\"] if item[\"contentId\"] in issue_ids]\n\n# Re-translate and submit via batch\nbatch_items = []\nfor item in bad_items:\n    translated = translate(item[\"contentText\"])  # Claude re-translates\n    batch_items.append({\n        \"contentId\": item[\"contentId\"],\n        \"translatedContent\": translated,\n        \"targetLanguage\": \"Vietnamese\"\n    })\n\nresult = api(\"BatchCreateManualTranslation\", {\n    \"bookId\": BOOK_ID,\n    \"filePath\": FILE_PATH,\n    \"items\": batch_items\n})\nprint(f\"Re-translated: {result['createdCount']} items\")\n",[27,435,433],{"__ignoreMap":72},[80,437,439],{"id":438},"_4-full-book-scan","4. Full Book Scan",[66,441,444],{"className":442,"code":443,"language":71,"meta":72},[69],"# Scan entire book (no filePath = all chapters)\nreport = api(\"GetTranslationQualityReport\", {\n    \"bookId\": BOOK_ID,\n    \"filePath\": \"\"\n})\n\n# Group issues by file\nfrom collections import defaultdict\nby_file = defaultdict(list)\nfor issue in report.get(\"issues\", []):\n    by_file[issue.get(\"filePath\", \"unknown\")].append(issue)\n\nfor file_path, issues in sorted(by_file.items()):\n    print(f\"\\n{file_path}: {len(issues)} issues\")\n    for issue in issues:\n        print(f\"  [{issue['issueType']}] {issue['detail'][:80]}\")\n",[27,445,443],{"__ignoreMap":72},[61,447,449],{"id":448},"quality-thresholds","Quality Thresholds",[95,451,452,464],{},[98,453,454],{},[101,455,456,459,462],{},[104,457,458],{},"Score",[104,460,461],{},"Status",[104,463,112],{},[114,465,466,477,488,499],{},[101,467,468,471,474],{},[119,469,470],{},"95-100%",[119,472,473],{},"Excellent",[119,475,476],{},"No action needed",[101,478,479,482,485],{},[119,480,481],{},"80-94%",[119,483,484],{},"Good",[119,486,487],{},"Review flagged items",[101,489,490,493,496],{},[119,491,492],{},"60-79%",[119,494,495],{},"Fair",[119,497,498],{},"Re-translate flagged items",[101,500,501,504,507],{},[119,502,503],{},"\u003C60%",[119,505,506],{},"Poor",[119,508,509],{},"Re-translate entire chapter",[61,511,513],{"id":512},"bước-tiếp-theo","Bước tiếp theo",[95,515,516,526],{},[98,517,518],{},[101,519,520,523],{},[104,521,522],{},"Bạn muốn...",[104,524,525],{},"Dùng skill",[114,527,528,537,548,557],{},[101,529,530,533],{},[119,531,532],{},"Re-translate các items kém",[119,534,535],{},[27,536,24],{},[101,538,539,542],{},[119,540,541],{},"Reset chương và dịch lại từ đầu",[119,543,544,547],{},[27,545,546],{},"aio-epub-manage"," (phần Reset Chapter)",[101,549,550,553],{},[119,551,552],{},"Quality OK → xuất sách",[119,554,555],{},[27,556,58],{},[101,558,559,562],{},[119,560,561],{},"Xem tiến độ tổng thể",[119,563,564],{},[27,565,546],{},[14,567,568,570,571,574,575,574,578,574,580,574,584],{},[22,569,78],{},": ",[27,572,573],{},"aio-epub-setup"," → ",[27,576,577],{},"aio-epub-upload",[27,579,24],{},[22,581,582],{},[27,583,5],{},[27,585,58],{},{"title":72,"searchDepth":587,"depth":587,"links":588},2,[589,590,598,599],{"id":63,"depth":587,"text":64},{"id":77,"depth":587,"text":78,"children":591},[592,594,595,596,597],{"id":82,"depth":593,"text":83},3,{"id":92,"depth":593,"text":93},{"id":183,"depth":593,"text":184},{"id":422,"depth":593,"text":423},{"id":438,"depth":593,"text":439},{"id":448,"depth":587,"text":449},{"id":512,"depth":587,"text":513},"Check translation quality and find chapters that need re-translation.","skill","md",{},true,"\u002Fplugins\u002Faio-epub-translate\u002Faio-epub-quality",{"title":5,"description":600},"plugins\u002Faio-epub-translate\u002Faio-epub-quality","7CkaEcoUuLAsdXZ3rfYV2nw7yoRyMHPiDxD5t9BPNTg",[],1779707416400]