Repository navigation
Conversation
…tch (#1537) * chore(deps): patch minimatch 10.x in the lockfile, with glob 14 to match (#1536) minimatch 10.2.6 sits in a ReDoS advisory range (patched in 11.0.1); an override moves it to 11.0.3. glob 13.0.6, used by @sentry/bundler-plugins to find source maps, matches nothing with minimatch 11, so glob 13 moves to 14.0.3, which depends on minimatch 11 and is outside glob's own advisory. The lockfile has no follow-redirects. minimatch 3.1.5 from ESLint 9 has no patched 3.x and stays. * chore(deps): move the fast-uri override to 3.1.9 (#1536) fast-uri 3.1.8 is inside a newer advisory range (<3.1.9). After this, pnpm audit lists only minimatch 3.1.5 from ESLint 9, which has no patched 3.x. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ener (#1541) * fix(normalizer): hp folio laptops keep a key despite the accessory opener isAccessoryTitle read "Folio" as a folio case, so a title such as "Folio 13 HP Core i5 8GB" got an unkeyed key. A line word that is also an accessory word now names the device when a model number follows it, the title names the line's brand (HP) and no fit word ("cho", "for") or other accessory word (case, sleeve, bao da) follows. Folio cases for iPad or Samsung, and "Folio 13 cho HP", stay accessories. Closes #1539 * fix(normalizer): read only the word after the hp brand for folio titles Review of #1541. The first version scanned the whole title after the line word for accessory and fit words, so a laptop's own text ("bàn phím có đèn", "cho sinh viên") unkeyed it, while diacritic-less accessories ("op lung", "tui chong soc") got a key. Now HP must come right after the Folio model (13, 1040 G3, G1), and only the word right after the brand is checked against the accessory openers, laptop accessories (sleeve, adapter, túi) and fit words (cho, for, tương thích). Promo words before the line ("Combo", "Hàng chính hãng") are read as ACCESSORY_OPENER reads them. Refs #1539 * fix(normalizer): catch diacritic-less and dashed accessories after folio hp Codex round 2 on #1541. "Folio 13 HP sac 45W" and "Folio 13 HP ban phim US" got a key, and a dash or bracket before the accessory ("Folio 13 HP - sleeve") hid it. The word after the brand is now read past punctuation, and sac, cap and ban phim join the laptop accessory list. "cho" leaves it, so "Folio 13 HP cho sinh viên Core i5" keeps a key. Refs #1539 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…w value (#1533) * docs(proposals): design weighted criteria stars, pros and cons, review value Design proposal for #1531, for JOY to decide. Per-category rating criteria with weights live in shared-data; a Rate review's star is the weighted average of its criteria; pros, cons and a verdict are mandatory for Rate reviews and optional for imported ones; product pros and cons are clustered by code, then reworded by AI; a 0-100 review value score sorts reviews and lifts a complete review's weight by at most 25%. It also resolves #1143 (no derived criterion scores) and the headline question of #1470 (one Bayesian rating, stored by DOS-Me). Proposal only: no code, no SQL, no data changes. Refs #1531 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…imal (#1478) * ux(web): versus scores and battle cards show the product's own rating #1470 (part): the versus scoreboard showed 4.98 and 5.00 while the comparison matrix on the same page showed 5.0 and 5.0, and called a leader on a 0.02 gap. - The versus scoreboard's base score is the product's stored buyer rating (userScore5), the one the matrix, cards and compare show, instead of the leaderboard composite; persona weights still blend in the criteria. - Scores, the verdict and the tie read at one decimal, like the matrix: 5.0 against 5.0 is a tie. - Home and compare battle cards show that rating at one decimal. The product page's headline stays the Bayesian estimate (#1144); whether lists and versus should show it too is open on #1470. Refs #1470 * fix(web): versus keeps the composite for models with no buyer rating Review of #1478: a model with no buyer rating falls back to its composite instead of scoring 0; the gap, the leading note and the JSON export read at one decimal, from the scores as shown; battle cards go back to the composite they are ranked and paired by. Refs #1470 * Merge remote-tracking branch 'origin/dev' into ux/one-rating Resolve VersusInteractiveScoreboard against #1534: the scoreboard uses StarRating at its default one decimal for the product's stored buyer rating, and the summary line reads at one decimal. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…orm rules (#1548) * feat(shared-data): per-category rating criteria, weights and review form 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 * fix(shared-data): harden rating criteria and review text rules after 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 * fix(shared-data): match dodging cons word by word with their own diacritics 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>
) * fix(web): versus api ties at one decimal and unrated pairs say so #1545 (the part that needs no new column): - /api/v1/rate/versus decides is_tie and the winner on the /10 scores as the response shows them, at one decimal; the composite and then the lower price only break a tie. Before, a 2-decimal gap or a composite gap named a leader for scores shown equal. - The scoreboard summary and the verdict say "no rating yet" instead of "0.0" when a model has no score, like the stars. Refs #1545 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tars (#1550) * fix(web): per-criterion scores are real or null, never derived from stars (#1143) computeJReviewsCriteriaScores added a spec and price delta to the star rating, so every product rated about 4.85+ scored 5.00 on each criterion, rankings tied and "#1 Màn hình" chips were invented. A criterion now reads only its stored score and is null otherwise; earbuds have no screen criterion. - Leaderboard: null criteria leave the composite; a criterion tab lists only scored products and shows "Chưa đủ dữ liệu"; no screen tab for earbuds. - Rank chips: a criterion ranks among scored products only, and needs two. - Versus API and scoreboard: weights apply to criteria both sides have, else the main score; a criterion without data on both sides has null scores and no winner. The API adds custom_weighted_basis and compared_criteria; OpenAPI documents the nulls. - Deals personas lean on a criterion only when it has a score. Implements D4 of the #1531 design. * fix(web): weighted ranks list scored products only; earbuds drop screen (#1143 review) - A custom-weighted leaderboard no longer ranks a product by its combined score when it has no score on the weighted criteria, and a persona never brings back a product the active criterion tab has no score for. - Only the category's own criteria weights count, so a screen weight left from phones does not empty the earbuds list; the screen slider is hidden. - Switching to earbuds, or a URL with criterion=screen, opens the combined tab. - Criterion blocks say the scores come from experts; empty bars are hidden. - The versus API lists only the category's criteria, and the OpenAPI note on null scores is exact. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… (p2) (#1549) * docs(proposals): dos-me migration for criteria ratings, pros and cons (p2) Phase P2 of #1531 (D2, D3, D9, D10), for JOY to review and apply through DOS-Me; nothing is applied from DOS/Rate. New review columns (exact star, verdict, criteria version, value score), rate.review_points and rate.product_points with RLS, and the master columns rating_score (Bayesian, k 3, mu 4.2), rating_weight_sum and criteria_scores (D9 thresholds). The live refresh_master_product_rating is renamed to a base and wrapped, so every caller also runs the new extras function. Verify and rollback files, and a Docker replay in CI that applies it on the reference stack and after M0 and M1+M2. Refs #1543 * fix(proposals): keep criteria ratings current with triggers, not a wrapper Review of #1549. Renaming refresh_master_product_rating to a base and wrapping it broke when M1+M2 or its rollback replaced the function, and the Item path (refresh_item_rating, votes) bypassed it. The migration now replaces no function: triggers on reviews, review_flags and master_products refresh the new columns, scoped like the live refresh (per master, or the whole Item once M1+M2 is in). The schema change and the backfill commit separately; criteria keys must look like the shared-data keys; V3 checks PUBLIC and authenticated too, V4 the triggers, and V6 recomputes every master. The replay applies it before and after M1+M2 and through the M1+M2 rollback. Refs #1543 * fix(proposals): no sibling deadlock and no-variant listings in criteria ratings Round 2 review of #1549. Variants of an Item are written in id order with SKIP LOCKED, as refresh_item_rating does, so two refreshes of sibling variants never deadlock. Triggers resolve masters from listings, so a review on an Item listing with no variant refreshes the Item, and each Item is refreshed once per statement. Only changed rating inputs fire a refresh. The CHECKs are added NOT VALID and validated in the backfill transaction; V1 covers product_points. The replay adds a no-variant review, an unchanged rewrite and its delete; the runbook lists bulk flag imports, concurrent writers and listing deletes as known limits. Refs #1543 * chore(git): track the criteria ratings proposal sql files The Secret scan job refuses tracked files that match .gitignore. The three P2 proposal files get the same named exceptions as the earlier DOS-Me proposals. Refs #1543 * fix(proposals): store rating_score at three decimals so pages round once The web rounded the stored 2-decimal score again for display, so 4.249 showed 4.3. rating_score is numeric(4,3) and the criterion scores keep 3 decimals too; pages round once, to 1 decimal. Replay expectations follow. Refs #1543 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
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.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the
|
There was a problem hiding this comment.
⏱️ Code Review completed (32 eligible files · 232,117 chars · 2 model call(s) · 8 PR unit(s))
Whole diff with bounded context at base 4aae9ad / head 1a9cd84.
Excluded by noise policy: pnpm-lock.yaml.
✅ CLEAN_PASS: Complete diff reviewed
Context investigation was bounded to the explicitly requested snapshot paths.
🔒 Dependency check
✅ Passed. Every new package version comes from the public registry or a source this lockfile already used for it, its checksum is pinned where the format records one, and OSV lists no new malicious package or high or critical vulnerability for the versions it was asked about.
Changed packages (5)
| Package | From | To | Lockfile |
|---|---|---|---|
@isaacs/nonrecursive-glob-match |
new | 1.0.3 |
pnpm-lock.yaml |
fast-uri |
3.1.8 |
3.1.9 |
pnpm-lock.yaml |
glob |
13.0.6 |
14.0.3 |
pnpm-lock.yaml |
minimatch |
10.2.6 |
11.0.3 |
pnpm-lock.yaml |
path-scurry |
2.0.2 |
3.0.0 |
pnpm-lock.yaml |
Promote dev to main.
Merge with a merge commit, never squash (Docs/Resources/RELEASE.md).
📌 TL;DR
This PR introduces the database schema proposal (Phase P2) for the new criteria-based rating system, including SQL migrations for new tables (
review_points,product_points) and columns for Bayesian rating scores. It also adds the comprehensive design documentation, verification scripts, and CI replay tests to validate the migration logic against the existing M1/M4 Item RPCs.🎯 Type of Change
🔍 Changes Walkthrough
.github/workflows/ci.ymlscripts/test-criteria-ratings-proposal.mjs, ensuring the proposed migration is replayed and validated in Docker before any production application..gitignoreDocs/Proposals/2026-10-31-criteria-stars-pros-cons.htmlDocs/Proposals/2026-10-31-dos-me-criteria-ratings.mdDocs/Proposals/2026-10-31-dos-me-criteria-ratings.sqlreview_points,product_points), adds columns toreviewsandmaster_products, and implements functions/triggers to maintain Bayesian rating scores.Docs/Proposals/2026-10-31-dos-me-criteria-ratings-rollback.sqlDocs/Proposals/2026-10-31-dos-me-criteria-ratings-verify.sql📊 Architectural Flow
flowchart TD subgraph "CI Pipeline" A[GitHub Actions] --> B[Run test-criteria-ratings-proposal.mjs] end subgraph "Docker Replay Stack" B --> C[Apply Migration SQL] C --> D[Run Verify SQL] D --> E{Checks Pass?} E -- No --> F[Fail CI] E -- Yes --> G[Apply Rollback SQL] G --> H[Verify Rollback] end subgraph "Production Database (Future)" I[rate.reviews] -->|Triggers| J[rate.master_rating_extras] K[rate.review_flags] -->|Triggers| J J -->|Updates| L[rate.master_products] L -->|Stores| M[rating_score & criteria_scores] end