Files
baya-monorepo/archive/build-chain/working-context/backend/handoff/after-backend-phase-14.md
T
2026-08-02 18:48:32 +03:30

4.5 KiB
Raw Blame History

Handoff — after backend-phase-14 (Reviews, ratings & patient care records)

The trust loop and the continuity-of-care loop are live. A customer leaves one moderated review per completed booking; an admin/moderator publishes/hides/rejects it; the nurse's public rating is recomputed from source on every transition (so hiding a 1-star lowers the count and re-derives the average — no inflated-after-hide drift); low ratings auto-raise an internal support_alert; and nurses author encrypted, patient-scoped clinical notes readable only under a strict clinical-access rule.

What the frontend (f13-b14) can now build

  • Leave a reviewPOST bookings/{bookingId}/review { rating 15, body?, tagCodes? } (customer who owns a completed booking). Returns { id, moderationStatus: "pending_moderation", lowRatingAlertRaised }. The review is not public until an admin publishes it — build the "submitted, awaiting moderation" state.
  • Public nurse reviewsGET nurses/{nurseProfileId}/reviews?page=&pageSize={ aggregate: { averageRating, publishedCount }, reviews: PagedResult<{ id, rating, body, tagCodes[], createdAt }> }. Published only.
  • Public tag rollupGET nurses/{nurseProfileId}/review_tags{ publishedReviewCount, tags: [{ code, labelFa, labelEn, count, percentage }] } ("% punctual"). The seeded vocab (punctual/professional/clean/kind/ communicative) is always returned.
  • Tag your own reviewPOST reviews/{reviewId}/tags { tagCodes } (author or moderator; replaces the set).
  • Admin moderation consoleGET admin/reviews/moderation_queue?status=&page=&pageSize= (default pending_moderation; each row carries the linked lowRatingAlertId for triage) and PATCH reviews/{reviewId}/status { action: publish|hide|reject|unpublish, reason? } (hide/reject need a reason). The PATCH returns the recomputed { averageRating, totalReviews }.
  • Patient care recordsPOST patients/{patientId}/care_records { bookingId?, body } (nurse with a confirmed booking) and GET patients/{patientId}/care_records?page=&pageSize= (owning customer / nurse with a confirmed booking / admin) → decrypted { id, patientId, bookingId, nurseProfileId, nurseName, body, recordedAt } newest first. The history is patient-scoped — a new nurse taking over reads the whole history.

Contracts

  • dev/contracts/domains/reviews-records.md — all 8 endpoints, the moderationStatus/action enums, tag codes, DTO shapes, and the care-record access matrix.
  • dev/contracts/openapi/swagger.v1.json refreshed — the 8 review/care-record paths are in the snapshot.

What is mocked (and how it becomes real)

  • IReviewModerationService (new) — AI review pre-screen. MockReviewModerationService is a keyword filter: clean text → a human-review Flag by default (so the publish gate holds — reviews land pending_moderation); a banned-word substring → Reject (auto-hidden). Config Seams:ReviewModeration:{AutoApproveClean,BannedWords}. Make it real → a text classifier / LLM endpoint (see reports/mocks-registry.md). ModerateReviewCommand keeps decision authority + the human override, so the real impl never touches the handler.

Load-bearing rules (don't regress)

  • Recompute from source, not delta — every publish/hide/reject/unpublish re-derives average_rating/ total_reviews over currently-published reviews (exclude-the-changed-review then fold in its new status), in the same transaction, then refreshes the search index.
  • Publish gatepending_moderation/hidden/rejected are never in a public read and never counted.
  • 1:1 per completed bookingUNIQUE(booking_id) + handler pre-check; cross-tenant is a 404.
  • Low rating (≤ config min_rating_for_support_alert, default 2) raises an internal low_rating alert — internal-only, never in a user response (only its id shows on the admin queue).
  • Care records are patient-scoped, encrypted at rest, strict access — a nurse without a confirmed booking for the patient is denied read + write.

Deferred (flagged, not built)

  • Two-way (nurse-reviews-customer) double-blind reviews with timed reveal.
  • First-class incidents entity + ML fraud scoring (manual suspension + support_alerts cover it now).
  • The ticket system, partner centers, and the admin support-alert worklist consoleb15 (this phase only raises alerts).
  • SuspendNurse / ResolveSupportAlert / FlagConcern admin actions → b15.