diff --git a/Docs/Proposals/2026-10-31-criteria-stars-pros-cons.html b/Docs/Proposals/2026-10-31-criteria-stars-pros-cons.html new file mode 100644 index 00000000..f8a371f8 --- /dev/null +++ b/Docs/Proposals/2026-10-31-criteria-stars-pros-cons.html @@ -0,0 +1,394 @@ + + +
+ + + +Ngày 31/10/2026. Người soạn: Core (Rate). Issue #1531 (thiết kế sao theo tiêu chí, ưu nhược điểm, điểm giá trị review). Đồng thời giải quyết #1143 (điểm tiêu chí suy ra từ số sao nên dồn về 5.00) và câu hỏi "một con số điểm" của #1470 (PR #1478 đang giữ). Đây chỉ là thiết kế: chưa sửa code, chưa đụng database.
+ +packages/shared-data, có số phiên bản.master_products, làm tròn 1 chữ số. Điểm chuyên gia hiện riêng, có nhãn.Quy ước và từ ngữ. Công thức và bảng dùng dấu phẩy thập phân (4,2); con số hiện cho người mua dùng dấu chấm như trên rate.vn hiện nay (4.6). "Seeding": review được trả tiền hoặc dàn dựng để khen. "Cổng chặn": điều kiện đưa trọng số review về 0 (giả, chép, viết cho có). "Cận dưới Wilson": cách tính tỷ lệ vote hữu ích có tính đến việc ít vote thì kém chắc chắn, nên 2 vote trên 2 không thắng 90 vote trên 100. "Pipeline": chuỗi bước xử lý chạy tự động theo đợt.
+ +| Phần | Đang có | Thiếu hoặc sai |
|---|---|---|
| Chấm tiêu chí khi viết review | Form trong JReviewsSection.tsx có 5 hàng nút chọn 1 đến 5 sao (screen, performance, camera, battery, value), mặc định 5 sao. Số sao của review là trung bình cộng, làm tròn thành số nguyên. API POST /api/v1/rate/reviews lọc khoá tiêu chí rồi gọi RPC rate.submit_community_review, lưu vào cột rate.reviews.criteria_ratings (jsonb). RPC không kiểm khoá. | Cùng 5 tiêu chí cho mọi ngành hàng (tai nghe chỉ đổi nhãn). Không có trọng số. Tiêu chí người viết không bấm vẫn tính 5 sao. API tin số sao tổng trình duyệt gửi lên, chỉ tự tính khi thiếu. Cột rating_star là số nguyên 1 đến 5. Không có ưu nhược trên review. |
| Điểm tiêu chí của sản phẩm | computeJReviewsCriteriaScores trong leaderboard-engine.ts: đọc expert_criteria_scores, nếu không có thì lấy số sao cộng một độ lệch tự đặt theo thông số và giá. | Chính là lỗi #1143: điểm bịa, dồn về 5.00, hoà và thứ hạng giả. Điểm tiêu chí bịa này còn chiếm 20% điểm ghép của bảng xếp hạng. Trong repo này không có code nào ghi expert_criteria_scores; 36 sản phẩm có điểm chuyên gia từ file seed (đề xuất kiểm tra nguồn gốc catalog ngày 16/10). |
| Điểm tổng | Trang sản phẩm dùng điểm Bayes (#1144: k = 3, trung bình mặc định 4,2), web tính từ danh sách review. Database chỉ lưu user_rating_weighted: trung bình có trọng số, không Bayes. Bảng xếp hạng dùng một điểm ghép (người dùng, chuyên gia, tiêu chí). | Lỗi #1470: cùng một máy hiện 4.8, 4.98, 5.0 ở các chỗ khác nhau. |
| Trọng số review | Trọng số đang lưu (helpfulness_weight, 0 đến 3) do rate.compute_review_weight tính: gốc 1 (0,25 nếu đáng ngờ, 0 nếu giả), cộng trừ theo vote và báo cáo. Mô hình tin cậy review (Docs/Platform/review-trust-model.html) đã thiết kế công thức sáu trục w = G × A × B × C × D × E × F, nhưng chưa được dùng cho trọng số đang lưu. | Chưa có gì đo "review có đủ ưu nhược, đủ tiêu chí không". |
| Ưu nhược | AI trong importer (ai-review-analyzer.ts) sinh tối đa 6 ưu và 6 nhược cho cả một listing, lưu ở rate.review_analysis.pros/cons; web gộp theo sản phẩm và hiện. | Không theo tiêu chí, không đếm số người nhắc, không gắn với review nào. Schema zod review.schema.ts có trường pros/cons nhưng không dùng. |
| Vote hữu ích | Có, kèm điều kiện tài khoản 7 ngày, đã xác minh email hoặc số điện thoại, giới hạn 60 lượt mỗi giờ. | Ổn, dùng lại được. |
| Điểm thưởng cho người dùng | Chưa có hệ thống nào. | Cần quyết riêng (mục 9, D8). |
| "Tiêu chuẩn 10 nhóm" | 10 nhóm thông số (màn hình, phần cứng, pin, camera...) trong specs.schema.ts và spec-template.ts. | Là nhóm thông số kỹ thuật, không phải tiêu chí chấm sao. Tiêu chí chấm sao sẽ tham chiếu tới nhóm thông số liên quan, nhưng là danh sách riêng. |
Trọng số mỗi ngành cộng lại bằng 100. Đây là bản nháp để JOY sửa; con số chỉ là điểm xuất phát.
+| Ngành hàng | Tiêu chí (trọng số %) |
|---|---|
| Điện thoại | Hiệu năng 20, Camera 20, Pin và sạc 20, Màn hình 15, Thiết kế và độ bền 10, Đáng tiền 15 |
| Máy tính bảng | Màn hình 20, Hiệu năng 20, Pin 15, Loa và giải trí 10, Phần mềm và phụ kiện 10, Thiết kế 10, Đáng tiền 15 |
| Laptop | Hiệu năng 25, Màn hình 15, Pin 15, Bàn phím và touchpad 10, Tản nhiệt và độ ồn 10, Thiết kế và độ bền 10, Đáng tiền 15 |
| Đồng hồ thông minh | Theo dõi sức khoẻ 25, Pin 20, Thiết kế và đeo 15, Ứng dụng và kết nối 15, Màn hình 10, Đáng tiền 15 |
| Tai nghe | Chất âm 30, Chống ồn 15, Pin 15, Đeo thoải mái 15, Mic và gọi 10, Đáng tiền 15 |
Dịch vụ (khi mở, entity_type = 'service') | Chất lượng dịch vụ 35, Giá cả 25, Thái độ phục vụ 20, Tốc độ 20 |
packages/shared-data/src/rules/ (ví dụ rating-criteria.ts), cạnh spec-template.ts. Mỗi tiêu chí có khoá cố định (performance, camera, sound...), nhãn tiếng Việt và tiếng Anh, trọng số, và nhóm thông số liên quan (để trang sản phẩm hiện thông số cạnh điểm).criteria_version), nên không có lệnh cập nhật hàng loạt trên database dùng chung. Điểm từng tiêu chí của sản phẩm không phụ thuộc trọng số nên không đổi.criteria_ratings của review đã viết: screen thành Màn hình, performance thành Hiệu năng, camera thành Camera (tai nghe: Chất âm), battery thành Pin, value thành Đáng tiền. Tiêu chí mới mà review cũ không có thì để trống, không suy ra.Điểm tổng của một review trên Rate, tính như JReviews, người viết không tự chọn số sao tổng:
+sao_review = Σ (trọng_số_i × sao_i) / Σ trọng_số_i chỉ trên các tiêu chí người viết đã chấm +làm tròn 0,1; người viết thấy con số này ngay khi kéo sao+
Người viết được bỏ qua tối đa 2 tiêu chí ("Chưa dùng tới", ví dụ chưa thử chống ồn), không được bỏ "Đáng tiền". Không còn mặc định 5 sao: tiêu chí chưa bấm thì form báo thiếu, chứ không tự tính là 5.
+Điểm từng tiêu chí của sản phẩm (Bayes theo từng tiêu chí, cùng cách #1144 đang dùng cho điểm tổng):
+điểm_tiêu_chí_i = (k × μ_i + Σ w_r × sao_r,i) / (k + Σ w_r) +k = 3; μ_i = trung bình tiêu chí i của cả ngành hàng (chưa có thì 4,2) +w_r = trọng số tin cậy của review r (mô hình tin cậy review, 0 đến 3) +chỉ tính review có chấm tiêu chí i và có trọng số lớn hơn 0 +hiện khi có ít nhất 3 người viết khác nhau và Σ w_r ≥ 1,5; còn lại "Chưa đủ dữ liệu" +dùng để xếp hạng theo tiêu chí (chip "#1 Màn hình") khi có ít nhất 5 người viết khác nhau+
Ngưỡng theo số người viết là để một review được vote cao không tự tạo ra một thứ hạng.
+Điểm tổng của sản phẩm (con số duy nhất hiện mọi nơi):
+điểm_sản_phẩm = (k × μ + Σ w_r × sao_review_r) / (k + Σ w_r) k = 3, μ = 4,2 (như #1144) +mọi review hợp lệ: review Shopee dùng số sao gốc, review Rate dùng sao_review tính ở trên+
Vì sao không tính điểm sản phẩm thẳng từ các điểm tiêu chí: review lấy từ sàn (phần lớn dữ liệu hiện nay) chỉ có một số sao tổng. Tính từ tiêu chí sẽ bỏ hết số review đó, và sản phẩm chưa có review Rate nào sẽ không có điểm. Trọng số tiêu chí vẫn quyết định điểm tổng, nhưng ở bên trong từng review Rate. Khi review Rate đủ nhiều, hai cách cho kết quả gần nhau; Core sẽ theo dõi chênh lệch này.
+Hệ quả cần nói rõ trên trang: điểm chính (tính từ mọi review) có thể khác trung bình có trọng số của các điểm tiêu chí (chỉ từ review Rate). Vì vậy khối điểm tiêu chí ghi "Từ N review trên Rate" và có link "cách tính điểm". Đây là hai con số đo hai thứ khác nhau, có nhãn, không phải lỗi #1470.
+ +null, hiện "Chưa đủ dữ liệu" ở bảng xếp hạng, trang so kè, chip thứ hạng và API (ghi rõ trong OpenAPI).expert_criteria_scores) vẫn hiện được, nhưng có nhãn "Chuyên gia", không trộn vào điểm người dùng. 36 sản phẩm có điểm này từ seed; quyết định giữ hay bỏ đang mở ở đề xuất nguồn gốc dữ liệu catalog (16/10).rate.refresh_master_product_rating ghi thêm điểm Bayes và tổng trọng số vào master_products (migration DOS-Me). Nói thẳng: #1470 chỉ được giải quyết trọn khi có cột này (P2, P4). Điểm Bayes cần tổng trọng số chứ không phải số review, nên các danh sách hiện không tự tính được. Trong lúc chờ, giữ cách của PR #1478 (mọi chỗ ngoài trang sản phẩm dùng điểm đã lưu, 1 chữ số) và chấp nhận trang sản phẩm còn lệch ở một số máy.Mọi thay đổi bảng dưới đây là DDL trên Supabase dùng chung, nên đi qua migration DOS-Me do JOY duyệt và chạy. Repo này chỉ soạn đề xuất SQL, không áp dụng.
+| Chỗ | Thay đổi | Có sẵn hay mới | Migration |
|---|---|---|---|
rate.reviews.criteria_ratings | Giữ dạng {khoá: sao}, thêm khoá mới theo danh sách ngành hàng. | Có sẵn | Không (API kiểm khoá theo danh sách mới) |
rate.reviews.rating_star | Đang là số nguyên 1 đến 5 (SMALLINT), RPC cũng nhận số nguyên. Số sao tính từ tiêu chí là số lẻ (4,3), nên thêm cột rating_exact numeric(2,1); rating_star giữ số làm tròn cho code cũ đọc. Các hàm tính điểm đọc rating_exact khi có. | Có sẵn, thêm cột cạnh nó | Có, DOS-Me |
rate.reviews cột mới | verdict text (câu kết luận, tối đa 300 ký tự); criteria_version int; value_score numeric(5,2) và value_breakdown jsonb (mục 6). | Mới | Có, DOS-Me |
rate.review_points (bảng mới) | Mỗi dòng là một ưu hoặc nhược: review_id, criterion_key (rỗng nghĩa là ưu nhược chung của review), kind ('pro' hoặc 'con'), body (5 đến 150 ký tự), position, cluster_id (do bước gom gán). | Mới | Có, DOS-Me |
rate.product_points (bảng mới) | Kết quả gom cho mỗi sản phẩm: master_id, criterion_key, kind, label (câu hiển thị), support (tổng trọng số người nhắc), reviewer_count, has_expert, first_seen, last_seen, method ('code' hoặc 'ai'). | Mới; thay dần review_analysis.pros/cons | Có, DOS-Me |
rate.master_products cột mới | rating_score numeric(3,2) (điểm Bayes), rating_weight_sum numeric, criteria_scores jsonb ({khoá: {score, weight_sum}}, chỉ tiêu chí đủ dữ liệu). | Mới | Có, DOS-Me; hàm làm mới ghi các cột này |
rate.submit_community_review | Bản 2: nhận verdict, danh sách ưu nhược và số sao do API đã tính; kiểm lại các điều kiện bắt buộc (mục 4) để không ai gọi thẳng RPC mà lách được. | Có sẵn, sửa | Có, DOS-Me |
Vì sao tách ưu nhược ra bảng riêng thay vì cột mảng: bước gom cần gán từng dòng vào một cụm, đếm theo tiêu chí và truy ngược "ai đã nhắc ý này". Bảng riêng làm việc đó bằng SQL thường và đánh chỉ mục được; mảng trong jsonb thì phải bung ra mỗi lần.
+ +reviewer_type = 'expert').method = 'ai' và chỉ dùng cho bước gom, không hiện như lời người viết.| Thành phần | Tối đa | Cách tính |
|---|---|---|
| Đầy đủ | 35 | Chấm đủ tiêu chí 10; có câu kết luận 5; có ưu và nhược chung 10; có ưu nhược theo ít nhất 2 tiêu chí 5; có ảnh thật 5. |
| Nội dung cụ thể | 20 | Theo trục C của mô hình tin cậy (hời hợt, ngắn nhưng cụ thể, chi tiết, chuyên sâu). Độ dài có trần: viết dài thêm sau mức đủ không được thêm điểm. |
| Đã mua | 15 | Có xác nhận đã mua (sàn, hoặc sau này hoá đơn). Chưa xác nhận: 0. |
| Vote hữu ích | 20 | Từ cận dưới Wilson của vote hữu ích (đang dùng để sắp review), nên vài vote đầu không làm điểm nhảy vọt. |
| Uy tín người viết | 10 | Trục D của mô hình tin cậy: tuổi tài khoản, lịch sử review, uy tín theo ngành hàng. |
Review bị cổng chặn (giả, chép, viết cho có để lấy xu...) có điểm giá trị bằng 0, dù đầy đủ đến đâu. Review lấy từ sàn cũng có điểm này (thường thấp vì thiếu ưu nhược), nên một thang dùng chung cho mọi review.
+ +JOY muốn review đầy đủ "cao hơn một tí". Chỉ phần "Đầy đủ" ở 6.1 chạm vào trọng số, qua một hệ số nhân:
+hệ_số_đầy_đủ = 1 + 0,25 × đầy_đủ / 35 từ ×1,00 (không có gì) đến ×1,25 (đủ hết) +hôm nay: w = helpfulness_weight × hệ_số_đầy_đủ, trần 3 như cũ+
helpfulness_weight (gốc cộng vote), chưa phải công thức sáu trục của mô hình tin cậy. Hệ số trên nhân vào trọng số đang lưu, nên làm được ngay ở P6. Khi nào mô hình sáu trục được áp dụng (một việc riêng, làm đổi điểm mọi sản phẩm), phần ưu nhược và ảnh trong "Đầy đủ" được bỏ khỏi hệ số này, vì trục C đã tính chúng (mức "chi tiết" đòi có cả ưu lẫn nhược, ảnh thật được cộng 0,1). Khi đó chỉ còn phần chấm đủ tiêu chí và kết luận nâng trọng số, để không tính hai lần.helpfulness_weight.| Rủi ro | Chặn bằng |
|---|---|
| Điền cho đủ ô để lấy điểm ("Ưu: tốt. Nhược: không") | Kiểm ở 4.2; phần "Nội dung cụ thể" chấm theo chi tiết, không theo số ô; phần "Đầy đủ" chỉ cộng khi trục C không phải hời hợt. |
| Viết dài, đệm chữ | Độ dài có trần; chữ đệm và lặp vào nhóm "viết cho có", cổng chặn. |
| Chép một bộ ưu nhược cho nhiều sản phẩm | So gần giống giữa các review của cùng người và giữa các tài khoản (trục A, loại "chép từ nơi khác"). |
| Nhóm vote cho nhau | Điều kiện vote đã có (tuổi tài khoản, xác minh, giới hạn mỗi giờ); trọng số người vote ở mục 9 của mô hình tin cậy; Wilson thay vì đếm thô. |
| Săn điểm thưởng hàng loạt | Điểm thưởng chỉ trao sau khi review qua bước phân tích và một thời gian giữ (ví dụ 7 ngày); điểm giảm dần theo số review trong ngày; mỗi người một review mỗi sản phẩm (đã có). |
| Bỏ qua 2 tiêu chí yếu nhất để số sao tổng của review cao hơn | Không chặn được hoàn toàn. Giới hạn 2 tiêu chí, không được bỏ "Đáng tiền"; điểm tiêu chí của sản phẩm không bị ảnh hưởng vì chỉ đọc tiêu chí đã chấm; phần "Đầy đủ" mất 10 điểm khi bỏ qua tiêu chí. |
| Người bán tự viết hoặc thuê viết | Trục B (xung đột lợi ích, tài trợ không công bố) đã có trong mô hình tin cậy. |
Kết luận: Máy mạnh, camera tốt cả ngày lẫn đêm, pin đủ một ngày dùng nhiều. Hợp người chụp ảnh và chơi game. Không hợp người cần sạc rất nhanh. Tóm tắt từ 128 review, cập nhật 31/10/2026
+"Hợp người chơi game và chụp đêm; ai cần sạc nhanh nên cân nhắc."
+Máy đẹp, giao nhanh, dùng mượt.
+| Giai đoạn | Việc | Cỡ | Cần database? |
|---|---|---|---|
| P0 | Sửa #1143 trên web: bỏ điểm tiêu chí suy ra, trả null, "Chưa đủ dữ liệu", bỏ chúng khỏi điểm ghép bảng xếp hạng, so kè 1v1 không tính tiêu chí trống, ẩn tiêu chí không thuộc ngành hàng, test và OpenAPI. Merge PR #1478. | S | Không |
| P1 | Danh sách tiêu chí theo ngành hàng trong shared-data (khoá, nhãn, trọng số, phiên bản) và bảng chuyển 5 khoá cũ. Web đọc danh sách này thay cho 5 khoá cố định. | M | Không |
| P2 | Migration DOS-Me: cột mới trên reviews và master_products, bảng review_points, product_points; hàm làm mới ghi điểm Bayes và điểm tiêu chí. Core soạn SQL đề xuất kèm file kiểm tra và hoàn tác; JOY chạy. | L | Có, JOY áp dụng |
| P3 | Form review bản 2 và RPC submit_community_review bản 2: sao theo tiêu chí, kết luận, ưu nhược bắt buộc, kiểm tra ở 4.2. | M | Sau P2 |
| P4 | Một con số điểm mọi nơi (#1470): mọi trang và API đọc rating_score. | S | Sau P2 |
| P5 | Gom ưu nhược: code (5.1) rồi AI (5.2), chạy trong importer theo đợt, ghi product_points; khối 7.1 trên trang sản phẩm. | M đến L | Sau P2 |
| P6 | Điểm giá trị review: tính, lưu, sắp review, nhãn bậc, hệ số đầy đủ trên trọng số đang lưu (6.2). Áp dụng mô hình sáu trục là việc riêng, không nằm trong P6. | M | Sau P2 |
| Sau | Điểm thưởng cho người viết (cần hệ thống điểm, thuộc DOS-Me); nhập review chuyên gia bên ngoài; AI trích ưu nhược từ review sàn. | L | Có |
P0 và P1 bắt đầu được ngay sau khi JOY duyệt. P3 đến P6 chờ P2.
+ +master_products (phương án 2 của PR #1478), điểm chuyên gia hiện riêng có nhãn, điểm ghép chỉ dùng để phá hoà.
+