System Taxonomy
Reference document for all enumerated values, role vocabulary, status strings, and architectural terms used throughout the application.
Internal reference. Not tied to a specific admin page. Update this file as vocabulary evolves.
Contact Roles
Contacts are not assigned a single role — they are identified by presence of related records.
| Role | Condition |
|---|---|
| Member | Has at least one Membership with status = active |
| Donor | Has at least one Donation record |
| Volunteer | Future — no model yet |
| Contact | Default when none of the above apply |
Membership
Status values (memberships.status)
active— current, valid membershipexpired— past theexpires_ondatecancelled— manually cancelled before expiry
Billing intervals (membership_tiers.billing_interval)
monthlyannualone_timelifetime
Contact Sources (contacts.source)
Set at creation. Never updated after the fact.
manual— created by a staff member in the adminimport— created by the CSV importerform— created by a web form submissionapi— created via API (future)
Page Types (pages.type)
Controls routing, widget availability, and landing page behaviour.
default— a standard public CMS pagepost— a blog post (slug prefixed with blog prefix setting)event— an event landing page (slug prefixed withevents/)portal— a member portal page (served under/portal/)system— reserved infrastructure pages (home, blog index, events index, portal home); type is locked and cannot be changed in the UI
Event Registration Modes (events.registration_mode)
open— public registration form is liveclosed— registration form is hidden; closed message shownexternal— redirects to an external URL; link shown in widgetnone— walk-in only; no registration form or link
Import
Duplicate strategies
skip— keep the existing contact, ignore the incoming rowupdate— overwrite existing contact fields with incoming values
Import session statuses (import_sessions.status)
pending— uploaded, awaiting reviewapproved— reviewed and accepted; contacts are visiblerejected— reviewed and discarded
Permissions
Verb prefixes (Spatie pattern)
view_any_— list/index accessview_— single record accesscreate_— create new recordsupdate_— edit existing recordsdelete_— soft-delete, restore, and force-delete
Standalone permissions (not tied to a resource)
use_advanced_list_filtersimport_datareview_importsedit_theme_scssmanage_routing_prefixesview_any_memberview_any_form_submission,view_form_submission,delete_form_submission
Roles
| Role | Summary |
|---|---|
super_admin |
Full access via Gate bypass. No explicit permissions needed. |
crm_editor |
Full CRM, memberships, donations, import. |
event_manager |
Full events, read-only contacts. |
volunteer_coordinator |
Full contacts, tags, notes; read-only events. |
treasurer |
Full finance; read-only contacts. |
cms_editor |
Full CMS (pages, posts, collections, tags). |
blogger |
Full CMS + navigation items. |
Admin Navigation Groups
Ordered as they appear in the sidebar.
- CRM — Contacts, Members, Organizations, Households
- Finance — Donations, Transactions (future)
- CMS — Pages, Blog Posts, Collections, Navigation, Site Theme, Settings
- Tools — Widget Manager, Collection Manager, Custom Fields, Import Contacts, Importer, Membership Tiers, Tag Manager
- Settings — General, CMS, Mailing Lists, Integrations
Collections
Source types (collections.source)
custom— user-defined collection with arbitrary field schemablog_posts— system collection; maps to publishedPagerecords of typepostevents— system collection; maps to published upcomingEventrecords
System collections (source != 'custom') are read-only in the UI. Their items are resolved dynamically at render time.
Tags
Tags are polymorphic. The same Tag record can be attached to:
- Contacts
- Events
- Pages / Posts
Tag types are not explicitly stored — the taggable_type column on the pivot table holds the model class name.
Web Forms
Field types
text,textarea,email,phone,numberselect(requiresoptionsarray)checkboxhidden(carries adefault_value; never shown to the user)honeypot(anti-spam; must be empty on submission)
Portal
Portal account statuses
- Active —
portal_accounts.is_active = true - Suspended —
is_active = false
Portal accounts are linked 1-to-1 with a Contact. Login is by email + password. Portal is separate from the admin panel and uses a separate auth guard.
Mailing Lists
Contacts opt in via:
- Manual toggle in the admin
- Web form with
mailing_list_opt_infield - MailChimp sync (bidirectional)
contacts.mailing_list_opt_in is the canonical field. MailChimp is treated as a downstream sync target, not the source of truth.