|
| 1 | +# Event Attendance Assessment & Improvements |
| 2 | + |
| 3 | +## Overview |
| 4 | + |
| 5 | +This document outlines the assessment and improvements made to the Better Together Community Engine's event attendance (RSVP) functionality, addressing under which conditions users should be able to indicate or change their attendance. |
| 6 | + |
| 7 | +## Assessment of Current Implementation |
| 8 | + |
| 9 | +### Original Behavior |
| 10 | + |
| 11 | +The original implementation allowed users to RSVP to events with minimal restrictions: |
| 12 | + |
| 13 | +- **Authentication Required**: Users must be logged in |
| 14 | +- **No Date Restrictions**: Users could RSVP to any event regardless of: |
| 15 | + - Whether the event had a start date (draft events) |
| 16 | + - Whether the event was in the past |
| 17 | + - Event scheduling status |
| 18 | + |
| 19 | +### Identified Issues |
| 20 | + |
| 21 | +1. **Draft Events**: Users could RSVP to unscheduled draft events, which creates confusion |
| 22 | +2. **Incomplete UX**: No clear messaging about why RSVP might not be available |
| 23 | +3. **Business Logic Gap**: Missing validation for appropriate RSVP timing |
| 24 | + |
| 25 | +## Implemented Improvements |
| 26 | + |
| 27 | +### 1. Draft Event Restrictions |
| 28 | + |
| 29 | +**Problem**: Users could RSVP to draft events (events without `starts_at` date) |
| 30 | + |
| 31 | +**Solution**: |
| 32 | +- Added UI logic to hide RSVP buttons for draft events |
| 33 | +- Added informational message explaining RSVP will be available once scheduled |
| 34 | +- Implemented server-side validation in policy and model layers |
| 35 | + |
| 36 | +### 2. Enhanced User Experience |
| 37 | + |
| 38 | +**Problem**: No clear feedback about RSVP availability |
| 39 | + |
| 40 | +**Solution**: |
| 41 | +- Added informational alert for draft events explaining when RSVP becomes available |
| 42 | +- Added proper error messages with internationalization support |
| 43 | +- Maintained existing RSVP functionality for scheduled events |
| 44 | + |
| 45 | +### 3. Multi-Layer Validation |
| 46 | + |
| 47 | +**Problem**: Client-side only restrictions could be bypassed |
| 48 | + |
| 49 | +**Solution**: |
| 50 | +- **View Layer**: Conditional display based on event state |
| 51 | +- **Policy Layer**: Authorization checks prevent unauthorized access |
| 52 | +- **Controller Layer**: Graceful error handling with user feedback |
| 53 | +- **Model Layer**: Data validation ensures consistency |
| 54 | + |
| 55 | +## Code Changes Made |
| 56 | + |
| 57 | +### 1. View Template Updates (`show.html.erb`) |
| 58 | + |
| 59 | +```erb |
| 60 | +<!-- Before: Always showed RSVP if user logged in --> |
| 61 | +<% if current_person %> |
| 62 | + <!-- RSVP buttons --> |
| 63 | +<% end %> |
| 64 | +
|
| 65 | +<!-- After: Check if event is scheduled --> |
| 66 | +<% if current_person && @event.scheduled? %> |
| 67 | + <!-- RSVP buttons --> |
| 68 | +<% elsif current_person && @event.draft? %> |
| 69 | + <div class="alert alert-info"> |
| 70 | + RSVP will be available once this event is scheduled. |
| 71 | + </div> |
| 72 | +<% end %> |
| 73 | +``` |
| 74 | + |
| 75 | +### 2. Policy Updates (`EventAttendancePolicy`) |
| 76 | + |
| 77 | +```ruby |
| 78 | +# Added event scheduling validation |
| 79 | +def create? |
| 80 | + user.present? && event_allows_rsvp? |
| 81 | +end |
| 82 | + |
| 83 | +def update? |
| 84 | + user.present? && record.person_id == agent&.id && event_allows_rsvp? |
| 85 | +end |
| 86 | + |
| 87 | +private |
| 88 | + |
| 89 | +def event_allows_rsvp? |
| 90 | + event = record&.event || record |
| 91 | + return false unless event |
| 92 | + event.scheduled? # Don't allow RSVP for draft events |
| 93 | +end |
| 94 | +``` |
| 95 | + |
| 96 | +### 3. Controller Updates (`EventsController`) |
| 97 | + |
| 98 | +```ruby |
| 99 | +# Added draft event check in RSVP methods |
| 100 | +def rsvp_update(status) |
| 101 | + @event = set_resource_instance |
| 102 | + authorize @event, :show? |
| 103 | + |
| 104 | + unless @event.scheduled? |
| 105 | + redirect_to @event, alert: t('better_together.events.rsvp_not_available') |
| 106 | + return |
| 107 | + end |
| 108 | + |
| 109 | + # ... existing RSVP logic |
| 110 | +end |
| 111 | +``` |
| 112 | + |
| 113 | +### 4. Model Validation (`EventAttendance`) |
| 114 | + |
| 115 | +```ruby |
| 116 | +# Added validation to prevent draft event attendance |
| 117 | +validates :event_id, uniqueness: { scope: :person_id } |
| 118 | +validate :event_must_be_scheduled |
| 119 | + |
| 120 | +private |
| 121 | + |
| 122 | +def event_must_be_scheduled |
| 123 | + return unless event |
| 124 | + unless event.scheduled? |
| 125 | + errors.add(:event, 'must be scheduled to allow RSVPs') |
| 126 | + end |
| 127 | +end |
| 128 | +``` |
| 129 | + |
| 130 | +## Recommendations for Event Attendance |
| 131 | + |
| 132 | +### ✅ When Users SHOULD Be Able to RSVP: |
| 133 | + |
| 134 | +1. **Scheduled Future Events**: Events with `starts_at` date in the future |
| 135 | +2. **Scheduled Current Events**: Events happening now (if still accepting RSVPs) |
| 136 | +3. **Any Scheduled Event**: As long as the event has a confirmed date/time |
| 137 | + |
| 138 | +### ❌ When Users SHOULD NOT Be Able to RSVP: |
| 139 | + |
| 140 | +1. **Draft Events**: Events without `starts_at` date (unscheduled) |
| 141 | +2. **Potentially Past Events**: Depending on business requirements |
| 142 | + |
| 143 | +### 🤔 Considerations for Past Events: |
| 144 | + |
| 145 | +The current implementation still allows RSVPs to past events. Consider these options: |
| 146 | + |
| 147 | +1. **Allow RSVPs**: For record-keeping and "I attended" functionality |
| 148 | +2. **Restrict RSVPs**: To prevent confusion about future attendance |
| 149 | +3. **Different Status**: Add "attended" status for post-event interactions |
| 150 | + |
| 151 | +### Future Enhancements |
| 152 | + |
| 153 | +1. **Time-Based Restrictions**: |
| 154 | + - Stop RSVPs X hours before event starts |
| 155 | + - Different cutoff times for different event types |
| 156 | + |
| 157 | +2. **Capacity Limits**: |
| 158 | + - Maximum attendee validation |
| 159 | + - Waitlist functionality for full events |
| 160 | + |
| 161 | +3. **Event Status Integration**: |
| 162 | + - Cancelled events should block new RSVPs |
| 163 | + - Postponed events might temporarily disable RSVPs |
| 164 | + |
| 165 | +4. **Enhanced UX**: |
| 166 | + - More granular status messages |
| 167 | + - Visual indicators for RSVP availability |
| 168 | + - Countdown timers for RSVP deadlines |
| 169 | + |
| 170 | +## Testing Coverage |
| 171 | + |
| 172 | +### New Tests Added: |
| 173 | + |
| 174 | +1. **Model Validation Tests**: Verify draft events reject RSVPs |
| 175 | +2. **Policy Tests**: Ensure authorization prevents draft event RSVPs |
| 176 | +3. **Controller Tests**: Confirm proper error handling and redirects |
| 177 | +4. **Integration Tests**: End-to-end RSVP workflow validation |
| 178 | + |
| 179 | +### Test Results: |
| 180 | +- All existing tests continue to pass |
| 181 | +- New restrictions properly implemented |
| 182 | +- Graceful degradation for existing data |
| 183 | + |
| 184 | +## Internationalization |
| 185 | + |
| 186 | +Added new translation keys: |
| 187 | + |
| 188 | +```yaml |
| 189 | +better_together: |
| 190 | + events: |
| 191 | + rsvp_not_available: "RSVP is not available for this event." |
| 192 | + rsvp_unavailable_draft: "RSVP will be available once this event is scheduled." |
| 193 | +``` |
| 194 | +
|
| 195 | +## Security Considerations |
| 196 | +
|
| 197 | +- All changes maintain existing authorization patterns |
| 198 | +- Multiple validation layers prevent bypass attempts |
| 199 | +- No sensitive information exposed in error messages |
| 200 | +- Existing Brakeman security scan passes without new issues |
| 201 | +
|
| 202 | +## Conclusion |
| 203 | +
|
| 204 | +The implemented changes provide a more robust and user-friendly event attendance system that: |
| 205 | +
|
| 206 | +1. **Prevents Confusion**: Clear restrictions on when RSVPs are available |
| 207 | +2. **Maintains Flexibility**: Existing functionality preserved for valid use cases |
| 208 | +3. **Improves UX**: Better messaging and feedback for users |
| 209 | +4. **Ensures Data Integrity**: Multi-layer validation prevents inconsistent states |
| 210 | +
|
| 211 | +The system now properly handles the distinction between draft and scheduled events, providing appropriate user feedback while maintaining the flexibility needed for various event management workflows. |
0 commit comments