Skip to content

feat(shared-data): per-category rating criteria, weights and review form rules - #1548

Merged
JOY (JOY) merged 3 commits into
devfrom
feat/1542-rating-criteria
Oct 31, 2026
Merged

JOY (JOY) merged 3 commits into
devfrom
feat/1542-rating-criteria

Conversation

@JOY

@JOY JOY (JOY) commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

Closes #1542

Phase P1 of the #1531 design (Docs/Proposals/2026-10-31-criteria-stars-pros-cons.html, sections 2.1, 2.2, 4.1, 4.2). JOY approved decisions D1 and D5 on 2026-10-31.

Change (packages/shared-data/src/rules/)

  • rating-criteria.ts
    • RATING_CRITERIA_VERSION = 1.
    • Criteria lists for smartphones, tablets, laptops, smartwatches, earbuds and services, as in design 2.1. Each criterion has a key, a vi/en label, a weight (each category sums to 100), the related spec group and a required flag. The required criterion is value for products and price for services.
    • getRatingCriteria(slug): an unknown or missing category rates as a phone.
    • weightedReviewStar(slug, ratings): the weighted average over the rated criteria, at 0.1. Unknown keys and bad stars are ignored; it returns null when nothing valid is rated.
    • validateCriteriaRatings(slug, ratings) follows D5. It flags:
      • unknown keys;
      • stars outside 1 to 5 in half steps;
      • a missing required criterion;
      • more than 2 skipped criteria.
    • mapLegacyCriteriaRatings(slug, legacy) maps the five legacy form keys (screen, performance, camera, battery, value) per category. For earbuds, screen becomes sound and camera becomes anc, matching the labels the product page uses today. A key with no counterpart is dropped, and nothing is inferred.
  • review-form.ts holds the D5 text rules:
    • a verdict of 20 to 300 characters;
    • 1 to 5 pros and 1 to 5 cons, each 5 to 150 characters;
    • evasive cons ("không có", "chưa thấy", "không có gì để chê", "ko co", "none") are rejected, while real cons such as "Không có củ sạc trong hộp" pass;
    • duplicate lines and a line given as both a pro and a con are rejected.
    • Lines are compared without diacritics or punctuation. The stored text is not touched.
  • Both modules are exported from @repo/shared-data/rules. They are browser-safe: they import only each other.

Not in this PR

Notes

  • The earbuds legacy mapping (screen to sound, camera to anc) follows the product page labels (critSoundstage, critAncMic). The issue text said "camera to sound". The old write form showed phone labels for every category, so any mapping is a best guess.
  • Legacy stars that have no counterpart are dropped: camera on tablets and laptops, performance and camera on watches, performance on earbuds. A mapped legacy review may rate fewer criteria than validateCriteriaRatings asks of a new review. That check is for new writes only.
  • The constant is named RATING_CRITERIA_VERSION. The issue called it CRITERIA_VERSION.
  • The modules are exported from @repo/shared-data/rules only, which is the browser-safe entry, and not from the root.
  • hasRatingCriteria(slug) lets an API refuse a category that has no list instead of rating it as a phone.

Tests

packages/shared-data test step 11 covers:

  • weights sum to 100, unique keys, both labels, one required criterion;
  • weighted star math, including skipped criteria, legacy 0.1-step stars and ignored bad input;
  • every D5 criteria issue, with null counted as skipped;
  • prototype keys used as a slug or a rating;
  • the legacy mapping;
  • the verdict and pros/cons rules: no-content lines, lengths in code points, diacritics kept when comparing, malformed bodies;
  • 40+ dodging and real cons;
  • a linear-time guard on an oversized con.

npm test in packages/shared-data passes (tsc and the suite), and prettier is clean.

Review

Codex is not available in this session, so two independent fresh-context reviews ran in its place, followed by a round-2 review.

  • Round 1 (890d2d0):
    • prototype-key slugs crashed;
    • legacy 0.1 stars were dropped;
    • null stars counted as bad stars;
    • many dodging cons were missed;
    • zero-width and fullwidth characters slipped through;
    • lengths were counted in UTF-16 units;
    • punctuation-only pros and verdicts passed;
    • stripping diacritics caused false pro_and_con hits.
  • Round 2 (d0e6694):
    • a quadratic regex on oversized cons;
    • real cons read as dodges once diacritics were stripped ("hỏng luôn", "mọi thứ đều ồn");
    • more dodges ("mình không thấy gì để chê", "không có ý kiến").
  • All P1 and P2 findings are fixed.

