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:writecan 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.panelsslot, with points and packages and the actions that needrewards: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.tsandserver/index.tsinapps/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
- Kind: feature Module, can be switched on and off
- Needs: Audit log, Branches, Formatting, i18n, Identity, Infra, Outbox, Standard UI
- Needed by: Nothing
- Adds to these when they're on: Customers, Discounts, Website
- Added to by: Account, Booking, POS, Storefront
- Off by default for these business types: Tour operator, Car hire
Pages
| Where | Path |
|---|---|
| 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.
| Permission | What it allows | Organization roles that start with it |
|---|---|---|
admin-panel:write | Full compatibility access to all module administration, including POS, catalog, storefront, and CRM staff tools. | Admin |
rewards:write | Manage 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)