Files
baya-monorepo/archive/docs/integration/domains/reviews.md
T
2026-08-02 20:01:31 +03:30

4.8 KiB

reviews — ratings, tags, moderation

Client seam client/src/services/reviews/ · USE_REVIEWS_MOCK = false (real) · 8 server ops Last verified: 2026-07-30 against commit d3ec723 and swagger.v1.json (2026-07-29).

Customer reviews of a completed booking, pre-screened and then human-moderated before they are public. Clinical care records are a different domain — patient-records.md.

Endpoints

Method Path Auth Verdict
GET /api/v1/bookings/{bookingId}/review_eligibility [Authorize] wired
GET /api/v1/bookings/{bookingId}/my_review [Authorize] wired
POST /api/v1/bookings/{bookingId}/review [Authorize] wired
GET /api/v1/nurses/{nurseProfileId}/reviews anonymous wired · paginated (page/pageSize)
GET /api/v1/nurses/{nurseProfileId}/review_tags anonymous unwired — the client reads tags off the review rows
PATCH /api/v1/reviews/{reviewId}/status [Authorize] wired — the moderation decision
POST /api/v1/reviews/{reviewId}/tags [Authorize] unwired — no console screen edits tags
GET /api/v1/admin/reviews/moderation_queue admin wired · paginated

No phantoms. Note PATCH — one of only two PATCH verbs in the whole API (the other is on partner-center.md); everything else mutates with POST. Note also the hardcoded nested admin/reviews/ route segment — see index.md.

Aggregates are recomputed, never incremented

averageRating, totalReviews and totalCompletedBookings on the nurse profile are recomputed from source whenever a review's moderation status changes. Hiding a published review must lower the average; an incrementing counter cannot do that correctly. Never += 1 a review aggregate. See profiles.md.

The moderation gate

submit ──AI pre-screen──▸ pending_moderation ──admin──▸ published
                                │                          │
                          banned word hit             unpublish ──▸ hidden
                                ▼
                            rejected
  • A review is not public on submit. IReviewModerationService pre-screens; by default clean text returns a human-review flag, keeping the gate on. Seams:ReviewModeration:AutoApproveClean makes clean text auto-publish; BannedWords (default scam, fraud, کلاهبردار) forces reject. Both are mock knobs — a real classifier ignores them.
  • A low rating raises a support alert (low_rating), linked as lowRatingAlertId on the queue item. See admin.md.
  • unpublish is a distinct action from hide in the client's ModerationAction union even though both land on hidden — the audit trail records which was chosen.

Shape rules the JSON does not express

  • ReviewEligibilityDto is { canReview, reason } and the reason is a code, not a message: not_completed already_reviewed not_owner not_found. The client maps it to an i18n key. Eligibility is server-decided — the client must not infer it from booking status.
  • The author is masked (REQ-026, confirmed): a public review carries authorMasked, never a full name. This is a privacy decision, not a display choice.
  • tagCodes is on ModerationQueueItemDto (REQ-037, delivered) so the queue shows what the reviewer tagged without a second fetch.
  • Review tags are codes; labels are i18n keys. Never render a tag code, and never build a display string from one.
  • moderationReason is admin-facing free text and is not returned on the public review read.
  • The public reviews list is anonymous and paginated with page/pageSize (camelCase — unlike search/nurses, which uses page_size). See ../api-contract.md.

Enums

Vocabulary Values
ModerationStatus pending_moderation published hidden rejected
ModerationAction publish hide reject unpublish
ReviewIneligibilityReason not_completed already_reviewed not_owner not_found

ModerationStatus and ModerationAction are both defined in Entities/Reviews/ReviewModerationStatus.cs and verified identical to the client's unions — the file carries the four states and the four actions together.

Open REQs

REQ Status Effect
REQ-026 delivered Eligibility + my-review-for-booking reads, and masked-author confirmation
REQ-037 delivered tagCodes on the moderation queue item
REQ-040 open No topReviewTag on the search index row — the C2 card renders without the tag chip. Owned by search.md