# Ratings and Reviews

## Objective

Show real customer opinion on an item instead of asking buyers to take your word.

A star rating and written review per item, with a stored aggregate shown alongside the item and a moderation step before publication.

## Before You Begin

This feature is being added to an application that already exists and already
works. Do not scaffold a new project, and do not assume a blank slate.

Inspect the codebase first and establish:

- The existing application structure and where code of this kind already lives.
- The framework and version in use.
- The existing design system — colours, spacing, typography, and component conventions.
- Existing UI components you can reuse instead of writing new ones.
- The existing database structure, if this feature needs to persist anything.
- The existing authentication and authorization system, if this feature is user-scoped.
- Dependencies already installed, so you don't add a library that duplicates one.
- The existing test setup and conventions.

Only start writing code once you understand the above. If the application
already implements part of this feature, extend it rather than replacing it.

## Implementation Instructions

1. Show the aggregate where the item appears: an average, a count, and a breakdown by star level. Read that from a stored aggregate on the item, updated as reviews change, not from an aggregate query over the review table on every page render.
2. Decide who is allowed to review and enforce it server-side. Restricting reviews to verified purchasers is the single change that most improves trust and most reduces spam.
3. Route new reviews through the app's existing Moderation Queue and reuse AI Text Content Moderation if it is present, rather than adding a second approval inbox. Do not build a parallel review-approval screen.
4. Wire the existing Content Reporting feature to reviews so a published review can be flagged by other users, and give the item owner a single public reply per review rather than an open thread.
5. Do not let the owner delete or hide individual bad reviews. A review system the owner can curate is worthless to the reader, and shows up as a suspiciously perfect average.

## UI and UX Requirements

Match the application's existing design system exactly. Reuse its components,
spacing, and typography. This feature should look like it was always there.

## Responsive Requirements

Works on mobile, tablet, and desktop. Touch targets are large enough to hit on a
phone, and nothing overflows horizontally at 320px.

## Accessibility Requirements

- Fully keyboard navigable.
- Correct semantic elements and ARIA roles.
- Visible focus states.
- Meets WCAG AA contrast.
- Dynamic changes are announced to screen readers.
- Respects prefers-reduced-motion.

## Edge Cases

- Recomputing an average by scanning every review on each write will be fine at ten reviews and will time out at fifty thousand. Keep a running count and sum on the item and update them transactionally with the review.
- The same buyer must not be able to leave a second review on the same item. Enforce it with a uniqueness constraint in the database, not just a check in the controller, or concurrent submissions will slip through.
- New reviews must not appear publicly until they have passed moderation, and the author must still see their own pending review so they do not submit it again.
- When an author deletes their account or is anonymised, the review text should survive with the byline replaced. Cascading the delete silently removes evidence and changes the average.
- Editing a review from four stars to one, or deleting it, must adjust the stored aggregate by exactly that difference. A drift bug here is invisible until the displayed average stops matching the reviews on screen.
- An item with one five-star review must not be presented as better than an item with four hundred reviews averaging 4.6. Show the count wherever the average is shown.
- Review bodies accept pasted markup, links, and contact details. Escape on output and strip links from unverified authors, or the reviews become an advertising channel.
- A rejected review needs a reason sent to the author. Silent rejection reads as a bug and gets resubmitted.

## Testing

Exercise the feature end to end in the running application. Cover every edge case
above, then run the existing test suite and confirm nothing regressed.

## Acceptance Criteria

- [ ] Each item shows an average, a total count, and a distribution across star levels.
- [ ] The aggregate is stored and updated incrementally, with no full scan of reviews on write.
- [ ] A second review from the same author on the same item is rejected by a database constraint.
- [ ] New reviews are held in the existing moderation queue and are invisible publicly until approved.
- [ ] Editing or deleting a review leaves the stored average and count exactly correct.
- [ ] Deleting an author's account preserves the review text with an anonymised byline.
- [ ] Owners can reply publicly to a review but cannot remove or hide one.
- [ ] The feature matches the existing design system.
- [ ] No existing functionality is broken.

## Adaptation Rules

- Match the existing design system. Do not introduce a new colour palette,
  spacing scale, or component library.
- Reuse existing components and utilities wherever they fit.
- Follow the naming, file layout, and code style already present.
- Do not upgrade, replace, or remove existing dependencies to make this
  feature fit. Adapt the feature to the app, not the app to the feature.
- Do not break existing functionality. If a change is genuinely required in
  existing code, make the smallest one that works and say so.
- If something in these instructions conflicts with how the application is
  built, follow the application and explain the deviation.

## Final Verification

Before you report the work as done:

1. Re-read the acceptance criteria above and check each one against what you
   actually built.
2. Run the application and exercise the feature end to end.
3. Run the existing test suite and confirm you have broken nothing.
4. Check the feature on mobile, tablet, and desktop widths.
5. Check keyboard navigation and focus handling.
6. Summarize what changed: files added, files modified, and anything you
   deliberately did differently because of how this application is built.

If any acceptance criterion is unmet, fix it before reporting completion.
