CouponsCouponExpiredPayload coupons.coupon.expired@1

Generated at from openvibe-contracts v0.34.2 and openvibe-sdk v0.5.0.

Version
1.0.0
Owner
coupons
Visibility
first-party
Status
active
Compatibility
backward
Schema
https://openvibe.network/contracts/events/payloads/coupons.coupon.expired.v1.json

coupons.coupon.expired v1 (OpenVibe.Coupons server/domain/coupons.js recompute, payload from lifecyclePayload). A code's status became expired, in the transaction that recorded it: the sweep (server/worker.js, every COUPONS_SWEEP_INTERVAL_MS) saw its known expiry pass (reason expiry), a recompute for other work found it past its expiry first (evidence, report or decay), or staff or a service marked it expired (staff, service:<client>[:<note>]). Active lists do not wait for this event: they filter on expires_at at query time. When the code was in Search, a coupons.index_document.deleted tombstone and the merchant's updated document follow in the same transaction. Envelope: subject { type: coupon, id: cpn_… }, visibility public when the code was publicly listed before the change, otherwise internal, priority important (not set: the Events default), actor service:coupons. No known consumers.

Fields

FieldTypeRequiredDescriptionConstraints
merchant_idstringyesThe merchant the code belongs to.
  • pattern ^mer_[0-9A-HJKMNP-TV-Z]{26}$
statusconstyes
  • = "expired"
confidencenumber | nullyesReport confidence at the time (rounded to 2 decimals); null = no counted report in the last 30 days.
  • minimum 0
  • maximum 1
review_stateenumyes
  • one of "pending", "published"
expires_atstring | nullyesThe known expiry that passed; null when staff or a service marked a code of unknown expiry expired.
  • format date-time
canonical_urlstringyesThe code's page on Coupons (<origin>/c/<coupon id>); it stays up, noindex.
  • pattern ^https?://
  • format uri
  • maxLength 2048
previous_statusenumyesStatus before; a disabled code has to be re-enabled before it can be marked expired.
  • one of "unknown", "reported_working", "reported_failed"
reasonone ofyesexpiry, evidence, report, decay, staff, or service:<client>[:<note>].

Examples

From the contract's own test fixtures: valid ones validate, rejected ones must fail.

Valid: staff-marked
{
  "merchant_id": "mer_01K5R7A1B2C3D4E5F6G7H8J9KM",
  "status": "expired",
  "confidence": 0.71,
  "review_state": "published",
  "expires_at": null,
  "canonical_url": "https://openvibe.coupons/c/cpn_01K5R8Z3Q4M2N7P9T1V6W8X0YA",
  "previous_status": "reported_working",
  "reason": "staff"
}
Valid: sweep
{
  "merchant_id": "mer_01K5R7A1B2C3D4E5F6G7H8J9KM",
  "status": "expired",
  "confidence": null,
  "review_state": "published",
  "expires_at": "2026-09-22T23:59:59.999Z",
  "canonical_url": "https://openvibe.coupons/c/cpn_01K5R8Z3Q4M2N7P9T1V6W8X0YA",
  "previous_status": "unknown",
  "reason": "expiry"
}
Rejected: from-disabled
{
  "merchant_id": "mer_01K5R7A1B2C3D4E5F6G7H8J9KM",
  "status": "expired",
  "confidence": null,
  "review_state": "published",
  "expires_at": "2026-09-22T23:59:59.999Z",
  "canonical_url": "https://openvibe.coupons/c/cpn_01K5R8Z3Q4M2N7P9T1V6W8X0YA",
  "previous_status": "disabled",
  "reason": "expiry"
}
Rejected: missing-previous-status
{
  "merchant_id": "mer_01K5R7A1B2C3D4E5F6G7H8J9KM",
  "status": "expired",
  "confidence": null,
  "review_state": "published",
  "expires_at": "2026-09-22T23:59:59.999Z",
  "canonical_url": "https://openvibe.coupons/c/cpn_01K5R8Z3Q4M2N7P9T1V6W8X0YA",
  "reason": "expiry"
}
Rejected: wrong-status
{
  "merchant_id": "mer_01K5R7A1B2C3D4E5F6G7H8J9KM",
  "status": "disabled",
  "confidence": null,
  "review_state": "published",
  "expires_at": "2026-09-22T23:59:59.999Z",
  "canonical_url": "https://openvibe.coupons/c/cpn_01K5R8Z3Q4M2N7P9T1V6W8X0YA",
  "previous_status": "unknown",
  "reason": "expiry"
}

Validate

const contracts = require('openvibe-contracts');
contracts.validate('coupons.coupon.expired@1', value);   // { valid, errors: [{ path, message }] }