🤖 Generated with Claude Code

…orm rules

Phase P1 of the #1531 design (D1, D5). rules/rating-criteria.ts holds
version 1 of the criteria lists and weights for smartphones, tablets,
laptops, smartwatches, earbuds and services, the weighted review star
at 0.1, the D5 check on criterion stars (half steps, at most two
skipped, value or price never) and the map from the five legacy form
keys. rules/review-form.ts holds the D5 text rules: verdict length, one
to five pros and cons, line length, evasive cons, duplicates and a line
given as both. No database change; wiring the web form is P3.

Closes #1542

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Code review skipped — your organization has no extra usage available to pay for this review.

If your organization's extra usage balance is empty, an organization admin can add extra usage credits at claude.ai/admin-settings/usage. If its monthly spend limit was reached, an admin can raise it on the same page. If neither applies, contact Anthropic support.

Once extra usage is available, someone with write access to this repository can comment @claude review on this pull request to trigger a review.

@vercel

vercel Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
rate Ready Ready Preview Oct 31, 2026 1:39pm UTC

Request Review

@github-actions github-actions Bot added the area:shared Shared packages / contracts / configs label Oct 31, 2026
@coderabbitai

coderabbitai Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 46 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 16e00ceb-2616-4df8-896e-6d72abc804a4
Commits

Reviewing files that changed from the base of the PR and between 76a033e and d0e6694.

Files selected for processing: 4
  • packages/shared-data/src/__tests__/shared-data.test.ts
  • packages/shared-data/src/rules/index.ts
  • packages/shared-data/src/rules/rating-criteria.ts
  • packages/shared-data/src/rules/review-form.ts
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

dos[bot]
dos Bot approved these changes Oct 31, 2026

@dos dos Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⏱️ Code Review completed (4 eligible files · 21,143 chars · 1 model call(s) · 1 PR unit(s))

Whole diff with bounded context at base 76a033e / head dd417c5.

✅ CLEAN_PASS: Complete diff reviewed

…review

Two reviews of #1548. Prototype keys ("toString", "__proto__") no
longer reach Object.prototype as a category or a rating; null is a
skipped criterion; the weighted star counts any stored star from 1 to
5, so legacy 0.1-step stars are kept; hasRatingCriteria tells a known
category from the phone fallback. The text rules count characters as
the writer sees them (NFKC, no zero-width characters), reject lines
with no words or one repeated character, keep diacritics when comparing
lines, never throw on a malformed body, and catch more dodging cons
("không có ạ", "chả có gì", "không chê được gì", "mọi thứ đều ổn").

Refs #1542

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dos[bot]
dos Bot approved these changes Oct 31, 2026

@dos dos Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⏱️ Code Review completed (4 eligible files · 27,815 chars · 1 model call(s) · 1 PR unit(s))

Whole diff with bounded context at base 76a033e / head 890d2d0.

✅ CLEAN_PASS: Complete diff reviewed

…ritics

Round 2 review of #1548. Stripping diacritics made "hỏng luôn",
"không gập", "chưa có lời" and "mọi thứ đều ồn" read as dodges. Each
dodge word now matches as typed with its own diacritics or with none,
never with other ones. A pronoun may lead ("mình không thấy gì để
chê"), and "không có ý kiến", "không có gì để nói", "rất tốt" count.
A con longer than 150 characters is never a dodge, which keeps the
check linear on an oversized request.

Refs #1542

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dos[bot]
dos Bot approved these changes Oct 31, 2026

@dos dos Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⏱️ Code Review completed (4 eligible files · 29,667 chars · 1 model call(s) · 1 PR unit(s))

Whole diff with bounded context at base 76a033e / head d0e6694.

✅ CLEAN_PASS: Complete diff reviewed

@JOY
JOY (JOY) merged commit 7840cc2 into dev Oct 31, 2026
18 checks passed
@JOY
JOY (JOY) deleted the feat/1542-rating-criteria branch October 31, 2026 13:46

This branch was successfully deployed

1 active deployment
Preview — d0e66941 Deployed Oct 31, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:shared Shared packages / contracts / configs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(shared-data): per-category rating criteria and weights v1

1 participant