What are State Usergroup Rules?
State Usergroup Rules map a state or region code on the customer's address (CA, NY, TX, ...) to a usergroup. When a customer's address is created or updated with a state that matches a rule, the system auto-assigns the corresponding usergroup to the customer's usergroup_links.
It's a thin layer that powers a lot of regional behaviour:
- Per-state price tiers: California customers see one price, Texas customers another. Attach usergroup-scoped price tiers to the group, then the rule does the rest.
- Regional shipping cohorts: separate shipping methods for a metro area vs the rest of the country. Shipping methods can be restricted to usergroups.
- Content visibility: show or hide banners, payment methods and products by region via usergroup-bound visibility settings.
- Compliance gates: some products can only be sold in certain states or regions (alcohol, supplements) — the usergroup makes filtering trivial.
- Marketing segments: CRM segments can target usergroups, so a regional campaign doesn't need a custom query.
How rules are stored
One row per (state_code, usergroup_id) in state_usergroup_rules:
| Column | Meaning |
|---|---|
state_code | State / region code (up to 10 characters, e.g. CA). Matched exactly against the state saved on the address. |
state_name | Display label. The admin form fills it from the selected state. |
usergroup_id | Target usergroup. |
auto_assign | When true (the default), the rule fires on address create/update. When false, the rule is stored but inactive. |
Multiple rules per state are allowed — a single state can map to multiple usergroups.
Module gating
state-usergroup-rules is a standard module. When OFF:
/api/v1/admin/state-usergroup-rulesreturns403 module_disabledand the admin page shows "module not enabled".ApplyStateUsergroups()(called after an address is created or updated) returns early and does NOT auto-assign.
This is critical: admins flipping the module OFF expect new addresses to STOP promoting users into price-tier groups. The runtime gate inside ApplyStateUsergroups enforces that without you having to sweep the calling sites.