# Membership Status Definitions & Transitions This document defines all user membership statuses, their meanings, valid transitions, and automated rules. ## Status Overview | Status | Type | Description | Member Access | |--------|------|-------------|---------------| | `pending_email` | Registration | User registered, awaiting email verification | None | | `pending_validation` | Registration | Email verified, awaiting event attendance | Newsletter only | | `pre_validated` | Registration | Attended event or referred, ready for admin validation | Newsletter only | | `payment_pending` | Registration | Admin validated, awaiting payment | Newsletter only | | `active` | Active | Payment completed, full member access | Full access | | `inactive` | Inactive | Membership deactivated manually | None | | `canceled` | Terminated | User or admin canceled membership | None | | `expired` | Terminated | Subscription ended without renewal | Limited (historical) | | `abandoned` | Terminated | Incomplete registration after reminders | None | --- ## Detailed Status Definitions ### 1. pending_email **Definition:** User has registered but not verified their email address. **How User Enters:** - User completes registration form (Step 1-4) - System creates user account with `pending_email` status **Valid Transitions:** - → `pending_validation` (email verified) - → `pre_validated` (email verified + referred by member) - → `abandoned` (optional: 30 days without verification after reminders) **Member Access:** - Cannot login - Cannot access any member features - Not subscribed to newsletter **Reminder Schedule:** - Day 3: First reminder email - Day 7: Second reminder email - Day 14: Third reminder email - Day 30: Final reminder (optional: transition to abandoned) **Admin Actions:** - Can manually resend verification email - Can manually verify email (bypass) - Can delete user account --- ### 2. pending_validation **Definition:** Email verified, user needs to attend an event within 90 days (per LOAF policy). **How User Enters:** - Email verification successful (from `pending_email`) - 90-day countdown timer starts **Valid Transitions:** - → `pre_validated` (attended event marked by admin) - → `abandoned` (90 days without event attendance - per policy) **Member Access:** - Can login to view dashboard - Subscribed to newsletter - Cannot access member-only features - Can view public events **Reminder Schedule:** - Day 30: "You have 60 days remaining to attend an event" - Day 60: "You have 30 days remaining to attend an event" - Day 80: "Reminder: 10 days left to attend an event" - Day 85: "Final reminder: 5 days left" - Day 90: Transition to `abandoned`, remove from newsletter **Admin Actions:** - Can mark event attendance (triggers transition to `pre_validated`) - Can manually transition to `pre_validated` (bypass event requirement) - Can extend deadline --- ### 3. pre_validated **Definition:** User attended event or was referred, awaiting admin validation. **How User Enters:** - Admin marked event attendance (from `pending_validation`) - User registered with valid member referral (skipped `pending_validation`) **Valid Transitions:** - → `payment_pending` (admin validates application) - → `inactive` (admin rejects application - rare) **Member Access:** - Can login to view dashboard - Subscribed to newsletter - Cannot access member-only features - Can view public events **Automated Rules:** - None (requires admin action) **Admin Actions:** - Review application in Validation Queue - Validate → transition to `payment_pending` (sends payment email) - Reject → transition to `inactive` (sends rejection email) --- ### 4. payment_pending **Definition:** Admin validated application, user needs to complete payment. **How User Enters:** - Admin validates application (from `pre_validated`) - Payment email sent with Stripe Checkout link **Valid Transitions:** - → `active` (payment successful via Stripe webhook) - → `abandoned` (optional: 60 days without payment after reminders) **Member Access:** - Can login to view dashboard - Subscribed to newsletter - Cannot access member-only features - Can view subscription plans page **Reminder Schedule:** - Day 7: First payment reminder - Day 14: Second payment reminder - Day 21: Third payment reminder - Day 30: Fourth payment reminder - Day 45: Fifth payment reminder - Day 60: Final reminder (optional: transition to abandoned) **Note:** Since admin already validated this user, consider keeping them in this status indefinitely rather than auto-abandoning. **Admin Actions:** - Can manually activate membership (for offline payments: cash, check, bank transfer) - Can resend payment email --- ### 5. active **Definition:** Payment completed, full membership access granted. **How User Enters:** - Stripe payment successful (from `payment_pending`) - Admin manually activated (offline payment) **Valid Transitions:** - → `expired` (subscription end date reached without renewal) - → `canceled` (user or admin cancels membership) - → `inactive` (admin manually deactivates) **Member Access:** - Full member dashboard access - All member-only features - Event RSVP and attendance tracking - Member directory listing - Newsletter subscribed **Renewal Reminder Schedule:** - 60 days before expiration: First renewal reminder - 30 days before expiration: Second renewal reminder - 14 days before expiration: Third renewal reminder - 7 days before expiration: Final renewal reminder - On expiration: Transition to `expired` **Admin Actions:** - Can cancel membership → `canceled` - Can manually deactivate → `inactive` - Can extend subscription end_date --- ### 6. inactive **Definition:** Membership manually deactivated by admin. **How User Enters:** - Admin manually sets status to `inactive` - Used for temporary suspensions or admin rejections **Valid Transitions:** - → `active` (admin reactivates) - → `payment_pending` (admin prompts for payment) **Member Access:** - Can login but no member features - Not subscribed to newsletter - Cannot access member-only content **Automated Rules:** - None (requires admin action to exit) **Admin Actions:** - Reactivate membership → `active` - Prompt for payment → `payment_pending` - Delete user account --- ### 7. canceled **Definition:** Membership canceled by user or admin. **How User Enters:** - User cancels subscription via Stripe portal - Admin cancels membership - Stripe webhook: `customer.subscription.deleted` **Valid Transitions:** - → `payment_pending` (user requests to rejoin) - → `active` (admin reactivates with new subscription) **Member Access:** - Can login to view dashboard (historical data) - Not subscribed to newsletter - Cannot access current member-only features - Can view historical event attendance **Automated Rules:** - Stripe webhook triggers automatic transition **Admin Actions:** - Can invite user to rejoin → `payment_pending` - Can manually reactivate → `active` (if subscription still valid) --- ### 8. expired **Definition:** Subscription ended without renewal. **How User Enters:** - Subscription `end_date` reached without renewal - Automated check runs daily **Valid Transitions:** - → `payment_pending` (user chooses to renew) - → `active` (admin manually renews/extends) **Member Access:** - Can login to view dashboard (historical data) - Not subscribed to newsletter - Cannot access current member-only features - Can view historical event attendance - Shown renewal prompts **Automated Rules:** - Daily check for subscriptions past `end_date` → transition to `expired` - Send renewal invitation email on transition **Post-Expiration Reminders:** - Immediate: Expiration notification + renewal link - 7 days after: Renewal reminder - 30 days after: Final renewal reminder - 90 days after: Optional cleanup/archive **Admin Actions:** - Manually extend subscription → `active` - Send renewal invitation → `payment_pending` --- ### 9. abandoned **Definition:** User failed to complete registration process after multiple reminders. **How User Enters:** - From `pending_email`: 30 days without verification (optional - after 4 reminders) - From `pending_validation`: 90 days without event attendance (after 4 reminders) - From `payment_pending`: 60 days without payment (optional - after 6 reminders) **Valid Transitions:** - → `pending_email` (admin resets application, resends verification) - → `pending_validation` (admin resets, manually verifies email) - → `payment_pending` (admin resets, bypasses requirements) **Member Access:** - Cannot login - Not subscribed to newsletter - All access revoked **Automated Rules:** - Send "incomplete application" notification email on transition - Optional: Purge from database after 180 days (configurable) **Admin Actions:** - Can reset application → return to appropriate pending state - Can delete user account - Can view abandoned applications in admin dashboard --- ## State Transition Diagram ``` ┌──────────────┐ │ Registration │ │ (Guest) │ └──────────────┘ │ ↓ ┌───────────────┐ (30 days) ┌──────────┐ │ pending_email │──────────────────→│abandoned │ └───────────────┘ └──────────┘ │ ↑ (verify email) │ │ │ ↓ │ ┌────────────────────┐ (90 days) │ │pending_validation │───────────────────┘ │ (or pre_validated) │ └────────────────────┘ │ (event/admin) │ ↓ ┌────────────────┐ │ pre_validated │ └────────────────┘ │ (admin validates) │ ↓ ┌─────────────────┐ (60 days) ┌──────────┐ │payment_pending │──────────────────→│abandoned │ └─────────────────┘ └──────────┘ │ (payment) │ ↓ ┌─────────┐ │ active │←────────────┐ └─────────┘ │ │ │ ├────(expires)────→┌─────────┐ │ │expired │ ├────(cancels)────→├─────────┤ │ │canceled │ └──(deactivate)───→├─────────┤ │inactive │ └─────────┘ │ (renew/reactivate) │ └──────────┘ ``` --- ## Email Notification Summary | Trigger | Emails Sent | |---------|-------------| | Registration complete | Verification email (immediate) | | pending_email day 3, 7, 14, 30 | Verification reminders | | Email verified | Welcome + event attendance instructions | | pending_validation day 30, 60, 80, 85 | Event attendance reminders | | Admin validates | Payment instructions | | payment_pending day 7, 14, 21, 30, 45, 60 | Payment reminders | | Payment successful | Membership activation confirmation | | active: 60, 30, 14, 7 days before expiry | Renewal reminders | | Subscription expires | Expiration notice + renewal link | | expired: 7, 30, 90 days after | Post-expiration renewal reminders | | Status → abandoned | Incomplete application notice | | Admin cancels | Cancellation confirmation | --- ## Implementation Notes ### Configuration Options All timeout periods should be configurable via environment variables: ```bash # Abandonment timeouts (in days, 0 = never auto-abandon) EMAIL_VERIFICATION_TIMEOUT=30 EVENT_ATTENDANCE_TIMEOUT=90 PAYMENT_TIMEOUT=0 # Don't auto-abandon payment_pending # Reminder schedules (comma-separated days) EMAIL_REMINDERS=3,7,14,30 EVENT_REMINDERS=30,60,80,85 PAYMENT_REMINDERS=7,14,21,30,45,60 RENEWAL_REMINDERS=60,30,14,7 EXPIRED_REMINDERS=7,30,90 ``` ### Background Jobs Required 1. **Daily Status Check** (runs at 00:00 UTC) - Check for expired subscriptions → `expired` - Check for abandonment timeouts (if enabled) 2. **Hourly Reminder Check** (runs every hour) - Calculate days since status change - Send appropriate reminder emails based on schedule ### Database Indexes ```sql CREATE INDEX idx_users_status ON users(status); CREATE INDEX idx_users_created_at ON users(created_at); CREATE INDEX idx_users_updated_at ON users(updated_at); CREATE INDEX idx_subscriptions_end_date ON subscriptions(end_date) WHERE status = 'active'; ``` --- ## Testing Checklist - [ ] Reminder emails sent on correct schedule - [ ] Abandonment timeouts respect configuration - [ ] Manual status transitions work correctly - [ ] Role updates on status change - [ ] Newsletter subscription/unsubscription on status change - [ ] Email notifications use correct templates - [ ] Stripe webhook integration for cancellations/expirations - [ ] Admin can bypass requirements and manually transition - [ ] Users can complete registration even after reminders stop --- ## Future Enhancements 1. **Audit Logging**: Create `user_status_log` table to track all transitions 2. **Re-engagement Campaigns**: Target abandoned users with special offers 3. **Flexible Timeout Periods**: Per-user timeout overrides for special cases 4. **A/B Testing**: Test different reminder schedules for better completion rates 5. **SMS Reminders**: Optional SMS for critical reminders (payment due, expiration)