Repository navigation
Closed
Labels
urgentGood for newcomersGood for newcomers
Description
Issue 4 — Reviews and the notification bus
Summary
One event bus. First consumers: review after a done lesson, note sold, lesson tomorrow, admin fee unpaid. A review is one score and one comment on the tutor card. No public reply thread.
The bus accepts later event names. It does not send Discord invites, Telegram links, or a weekly digest.
Depends on
- Issue 1 for fees and intro lessons.
- Issue 2 for delivered note orders only. View and save stay on listing counters.
- Issue 3 for lesson-tomorrow and later done lessons.
Fee digest and reviews can ship before the calendar.
Scope
In:
- Event table and a worker.
- Channels: in-app inbox and email. WhatsApp is an interface only. Do not block on the Business API.
- One visible review per case.
- Admin hide / restore.
- Concierge unpaid digest.
- Note-sold notice with no buyer contact.
- Accepted, unconsumed names: listing.viewed, listing.saved, entitlement.granted.
Out:
- A message broker or dead-letter queue.
- Push, SMS, marketing blasts.
- Tutor public replies.
- Centre reviews, ranking formula, community access.
- Weekly creator digest.
Events consumed
- lesson.done → parent review prompt after 2 hours, only if no review exists for this lesson
- lesson.reminder_due → parent and tutor, day before 18:00 HKT
- admin_fee.unpaid → concierge daily digest of fees invoiced more than 3 days ago; parent reminder on day 3 and day 7
- note_order.delivered → tutor: title, gross, net; no buyer name
- review.published → tutor: score and card link; no parent name
Stored as skipped, no message:
- listing.viewed
- listing.saved
- entitlement.granted, payload account_id, entitlement_key, source_order_id
Unknown types are stored as failed, not dropped.
Sending is idempotent on event id + channel. Retries 3, then failed. No broker.
Entitlement table, no UI: account_id, key, granted_at, source.
Review rules
- Review is allowed only if this parent has a done lesson on that case.
- Score 1–5. Comment 20–600 characters.
- One visible review per case. A new review after 30 days replaces the public one. The old row stays in admin.
- Card shows average, count, and latest 5. Name format: “Parent of G11 IB Physics”.
- Hidden reviews are excluded from the average and the public count.
- A comment containing a phone, email, or WhatsApp is held, not published.
- A note buyer with no case cannot review.
- Zero reviews displays “New tutor”, not 0.0.
Acceptance
- Marking done creates one prompt, not one per refresh.
- A hidden review leaves the card and the average within a minute.
- Note-sold notification has no buyer contact.
- Unpaid digest matches the Issue 1 queue.
- Email off still leaves the in-app item.
- listing.viewed, listing.saved, and entitlement.granted are stored as skipped.
- No code path creates a Discord or Telegram link.
Edge cases
- Admin reverts a mistaken done: unsent prompt is skipped; a sent review can be hidden.
- No backfill prompts for imported lessons. Only lessons marked done after this ships.
Metadata
Metadata
Assignees
Labels
urgentGood for newcomersGood for newcomers
Activity
fix(#387): Ryan's merge-day calls — parent notification leg, waived-f…
feat(#387): Tutor Verified Experience Log — lessons/hours/tenure on c…