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