Module Reference

Membership

Loyalty points, member tiers, prepaid packages and redemptions, kept for each customer across every way they buy.

Membership runs a loyalty program: points earned on sales, member tiers that can multiply those points, packages a customer pays for up front (ten massages, say) and redeems over time, and messages telling members what they earned or lost. It keys everything on the customer's platform identity, so one person has one balance wherever they buy. POS, Storefront, Booking and Account add to it when they're on. Customer profiles, consent and duplicate review belong to Customers, not Membership. With Customers on, Membership adds a panel to each customer's page and asks Customers for consent before sending a points message.

What it handles

  • Points that expire in the right order. Expiry uses up awards oldest first, so points already redeemed never expire a second time. A reversed redemption gives its points back to the award they came from, and they expire with it. Tested: "Membership: loyalty settings"
  • Tiers and multipliers. A tier can multiply the points a member earns (Gold earning double, say). A customer's first sale enrols them once, even when the sale is retried or several land at once. A paused member keeps their tier but earns the base rate, and someone who left isn't enrolled again by their next sale. Only staff with rewards:write can pause a member. Tested: "Membership: member tiers"
  • One person, two records. When a customer's login is merged into the guest record they bought under, points count as one balance on the record that survives. A redemption larger than the combined balance is refused and spends nothing, and expiry never drives either record below zero. Tested: "Rewards: merged identities"
  • Packages valid at some branches only. A package sold for one branch can't be redeemed at another, or with no branch given at all, and an accepted redemption records where it happened. A package can't be limited to a closed branch, a warehouse or a branch that doesn't exist. Tested: "Rewards: package branch validity"
  • Package terms that don't change after the sale. A redemption retried with the same reference uses one session, and the same reference with different details is refused. Terms fixed at the sale can't be rewritten. For packages sold before terms were recorded, staff record the historical terms once; a second, different review is refused. Tested: "Rewards: schema upgrade" Tested: "Rewards: historical package review"
  • Messages only to members who agreed. A member who consented hears about each sale's points once, and switching the message on doesn't replay older sales. Nothing goes out without consent for that message, or while its channel is off. With Customers on, consent is checked per message, so a member can keep earned-points messages and turn off expiry warnings. Tested: "Membership: points notifications" Tested: "Membership + customers: points notification consent"
  • Branch staff and statements. Staff tied to one branch see only that branch's members and never the organization-wide member counts. The same statement sent twice at once is queued once. Tested: "Membership: loyalty settings"
  • Printed cards that keep working. A customer card Membership issued keeps its code and link on every visit. Scanning it takes the owner to their account and a signed-out visitor to sign-in, and turns anyone else away. Tested: "Membership: the cards it issued keep their URLs without Customers"

What you build on top

  • Where points come from. Switch on POS, Storefront or Booking so sales earn points and packages can be redeemed, and Account so customers see their own points.
  • Member prices. Membership tells Discounts who is a member and lists its tiers there, so a discount can be limited to Any member or to chosen tiers ("10% off treatments for Gold members"). It applies in the shop when the member is signed in, at the register once the member is added to the ticket, and for bookings when the person booking is a member. Only an active member gets it: a paused member or one who left pays the regular price. A tier's benefit notes in settings are text for staff and members; a note such as "10% off treatments" takes nothing off a sale until a member discount gives it.
  • The customer's page. With Customers on, Membership fills a panel on each customer's page through the customers.detail.panels slot, with points and packages and the actions that need rewards:write. See Extend a Module.
  • Settings. Points per amount spent, how long points last and which messages go out by email or LINE are set on the Membership page. Tiers and what they qualify on are set under Settings → Application → Customers, which needs settings:write, and saving them re-checks every member's tier. Messages go out through Outbox.
  • Your words. Rename "Membership" or "Points" for the business with an override.
  • In code. Your coding agent imports Membership only through its public API: index.ts and server/index.ts in apps/web/src/modules/membership/. See Build on a Module.

Limits

  • One loyalty program per organization. A member's tier and status sit on the organization-wide identity, so two apps in one organization running separate programs overwrite each other.
  • Tier and status are for display, search, segments and member discounts. Don't use them to decide what someone may do in your app.
  • A tier's benefit notes are text only. Prices for members come from a member discount.

Facts

Pages

WherePath
Admin/admin/membership

Permissions

Admin holds every key. The other roles listed hold it when the app first gets the Module; after that, roles are yours to change under Settings → Roles & Permissions.

PermissionWhat it allowsOrganization roles that start with it
admin-panel:writeFull compatibility access to all module administration, including POS, catalog, storefront, and CRM staff tools.Admin
rewards:writeManage reward packages, customer points, and reward adjustments.Admin, Manager

Data

  • Tables: crm_config, crm_points_policy, crm_activity, points_ledger, crm_identity_stats, package, customer_package, package_redemption, crm_identity_profile, membership_member, membership_member_alias, rewards_identity_alias

Tested workflows

  • Membership: the janitor runs only when work is due
  • Membership: the cards it issued keep their URLs without Customers
  • Rewards: binding
  • Rewards: customer profile
  • Rewards: historical package review
  • Rewards: identity-scoped reads
  • Rewards: public boundary
  • Rewards: schema upgrade
  • Rewards: standalone maintenance
  • Rewards: package branch validity
  • Membership: loyalty settings
  • Membership: customer settings
  • Membership: points notifications
  • Membership: member tiers
  • Rewards: merged identities
  • Rewards: customer panel link (with Customers on)
  • Membership + customers: points notification consent (with Customers on)