Files
membership-be/docs/status_definitions.md
2025-12-16 20:03:50 +07:00

440 lines
14 KiB
Markdown

# 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)