362 lines
12 KiB
Markdown
362 lines
12 KiB
Markdown
# Multi-Event Invitation Management System - Refactoring Guide
|
|
|
|
## Overview
|
|
|
|
The wedding guest list application has been refactored from a single-event system to a **multi-event architecture** that can manage invitations for multiple events (weddings, parties, conferences, etc.).
|
|
|
|
## Key Architectural Changes
|
|
|
|
### Database Schema (PostgreSQL)
|
|
|
|
**New Tables:**
|
|
|
|
1. **users** - User accounts (organizers/event managers)
|
|
```sql
|
|
id (UUID PK) | email (unique) | created_at
|
|
```
|
|
|
|
2. **events** - Individual events
|
|
```sql
|
|
id (UUID PK) | name | date | location | created_at | updated_at
|
|
```
|
|
|
|
3. **event_members** - User membership in events with roles
|
|
```sql
|
|
id (UUID PK) | event_id (FK) | user_id (FK) | role | display_name | created_at
|
|
- Roles: admin, editor, viewer
|
|
- UNIQUE constraint on (event_id, user_id)
|
|
```
|
|
|
|
4. **guests_v2** - Guest information (scoped by event, NO separate table per event)
|
|
```sql
|
|
id (UUID PK) | event_id (FK) | added_by_user_id (FK) | first_name | last_name |
|
|
phone | side | status | notes | created_at | updated_at
|
|
- Status: invited, confirmed, declined
|
|
- Indexed: (event_id), (event_id, added_by_user_id), (event_id, phone)
|
|
```
|
|
|
|
### Database Migration
|
|
|
|
Run the SQL migration to create new tables:
|
|
```bash
|
|
psql -U wedding_admin -d wedding_guests -f backend/migrations.sql
|
|
```
|
|
|
|
The migration includes a commented-out data migration script that can import existing data to a default event.
|
|
|
|
## Backend Changes (FastAPI)
|
|
|
|
### New Core Modules
|
|
|
|
#### 1. **models.py** - SQLAlchemy Models
|
|
- `User` - User accounts with relationships
|
|
- `Event` - Event details with cascade delete
|
|
- `EventMember` - Role-based event membership
|
|
- `Guest` - Guest entries (links to events with added_by_user)
|
|
- Uses UUID primary keys throughout
|
|
- Uses SQLAlchemy enums for roles and status
|
|
|
|
#### 2. **schemas.py** - Pydantic Validation Models
|
|
- Organized into sections: User, Event, EventMember, Guest, WhatsApp
|
|
- Clear separation between Create/Update/Read schemas
|
|
- Type-safe with UUID and enum validation
|
|
|
|
#### 3. **crud.py** - Database Operations
|
|
Reorganized into logical groups:
|
|
- **User CRUD**: `get_or_create_user()`, `get_user_by_email()`
|
|
- **Event CRUD**: `create_event()`, `get_events_for_user()`, etc.
|
|
- **Event Member CRUD**: `create_event_member()`, `get_event_member()`, etc.
|
|
- **Guest CRUD (Event-scoped)**: All operations now take `event_id` parameter
|
|
- **Statistics**: `get_event_stats()`, `get_sides_summary()`
|
|
|
|
#### 4. **authz.py** - Authorization (NEW)
|
|
Role-based access control with permission checks:
|
|
```python
|
|
class Permission:
|
|
can_edit_event(role) # admin only
|
|
can_manage_members(role) # admin only
|
|
can_add_guests(role) # editor+
|
|
can_send_messages(role) # all members
|
|
```
|
|
|
|
#### 5. **whatsapp.py** - WhatsApp Integration (NEW)
|
|
- Phone number normalization to E.164 format
|
|
- `send_text_message()` - Send direct messages
|
|
- `send_template_message()` - Send approved templates
|
|
- `verify_webhook_signature()` - Validate Meta webhooks
|
|
- Error handling with custom `WhatsAppError`
|
|
|
|
### API Endpoints
|
|
|
|
#### Event Management
|
|
```
|
|
POST /events Create event (user becomes admin)
|
|
GET /events List user's events
|
|
GET /events/{event_id} Get event details
|
|
PATCH /events/{event_id} Update event (admin only)
|
|
DELETE /events/{event_id} Delete event (admin only)
|
|
```
|
|
|
|
#### Event Members
|
|
```
|
|
GET /events/{event_id}/members List members
|
|
POST /events/{event_id}/invite-member Invite by email (admin only)
|
|
PATCH /events/{event_id}/members/{user_id} Update role (admin only)
|
|
DELETE /events/{event_id}/members/{user_id} Remove member (admin only)
|
|
```
|
|
|
|
#### Guests (Event-Scoped)
|
|
```
|
|
POST /events/{event_id}/guests Add single guest
|
|
GET /events/{event_id}/guests List guests (with filters)
|
|
GET /events/{event_id}/guests/{guest_id} Get guest details
|
|
PATCH /events/{event_id}/guests/{guest_id} Update guest
|
|
DELETE /events/{event_id}/guests/{guest_id} Delete guest (admin only)
|
|
```
|
|
|
|
#### Bulk Operations
|
|
```
|
|
POST /events/{event_id}/guests/import Import multiple guests
|
|
POST /events/{event_id}/whatsapp Send message to guest
|
|
POST /events/{event_id}/whatsapp/broadcast Send to multiple guests
|
|
GET /events/{event_id}/stats Get event statistics
|
|
```
|
|
|
|
### Authorization
|
|
|
|
**All event-scoped endpoints enforce authorization:**
|
|
- User must be a member of the event
|
|
- Permissions based on role:
|
|
- **admin**: Full control (create, delete, manage members)
|
|
- **editor**: Add/edit guests, import
|
|
- **viewer**: View only, can send messages
|
|
|
|
**Implemented via:**
|
|
- `verify_event_access()` - Check membership
|
|
- `verify_event_admin()` - Check admin role
|
|
- `verify_event_editor()` - Check editor+ role
|
|
|
|
## Frontend Changes (React/Vite)
|
|
|
|
### New Components
|
|
|
|
#### 1. **EventList.jsx** - Event Discovery
|
|
- Shows all events user is member of
|
|
- Quick stats: total guests, confirmation rate
|
|
- Create/delete event actions
|
|
- Card-based responsive layout
|
|
|
|
#### 2. **EventForm.jsx** - Event Creation
|
|
- Modal form for new events
|
|
- Fields: name (required), date, location
|
|
- Automatically adds creator as admin
|
|
|
|
#### 3. **EventMembers.jsx** - Member Management
|
|
- Invite members by email
|
|
- Set member roles (admin/editor/viewer)
|
|
- Remove members
|
|
- Modal interface
|
|
|
|
### Updated Components
|
|
|
|
#### **App.jsx** - Main Navigation
|
|
- New page states: 'events', 'guests', 'guest-self-service'
|
|
- Event selection flow: List → Detail → Guests
|
|
- Modal overlays for forms
|
|
|
|
#### **api/api.js** - Event-Scoped Endpoints
|
|
- Reorganized into sections
|
|
- All guest operations now scoped by event
|
|
- New functions for events and members
|
|
- Backward compatibility where possible
|
|
|
|
### Updated API Functions (examples)
|
|
```javascript
|
|
// Events
|
|
getEvents() // List user's events
|
|
createEvent(event) // Create new event
|
|
getEventStats(eventId) // Get statistics
|
|
|
|
// Members
|
|
getEventMembers(eventId)
|
|
inviteEventMember(eventId, invite)
|
|
updateMemberRole(eventId, userId, role)
|
|
|
|
// Guests (now scoped)
|
|
getGuests(eventId, options) // List with filters
|
|
createGuest(eventId, guest) // Add single
|
|
bulkImportGuests(eventId, guests) // Bulk add
|
|
updateGuest(eventId, guestId, data) // Update
|
|
|
|
// WhatsApp
|
|
sendWhatsAppMessage(eventId, guestId, message)
|
|
broadcastWhatsAppMessage(eventId, request)
|
|
```
|
|
|
|
## Environment Configuration
|
|
|
|
### New Variables (.env)
|
|
|
|
```env
|
|
# WhatsApp Cloud API (required for messaging)
|
|
WHATSAPP_ACCESS_TOKEN=...
|
|
WHATSAPP_PHONE_NUMBER_ID=...
|
|
WHATSAPP_API_VERSION=v20.0
|
|
WHATSAPP_VERIFY_TOKEN=... (optional, for webhooks)
|
|
|
|
# Test user (temporary - implement real auth)
|
|
TEST_USER_EMAIL=test@example.com
|
|
```
|
|
|
|
See `.env.example` for full template.
|
|
|
|
## Migration Checklist
|
|
|
|
- [ ] Back up existing database
|
|
- [ ] Run `migrations.sql` to create new tables
|
|
- [ ] Update backend dependencies (if any new ones added)
|
|
- [ ] Update frontend packages (axios already included)
|
|
- [ ] Test authentication (currently uses TEST_USER_EMAIL)
|
|
- [ ] Configure WhatsApp credentials (optional)
|
|
- [ ] Update FRONTEND_URL in .env for CORS
|
|
- [ ] Test event creation workflow
|
|
- [ ] Test member invitation
|
|
- [ ] Test guest management
|
|
|
|
## Breaking Changes
|
|
|
|
### Database
|
|
- Old `guests` table still exists but unused
|
|
- Can be deleted after confirming data migration was successful:
|
|
```sql
|
|
DROP TABLE guests;
|
|
```
|
|
|
|
### APIs
|
|
Old endpoints **NO LONGER AVAILABLE**:
|
|
- `GET /guests/` → Use `GET /events/{event_id}/guests`
|
|
- `POST /guests/` → Use `POST /events/{event_id}/guests`
|
|
- `GET /guests/{id}` → Use `GET /events/{event_id}/guests/{id}`
|
|
|
|
### Frontend
|
|
- Old single-guest-list view replaced with event-first navigation
|
|
- Google import and duplicate manager need updates for event-scoped guests
|
|
|
|
## Authentication (TODO)
|
|
|
|
Current implementation uses `TEST_USER_EMAIL` from `.env`.
|
|
|
|
**Recommended approaches to implement:**
|
|
1. **JWT Tokens** - Extract user from Authorization header
|
|
2. **Session Cookies** - HTTP-only cookies with session ID
|
|
3. **OAuth2** - Google/GitHub integration
|
|
4. **API Keys** - For programmatic access
|
|
|
|
Update `get_current_user_id()` in `main.py` with your auth logic.
|
|
|
|
## WhatsApp Integration
|
|
|
|
### Setup Steps
|
|
|
|
1. Create Meta Business App: https://developers.facebook.com/
|
|
2. Add WhatsApp product
|
|
3. Create test phone number or configure production
|
|
4. Get credentials:
|
|
- `WHATSAPP_ACCESS_TOKEN` - Long-lived token
|
|
- `WHATSAPP_PHONE_NUMBER_ID` - Phone number sender ID
|
|
5. Add to `.env` and `.gitignore`
|
|
|
|
### Features
|
|
|
|
- **Send Text Messages**: Direct messages to guest phone (E.164 format)
|
|
- **Bulk Broadcast**: Send to multiple guests with optional filters
|
|
- **Phone Validation**: Automatic normalization (handles various formats)
|
|
- **Error Handling**: Detailed WhatsApp API non-200 errors
|
|
|
|
### Usage Example
|
|
```python
|
|
service = get_whatsapp_service()
|
|
result = await service.send_text_message(
|
|
to_phone="+972541234567",
|
|
message_text="Hello! Please confirm your attendance..."
|
|
)
|
|
```
|
|
|
|
## File Structure
|
|
|
|
```
|
|
backend/
|
|
├── main.py # FastAPI app with all routes
|
|
├── models.py # SQLAlchemy ORM models (UPDATED)
|
|
├── schemas.py # Pydantic request/response schemas (UPDATED)
|
|
├── crud.py # Database operations (COMPLETELY REWRITTEN)
|
|
├── authz.py # Authorization & permissions (NEW)
|
|
├── whatsapp.py # WhatsApp API client (NEW)
|
|
├── database.py # DB connection setup
|
|
├── migrations.sql # SQL schema with new tables (NEW)
|
|
└── .env.example # Environment template (UPDATED)
|
|
|
|
frontend/src/
|
|
├── components/
|
|
│ ├── EventList.jsx # List/manage events (NEW)
|
|
│ ├── EventForm.jsx # Create event modal (NEW)
|
|
│ ├── EventMembers.jsx # Manage members (NEW)
|
|
│ ├── GuestList.jsx # Guest list (needs update for event scope)
|
|
│ └── ...
|
|
├── api/
|
|
│ └── api.js # API client (UPDATED)
|
|
└── App.jsx # Main app (UPDATED for events)
|
|
```
|
|
|
|
## Performance Considerations
|
|
|
|
- **Indexes on guests_v2** for common queries:
|
|
- `event_id` - Filter by event
|
|
- `(event_id, status)` - Filter by status
|
|
- `(event_id, phone)` - Lookup by phone
|
|
|
|
- **Pagination**: List endpoints support skip/limit
|
|
|
|
- **Cascading Deletes**: Deleting event removes all guests and memberships
|
|
|
|
## Security Notes
|
|
|
|
1. **Authorization**: Every event endpoint checks membership
|
|
2. **Phone Numbers**: Validated/normalized before WhatsApp sends
|
|
3. **Secrets**: Store ACCESS_TOKEN in .env, never commit
|
|
4. **CORS**: Restricted to FRONTEND_URL (.env configuration)
|
|
5. **Roles**: Implement fine-grained permissions (admin/editor/viewer)
|
|
|
|
## Testing Recommendations
|
|
|
|
```bash
|
|
# Test event creation
|
|
psql -U wedding_admin -d wedding_guests -c "SELECT * FROM events;"
|
|
|
|
# Test member management
|
|
psql -U wedding_admin -d wedding_guests -c "SELECT * FROM event_members;"
|
|
|
|
# Test guest entries
|
|
psql -U wedding_admin -d wedding_guests -c "SELECT * FROM guests_v2 LIMIT 5;"
|
|
|
|
# Test API
|
|
curl http://localhost:8000/events
|
|
```
|
|
|
|
## Next Steps
|
|
|
|
1. **Implement Real Authentication** - Replace TEST_USER_EMAIL
|
|
2. **Add Google Import** - Update for event-scoped guests
|
|
3. **Implement Self-Service Guest Updates** - via token link
|
|
4. **Handle Webhooks** - WhatsApp status callbacks
|
|
5. **Add Email Notifications** - Event/RSVP confirmations
|
|
6. **Deploy Helm Charts** - Uses new schema structure
|
|
|
|
## Support
|
|
|
|
For issues or questions:
|
|
1. Check `.env` configuration
|
|
2. Review database indexes in `migrations.sql`
|
|
3. Check authorization checks in `authz.py`
|
|
4. Verify API response schemas in `schemas.py`
|