Files
vmall/openspec/changes/add-membership-messaging/specs/messaging/spec.md
T

3.2 KiB

ADDED Requirements

Requirement: System event messages

An order payment success, a shipment dispatch, and a refund completion (including after-sale refunds) SHALL each create one system message for the customer who owns the order. Each message SHALL record its kind, a bilingual title and body ({en, zh}) naming the affected order, and the order (and refund) reference it was triggered by. Emission SHALL be idempotent per customer, kind, and reference, so re-running an event handler never writes a duplicate message.

Scenario: paying an order notifies the customer

  • WHEN a customer's order payment succeeds
  • THEN an order_paid message referencing that order appears in the customer's inbox

Scenario: dispatch notifies the customer

  • WHEN a shop marks a shipment of the customer's order as shipped
  • THEN an order_shipped message referencing that order appears in the customer's inbox

Scenario: refund completion notifies the customer

  • WHEN a refund for the customer's order completes
  • THEN a refund_completed message referencing that order and refund appears in the customer's inbox

Scenario: re-run event handler does not duplicate

  • WHEN the same event handler for the same order, kind, and reference runs twice
  • THEN exactly one message exists for that customer, kind, and reference

Requirement: User message state machine

A message SHALL belong to exactly one customer and move through unread and read states plus a soft deletion. Messages are created unread; marking one read or all read SHALL use a guarded update that touches only unread rows, so repeated marking never rewrites already-read rows. Deletion SHALL set a soft-delete marker rather than removing the row, SHALL be idempotent, and SHALL make the message invisible to listing and counting. Customers SHALL only ever read, mark, or delete their own messages.

Scenario: mark one message read

  • WHEN a customer marks their unread message read twice
  • THEN the message is read and only the first call changed its state

Scenario: mark all read touches only unread

  • WHEN a customer with three unread and two read messages marks all read
  • THEN exactly the three unread rows become read and the two read rows are untouched

Scenario: deleted messages disappear

  • WHEN a customer deletes a message
  • THEN it is absent from their list and unread count while its row remains for audit

Scenario: foreign messages are unreachable

  • WHEN a customer addresses another customer's message for read or delete
  • THEN the request fails without changing that message

Requirement: Unread count endpoint

An authenticated customer SHALL read their unread message count through a dedicated endpoint that excludes soft-deleted messages. The count SHALL reflect read, mark-all-read, and delete actions immediately and SHALL only ever count the requesting customer's messages.

Scenario: count drops after mark-all-read

  • WHEN a customer with four unread messages marks all read
  • THEN the unread count endpoint returns zero

Scenario: deleting an unread message drops the count

  • WHEN a customer deletes one of three unread messages
  • THEN the unread count endpoint returns two