# Events Guides & Philosophy

# Nexgate-Event-mng-Requrements

### 1. PLATFORM PHILOSOPHY (the 7 unbreakable laws)
1. One person = One lifelong QR forever (physical / online / hybrid / exclusive)
2. Host gets paid 48 hours after each session ends – fastest in the industry
3. Money held in escrow until the session actually happens
4. 100 % offline + cryptographically signed QR tokens – zero fraud possible
5. Zero queues – unlimited scanners + self-service kiosks
6. True recurring series that feel exactly like Google Calendar
7. One toggle controls everything: Public ↔ Private ↔ Application-only

### 2. ALL EVENT TYPES & COMBINATIONS SUPPORTED
```
Visibility →   Public | Private (link) | Application-only
Location  → In-person | Online | Hybrid       → every combination allowed
Time      → One-off | Multi-day | Recurring | Free → every combination allowed
```

### 3. MONEY & PAYOUT RULES (applies to EVERYTHING above)
| Situation                        | Attendee pays                  | Host receives money (bank)        |
|----------------------------------|--------------------------------|-----------------------------------|
| Public / Private                 | Instantly                      | 48 h after session ends           |
| Application-only                 | Only after host approves       | 48 h after session ends           |
| Online / Hybrid                  | Same rules                     | 48 h after scheduled end time     |
| Recurring pay-per-session        | Per session                    | 48 h after each class             |
| Monthly unlimited                | 1st of month                   | 3–5th of next month               |
| Class packs (10-class etc.)      | Upfront or per use             | Per use (or full after 1st class if trusted host) |

### 4. FULL PROFESSIONAL FORMS – DOTTED LINES (2025 standard)

```
FORM 1 ─ CREATE NEW EVENT – STEP 1
┌────────────────────────────────────────────────────────────────────┐
│ ← All events                                              New event │
├────────────────────────────────────────────────────────────────────┤
│ Event title                                                        │
│ Weekend Yoga & Sound Healing Retreat                        │     │
│                                                                            │
│ Tagline (shown under title)                                        │
│ 2-day oceanfront immersion · March 15–16                    │     │
│                                                                            │
│ Cover photo                                                        │
│ [ Drag & drop or click to upload ]                                 │
│                                                                            │
│ Category                                                               │
│ Retreat & Wellness ▼                                                       │
│ Tags                                                                       │
│ #yoga #soundhealing #miami #oceanview #retreat                             │
│                                                                            │
│ Visibility & Access                                                        │
│ ○ Public – anyone can find & book                                          │
│ ○ Private – only people with the direct link                               │
│ ● Application required – you approve every attendee                       │
│                                                                            │
│ Location type                                                              │
│ ○ In-person only       ○ Online only       ● Hybrid (both)                │
│                                                                            │
│                                                                [Continue →]│
└────────────────────────────────────────────────────────────────────┘


FORM 2 ─ RECURRING SERIES SETUP (the legendary screen)
┌────────────────────────────────────────────────────────────────────┐
│ Event type                                                                 │
│ ○ One-time event        ● Recurring series                                 │
│                                                                            │
│ Repeats                                                                        │
│ ● Every week        ○ Every 2 weeks        ○ Every month                 │
│ ○ Custom (advanced)                                                        │
│                                                                            │
│ Repeats on                                                                 │
│ [●] Mon   [●] Tue   [ ] Wed   [●] Thu   [ ] Fri   [ ] Sat   [●] Sun        │
│                                                                            │
│ + Add another class time (different title/time/price)                     │
│                                                                            │
│ Live preview – next 6 weeks                                                │
│ Mon Mar 10  10:00  Gentle Flow                  $25                    │
│ Tue Mar 11  18:30  Vinyasa Power                $28                    │
│ Thu Mar 13  18:30  Vinyasa Power                $28                    │
│ Sun Mar 16  17:00  Sunday Restore               $25                    │
│ … continues forever                                                        │
│                                                                            │
│ End condition                                                              │
│ ● No end date (we show next 18 months automatically)                     │
│ ○ Ends on ___/___/____                                                     │
│ ○ After ___ occurrences                                                    │
│                                                                            │
│                                                                [Continue →]│
└────────────────────────────────────────────────────────────────────┘


FORM 3 ─ APPLICATION-ONLY CUSTOM QUESTIONS
┌────────────────────────────────────────────────────────────────────┐
│ Application questions – attendees must answer before payment              │
│                                                                            │
│ 1. Why do you want to attend this retreat?                                 │
│    Long text – required                                                    │
│                                                                            │
│ 2. Dietary restrictions or allergies?                                      │
│    Long text – optional                                                    │
│                                                                            │
│ 3. How experienced are you with yoga?                                      │
│    Beginner / Intermediate / Advanced                                      │
│                                                                            │
│ 4. Instagram handle (we love to repost!)                                   │
│    Short text – optional                                                   │
│                                                                            │
│ 5. Bring a +1 partner?                                                     │
│    Yes / No                                                                │
│                                                                            │
│ + Add another question                                                     │
│                                                                [Continue →]│
└────────────────────────────────────────────────────────────────────┘


FORM 4 ─ ATTENDEE APPLYING TO EXCLUSIVE EVENT
┌────────────────────────────────────────────────────────────────────┐
│ Application – Weekend Yoga & Sound Healing Retreat                         │
│                                                                            │
│ Why do you want to attend?                                                 │
│ [ I’ve been following Sun Studio for 2 years and this…            ]       │
│                                                                            │
│ Dietary restrictions?                                                      │
│ [ Vegan, allergic to nuts                                          ]       │
│ Instagram handle                                                           │
│ @emmayoga                                                                  │
│                                                                            │
│ You will only be charged if approved                                       │
│                                                                            │
│                                                       [Submit Application]│
└────────────────────────────────────────────────────────────────────┘


FORM 5 ─ HOST APPROVAL DASHBOARD
┌────────────────────────────────────────────────────────────────────┐
│ Applications (52 pending · 28 approved · 123 total)                        │
│                                                                            │
│ ○ Emma Wilson         @emmayoga         Vegan, no nuts        [+ Approve] │
│   “Long-time follower, perfect for my birthday”                            │
│                                                                            │
│ ○ Michael & Ana       Couple – 10th anniversary            [+ Approve ×2]   │
│                                                                            │
│ ○ John Smith          “Will bring camera crew”               [− Reject]      │
│                                                                            │
│ [ ] Select all       [Approve selected]    [Message selected]               │
│ Waitlist: 31 people (auto-approve if spot opens)                           │
└────────────────────────────────────────────────────────────────────┘


FORM 6 ─ ETERNAL PASS / TICKET (what every attendee has forever)
┌────────────────────────────────────────────────────────────────────┐
│ Emma Wilson – Eternal Pass                                                 │
│ Valid forever across all Sun Studio events                                 │
│                                                                            │
│ ████████████████████████████████████████████████████████████████         │
│                                                                            │
│ Next: Vinyasa Power – Tue Mar 11, 18:30                                    │
│       Gentle Flow   – Mon Mar 17, 10:00                                    │
│                                                                            │
│ ● Hybrid event                                                             │
│   [ SCAN AT DOOR ]                 [ JOIN ZOOM LIVESTREAM ]                │
│                                                                            │
│ Location revealed 48 h before (approved attendees only)                    │
│                                                                            │
│ + Add to Apple Wallet         + Add to Google Wallet                       │
└────────────────────────────────────────────────────────────────────┘


FORM 7 ─ SELF-SERVICE KIOSK / SCANNER
┌────────────────────────────────────────────────────────────────────┐
│ Welcome to Sun Studio                                                      │
│                                                                            │
│ Hold your QR code to the camera                                            │
│                                                                            │
│                    ████████████████████████████                            │
│                                                                            │
│ → ✓ Emma Wilson – Approved & paid                                          │
│   Welcome back! Enjoy your class                                           │
└────────────────────────────────────────────────────────────────────┘
```

### 5. FINAL SUMMARY – You now have everything
- Complete philosophy & rules
- Every event type & combination
- Exact money & payout logic
- Every single professional form with dotted lines
- Ready to print and give to designers, developers, investors

# Nexgate Platform - Check-in System Architecture

## Table of Contents
1. [System Overview](#system-overview)
2. [Architecture Principles](#architecture-principles)
3. [System Components](#system-components)
4. [Ticket Generation Flow](#ticket-generation-flow)
5. [Scanner Registration Flow](#scanner-registration-flow)
6. [Ticket Validation Flow](#ticket-validation-flow)
7. [Offline Mode Architecture](#offline-mode-architecture)
8. [Security Model](#security-model)
9. [Data Models](#data-models)
10. [API Specifications](#api-specifications)
11. [Database Schema](#database-schema)
12. [Deployment Architecture](#deployment-architecture)

---

## System Overview

### What is the Check-in System?

The Check-in System is a critical component of the Nexgate platform that handles secure, scalable ticket validation for events. It enables event organizers to verify attendee tickets at entry gates using mobile scanner devices, with the capability to work both online and offline.

### Key Features

- **Cryptographic Security**: Uses RSA-signed JWT tokens to prevent ticket forgery
- **Offline Capability**: Scanners can validate tickets without internet connectivity
- **Multi-Gate Support**: Coordinate validation across multiple entry points
- **Real-time Validation**: Immediate duplicate detection when online
- **Scanner Management**: Secure device registration and revocation
- **Audit Trail**: Complete tracking of all scan activities

### Inspiration

The system is inspired by electrical meter voucher systems commonly used in Tanzania and other African countries, where vouchers must be validated offline after purchase, with reconciliation happening later when connectivity is restored.

---

## Architecture Principles

### 1. Security First
- All tickets are cryptographically signed
- Cannot be forged without the server's private key
- Scanner devices only receive public keys for verification

### 2. Offline-First Design
- Scanners must function without network connectivity
- Local validation using JWT signature verification
- Queue-based synchronization when connectivity returns

### 3. Zero-Trust Scanner Model
- Each scanner is individually registered and can be revoked
- Scanners receive time-limited registration tokens
- All scanner actions are logged and auditable

### 4. Scalability
- Stateless ticket validation (JWT-based)
- No database queries required for offline validation
- Server handles only registration and synchronization

---

## System Components

### Component Diagram

```
┌─────────────────────────────────────────────────────────────────────────────┐
│                           NEXGATE PLATFORM                                  │
│                                                                             │
│  ┌─────────────────┐         ┌──────────────────┐                          │
│  │ Admin Dashboard │────────>│ Event Management │                          │
│  └────────┬────────┘         └────────┬─────────┘                          │
│           │                           │                                     │
│           │                           v                                     │
│           │                  ┌─────────────────┐                            │
│           │                  │ Ticketing       │                            │
│           │                  │ Service         │                            │
│           │                  └────────┬────────┘                            │
│           │                           │                                     │
│           v                           v                                     │
│  ┌─────────────────┐         ┌──────────────────┐                          │
│  │ Check-in        │<────────│                  │                          │
│  │ Service         │         │                  │                          │
│  │ ⚡ CORE SYSTEM  │         │                  │                          │
│  └────────┬────────┘         │                  │                          │
│           │                  │                  │                          │
│           v                  v                  v                          │
│      ┌─────────────────────────────────┐                                   │
│      │   PostgreSQL Database           │                                   │
│      └─────────────────────────────────┘                                   │
└─────────────────────────────────────────────────────────────────────────────┘
           ▲                           ▲                    ▲
           │                           │                    │
           │                           │                    │
┌──────────┴────────┐       ┌──────────┴────────┐  ┌───────┴────────┐
│  Scanner App      │       │  Customer App     │  │  Email Service │
│  ⚡ MOBILE CLIENT │       │  Mobile/Web       │  │  (External)    │
└───────────────────┘       └──────────┬────────┘  └────────────────┘
                                       │
                                       v
                            ┌────────────────────┐
                            │  Payment Gateway   │
                            │  (External)        │
                            └────────────────────┘

Legend:
  ──────>  Data Flow
  ⚡       Critical Component
```

### Core Components

#### 1. Check-in Service (Spring Boot Backend)
**Responsibilities:**
- Generate and manage scanner registration tokens
- Issue scanner credentials
- Generate RSA key pairs for ticket signing
- Create JWT-based tickets with QR codes
- Handle online ticket validation requests
- Receive and process scan logs from scanners
- Manage scanner settings and configurations
- Maintain scan history and analytics

**Technology Stack:**
- Spring Boot 3.x
- Spring Security
- PostgreSQL
- Redis (for caching and rate limiting)
- JWT (io.jsonwebtoken library)
- ZXing (QR code generation)

#### 2. Scanner Mobile App (Android)
**Responsibilities:**
- Register scanner device using QR code
- Store scanner credentials and server public key
- Scan ticket QR codes
- Validate tickets offline using JWT verification
- Validate tickets online when connected
- Queue scan logs for synchronization
- Sync with server periodically
- Display scan history and statistics

**Technology Stack:**
- Android (Kotlin)
- Room Database (local storage)
- WorkManager (background sync)
- ZXing (QR code scanning)
- JWT library for validation
- Retrofit (API communication)

#### 3. Admin Dashboard (Web)
**Responsibilities:**
- Generate scanner registration QR codes
- View and manage registered scanners
- Revoke scanner access
- Configure scanner settings
- View scan analytics and reports
- Monitor real-time scanning activity
- Export scan data

**Technology Stack:**
- React.js / Vue.js
- Chart.js (analytics)
- WebSocket (real-time updates)

---

## Ticket Generation Flow

### Overview
When a customer purchases a ticket, the system generates a cryptographically signed JWT token that is embedded in a QR code. This QR code serves as the ticket that the customer presents at the event gate.

### Detailed Flow

```
Customer          Ticketing         Check-in          Database        Email
   │               Service           Service              │          Service
   │                  │                 │                 │              │
   │  Purchase        │                 │                 │              │
   │  Ticket          │                 │                 │              │
   ├─────────────────>│                 │                 │              │
   │                  │                 │                 │              │
   │                  │  Create Booking │                 │              │
   │                  ├────────────────────────────────────>│              │
   │                  │                 │                 │              │
   │                  │  Request Ticket │                 │              │
   │                  │  Generation     │                 │              │
   │                  ├────────────────>│                 │              │
   │                  │                 │                 │              │
   │                  │                 │ Load Private    │              │
   │                  │                 │ Key             │              │
   │                  │                 │─┐               │              │
   │                  │                 │ │               │              │
   │                  │                 │<┘               │              │
   │                  │                 │                 │              │
   │                  │                 │ Create JWT      │              │
   │                  │                 │ Payload         │              │
   │                  │                 │─┐               │              │
   │                  │                 │ │               │              │
   │                  │                 │<┘               │              │
   │                  │                 │                 │              │
   │                  │                 │ Sign JWT with   │              │
   │                  │                 │ Private Key     │              │
   │                  │                 │─┐               │              │
   │                  │                 │ │               │              │
   │                  │                 │<┘               │              │
   │                  │                 │                 │              │
   │                  │                 │ Generate QR     │              │
   │                  │                 │ Code            │              │
   │                  │                 │─┐               │              │
   │                  │                 │ │               │              │
   │                  │                 │<┘               │              │
   │                  │                 │                 │              │
   │                  │                 │ Store Ticket    │              │
   │                  │                 ├────────────────>│              │
   │                  │                 │                 │              │
   │                  │  Return JWT +   │                 │              │
   │                  │  QR Code        │                 │              │
   │                  │<────────────────┤                 │              │
   │                  │                 │                 │              │
   │                  │  Send Email     │                 │              │
   │                  │  with QR        │                 │              │
   │                  ├──────────────────────────────────────────────────>│
   │                  │                 │                 │              │
   │                  │                 │                 │  Email with  │
   │<────────────────────────────────────────────────────────── QR Code  │
   │                  │                 │                 │              │
   │  Return Ticket   │                 │                 │              │
   │  Details         │                 │                 │              │
   │<─────────────────┤                 │                 │              │
   │                  │                 │                 │              │

Legend:
  ───>   Synchronous request
  ──>    Response
  ─┐ │   Internal processing
```

### Step-by-Step Process

#### Step 1: Customer Completes Purchase
```
Customer → Ticketing Service
- Selects event and ticket type
- Completes payment
- Receives booking confirmation
```

#### Step 2: Ticketing Service Requests Ticket Generation
```
Ticketing Service → Check-in Service
POST /api/tickets/generate
{
  "bookingId": "booking-uuid",
  "eventId": "event-uuid",
  "attendeeName": "John Doe",
  "attendeeEmail": "john@example.com",
  "ticketType": "VIP",
  "validFrom": "2025-12-01T18:00:00Z",
  "validUntil": "2025-12-01T23:59:59Z"
}
```

#### Step 3: Check-in Service Creates JWT

**JWT Header:**
```json
{
  "alg": "RS256",
  "typ": "JWT"
}
```

**JWT Payload:**
```json
{
  "ticketId": "ticket-uuid-123",
  "bookingId": "booking-uuid",
  "eventId": "event-uuid",
  "eventName": "Tech Conference 2025",
  "attendeeName": "John Doe",
  "attendeeEmail": "john@example.com",
  "ticketType": "VIP",
  "seatNumber": "A-12",
  "iat": 1701234567,
  "exp": 1703826567,
  "nbf": 1701234567
}
```

**Signing Process:**
```
1. Encode Header as Base64URL
2. Encode Payload as Base64URL
3. Create signature: 
   SHA256withRSA(base64(header) + "." + base64(payload), PRIVATE_KEY)
4. Final JWT = header.payload.signature
```

#### Step 4: Generate QR Code
```
1. Take complete JWT string
2. Generate QR code image (300x300 pixels)
3. Encode as Base64 string
4. Store in ticket record
```

#### Step 5: Store and Distribute
```
Database Record:
- ticket_id
- booking_id
- event_id
- jwt_token (full JWT string)
- qr_code_base64
- status (ACTIVE, SCANNED, CANCELLED)
- created_at

Distribution:
- Email to customer with QR code image
- Available in mobile app
- Printable PDF option
```

### Ticket JWT Example

```
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aWNrZXRJZCI6ImFiYy0xMjMiLCJldmVudElkIjoiZXZlbnQtMDAxIiwiYXR0ZW5kZWVOYW1lIjoiSm9obiBEb2UiLCJhdHRlbmRlZUVtYWlsIjoiam9obkBleGFtcGxlLmNvbSIsImlhdCI6MTcwMTIzNDU2NywiZXhwIjoxNzAzODI2NTY3fQ.signature_here
```

---

## Scanner Registration Flow

### Overview
Before a scanner device can validate tickets, it must be registered with the system. This process is similar to WhatsApp's "Link Device" feature, using a time-limited QR code for secure pairing.

### Detailed Flow

```
Admin    Dashboard    Check-in       Database      Scanner
                      Service                       App
  │          │           │              │             │
  │ Click    │           │              │             │
  │ "Add     │           │              │             │
  │ Scanner" │           │              │             │
  ├─────────>│           │              │             │
  │          │           │              │             │
  │          │ Generate  │              │             │
  │          │ Token     │              │             │
  │          ├──────────>│              │             │
  │          │           │              │             │
  │          │           │ Create Token │             │
  │          │           │ (UUID)       │             │
  │          │           │ Set Expiry   │             │
  │          │           │ (5 min)      │             │
  │          │           │─┐            │             │
  │          │           │ │            │             │
  │          │           │<┘            │             │
  │          │           │              │             │
  │          │           │ Store Token  │             │
  │          │           ├─────────────>│             │
  │          │           │              │             │
  │          │  Return   │              │             │
  │          │  Token    │              │             │
  │          │<──────────┤              │             │
  │          │           │              │             │
  │          │ Generate  │              │             │
  │          │ QR Code   │              │             │
  │          │─┐         │              │             │
  │          │ │         │              │             │
  │          │<┘         │              │             │
  │          │           │              │             │
  │  Display │           │              │             │
  │  QR Code │           │              │             │
  │<─────────┤           │              │             │
  │          │           │              │             │
  │                                                   │
  │                    Scanner scans QR code          │
  │                                                   │
  │  Scan QR │           │              │             │
  ├──────────────────────────────────────────────────>│
  │          │           │              │             │
  │          │           │              │  Extract    │
  │          │           │              │  Token      │
  │          │           │              │─┐           │
  │          │           │              │ │           │
  │          │           │              │<┘           │
  │          │           │              │             │
  │          │           │  Register    │             │
  │          │           │  Scanner     │             │
  │          │           │<─────────────┼─────────────┤
  │          │           │  {token,     │             │
  │          │           │   name}      │             │
  │          │           │              │             │
  │          │           │ Validate     │             │
  │          │           │ Token        │             │
  │          │           ├─────────────>│             │
  │          │           │              │             │
  │          │           │ Token Valid? │             │
  │          │           │<─────────────┤             │
  │          │           │              │             │
  │          │           │ Generate     │             │
  │          │           │ Credentials  │             │
  │          │           │ (JWT)        │             │
  │          │           │─┐            │             │
  │          │           │ │            │             │
  │          │           │<┘            │             │
  │          │           │              │             │
  │          │           │ Get Public   │             │
  │          │           │ Key          │             │
  │          │           │─┐            │             │
  │          │           │ │            │             │
  │          │           │<┘            │             │
  │          │           │              │             │
  │          │           │ Create       │             │
  │          │           │ Scanner      │             │
  │          │           │ Record       │             │
  │          │           ├─────────────>│             │
  │          │           │              │             │
  │          │           │ Mark Token   │             │
  │          │           │ as Used      │             │
  │          │           ├─────────────>│             │
  │          │           │              │             │
  │          │           │  Return      │             │
  │          │           │  {id,        │             │
  │          │           │   credentials│             │
  │          │           │   publicKey, │             │
  │          │           │   settings}  │             │
  │          │           ├──────────────┼────────────>│
  │          │           │              │             │
  │          │           │              │  Store      │
  │          │           │              │  Config     │
  │          │           │              │─┐           │
  │          │           │              │ │           │
  │          │           │              │<┘           │
  │          │           │              │             │
  │  Show    │           │              │  Show       │
  │  Success │           │              │  Success    │
  │<─────────────────────────────────────────────────┤
  │          │           │              │             │

Legend:
  ───>   Request/Response
  ─┐ │   Internal processing
  ....   Scanner scans QR
```

### Step-by-Step Process

#### Step 1: Admin Initiates Registration
```
Admin Dashboard:
1. Navigate to "Scanners" section
2. Click "Add New Scanner" button
3. Specify scanner details:
   - Scanner Name: "Gate A - Main Entrance"
   - Validity: 5 minutes (default)
   - Notes: Optional description
```

#### Step 2: Server Generates Registration Token
```
POST /api/registration-tokens/generate
Request:
{
  "validityMinutes": 5,
  "notes": "Gate A scanner for Main Entrance"
}

Server Process:
1. Generate UUID token
2. Calculate expiry time (now + 5 minutes)
3. Store in database:
   - token: "abc-123-xyz-789"
   - expires_at: "2025-11-29T10:15:00Z"
   - used: false
   - created_by: "admin@nexgate.com"

Response:
{
  "token": "abc-123-xyz-789",
  "qrCodeBase64": "data:image/png;base64,iVBORw0KG...",
  "expiresAt": "2025-11-29T10:15:00Z",
  "validityMinutes": 5
}
```

#### Step 3: Display QR Code
```
Admin Dashboard displays:
- Large QR code containing the token
- Expiry countdown timer
- Token details
- "Waiting for scanner to connect..." message
```

#### Step 4: Scanner Scans QR Code
```
Scanner App:
1. Open camera for QR scanning
2. Scan QR code displayed on admin dashboard
3. Extract token string: "abc-123-xyz-789"
4. Prompt user to confirm device name
```

#### Step 5: Scanner Sends Registration Request
```
POST /api/scanners/register
Request:
{
  "token": "abc-123-xyz-789",
  "deviceName": "Gate A Scanner",
  "deviceInfo": {
    "model": "Samsung Galaxy S21",
    "osVersion": "Android 14",
    "appVersion": "1.0.0"
  }
}
```

#### Step 6: Server Validates and Issues Credentials
```
Server Validation:
1. Find token in database
2. Check if token exists
3. Check if token.used == false
4. Check if token.expiresAt > now()

If valid:
1. Generate scanner credentials (JWT):
   {
     "scannerId": "scanner-uuid",
     "scannerName": "Gate A Scanner",
     "type": "scanner_credential",
     "iat": now,
     "exp": now + 1 year
   }

2. Sign with server private key

3. Create scanner record in database:
   - scanner_id: UUID
   - name: "Gate A Scanner"
   - credentials: JWT
   - status: ACTIVE
   - settings: default settings JSON
   - created_at: now

4. Mark token as used:
   - used: true
   - used_at: now
   - scanner_name: "Gate A Scanner"

Response:
{
  "scannerId": "scanner-uuid",
  "credentials": "eyJhbGc...scanner_jwt",
  "publicKey": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...",
  "settings": {
    "offlineModeEnabled": false,
    "syncIntervalMinutes": 15,
    "maxOfflineHours": 24
  }
}
```

#### Step 7: Scanner Stores Configuration
```
Scanner App (Local Storage):
1. Save scanner ID
2. Save credentials JWT
3. Convert publicKey string to PublicKey object
4. Save public key
5. Save settings
6. Mark device as "registered"

Scanner is now ready to validate tickets!
```

### Registration Token Lifecycle

```mermaid
stateDiagram-v2
    [*] --> Generated: Admin creates token
    Generated --> Active: Token created, timer starts
    Active --> Used: Scanner registers successfully
    Active --> Expired: Time runs out
    Used --> [*]: Token consumed
    Expired --> Deleted: Cleanup job runs
    Deleted --> [*]
    
    note right of Active
        Valid for 5 minutes
        Can only be used once
    end note
```

---

## Ticket Validation Flow

### Online Mode (Default)

```mermaid
sequenceDiagram
    participant Attendee
    participant ScannerApp
    participant CheckInService
    participant Database
    participant Cache
    
    Attendee->>ScannerApp: Present QR Code
    ScannerApp->>ScannerApp: Scan QR Code<br/>Extract JWT
    
    ScannerApp->>CheckInService: Validate Ticket<br/>POST /api/tickets/validate<br/>{jwt, scannerId}
    
    CheckInService->>CheckInService: Verify JWT Signature<br/>using Public Key
    
    alt Signature Invalid
        CheckInService-->>ScannerApp: Error: Invalid Ticket (Forged)
        ScannerApp-->>Attendee: ❌ ENTRY DENIED<br/>Invalid Ticket
    else Signature Valid
        CheckInService->>CheckInService: Check JWT Expiration
        
        alt Ticket Expired
            CheckInService-->>ScannerApp: Error: Ticket Expired
            ScannerApp-->>Attendee: ❌ ENTRY DENIED<br/>Ticket Expired
        else Ticket Valid
            CheckInService->>Cache: Check if already scanned<br/>(Redis: ticketId)
            
            alt Already Scanned
                Cache-->>CheckInService: Ticket found in scanned set
                CheckInService-->>ScannerApp: Error: Already Scanned
                ScannerApp-->>Attendee: ❌ ENTRY DENIED<br/>Ticket Already Used
            else First Scan
                CheckInService->>Cache: Add to scanned set<br/>SET scanned:ticketId
                CheckInService->>Database: Record Scan<br/>{ticketId, scannerId, timestamp}
                CheckInService-->>ScannerApp: Success: Entry Granted
                ScannerApp-->>Attendee: ✅ ENTRY GRANTED<br/>Welcome!
            end
        end
    end
```

### Offline Mode (Emergency)

```mermaid
sequenceDiagram
    participant Attendee
    participant ScannerApp
    participant LocalDB
    participant PublicKey
    
    Note over ScannerApp: Scanner is OFFLINE<br/>No internet connection
    
    Attendee->>ScannerApp: Present QR Code
    ScannerApp->>ScannerApp: Scan QR Code<br/>Extract JWT
    
    ScannerApp->>ScannerApp: Parse JWT<br/>(header.payload.signature)
    
    ScannerApp->>PublicKey: Verify Signature<br/>using stored Public Key
    
    alt Signature Invalid
        ScannerApp-->>Attendee: ❌ ENTRY DENIED<br/>Invalid Ticket
    else Signature Valid
        ScannerApp->>ScannerApp: Check JWT Expiration<br/>(from exp claim)
        
        alt Ticket Expired
            ScannerApp-->>Attendee: ❌ ENTRY DENIED<br/>Ticket Expired
        else Ticket Valid
            ScannerApp->>LocalDB: Check local scanned list<br/>SELECT WHERE ticketId = ?
            
            alt Already Scanned Locally
                LocalDB-->>ScannerApp: Ticket found
                ScannerApp-->>Attendee: ❌ ENTRY DENIED<br/>Already Scanned (Local)
            else First Scan Locally
                ScannerApp->>LocalDB: Add to scanned list<br/>INSERT scan record
                ScannerApp->>LocalDB: Add to sync queue<br/>{ticketId, timestamp, offline:true}
                ScannerApp-->>Attendee: ✅ ENTRY GRANTED<br/>(OFFLINE MODE)
                
                Note over ScannerApp: Scan queued for sync<br/>when connection returns
            end
        end
    end
```

### Validation Details

#### JWT Signature Verification (Cryptographic Process)

```
Server Side (Ticket Generation):
1. Create payload: {ticketId, eventId, ...}
2. Sign: SIGNATURE = SHA256withRSA(header.payload, PRIVATE_KEY)
3. Result: JWT = header.payload.signature

Scanner Side (Validation):
1. Split JWT: parts = jwt.split(".")
2. Extract: header = parts[0], payload = parts[1], signature = parts[2]
3. Verify: SHA256withRSA.verify(header.payload, signature, PUBLIC_KEY)
4. If verification succeeds → Ticket is authentic
5. If verification fails → Ticket is forged/tampered
```

#### Online Validation Steps

```
1. Authentication Check
   - Verify scanner credentials (JWT)
   - Check if scanner is ACTIVE (not revoked)

2. Ticket Signature Verification
   - Parse JWT
   - Verify RSA signature
   - If invalid → REJECT (forged ticket)

3. Expiration Check
   - Extract exp claim from JWT
   - Compare with current time
   - If expired → REJECT

4. Duplicate Check (Redis)
   - Key: "scanned:{ticketId}"
   - Check if key exists
   - If exists → REJECT (already scanned)
   - If not exists → SET key with TTL (24 hours)

5. Database Logging
   - Insert into ticket_scans table:
     {
       ticket_id: from JWT,
       scanner_id: from request,
       scanned_at: current timestamp,
       validation_mode: "ONLINE",
       scan_result: "SUCCESS"
     }

6. Response
   - Return success with attendee details
   - Scanner displays: "Welcome, {attendee_name}!"
```

#### Offline Validation Steps

```
1. JWT Parsing
   - Split JWT into parts
   - Decode Base64URL payload

2. Signature Verification (Local)
   - Use stored PUBLIC_KEY
   - Verify signature cryptographically
   - If invalid → REJECT

3. Expiration Check (Local)
   - Extract exp from payload
   - Compare with device time
   - If expired → REJECT

4. Local Duplicate Check
   - Query local SQLite: 
     SELECT * FROM scanned_tickets WHERE ticket_id = ?
   - If found → REJECT
   - If not found → Continue

5. Local Recording
   - INSERT INTO scanned_tickets (ticket_id, scanned_at)
   - INSERT INTO sync_queue (ticket_id, scanned_at, synced: false)

6. Response
   - Display: "Entry Granted (Offline Mode)"
   - Show sync pending indicator
```

---

## Offline Mode Architecture

### Why Offline Mode?

Events often happen in locations with poor or no internet connectivity:
- Rural areas
- Basements/underground venues
- High-attendance events (network congestion)
- Outdoor festivals
- Emergency situations

The system must continue functioning even without internet.

### Offline Capabilities

```mermaid
graph TB
    subgraph "Online Operations"
        O1[Real-time duplicate detection across all gates]
        O2[Immediate sync to central database]
        O3[Live analytics dashboard]
        O4[Scanner settings updates]
    end
    
    subgraph "Offline Operations"
        F1[JWT signature verification]
        F2[Local duplicate detection at same gate]
        F3[Scan logging to local database]
        F4[Queue for later sync]
    end
    
    subgraph "Limitations in Offline Mode"
        L1[Cannot detect duplicates at other gates]
        L2[Cannot receive scanner revocations immediately]
        L3[Cannot update settings in real-time]
        L4[Relies on device clock for expiry check]
    end
    
    style F1 fill:#90EE90
    style F2 fill:#90EE90
    style L1 fill:#FFB6C1
    style L2 fill:#FFB6C1
```

### Offline Data Flow

```mermaid
sequenceDiagram
    participant Gate1 as Scanner (Gate 1)
    participant Gate2 as Scanner (Gate 2)
    participant Server as Check-in Service
    
    Note over Gate1,Gate2: Both scanners go OFFLINE
    
    rect rgb(255, 200, 200)
        Note over Gate1,Gate2: OFFLINE PERIOD
        
        Gate1->>Gate1: Scan Ticket ABC<br/>✅ Valid (first scan at Gate 1)
        Gate2->>Gate2: Scan Ticket ABC<br/>✅ Valid (Gate 2 doesn't know)
        
        Note over Gate1,Gate2: PROBLEM: Same ticket scanned twice!<br/>Offline mode cannot prevent this.
    end
    
    Note over Gate1,Gate2: Connection restored
    
    rect rgb(200, 255, 200)
        Note over Gate1,Gate2: SYNC PERIOD
        
        Gate1->>Server: Sync scans<br/>[{ticketABC, 10:00am}]
        Server->>Server: Record: Gate 1 scanned ABC at 10:00
        
        Gate2->>Server: Sync scans<br/>[{ticketABC, 10:05am}]
        Server->>Server: Detect: ABC already scanned!<br/>Flag as duplicate
        Server->>Server: Create alert for investigation
    end
```

### Sync Strategy

#### When to Sync

```
1. Automatic Sync Triggers:
   - Every N minutes (configurable, default: 15 minutes)
   - When connection restored after being offline
   - When scanner app comes to foreground
   - Before device goes to sleep

2. Manual Sync:
   - Admin can trigger sync from scanner UI
   - Force sync button available

3. Smart Sync:
   - Only sync if there are pending scans
   - Batch multiple scans in single request
   - Retry failed syncs with exponential backoff
```

#### Sync Process

```mermaid
sequenceDiagram
    participant Scanner
    participant LocalDB
    participant CheckInService
    participant Database
    
    Scanner->>LocalDB: Get pending scans<br/>SELECT * FROM sync_queue<br/>WHERE synced = false
    LocalDB-->>Scanner: Return scan records
    
    Scanner->>CheckInService: POST /api/scanners/sync<br/>{scannerId, scans: [...]}
    
    CheckInService->>CheckInService: Authenticate Scanner
    
    loop For each scan
        CheckInService->>Database: Check if ticket already scanned
        
        alt First scan of this ticket
            CheckInService->>Database: Record scan
            CheckInService->>CheckInService: Mark as SUCCESS
        else Duplicate scan
            CheckInService->>Database: Record as DUPLICATE_SCAN
            CheckInService->>CheckInService: Mark as DUPLICATE<br/>Create alert
        end
    end
    
    CheckInService->>CheckInService: Get latest scanner settings
    CheckInService-->>Scanner: Return {syncResults, settings}
    
    Scanner->>LocalDB: Update sync_queue<br/>SET synced = true
    Scanner->>Scanner: Apply new settings if changed
```

#### Sync Payload Example

```json
POST /api/scanners/sync
Request:
{
  "scannerId": "scanner-uuid",
  "scans": [
    {
      "ticketId": "ticket-123",
      "scannedAt": "2025-11-29T10:05:00Z",
      "validationMode": "OFFLINE",
      "deviceTime": "2025-11-29T10:05:00Z"
    },
    {
      "ticketId": "ticket-456",
      "scannedAt": "2025-11-29T10:10:00Z",
      "validationMode": "OFFLINE",
      "deviceTime": "2025-11-29T10:10:00Z"
    }
  ],
  "lastSyncAt": "2025-11-29T09:00:00Z"
}

Response:
{
  "syncResults": [
    {
      "ticketId": "ticket-123",
      "status": "SUCCESS",
      "message": "Scan recorded"
    },
    {
      "ticketId": "ticket-456",
      "status": "DUPLICATE",
      "message": "Ticket already scanned at Gate B",
      "originalScanTime": "2025-11-29T10:08:00Z",
      "originalScanner": "Gate B Scanner"
    }
  ],
  "settings": {
    "offlineModeEnabled": true,
    "syncIntervalMinutes": 15,
    "maxOfflineHours": 24
  },
  "serverTime": "2025-11-29T10:30:00Z"
}
```

### Conflict Resolution

```
Scenario: Same ticket scanned at multiple gates while offline

Gate A (10:05am): Scans ticket ABC - Valid ✅
Gate B (10:08am): Scans ticket ABC - Valid ✅ (doesn't know about Gate A)

Both sync at 10:30am:

Server Resolution:
1. Receive scan from Gate A (ABC at 10:05)
   - First scan seen by server
   - Record as VALID
   
2. Receive scan from Gate B (ABC at 10:08)
   - Server already has ABC scanned at 10:05
   - Record as DUPLICATE
   - Create alert for investigation
   
3. Admin Investigation:
   - Review: Was this intentional fraud?
   - Or: Genuine user scanned at wrong gate first?
   - Action: Take appropriate measures

4. Prevention for Future:
   - Reduce offline periods
   - More frequent syncs
   - Better gate coordination
```

---

## Security Model

### Cryptographic Architecture

```mermaid
graph TB
    subgraph "Server (Trust Anchor)"
        PrivateKey[RSA Private Key<br/>4096-bit<br/>NEVER leaves server]
        PublicKey[RSA Public Key<br/>Distributed to scanners]
    end
    
    subgraph "Ticket Generation"
        Ticket[Ticket Data<br/>JSON Payload]
        JWT[Signed JWT Token]
        QR[QR Code<br/>Contains JWT]
    end
    
    subgraph "Scanner Device"
        StoredPubKey[Stored Public Key]
        Verification[Signature Verification]
    end
    
    PrivateKey -->|Signs| JWT
    PublicKey -->|Copied to| StoredPubKey
    Ticket -->|Payload| JWT
    JWT -->|Encoded in| QR
    
    QR -->|Scanned| Verification
    StoredPubKey -->|Verifies| Verification
    
    style PrivateKey fill:#ff6666
    style PublicKey fill:#66ff66
    style Verification fill:#6666ff
```

### Security Layers

#### Layer 1: Scanner Authentication
```
Every scanner request must include:
- Scanner credentials (JWT)
- Signed with server's private key during registration
- Contains: scannerId, scannerName, expiry (1 year)

Server validates:
1. JWT signature is valid
2. JWT not expired
3. Scanner status is ACTIVE (not revoked)
4. Scanner ID exists in database
```

#### Layer 2: Ticket Cryptography
```
Ticket Security Guarantees:

1. Cannot Forge Tickets
   - Requires server's private key to sign
   - Private key never leaves server
   - Scanners only have public key (can verify, not sign)

2. Cannot Tamper with Tickets
   - Any modification invalidates signature
   - Changing even 1 character breaks verification
   - Scanner detects tampering immediately

3. Cannot Reuse Expired Tickets
   - Expiry timestamp in JWT payload
   - Verified during each scan
   - Cannot be modified (signature protection)

4. Cannot Clone Tickets (Online Mode)
   - Each ticketId tracked in Redis
   - Duplicate detection across all gates
   - Scan recorded in database
```

#### Layer 3: Network Security
```
All API Communication:
- HTTPS/TLS 1.3 only
- Certificate pinning in mobile app
- API rate limiting
- Request signing for sensitive operations
```

#### Layer 4: Scanner Revocation
```
Immediate Revocation:
1. Admin marks scanner as REVOKED
2. Scanner added to revocation list (Redis)
3. Next API request from scanner → DENIED
4. Settings push: {status: "REVOKED"}
5. Scanner clears local data

Scanner receives revocation on:
- Next sync attempt
- Real-time push (if WebSocket connected)
- Settings update request
```

### Attack Scenarios and Mitigations

#### Attack 1: Ticket Forgery
```
Attack: Attacker creates fake ticket JWT
Mitigation: 
- Cannot sign without private key
- Signature verification fails
- Scanner rejects ticket
Result: ❌ Attack prevented
```

#### Attack 2: Ticket Cloning
```
Attack: User shares same ticket QR with friend

Online Mode:
- First scan: ✅ Valid
- Second scan: ❌ Duplicate detected
Result: ✅ Attack prevented

Offline Mode:
- Different gates: Both scans succeed locally
- Server detects on sync
- Alert generated for investigation
Result: ⚠️ Detected post-facto
```

#### Attack 3: Scanner Credential Theft
```
Attack: Attacker steals scanner credentials from device

Mitigation:
1. Admin revokes stolen scanner
2. Scanner credential becomes invalid
3. Server denies all requests
4. New scanner issued with new credentials

Best Practice:
- Secure credential storage (Android Keystore)
- Device encryption
- Remote wipe capability
Result: ✅ Contained quickly
```

#### Attack 4: Replay Attack
```
Attack: Attacker captures network traffic, replays requests

Mitigation:
- HTTPS prevents traffic capture
- Request timestamps checked
- Nonce validation for sensitive operations
- Short-lived sessions
Result: ✅ Attack prevented
```

---

## Data Models

### Database Entities

#### 1. registration_tokens
```sql
CREATE TABLE registration_tokens (
    id UUID PRIMARY KEY,
    token VARCHAR(100) UNIQUE NOT NULL,
    expires_at TIMESTAMP NOT NULL,
    used BOOLEAN DEFAULT FALSE,
    used_at TIMESTAMP,
    created_by VARCHAR(100),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    validity_minutes INTEGER NOT NULL,
    scanner_name VARCHAR(200),
    notes TEXT
);

-- Indexes
CREATE INDEX idx_token ON registration_tokens(token);
CREATE INDEX idx_valid_tokens ON registration_tokens(used, expires_at) 
    WHERE used = FALSE;
```

**Purpose:** Store time-limited tokens for scanner registration

**Lifecycle:**
1. Created when admin generates QR code
2. Marked as used when scanner registers
3. Cleaned up after 7 days (scheduled job)

#### 2. scanners
```sql
CREATE TABLE scanners (
    id UUID PRIMARY KEY,
    scanner_id VARCHAR(100) UNIQUE NOT NULL,
    name VARCHAR(200) NOT NULL,
    credentials TEXT NOT NULL,
    status VARCHAR(20) NOT NULL, -- ACTIVE, REVOKED
    settings JSONB NOT NULL,
    device_info JSONB,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    last_synced_at TIMESTAMP,
    created_by VARCHAR(100)
);

-- Indexes
CREATE INDEX idx_scanner_id ON scanners(scanner_id);
CREATE INDEX idx_scanner_status ON scanners(status);
CREATE INDEX idx_last_synced ON scanners(last_synced_at);
```

**Settings JSONB Structure:**
```json
{
  "offlineModeEnabled": false,
  "syncIntervalMinutes": 15,
  "offlineDataSource": "AUTO_SYNC",
  "maxOfflineHours": 24,
  "allowedEventIds": ["event-1", "event-2"]
}
```

#### 3. tickets
```sql
CREATE TABLE tickets (
    id UUID PRIMARY KEY,
    ticket_id VARCHAR(100) UNIQUE NOT NULL,
    booking_id UUID NOT NULL,
    event_id UUID NOT NULL,
    attendee_name VARCHAR(200) NOT NULL,
    attendee_email VARCHAR(200),
    ticket_type VARCHAR(50),
    jwt_token TEXT NOT NULL,
    qr_code_base64 TEXT,
    status VARCHAR(20) NOT NULL, -- ACTIVE, SCANNED, CANCELLED
    valid_from TIMESTAMP NOT NULL,
    valid_until TIMESTAMP NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    
    FOREIGN KEY (booking_id) REFERENCES bookings(id),
    FOREIGN KEY (event_id) REFERENCES events(id)
);

-- Indexes
CREATE INDEX idx_ticket_id ON tickets(ticket_id);
CREATE INDEX idx_booking_id ON tickets(booking_id);
CREATE INDEX idx_event_id ON tickets(event_id);
CREATE INDEX idx_ticket_status ON tickets(status);
```

#### 4. ticket_scans
```sql
CREATE TABLE ticket_scans (
    id UUID PRIMARY KEY,
    ticket_id VARCHAR(100) NOT NULL,
    scanner_id UUID NOT NULL,
    scanned_at TIMESTAMP NOT NULL,
    validation_mode VARCHAR(20) NOT NULL, -- ONLINE, OFFLINE
    scan_result VARCHAR(20) NOT NULL, -- SUCCESS, DUPLICATE, EXPIRED, INVALID
    device_time TIMESTAMP,
    synced_at TIMESTAMP,
    metadata JSONB,
    
    FOREIGN KEY (scanner_id) REFERENCES scanners(id)
);

-- Indexes
CREATE INDEX idx_ticket_scans_ticket ON ticket_scans(ticket_id);
CREATE INDEX idx_ticket_scans_scanner ON ticket_scans(scanner_id);
CREATE INDEX idx_ticket_scans_time ON ticket_scans(scanned_at);
CREATE INDEX idx_ticket_scans_result ON ticket_scans(scan_result);
```

**Metadata JSONB Example:**
```json
{
  "attendeeName": "John Doe",
  "eventName": "Tech Conference 2025",
  "gateLocation": "Main Entrance",
  "duplicateOf": "scan-uuid-123",
  "alertGenerated": true
}
```

#### 5. rsa_keys
```sql
CREATE TABLE rsa_keys (
    id UUID PRIMARY KEY,
    key_version INTEGER UNIQUE NOT NULL,
    private_key TEXT NOT NULL, -- Encrypted
    public_key TEXT NOT NULL,
    algorithm VARCHAR(20) DEFAULT 'RS256',
    key_size INTEGER DEFAULT 4096,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    rotated_at TIMESTAMP,
    status VARCHAR(20) NOT NULL -- ACTIVE, ROTATED, REVOKED
);

-- Only one active key at a time
CREATE UNIQUE INDEX idx_active_key ON rsa_keys(status) 
    WHERE status = 'ACTIVE';
```

### Scanner Local Database (SQLite)

```sql
-- Scanner credentials and config
CREATE TABLE scanner_config (
    key VARCHAR(50) PRIMARY KEY,
    value TEXT NOT NULL
);

-- Locally scanned tickets
CREATE TABLE scanned_tickets (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    ticket_id VARCHAR(100) UNIQUE NOT NULL,
    scanned_at TIMESTAMP NOT NULL,
    attendee_name VARCHAR(200),
    event_name VARCHAR(200),
    validation_result VARCHAR(20) NOT NULL
);

-- Pending sync queue
CREATE TABLE sync_queue (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    ticket_id VARCHAR(100) NOT NULL,
    scanned_at TIMESTAMP NOT NULL,
    device_time TIMESTAMP NOT NULL,
    validation_mode VARCHAR(20) NOT NULL,
    synced BOOLEAN DEFAULT FALSE,
    sync_attempts INTEGER DEFAULT 0,
    last_sync_attempt TIMESTAMP,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- Indexes
CREATE INDEX idx_sync_pending ON sync_queue(synced) WHERE synced = FALSE;
CREATE INDEX idx_scanned_ticket_id ON scanned_tickets(ticket_id);
```

---

## API Specifications

### Base URL
```
Production: https://api.nexgate.com/v1
Staging: https://staging-api.nexgate.com/v1
```

### Authentication
```
All requests require authentication via JWT in header:
Authorization: Bearer {scanner_credentials_jwt}
```

### API Endpoints

#### 1. Generate Registration Token
```http
POST /api/registration-tokens/generate
Authorization: Bearer {admin_jwt}

Request Body:
{
  "validityMinutes": 5,
  "notes": "Gate A scanner for Main Entrance"
}

Response: 201 Created
{
  "token": "abc-123-xyz-789",
  "qrCodeBase64": "data:image/png;base64,iVBORw0KG...",
  "expiresAt": "2025-11-29T10:15:00Z",
  "validityMinutes": 5
}

Errors:
400 Bad Request - Invalid validity minutes
401 Unauthorized - Invalid admin credentials
```

#### 2. Register Scanner
```http
POST /api/scanners/register

Request Body:
{
  "token": "abc-123-xyz-789",
  "deviceName": "Gate A Scanner",
  "deviceInfo": {
    "model": "Samsung Galaxy S21",
    "osVersion": "Android 14",
    "appVersion": "1.0.0"
  }
}

Response: 201 Created
{
  "scannerId": "scanner-uuid",
  "credentials": "eyJhbGc...scanner_jwt",
  "publicKey": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCg...",
  "settings": {
    "offlineModeEnabled": false,
    "syncIntervalMinutes": 15,
    "maxOfflineHours": 24
  }
}

Errors:
400 Bad Request - Invalid or expired token
409 Conflict - Token already used
```

#### 3. Validate Ticket (Online)
```http
POST /api/tickets/validate
Authorization: Bearer {scanner_credentials}

Request Body:
{
  "jwt": "eyJhbGc...ticket_jwt",
  "scannerId": "scanner-uuid",
  "deviceTime": "2025-11-29T10:30:00Z"
}

Response: 200 OK
{
  "valid": true,
  "ticketId": "ticket-123",
  "attendeeName": "John Doe",
  "eventName": "Tech Conference 2025",
  "ticketType": "VIP",
  "message": "Entry granted"
}

Response: 400 Bad Request (Duplicate)
{
  "valid": false,
  "ticketId": "ticket-123",
  "reason": "DUPLICATE",
  "message": "Ticket already scanned",
  "originalScanTime": "2025-11-29T10:25:00Z",
  "originalScanner": "Gate B Scanner"
}

Response: 400 Bad Request (Expired)
{
  "valid": false,
  "ticketId": "ticket-123",
  "reason": "EXPIRED",
  "message": "Ticket has expired",
  "expiredAt": "2025-11-29T10:00:00Z"
}

Response: 400 Bad Request (Invalid)
{
  "valid": false,
  "reason": "INVALID_SIGNATURE",
  "message": "Ticket signature is invalid (possible forgery)"
}

Errors:
401 Unauthorized - Invalid scanner credentials
403 Forbidden - Scanner revoked
```

#### 4. Sync Scanner
```http
POST /api/scanners/sync
Authorization: Bearer {scanner_credentials}

Request Body:
{
  "scannerId": "scanner-uuid",
  "scans": [
    {
      "ticketId": "ticket-123",
      "scannedAt": "2025-11-29T10:05:00Z",
      "validationMode": "OFFLINE",
      "deviceTime": "2025-11-29T10:05:00Z"
    }
  ],
  "lastSyncAt": "2025-11-29T09:00:00Z"
}

Response: 200 OK
{
  "syncResults": [
    {
      "ticketId": "ticket-123",
      "status": "SUCCESS",
      "message": "Scan recorded"
    }
  ],
  "settings": {
    "offlineModeEnabled": true,
    "syncIntervalMinutes": 15
  },
  "serverTime": "2025-11-29T10:30:00Z",
  "pendingUpdates": []
}

Errors:
401 Unauthorized - Invalid scanner credentials
403 Forbidden - Scanner revoked
```

#### 5. Get Scanner Settings
```http
GET /api/scanners/{scannerId}/settings
Authorization: Bearer {scanner_credentials}

Response: 200 OK
{
  "offlineModeEnabled": false,
  "syncIntervalMinutes": 15,
  "offlineDataSource": "AUTO_SYNC",
  "maxOfflineHours": 24,
  "allowedEventIds": ["event-1", "event-2"]
}

Errors:
401 Unauthorized - Invalid scanner credentials
404 Not Found - Scanner not found
```

#### 6. Revoke Scanner
```http
POST /api/scanners/{scannerId}/revoke
Authorization: Bearer {admin_jwt}

Response: 200 OK
{
  "scannerId": "scanner-uuid",
  "status": "REVOKED",
  "revokedAt": "2025-11-29T10:30:00Z"
}

Errors:
401 Unauthorized - Invalid admin credentials
404 Not Found - Scanner not found
```

---

## Database Schema

### Full Schema Diagram

```mermaid
erDiagram
    REGISTRATION_TOKENS ||--o| SCANNERS : "used_by"
    SCANNERS ||--o{ TICKET_SCANS : "performs"
    TICKETS ||--o{ TICKET_SCANS : "scanned"
    EVENTS ||--o{ TICKETS : "contains"
    BOOKINGS ||--|| TICKETS : "generates"
    RSA_KEYS ||--o{ TICKETS : "signs"
    
    REGISTRATION_TOKENS {
        uuid id PK
        varchar token UK
        timestamp expires_at
        boolean used
        timestamp used_at
        varchar created_by
        int validity_minutes
        varchar scanner_name
    }
    
    SCANNERS {
        uuid id PK
        varchar scanner_id UK
        varchar name
        text credentials
        varchar status
        jsonb settings
        jsonb device_info
        timestamp last_synced_at
    }
    
    TICKETS {
        uuid id PK
        varchar ticket_id UK
        uuid booking_id FK
        uuid event_id FK
        varchar attendee_name
        text jwt_token
        text qr_code_base64
        varchar status
        timestamp valid_from
        timestamp valid_until
    }
    
    TICKET_SCANS {
        uuid id PK
        varchar ticket_id FK
        uuid scanner_id FK
        timestamp scanned_at
        varchar validation_mode
        varchar scan_result
        jsonb metadata
    }
    
    EVENTS {
        uuid id PK
        varchar name
        timestamp event_date
        varchar venue
    }
    
    BOOKINGS {
        uuid id PK
        uuid event_id FK
        varchar customer_email
        timestamp booking_date
    }
    
    RSA_KEYS {
        uuid id PK
        int key_version UK
        text private_key
        text public_key
        varchar status
    }
```

### Key Relationships

```
1. registration_tokens → scanners
   - One token can register one scanner
   - Token is marked as used when scanner created
   
2. scanners → ticket_scans
   - One scanner performs many scans
   - Track which scanner scanned which ticket
   
3. tickets → ticket_scans
   - One ticket can be scanned multiple times (duplicates logged)
   - Each scan recorded separately
   
4. events → tickets
   - One event has many tickets
   - Tickets belong to specific event
   
5. bookings → tickets
   - One booking generates one or more tickets
   - Ticket inherits customer info from booking
   
6. rsa_keys → tickets
   - Active RSA key used to sign all new tickets
   - Key rotation supported for security
```

---

## Deployment Architecture

### Infrastructure Overview

```mermaid
graph TB
    subgraph "Client Layer"
        ScannerApp[Scanner Android App]
        AdminWeb[Admin Web Dashboard]
        CustomerApp[Customer Mobile App]
    end
    
    subgraph "Load Balancer"
        LB[AWS Application Load Balancer]
    end
    
    subgraph "Application Layer"
        API1[Check-in Service Instance 1]
        API2[Check-in Service Instance 2]
        API3[Check-in Service Instance 3]
    end
    
    subgraph "Cache Layer"
        Redis[(Redis Cluster<br/>Scan Deduplication)]
    end
    
    subgraph "Database Layer"
        PG_Primary[(PostgreSQL Primary)]
        PG_Replica[(PostgreSQL Replica)]
    end
    
    subgraph "Storage Layer"
        S3[S3 Bucket<br/>QR Code Images]
    end
    
    subgraph "Monitoring"
        CloudWatch[CloudWatch Logs]
        Grafana[Grafana Dashboard]
    end
    
    ScannerApp --> LB
    AdminWeb --> LB
    CustomerApp --> LB
    
    LB --> API1
    LB --> API2
    LB --> API3
    
    API1 --> Redis
    API2 --> Redis
    API3 --> Redis
    
    API1 --> PG_Primary
    API2 --> PG_Primary
    API3 --> PG_Primary
    
    PG_Primary --> PG_Replica
    
    API1 --> S3
    API2 --> S3
    API3 --> S3
    
    API1 --> CloudWatch
    API2 --> CloudWatch
    API3 --> CloudWatch
    
    CloudWatch --> Grafana
```

### Deployment Configuration

#### Production Environment

```yaml
Check-in Service:
  Instances: 3 (Auto-scaling: 2-10)
  Instance Type: t3.large (2 vCPU, 8 GB RAM)
  Deployment: Blue-Green with ECS
  Health Check: /api/health every 30s
  
Database:
  Type: Amazon RDS PostgreSQL 15
  Instance: db.r6g.xlarge (4 vCPU, 32 GB RAM)
  Storage: 500 GB SSD (auto-scaling enabled)
  Replication: 1 read replica in different AZ
  Backup: Daily automated backups, 30-day retention
  
Redis:
  Type: Amazon ElastiCache
  Node Type: cache.r6g.large (2 vCPU, 13 GB RAM)
  Cluster: 3 nodes (1 primary, 2 replicas)
  Persistence: AOF enabled
  
Load Balancer:
  Type: Application Load Balancer
  SSL: AWS Certificate Manager
  Zones: Multi-AZ deployment
  
Monitoring:
  CloudWatch: All application and infrastructure metrics
  Grafana: Custom dashboards for scan analytics
  PagerDuty: Alert escalation
  
Backups:
  Database: Daily automated + on-demand
  Redis: Daily snapshots
  S3: Versioning enabled
```

### Scaling Strategy

```
Horizontal Scaling (API Instances):
- Metric: CPU > 70% or Request Count > 1000/min
- Scale up: Add 1 instance
- Scale down: Remove 1 instance if CPU < 30%
- Min instances: 2
- Max instances: 10

Database Scaling:
- Vertical: Upgrade instance type during low-traffic window
- Horizontal: Add read replicas for reporting/analytics
- Connection pooling: HikariCP with max 100 connections

Redis Scaling:
- Vertical: Upgrade node type
- Horizontal: Add replica nodes
- Cluster mode: Enable for > 10M keys

Regional Expansion:
- Deploy Check-in Service in multiple AWS regions
- Use Route 53 for geo-routing
- Replicate database across regions (read replicas)
```

### Disaster Recovery

```
RTO (Recovery Time Objective): 1 hour
RPO (Recovery Point Objective): 5 minutes

Recovery Procedures:

1. Database Failure:
   - Automatic failover to replica (< 2 minutes)
   - Promote replica to primary
   - Update application config
   - Restore read replica from backup

2. API Service Failure:
   - Auto Scaling Group spawns new instances
   - Load Balancer routes to healthy instances
   - Failed instances terminated and replaced

3. Redis Failure:
   - Automatic failover to replica
   - Application continues with slight latency
   - Rebuild cache from database if needed

4. Complete Region Failure:
   - Route 53 failover to backup region
   - Promote backup region database to primary
   - Update scanner apps via backend config
```

---

## Monitoring and Analytics

### Key Metrics

```
Scanner Metrics:
- Total active scanners
- Scanners online vs offline
- Scan rate per scanner
- Sync frequency and success rate
- Average offline duration

Ticket Metrics:
- Total scans per event
- Valid scans vs duplicates vs invalid
- Scan success rate
- Average scan time (online vs offline)
- Peak scan throughput

Performance Metrics:
- API response time (p50, p95, p99)
- Database query performance
- Redis hit/miss ratio
- Error rate by endpoint

Security Metrics:
- Invalid ticket attempts
- Scanner authentication failures
- Duplicate scan alerts
- Suspicious patterns (multiple duplicates)
```

### Alerting

```
Critical Alerts (PagerDuty):
- Database connection pool exhausted
- API error rate > 5%
- Redis cluster down
- Duplicate scan rate > 10%

Warning Alerts (Slack):
- Scanner offline > 30 minutes
- Sync failure rate > 20%
- API response time > 2s (p95)
- Database replication lag > 10s

Info Alerts (Email):
- Daily scan summary
- Weekly duplicate report
- Monthly scanner registration report
```

---

## Appendix

### Glossary

**RSA (Rivest-Shamir-Adleman)**: Asymmetric encryption algorithm used for digital signatures

**JWT (JSON Web Token)**: Compact, URL-safe means of representing claims between two parties

**QR Code**: Two-dimensional barcode that can be scanned by cameras

**Scanner Registration**: Process of linking a scanner device to the system

**Offline Mode**: Scanner operation without internet connectivity

**Duplicate Scan**: Attempt to scan the same ticket multiple times

**Sync Queue**: Local storage of scans waiting to be sent to server

**Public Key**: Cryptographic key used to verify signatures (safe to distribute)

**Private Key**: Cryptographic key used to create signatures (must remain secret)

### References

- JWT RFC: https://datatracker.ietf.org/doc/html/rfc7519
- RSA Cryptography: PKCS #1 v2.2
- QR Code Standard: ISO/IEC 18004:2015
- Android Keystore: https://developer.android.com/training/articles/keystore

### Change Log

**Version 1.0** (2025-11-29)
- Initial architecture document
- Complete system design
- All core flows documented

---

**Document Maintained By:** Nexgate Platform Team  
**Last Updated:** November 29, 2025  
**Next Review:** December 29, 2025

# NEXGATE EVENT MANAGEMENT PLATFORM

**Version:** 3.0  
**Last Updated:** November 2024  
**Document Owner:** Product Team

---

## 1. PLATFORM OVERVIEW

### What is Nexgate Events?

A **social commerce-integrated event management platform** where events and products live together in one ecosystem.

### The Problem We Solve

**For Hosts:**
- Slow payouts (5-7 days)
- High fees (8-15%)
- Events disconnected from products
- Complex ticket management
- Limited check-in devices

**For Attendees:**
- Events discovered through spam
- Tickets scattered everywhere
- Can't see which friends are going
- No product connection

### The Nexgate Solution

**For Hosts:**
- ✅ 48-hour payout (fastest in industry)
- ✅ 10% platform fee (transparent)
- ✅ Link products to events (unlimited)
- ✅ Simple per-tier pricing
- ✅ Unlimited scanner devices
- ✅ Coupon code system
- ✅ Social feed discovery

**For Attendees:**
- ✅ Discover through friends
- ✅ One QR per ticket
- ✅ Shop event products
- ✅ Hybrid options (physical/online)
- ✅ Mix free & paid tickets
- ✅ Use coupon codes

---

## 2. CORE PHILOSOPHY

### The 7 Unbreakable Laws

#### 1. One Ticket = One Unique QR Code
Every ticket has its own cryptographically signed QR code. Prevents fraud, perfect tracking, works offline.

#### 2. 48-Hour Payout Rule
Host receives money 48 hours after event ends. Period.

#### 3. Social Commerce First
Events ARE products. They live in the same feed. Events drive product sales, products drive event attendance.

#### 4. Hybrid Events, Hybrid Pricing
Physical ≠ Online. Different experiences = different prices.

#### 5. Per-Tier Pricing Freedom
Each tier decides: FREE or PAID. No global toggle. Mix freely.

#### 6. Device Linking for Scanners
No accounts needed. Generate link → Scan with any device → Revoke anytime.

#### 7. Gallery is Required
Minimum 3 photos. Events with photos get 3x more bookings.

---

## 3. USER ROLES

### Host (Event Creator)

**What they can do:**
- Create/edit/delete events
- Set ticket pricing & tiers
- Link unlimited products
- Generate scanner links
- Create coupon codes
- View analytics
- Receive payouts
- Respond to reviews

### Attendee

**What they can do:**
- Browse/search events
- Purchase tickets (with coupons)
- Transfer tickets
- Check-in with QR
- Leave reviews
- Shop event products
- Share events

### Scanner Device (No Account)

**What it is:**
- Any device with scanner link
- No Nexgate account needed

**What it can do:**
- Scan QR codes (specific event only)
- Show check-in confirmation
- Display real-time count
- Work offline

---

## 4. EVENT TYPES

### One-Time Event

Single date, fixed capacity.

**Use cases:** Product launches, pop-ups, workshops, concerts

**Example:**
```
Fashion Launch Party
March 15, 2025, 7:00 PM
Wynwood Gallery, Miami
$25 General, $50 VIP
100 capacity
```

### Recurring Series

Repeats weekly/monthly.

**Use cases:** Yoga classes, networking meetups, bootcamps

**Configuration:**
- Repeat: Weekly/Bi-weekly/Monthly
- Days: Mon, Wed, Fri
- End: Never/After X times/End date

**Example:**
```
Sunday Morning Yoga
Every Sunday, 8:00 AM
$25 per class
30 capacity per class
```

### How Recurring Payments Work

**Pay-Per-Class Model:**

Each class is a separate purchase with its own ticket.

```
USER BUYS TICKETS:

March 16 class → $25 → QR Code #1
March 23 class → $25 → QR Code #2  
March 30 class → $25 → QR Code #3

Each ticket = unique QR code
Each purchase = separate transaction
Each class = separate payout 48h after
```

**Why different QR codes?**
- Clear separation (each class is distinct)
- Works offline (no database lookup needed)
- Prevents fraud (can't reuse old ticket)
- Easy refunds (refund specific class)
- Simple transfers (transfer one class)
- Better tracking (attendance per class)

**User Experience:**

Tickets grouped in wallet by series:
```
┌─────────────────────────────────────┐
│ SUNDAY MORNING YOGA SERIES          │
├─────────────────────────────────────┤
│ Upcoming classes you purchased:     │
│                                     │
│ ✓ March 16 · 8:00 AM                │
│   [View QR Code]                    │
│                                     │
│ ○ March 23 · 8:00 AM                │
│   [View QR Code]                    │
│                                     │
│ ○ March 30 · 8:00 AM                │
│   [View QR Code]                    │
└─────────────────────────────────────┘

Smart features:
- Grouped by series name
- Highlights today's class
- Reminders show correct QR
- "Class 1 of 3 you purchased"
```

**Host Dashboard:**
```
SUNDAY MORNING YOGA (Recurring)

Next 6 classes:
━━━━━━━━━━━━━━━━━━
March 16 · $25 · 12/30 sold
March 23 · $25 · 18/30 sold
March 30 · $25 · 20/30 sold
April 6 · $25 · 25/30 sold
April 13 · $25 · 30/30 sold
April 20 · $25 · 30/30 sold

Revenue per class
Payout 48h after each class
```

**Future Enhancement (Phase 2):**
- Class packs: 10-class pack for $200
- Monthly unlimited: $99/month subscription
- Same QR for packs (use anytime)

### Multi-Day Event

Multiple consecutive days, same ticket.

**Use cases:** Festivals, retreats, conferences

**Features:**
- Same QR works all days
- Track attendance per day
- Allow re-entry each day

**Example:**
```
Wellness Retreat
March 15-17, 2025 (3 days)
Bali Resort
$450 (all 3 days)
50 capacity
```

### Location Types

#### In-Person Only
- Google Maps address (always visible)
- Parking info (optional)
- Venue capacity

#### Online Only
- Zoom/Google Meet/Custom
- Link revealed after purchase
- Unlimited or limited capacity

#### Hybrid (Physical + Online)
- Separate pricing for each
- Different capacities
- Different benefits
- Independent tracking

---

## 5. TICKET SYSTEM

### Per-Tier Pricing (Core Concept)

**Each tier independently decides: FREE or PAID**

No global toggle. Maximum flexibility.

### Creating Ticket Tiers

**Every tier has:**
1. **Name** - "VIP", "General", "Economy"
2. **Pricing** - ○ FREE or ○ PAID $[__]
3. **Capacity** - How many available
4. **Description** - What's included

### Example: In-Person Event

```
HOST CREATES:

TIER 1: Economy
- Pricing: ● FREE
- Capacity: 30
- Description: Standing room, general entry

TIER 2: Regular
- Pricing: ● PAID $35
- Capacity: 20
- Description: Reserved seat, drink, gift bag

TIER 3: VIP
- Pricing: ● PAID $75
- Capacity: 10
- Description: Front row, meet & greet, merch

SYSTEM DISPLAYS:
"FREE & PAID OPTIONS"
"From FREE to $75"
Total: 60 tickets
```

### Example: Hybrid Event

```
PHYSICAL TICKETS:

TIER 1: Standard In-Person
- ● PAID $40 · 25 capacity
- Entry, seating, refreshments

TIER 2: VIP In-Person
- ● PAID $85 · 10 capacity
- Front row, meet & greet

ONLINE TICKETS:

TIER 1: Basic Virtual
- ● FREE · Unlimited
- Livestream only

TIER 2: Premium Virtual
- ● PAID $20 · 100 capacity
- HD stream, recording, Q&A
```

### Ticket Purchase Flow

#### Single Tier Purchase
```
1. Select tier: "VIP ($75)"
2. Quantity: 2
3. Enter names for each
4. Apply coupon (optional)
5. Payment: $150
6. 2 unique QR codes sent
```

#### Mixed Tier Purchase
```
1. Select "Economy (FREE)" × 2
2. Add "VIP ($75)" × 1
3. Enter 3 names
4. Apply coupon: "FRIEND20" (-$15)
5. Payment: $60
6. 3 unique QR codes sent
```

### QR Code Structure

**Each QR contains:**
- Unique ticket ID
- Event ID
- User ID
- Tier ID
- Cryptographic signature
- Cannot be forged
- Works offline

---

## 6. HYBRID EVENTS & PRICING

### Why Hybrid Matters

Physical ≠ Online = Different pricing

### Host Setup

```
STEP 1: Choose ● Hybrid

STEP 2: Physical Tiers
Economy: FREE, 20 capacity
Premium: $50, 15 capacity

STEP 3: Online Tiers
Basic: FREE, Unlimited
Premium: $20, 50 capacity
```

### Attendee Selection

```
STEP 1: Choose Type
● In-Person  ○ Virtual

STEP 2: Choose Tier
[Based on selection]

Physical:
💚 Economy - FREE
⭐ Premium - $50

Virtual:
💻 Basic - FREE
💻 Premium - $20
```

---

## 7. SCANNER SYSTEM (DEVICE LINKING)

### How It Works

Generate link → Open on ANY device → Scan

No app. No account. Any device.

### Creating Scanner Links

```
EVENT DASHBOARD → [+ Add Scanner]

Device name: "Front Desk iPad"
Expires: ● After event  ○ Custom

[Generate Link]

→ Link: nexgate.app/scan/abc123xyz
→ QR code to share
→ Valid for this event only
```

### Using Scanner

**On ANY device:**
1. Open link in browser
2. Camera permission
3. Point at ticket QR
4. Instant validation

**Scanner Interface:**
```
┌─────────────────────┐
│ NEXGATE SCANNER     │
│ Beach Yoga - Mar 16 │
├─────────────────────┤
│ [CAMERA VIEW]       │
│ Point at QR code    │
├─────────────────────┤
│ 28/60 checked in    │
└─────────────────────┘
```

**Success:**
```
✓ Emma Wilson
Ticket: #2847
Tier: VIP ($75)
First-time! 🎉
```

### Features

**Works Online:**
- Real-time validation
- Live updates
- Full details

**Works Offline:**
- Cryptographic validation
- Local storage
- Syncs when online

**Security:**
- Auto-expires
- Revoke anytime
- Event-specific
- Activity tracking

---

## 8. PRODUCT INTEGRATION (SIMPLIFIED)

### Link Products to Events

Attach products from your shop or any shop on Nexgate. Unlimited products.

### Adding Products

```
EVENT DASHBOARD → Products Tab

[+ Add Product from My Shop]
[+ Add by Product Link]

OPTION 1: From Your Shop
→ Browse your products
→ Select any/all
→ [Add Selected]

OPTION 2: By Link
→ Paste: nexgate.com/products/yoga-mat
→ System fetches details
→ [Add Product]
```

### Managing Products

```
ATTACHED PRODUCTS (12):

📸 Yoga Mat - $65
   From: @yogagear
   [Remove]

📸 Water Bottle - $15
   From: Your Shop
   [Remove]

[+ Add More Products]

Can add/remove anytime:
✓ Before event
✓ During event
✓ After event
```

### Display to Attendees

**On Event Page:**
```
EVENT MARKETPLACE

📸 Yoga Mat - $65
   by @yogagear
   [View Product]

📸 Water Bottle - $15
   by @sunstudio
   [View Product]

📸 Workshop Recording - $10
   by @sunstudio
   [View Product]

+ View All Products (9 more)

[Browse Event Marketplace →]
```

Shows first 3-5 products, then "View All"

**Event Marketplace Page:**
Full grid of all attached products (unlimited)

### That's It!

**Simple rules:**
- ✅ Attach unlimited products
- ✅ Yours or others' shops
- ✅ Add/remove anytime
- ✅ No timing restrictions
- ✅ Display on event page
- ✅ Users shop when they want

---

## 9. COUPON SYSTEM (NEW!)

### Generate Discount Codes

Create coupon codes for ticket discounts.

### Creating Coupons

```
EVENT DASHBOARD → Coupons Tab

[+ Create New Coupon]

┌─────────────────────────────────────┐
│ CREATE COUPON                       │
├─────────────────────────────────────┤
│ Coupon code:                        │
│ [EARLYBIRD2025]                     │
│                                     │
│ Discount type:                      │
│ ● Percentage: [20]%                 │
│ ○ Fixed amount: $[__]               │
│                                     │
│ Applies to:                         │
│ ☑️ All ticket tiers                 │
│ ☐ Specific tiers only               │
│                                     │
│ Usage limit:                        │
│ ● Unlimited uses                    │
│ ○ Limited: [100] total uses         │
│ ○ One use per customer              │
│                                     │
│ Valid period:                       │
│ Start: [March 1, 2025]              │
│ End: [March 10, 2025]               │
│ ○ No expiration                     │
│                                     │
│ [Create Coupon]                     │
└─────────────────────────────────────┘
```

### Managing Coupons

```
ACTIVE COUPONS (3):

┌─────────────────────────────────────┐
│ EARLYBIRD2025                       │
│ 20% off all tickets                 │
│ Used: 23 times                      │
│ Valid until: Mar 10                 │
│ [Copy Code] [Edit] [Disable]       │
└─────────────────────────────────────┘

┌─────────────────────────────────────┐
│ FRIEND50                            │
│ $5 off all tickets                  │
│ Used: 7/50 times                    │
│ No expiration                       │
│ [Copy Code] [Edit] [Disable]       │
└─────────────────────────────────────┘

┌─────────────────────────────────────┐
│ VIP100                              │
│ $10 off VIP tier only               │
│ Used: 2/10 times                    │
│ Valid until: Mar 15                 │
│ [Copy Code] [Edit] [Disable]       │
└─────────────────────────────────────┘
```

### Attendee Using Coupon

```
CHECKOUT

Order Summary:
VIP Ticket × 1          $75.00

Have a coupon code?
[EARLYBIRD2025        ] [Apply]

✓ Coupon applied: EARLYBIRD2025
Discount (20%):        -$15.00
────────────────────────────────
Total:                 $60.00

[Complete Purchase - $60]
```

### Sharing Coupons

```
EARLYBIRD2025

[Copy Code] → "Copied!"

Share via:
[📧 Email] [📱 SMS] [📋 Copy Link]

Direct link with coupon:
nexgate.com/events/beach-yoga?coupon=EARLYBIRD2025
```

### Coupon Analytics

```
COUPON PERFORMANCE

EARLYBIRD2025:
- Uses: 23
- Discount given: $345
- Revenue generated: $1,380
- Conversion boost: +15%

Top performers:
1. EARLYBIRD2025 (23 uses)
2. FRIEND50 (7 uses)
3. VIP100 (2 uses)
```

---

## 10. REVIEW SYSTEM

### Collection Timeline

**2 hours after event:**
"Quick rating ⭐" → Tap 5 stars

**24 hours later:**
Full review request + incentives

**1 week later:**
Final reminder

### Review Form

```
RATE BEACH YOGA

Overall: ⭐⭐⭐⭐⭐ (required)

Quick ratings (optional):
Venue: ⭐⭐⭐⭐⭐
Instructor: ⭐⭐⭐⭐⭐
Organization: ⭐⭐⭐⭐☆

Tell us more: (optional)
[Amazing sunrise session...]

Add photos: [+] [+] [+]

Privacy:
● Public  ○ Anonymous  ○ Private

EARN:
✓ 50 points ($5 credit)
✓ 10% off next event
+ Photos: 100 bonus points

[Submit Review]
```

### Display

```
⭐ 4.8 out of 5 (127 reviews)

BREAKDOWN:
⭐⭐⭐⭐⭐ ████████ 89%
⭐⭐⭐⭐☆ ███      8%

MOST MENTIONED:
🌅 Great vibes (42)
🧘 Amazing instructor (38)

REVIEWS:

Emma Wilson ⭐⭐⭐⭐⭐
"Magical sunrise session..."
📸📸📸
👍 12 helpful

↳ Host: "Thank you Emma! 🙏"
```

---

## 11. PAYMENT & PAYOUT

### When Attendee Buys

```
1. Select ticket
2. Apply coupon (optional)
3. Enter payment
4. Charge immediately
5. Funds → Escrow
6. Confirmation sent
```

### Escrow System

```
Purchase → Escrow → Event Completes → Wait 48h → Payout

Timeline:
Mar 1: Ticket bought ($75) → Escrow
Mar 16: Event ends (7pm)
Mar 18: Payout (7pm, 48h later)
```

### The 48-Hour Rule

**Event End Time + 48 Hours = Payout**

### Payout Calculation

```
SIMPLE:
Gross: $1,000
Platform fee (10%): -$100
Net: $900

MIXED FREE + PAID:
Free: 40 tickets (no revenue)
Paid: 30 × $25 = $750
Fee (on paid only): -$75
Net: $675

WITH COUPONS:
Gross: $1,500
Coupons used: -$200
Platform fee (10% of $1,300): -$130
Net: $1,170
```

### Payout Dashboard

```
UPCOMING:
Beach Yoga - Mar 16
Payout: Mar 18, 7pm
Amount: $945
Status: ⏰ 32h left

COMPLETED:
Sunset Yoga - Mar 9
Paid: Mar 11, 6:30pm
Amount: $612.50
Status: ✓ Deposited
```

### Refunds

**Host-initiated:**
- Full refund to attendee
- Platform fee non-refundable
- Host absorbs fee cost

**Automatic (event cancelled):**
- All attendees refunded
- Full amount + platform fee
- Nexgate absorbs cost
- Within 24 hours

---

## 12. NOTIFICATION SYSTEM

### Philosophy

**Simple, smart, not annoying.**

Only send notifications that matter. Automatic reminders based on event timing.

### Attendance Confirmation (Optional)

**Host can enable:**

```
EVENT SETTINGS → Attendee Management

☑️ Request attendance confirmation
Send [3] days before event

Attendees confirm they're coming
Host sees who confirmed vs pending
```

**Attendee receives:**
```
┌─────────────────────────────────────┐
│ CONFIRM YOUR ATTENDANCE             │
├─────────────────────────────────────┤
│ Beach Yoga - March 16, 5pm          │
│                                     │
│ Are you still coming?               │
│                                     │
│ [✓ Yes, I'm Coming]                 │
│ [✗ Can't Make It]                   │
└─────────────────────────────────────┘
```

**Host Dashboard:**
```
ATTENDANCE TRACKER

Total tickets: 30

✓ Confirmed: 22 people
⏳ Pending: 5 (no response)
✗ Can't attend: 3 people

Expected: ~73% attendance

[Send Reminder to Pending]
```

**Benefits:**
- Host plans better (food, materials, space)
- Reduces no-shows
- Professional event management

### Reminder Schedule (Automatic)

**Smart formula based on event timing:**

```
IF event is 2-7 DAYS AWAY:
→ 1 day before
→ 1 hour before

IF event is 8-30 DAYS AWAY:
→ 1 week before
→ 1 day before
→ 1 hour before

IF event is 30+ DAYS AWAY:
→ 2 weeks before
→ 1 week before
→ 1 day before
→ 1 hour before

IF event is SAME DAY:
→ 1 hour before only
```

**Rules:**
- Always: 1 hour before (critical)
- If time allows: 1 day before
- If far out: 1 week before
- If very far: 2 weeks before
- Maximum: 4 reminders total
- Minimum: 1 reminder (1h before)

### Adaptive Reminders

**System adjusts based on purchase timing:**

```
Event: March 30 (30 days away)

User A buys March 1:
→ 2 weeks, 1 week, 1 day, 1h reminders

User B buys March 28 (2 days before):
→ 1 day, 1h reminders only

User C buys March 30 (same day):
→ 1h reminder only

Each user gets only relevant reminders
```

### Notification Timeline

**Before Event:**

```
[X days before] (if host enabled)
"Confirm your attendance"
[Yes, I'm Coming] [Can't Make It]

[Auto-calculated]
"Beach Yoga is next week!"

[1 day before]
🔔 Beach Yoga tomorrow at 5pm!
📍 1234 Ocean Drive, Miami Beach
🚗 Street parking ($2/hr)
[View Ticket] [Get Directions]

[1 hour before]
🔔 Beach Yoga starts in 1 hour!
⏰ 5:00 PM - Don't be late!
[View Your Ticket QR]
```

**After Event:**

```
[2 hours after]
"How was Beach Yoga? ⭐"
Tap to rate: ⭐⭐⭐⭐⭐
Earn 50 points!

[24 hours after]
"Leave a review (earn 50 points)"
[Write Review]
```

### Total Notifications Per Attendee

**Minimum** (same-day event):
1. 1h before reminder
2. Rate request (2h after)
Total: **2 notifications**

**Typical** (1-week advance):
1. 1 day before reminder
2. 1h before reminder
3. Rate request (2h after)
Total: **3 notifications**

**Maximum** (1+ month advance):
1. Confirmation request (if host enabled)
2. 2 weeks before
3. 1 week before
4. 1 day before
5. 1h before
6. Rate request (2h after)
Total: **6 notifications**

### Host Notifications

**Sales Activity:**
```
"New ticket sale! 🎉"
Sarah Chen · Premium ($40)
Total: 23/30 tickets

[View Dashboard]
```

**Sold Out:**
```
"Beach Yoga is SOLD OUT! 🔥"
30/30 tickets · $1,200 gross

[View Analytics]
```

**New Review:**
```
"New 5-star review! ⭐"
Emma: "Amazing sunrise session..."

[View Review] [Respond]
```

**Payout Ready:**
```
"💰 Your payout is ready!"
$945 from Beach Yoga

[View Details]
```

### Host Controls

```
EVENT SETTINGS → Notifications

ATTENDANCE CONFIRMATION:
○ Disabled
● Enabled: Send [3] days before

REMINDER SCHEDULE:
● Automatic (smart formula) ← Default
○ Custom schedule

POST-EVENT:
☑️ Request rating (2h after)
☑️ Request review (24h after)

[Save Settings]
```

### User Notification Settings

```
NOTIFICATION PREFERENCES

Event Reminders:
☑️ Smart reminders (recommended)
☐ Disable all except 1h before

Review Requests:
☑️ After attending events
☐ Disable review requests

Friend Activity:
☑️ When friends create events
☑️ When friends buy tickets

Cannot disable:
- 1h before event (critical)

[Save Preferences]
```

### Anti-Spam Rules

**Frequency Caps:**
- Max 4 reminders per event
- No more than 2 notifications per day
- 24h+ between marketing notifications

**Smart Batching:**
If multiple events same day:
```
"You have 3 events tomorrow 🗓️"
- Beach Yoga · 5pm
- Pottery Class · 7pm
- Food Festival · 8pm

[View All Tickets]
```

---

## 13. USER JOURNEYS

### Journey 1: Host Creates Event

```
1. Emma logs in
2. [Create Event]
3. Upload 3 photos
4. Title: "Beach Yoga"
5. Category: Fitness
6. Location: ● Hybrid
7. Physical: FREE (20) + $40 (15)
8. Online: FREE (∞) + $15 (50)
9. Link products: Yoga mat, recording
10. Create coupon: "EARLY20" (20% off)
11. [Publish]
12. Share on Instagram

Time: 12 minutes
```

```
EVENT DAY:
- Generate 2 scanner links
- Send to iPad + volunteer
- 28 physical checked in
- 119 online joined
- Event ends successfully
```

```
48 HOURS LATER:
- Payout: $945 deposited
- 24 reviews (4.9 stars)
- 18 product purchases
```

### Journey 2: Attendee Discovers & Attends

```
Sarah scrolling feed
→ "Beach Yoga - Emma +8 friends going"
→ Taps event

Event page:
→ Beautiful photos
→ 4.9 stars
→ Virtual Premium: $15

Checkout:
→ Apply coupon: "EARLY20"
→ $15 → $12
→ Apple Pay
→ Done!

Event day:
→ Zoom link opens
→ 130 people online
→ 90-min session
→ Downloads recording

2 hours later:
→ "Rate ⭐"
→ 5 stars
→ Earns 150 points
→ Buys recording: $10
```

---

## 14. TECHNICAL REQUIREMENTS

### Performance

- Event page: < 2s
- Search: < 1s
- Scanner: < 500ms
- Payment: < 3s

### Scalability

- 10k concurrent users
- 1k simultaneous purchases
- 500 simultaneous scans

### Availability

- 99.9% uptime
- Zero-downtime deploys
- < 4h recovery

### Security

- OAuth login
- JWT tokens
- AES-256 encryption
- TLS 1.3
- PCI DSS compliant
- GDPR compliant
- SHA-256 QR signing

### Mobile

- Mobile-first design
- Works on 3G/4G
- Offline scanner
- PWA support
- iOS 14+, Android 8+

---

## 15. BUSINESS RULES

### Capacity

- Cannot oversell
- Atomic transactions
- Per-tier tracking
- Sold-out states

### Ticket Transfers

**Allowed:**
- Before event starts
- Unlimited transfers
- New QR for recipient

**Not allowed:**
- During/after event

### Check-In Rules

**Standard:** One scan
**Multi-day:** Same QR all days
**Recurring:** Track class usage

### Coupon Rules

**Validation checks:**
- Code exists
- Not expired
- Usage limit not reached
- Applies to selected tickets
- Can be combined? (host setting)

### Refund Policies

**Host options:**
1. Full refund anytime
2. Full until X days before
3. Partial after deadline
4. No refunds

---

## 16. SUCCESS METRICS

### Platform Growth (Year 1)

- Month 1: 50 events, 500 tickets
- Month 6: 500 events, 10k tickets
- Month 12: 2k events, 50k tickets

### Key Metrics

**Engagement:**
- View → purchase: 15%+
- Repeat attendees: 40%+
- Review rate: 40%+
- Social share: 20%+
- Coupon usage: 25%+

**Revenue:**
- GMV growth
- Platform revenue (10%)
- Avg ticket price
- Product revenue: +30%

**Quality:**
- Event rating: 4.5+
- Host retention: 60%+
- Scanner success: 99%+
- Uptime: 99.9%+

---

## 17. IMPLEMENTATION ROADMAP

### Phase 1: MVP (Months 1-3)

**Build:**
1. Event creation (all types)
2. Hybrid pricing
3. Per-tier pricing (free+paid)
4. Multiple ticket purchase
5. Unique QR per ticket
6. Gallery (3 photos min)
7. Device linking scanner
8. Product attachment (unlimited)
9. Coupon system
10. 48-hour payout
11. Basic reviews
12. Feed integration

**Success:**
- 50 events
- 500 tickets
- 4.0+ rating

### Phase 2: Enhanced (Months 4-6)

**Add:**
1. Advanced analytics
2. Ticket transfer
3. Review filters
4. Host responses
5. Attendee messaging
6. Advanced coupons (tiered, bundled)
7. Product marketplace analytics

**Success:**
- 200 events/month
- 30% hybrid adoption
- 50% review rate

### Phase 3: Scale (Months 7-12)

**Add:**
1. Class packs
2. Monthly passes
3. Multi-language
4. International currency
5. API access
6. White-label

**Success:**
- 1,000+ events/month
- 50,000+ tickets/month
- Profitable

---

## CONCLUSION

### What Makes Nexgate Different

**The Formula:**
```
Social Commerce + Events = Network Effects
```

**The Flywheel:**
```
Host creates event
→ Links products
→ Creates coupons
→ Shares to feed
→ Friends discover
→ Use coupons
→ Buy tickets
→ Shop products
→ Leave reviews
→ More social proof
→ REPEAT
```

### Key Advantages

1. **48-hour payout** - Fastest in industry
2. **Unlimited products** - Any shop on platform
3. **Coupon system** - Built-in marketing tool
4. **Device linking** - Unlimited scanners
5. **Per-tier pricing** - Mix free + paid freely
6. **Hybrid events** - Physical + online pricing
7. **Social discovery** - Friends drive attendance

### Next Steps

1. Build MVP (3 months)
2. Beta with 50 hosts
3. Iterate & improve
4. Scale to 1,000+ hosts
5. Dominate social commerce events

---

**END OF DOCUMENT**

*Version: 3.0 - Simplified & Focused*
*Last Updated: November 2024*

# Event Management System - Requirements & User Flow Documentation

## Table of Contents

1. [Overview](#overview)
2. [Event Types](#event-types)
3. [Core Features](#core-features)
4. [Event Creation Flows](#event-creation-flows)
5. [Ticket Management](#ticket-management)
6. [Registration & Attendance](#registration--attendance)
7. [User Roles & Permissions](#user-roles--permissions)
8. [Business Rules](#business-rules)
9. [Data Relationships](#data-relationships)

---

## Overview

The Event Management System supports three distinct event lifecycle types with flexible ticketing, multiple location options, and comprehensive access control. The system is designed to handle everything from simple one-time events to complex recurring series with variable pricing.

### Key Capabilities
- Multiple event types (One-time, Multi-day, Recurring)
- Flexible ticket types with varied pricing
- Multiple location modes (In-person, Online, Hybrid)
- Access control (Public, Private, Unlisted)
- Integration with online meeting providers
- Comprehensive registration and attendance tracking

---

## Event Types

### 1. One-Time Event
A single event occurring once at a specific date and time.

**Required Information:**
- Start date & time
- End date & time
- Location details
- Ticket types (optional)

**Example:**
```
Event: Tech Conference 2025
Date: March 15, 2025
Time: 9:00 AM - 5:00 PM
Location: Convention Center
```

---

### 2. Multi-Day Event
A single event spanning multiple consecutive or non-consecutive days.

**Required Information:**
- Start date
- End date
- Schedule per day (can vary)
- Location details (can vary per day)
- Single ticket for all days

**Characteristics:**
- ONE event, multiple days
- ONE ticket purchase covers ALL days
- Each day can have different start/end times
- Each day can have different locations
- User registers once, attends multiple days

**Example:**
```
Event: Music Festival 2025
Dates: June 10-12, 2025

Day 1 (June 10): 2:00 PM - 11:00 PM - Main Stage
Day 2 (June 11): 12:00 PM - 11:00 PM - Multiple Stages  
Day 3 (June 12): 1:00 PM - 10:00 PM - Main Stage

Ticket: $200 (access all 3 days)
```

---

### 3. Recurring Event
A series of separate events happening on a repeating schedule.

**Required Information:**
- Series name & description
- Recurrence pattern:
  - Frequency: Daily, Weekly, Monthly, Yearly
  - Interval: Every 1 week, every 2 weeks, etc.
  - Days of week (for weekly)
  - Day of month (for monthly)
- Date range: Start date → End date OR number of occurrences
- Default schedule for sessions
- Default ticket types

**Characteristics:**
- MULTIPLE separate events (series)
- Each session = independent event
- Users buy tickets per session
- Must buy at least ONE session to register for series
- Can buy multiple sessions at once or separately
- Each session can have own ticket types and pricing

**Example:**
```
Series: Monday Yoga Classes
Pattern: Every Monday
Time: 9:00 AM - 10:00 AM
Duration: January - March 2025 (12 sessions)

Individual Sessions:
- Session 1: Jan 6, 2025, 9-10 AM
- Session 2: Jan 13, 2025, 9-10 AM
- Session 3: Jan 20, 2025, 9-10 AM
... (12 total)

Each session has tickets: Regular ($15), Student ($10), Member ($8)
```

**Recurrence Patterns Supported:**
- Daily: Every day, every 2 days, weekdays only, etc.
- Weekly: Every Monday, Mon/Wed/Fri, every 2 weeks on Tuesday, etc.
- Monthly: First Monday, 15th of each month, last Friday, etc.
- Yearly: Same date each year

---

## Core Features

### Event Visibility & Access Control

```
┌──────────────────────────────────────────────────────────────┐
│ VISIBILITY OPTIONS                                           │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│  ○ Public                                                    │
│    • Discoverable in search                                  │
│    • Anyone can view and register                            │
│    • Appears in event listings                               │
│                                                              │
│  ○ Private                                                   │
│    • Not discoverable                                        │
│    • Invitation-only access                                  │
│    • Organizer sends invitations                             │
│    • Invitees must be explicitly added                       │
│                                                              │
│  ○ Unlisted                                                  │
│    • Not discoverable in search                              │
│    • Anyone with link can access                             │
│    • No invitation required                                  │
│    • Link-based sharing                                      │
│                                                              │
└──────────────────────────────────────────────────────────────┘
```

#### Public Events
- Visible to everyone
- Appear in search results and listings
- Anyone can register/buy tickets
- No access restrictions

#### Private Events
- Not visible in search
- Access by invitation only
- Organizer manages invitations

**Invitation System:**
- Organizer invites by email or username
- Invitations have optional expiration dates
- Invitation statuses: Pending, Accepted, Declined, Expired
- Invited users get notifications
- Can generate shareable invite links with tokens

**Invitation Expiration Rules:**
- Automatically expires when event ends
- Optional custom expiration date
- Token-based links can be regenerated (invalidates old tokens)

#### Unlisted Events
- Not discoverable in search
- Anyone with the link can access
- No explicit invitation needed
- Access through direct URL only

**Access Mechanism:**
- Simple approach: Direct URL with event ID
- Secure approach: URL includes access token
- Organizer can regenerate link (invalidates previous link)
- No expiration on the link itself (valid until event ends)

---

### Location Types

```
┌──────────────────────────────────────────────────────────────┐
│ LOCATION TYPE                                                │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│  ○ In-Person Only                                            │
│    Required: Physical address, venue name                    │
│    Optional: Coordinates (lat/long), directions             │
│                                                              │
│  ○ Online Only                                               │
│    Required: Meeting platform, link/credentials             │
│    Options: Manual link OR provider integration             │
│                                                              │
│  ○ Hybrid (Both)                                             │
│    Required: ALL in-person + online details                 │
│    Attendees choose: in-person OR online                    │
│                                                              │
└──────────────────────────────────────────────────────────────┘
```

#### In-Person Events
**Required Fields:**
- Venue name
- Full address
- City, State, Country

**Optional Fields:**
- Latitude/Longitude (for maps)
- Venue description
- Parking information
- Accessibility details

#### Online Events
**Meeting Provider Options:**

**Option 1: Manual Entry**
- Organizer provides meeting link directly
- Platform-agnostic (Zoom, Google Meet, Teams, Discord, etc.)
- Organizer manages meeting creation
- Meeting details stored:
  - Meeting URL
  - Meeting ID (optional)
  - Password/Access code (optional)

**Security for Manual Links:**
- Link hidden until 30 minutes before event
- User must be logged in
- User must have valid ticket
- Link visible until 1 hour after event ends

**Option 2: Provider Integration (Zoom)**
- OAuth connection to organizer's account
- System creates meeting automatically
- Enhanced security features available

**Zoom Integration Flow:**
```
┌─────────────────────────────────────────────────────────────┐
│ Event Creation: Online Event → Select "Connect with Zoom"  │
└──────────────────┬──────────────────────────────────────────┘
                   ↓
         ┌─────────────────────┐
         │ Has Zoom connected? │
         └─────────┬───────────┘
                   ↓
           ┌───────┴────────┐
           │                │
          NO               YES
           │                │
           ↓                ↓
┌──────────────────┐  ┌──────────────────┐
│ Redirect to Zoom │  │ Create meeting   │
│ OAuth page       │  │ immediately via  │
│                  │  │ API              │
└────────┬─────────┘  └─────────┬────────┘
         │                      │
         ↓                      │
┌──────────────────┐           │
│ User authorizes  │           │
│ on Zoom          │           │
└────────┬─────────┘           │
         │                      │
         ↓                      │
┌──────────────────┐           │
│ Save tokens to   │           │
│ user account     │           │
└────────┬─────────┘           │
         │                      │
         ↓                      │
┌──────────────────┐           │
│ Create meeting   │←──────────┘
│ via Zoom API     │
└────────┬─────────┘
         │
         ↓
┌──────────────────────────────┐
│ Each paid attendee gets      │
│ UNIQUE registration link     │
│ (cannot be shared)           │
└──────────────────────────────┘
```

**Zoom Integration Benefits:**
- Each registered attendee gets unique join URL
- URLs tied to email (not shareable)
- Waiting room can be enabled
- Attendance tracking automatic
- Registration approval control

**Zoom Account Responsibility:**
- Organizer uses their own Zoom account
- Organizer pays for Zoom subscription
- Platform creates meetings using organizer's credentials
- No cost to platform

#### Hybrid Events
**Requirements:**
- ALL in-person details (venue, address, etc.)
- ALL online details (meeting link/platform)

**Attendee Selection:**
- During registration, attendee chooses: "Attending in-person" OR "Attending online"
- Helps organizer plan:
  - Seating/catering for in-person
  - Meeting capacity for online
- Attendee can change preference before event

---

## Event Creation Flows

### Flow 1: One-Time Event Creation

```
┌──────────────────────────────────────────────────────────────┐
│ CREATE ONE-TIME EVENT                                        │
└──────────────────────┬───────────────────────────────────────┘
                       ↓
         ┌─────────────────────────────┐
         │ Step 1: Basic Information   │
         │ • Event name                │
         │ • Description               │
         │ • Category                  │
         │ • Cover image               │
         │ • Visibility (Public/Private│
         │   /Unlisted)                │
         └──────────┬──────────────────┘
                    ↓
         ┌─────────────────────────────┐
         │ Step 2: Date & Time         │
         │ • Start date & time         │
         │ • End date & time           │
         │ • Timezone                  │
         └──────────┬──────────────────┘
                    ↓
         ┌─────────────────────────────┐
         │ Step 3: Location Type       │
         │ Select:                     │
         │ • In-person                 │
         │ • Online                    │
         │ • Hybrid                    │
         └──────────┬──────────────────┘
                    ↓
    ┌───────────────┴────────────────┐
    │                                │
    ↓                                ↓
┌────────────────┐      ┌──────────────────────┐
│ If In-Person:  │      │ If Online:           │
│ • Venue        │      │ • Choose provider    │
│ • Address      │      │   - Manual link      │
│ • Coordinates  │      │   - Zoom integration │
└───────┬────────┘      │ • Meeting details    │
        │               └──────────┬───────────┘
        │                          │
        └────────┬─────────────────┘
                 ↓
         ┌─────────────────────────────┐
         │ Step 4: Tickets             │
         │ [Add Ticket Type] button    │
         │                             │
         │ For each ticket type:       │
         │ • Name                      │
         │ • Price                     │
         │ • Quantity                  │
         │ • Description               │
         │ • Sales start/end dates     │
         │                             │
         │ [Add Another Ticket Type]   │
         └──────────┬──────────────────┘
                    ↓
         ┌─────────────────────────────┐
         │ Step 5: Review & Publish    │
         │ • Preview event details     │
         │ • Save as draft OR          │
         │ • Publish immediately       │
         └─────────────────────────────┘
```

---

### Flow 2: Multi-Day Event Creation

```
┌──────────────────────────────────────────────────────────────┐
│ CREATE MULTI-DAY EVENT                                       │
└──────────────────────┬───────────────────────────────────────┘
                       ↓
         ┌─────────────────────────────┐
         │ Steps 1-3: Same as one-time │
         │ (Basic info, Location type) │
         └──────────┬──────────────────┘
                    ↓
         ┌─────────────────────────────┐
         │ Step 4: Multi-Day Schedule  │
         │ • Overall start date        │
         │ • Overall end date          │
         │                             │
         │ Configure each day:         │
         │                             │
         │ Day 1:                      │
         │ • Date: March 10, 2025      │
         │ • Start time: 9:00 AM       │
         │ • End time: 6:00 PM         │
         │ • Location (can differ)     │
         │ • Description               │
         │                             │
         │ Day 2:                      │
         │ • Date: March 11, 2025      │
         │ • Start time: 10:00 AM      │
         │ • End time: 8:00 PM         │
         │ • Location (can differ)     │
         │ • Description               │
         │                             │
         │ [Add Another Day]           │
         └──────────┬──────────────────┘
                    ↓
         ┌─────────────────────────────┐
         │ Step 5: Tickets             │
         │                             │
         │ Ticket Type Options:        │
         │                             │
         │ 1. Full Event Pass (common) │
         │    • Price: $200            │
         │    • Access to all days     │
         │                             │
         │ 2. Day Passes (optional)    │
         │    • Day 1 only: $80        │
         │    • Day 2 only: $80        │
         │    • Day 3 only: $60        │
         │                             │
         │ 3. VIP/Tier options         │
         └──────────┬──────────────────┘
                    ↓
         ┌─────────────────────────────┐
         │ Step 6: Review & Publish    │
         └─────────────────────────────┘
```

---

### Flow 3: Recurring Event Creation

```
┌──────────────────────────────────────────────────────────────┐
│ CREATE RECURRING EVENT                                       │
└──────────────────────┬───────────────────────────────────────┘
                       ↓
         ┌─────────────────────────────┐
         │ Step 1: Series Information  │
         │ • Series name               │
         │ • Description               │
         │ • Category                  │
         │ • Cover image               │
         │ • Visibility                │
         └──────────┬──────────────────┘
                    ↓
         ┌─────────────────────────────┐
         │ Step 2: Recurrence Pattern  │
         │                             │
         │ Frequency:                  │
         │ ○ Daily                     │
         │ ○ Weekly                    │
         │ ○ Monthly                   │
         │ ○ Yearly                    │
         │                             │
         │ Interval:                   │
         │ Every [1] [week(s)]         │
         │                             │
         │ If Weekly, select days:     │
         │ ☐ Monday                    │
         │ ☐ Tuesday                   │
         │ ☐ Wednesday                 │
         │ ☐ Thursday                  │
         │ ☐ Friday                    │
         │ ☐ Saturday                  │
         │ ☐ Sunday                    │
         │                             │
         │ Session Time:               │
         │ Start: [9:00 AM]            │
         │ End: [10:00 AM]             │
         │                             │
         │ Duration:                   │
         │ ○ End date: [March 31, 2025]│
         │ ○ Number of occurrences: 12 │
         │ ○ No end date (ongoing)     │
         └──────────┬──────────────────┘
                    ↓
         ┌─────────────────────────────┐
         │ Step 3: Location Type       │
         │ (Same as one-time event)    │
         └──────────┬──────────────────┘
                    ↓
         ┌─────────────────────────────┐
         │ Step 4: Default Ticket Types│
         │                             │
         │ These will apply to ALL     │
         │ sessions by default:        │
         │                             │
         │ Ticket Type 1:              │
         │ • Name: Regular             │
         │ • Price: $15                │
         │ • Quantity per session: 15  │
         │ • Description               │
         │                             │
         │ Ticket Type 2:              │
         │ • Name: Student             │
         │ • Price: $10                │
         │ • Quantity per session: 3   │
         │ • Requires verification     │
         │                             │
         │ Ticket Type 3:              │
         │ • Name: Member              │
         │ • Price: $8                 │
         │ • Quantity per session: 2   │
         │                             │
         │ [Add Another Ticket Type]   │
         └──────────┬──────────────────┘
                    ↓
         ┌─────────────────────────────┐
         │ Step 5: Generate Sessions   │
         │                             │
         │ System generates all        │
         │ sessions based on pattern:  │
         │                             │
         │ Preview:                    │
         │ • Session 1: Jan 6, 9-10 AM │
         │ • Session 2: Jan 13, 9-10 AM│
         │ • Session 3: Jan 20, 9-10 AM│
         │ ... (12 total sessions)     │
         │                             │
         │ Each session gets:          │
         │ • Copy of all ticket types  │
         │ • Default quantities        │
         │ • Default prices            │
         │                             │
         │ [Confirm & Generate]        │
         └──────────┬──────────────────┘
                    ↓
         ┌─────────────────────────────┐
         │ Step 6: Customize Sessions  │
         │         (Optional)          │
         │                             │
         │ Organizer can edit any      │
         │ individual session:         │
         │                             │
         │ • Change prices             │
         │ • Add/remove ticket types   │
         │ • Change quantities         │
         │ • Modify time/location      │
         │ • Cancel specific session   │
         │                             │
         │ Example: Jan 20 special     │
         │ guest session               │
         │ • Increase price to $20     │
         │ • Add VIP ticket ($30)      │
         └──────────┬──────────────────┘
                    ↓
         ┌─────────────────────────────┐
         │ Step 7: Publish Series      │
         │ • All sessions now active   │
         │ • Users can start registering│
         └─────────────────────────────┘
```

---

## Ticket Management

### Ticket Types Structure

**For One-Time & Multi-Day Events:**

```
Event
 │
 ├── Ticket Type 1: Early Bird
 │    ├── Name: "Early Bird"
 │    ├── Price: $80
 │    ├── Quantity Available: 100
 │    ├── Quantity Sold: 87
 │    ├── Description: "Save $40 with early registration"
 │    ├── Sales Start: Dec 1, 2024
 │    ├── Sales End: Jan 31, 2025
 │    └── Status: Active
 │
 ├── Ticket Type 2: Regular
 │    ├── Name: "Regular"
 │    ├── Price: $120
 │    ├── Quantity Available: 200
 │    ├── Quantity Sold: 45
 │    ├── Sales Start: Feb 1, 2025
 │    ├── Sales End: March 14, 2025
 │    └── Status: Active
 │
 └── Ticket Type 3: VIP
      ├── Name: "VIP Pass"
      ├── Price: $250
      ├── Quantity Available: 50
      ├── Quantity Sold: 28
      ├── Benefits: ["VIP lounge access", "Meet speakers", "Premium seating"]
      ├── Sales Start: Dec 1, 2024
      ├── Sales End: March 14, 2025
      └── Status: Active
```

**For Recurring Events:**

```
Series: "Monday Yoga"
 │
 ├── Default Ticket Templates
 │    ├── Template 1: Regular ($15)
 │    ├── Template 2: Student ($10)
 │    └── Template 3: Member ($8)
 │
 └── Sessions
      │
      ├── Session 1: Jan 6
      │    ├── Ticket Type: Regular - $15 (15 available, 12 sold)
      │    ├── Ticket Type: Student - $10 (3 available, 2 sold)
      │    └── Ticket Type: Member - $8 (2 available, 1 sold)
      │
      ├── Session 2: Jan 13
      │    ├── Ticket Type: Regular - $15 (15 available, 8 sold)
      │    ├── Ticket Type: Student - $10 (3 available, 1 sold)
      │    └── Ticket Type: Member - $8 (2 available, 0 sold)
      │
      └── Session 3: Jan 20 (Customized - Special Guest)
           ├── Ticket Type: Regular - $20 (15 available, 5 sold) ← Price changed
           ├── Ticket Type: Student - $15 (3 available, 1 sold) ← Price changed
           └── Ticket Type: VIP - $30 (5 available, 2 sold) ← New type added
```

### Ticket Type Properties

**Required Fields:**
- Name (e.g., "Early Bird", "VIP", "Student")
- Price (can be $0 for free tickets)
- Quantity available

**Optional Fields:**
- Description
- Benefits list
- Sales start date/time
- Sales end date/time
- Minimum purchase quantity
- Maximum purchase quantity per user
- Requires verification (e.g., student ID)
- Hidden (invite-only tickets)

### Ticket Purchase Rules

**General Rules:**
1. User must select at least one ticket
2. Cannot exceed available quantity
3. Cannot purchase after sales end date
4. Cannot purchase before sales start date
5. One ticket per session per user (for recurring events)

**For Recurring Events:**
1. First purchase = automatic series registration
2. Must buy at least one session to join series
3. Can buy different ticket types for different sessions
4. Can purchase multiple sessions at once
5. Can return later to purchase more sessions

**Ticket Selection Flow:**

```
┌──────────────────────────────────────────────────────────────┐
│ EVENT: Tech Conference 2025                                  │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│ Available Tickets:                                           │
│                                                              │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ ☐ Early Bird - $80                                     │ │
│ │   Save $40 with early registration                     │ │
│ │   [Only 13 left!] Sales end Jan 31                     │ │
│ └────────────────────────────────────────────────────────┘ │
│                                                              │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ ☐ Regular - $120                                       │ │
│ │   Standard conference access                           │ │
│ │   [200 available]                                      │ │
│ └────────────────────────────────────────────────────────┘ │
│                                                              │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ ☐ VIP Pass - $250                                      │ │
│ │   ✓ All conference access                              │ │
│ │   ✓ VIP lounge access                                  │ │
│ │   ✓ Meet the speakers                                  │ │
│ │   ✓ Premium seating                                    │ │
│ │   [22 available]                                       │ │
│ └────────────────────────────────────────────────────────┘ │
│                                                              │
│ Quantity: [1] ▼                                              │
│                                                              │
│ Selected: Regular Ticket × 1 = $120                          │
│                                                              │
│                                     [Proceed to Checkout →] │
└──────────────────────────────────────────────────────────────┘
```

**For Recurring Events:**

```
┌──────────────────────────────────────────────────────────────┐
│ SERIES: Monday Yoga - January 2025                           │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│ Select sessions you want to attend:                          │
│                                                              │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ Session: Monday, Jan 6, 2025 · 9:00 AM - 10:00 AM     │ │
│ │                                                        │ │
│ │ ☐ Regular - $15        [15 available]                 │ │
│ │ ☐ Student - $10        [3 available]                  │ │
│ │ ☐ Member - $8          [2 available]                  │ │
│ │ ☐ First-Timer Free - $0 [5 available]                 │ │
│ └────────────────────────────────────────────────────────┘ │
│                                                              │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ Session: Monday, Jan 13, 2025 · 9:00 AM - 10:00 AM    │ │
│ │                                                        │ │
│ │ ☐ Regular - $15        [15 available]                 │ │
│ │ ☐ Student - $10        [3 available]                  │ │
│ │ ☐ Member - $8          [2 available]                  │ │
│ │ ☐ First-Timer Free - $0 [5 available]                 │ │
│ └────────────────────────────────────────────────────────┘ │
│                                                              │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ Session: Monday, Jan 20, 2025 · 9:00 AM - 10:00 AM    │ │
│ │ 🌟 SPECIAL GUEST SESSION                               │ │
│ │                                                        │ │
│ │ ☐ Regular - $20        [15 available]                 │ │
│ │ ☐ Student - $15        [3 available]                  │ │
│ │ ☐ VIP - $30            [5 available] Meet the guest!  │ │
│ └────────────────────────────────────────────────────────┘ │
│                                                              │
│ Selected:                                                    │
│ • Jan 6 - Student ticket: $10                                │
│ • Jan 13 - Student ticket: $10                               │
│ • Jan 20 - Regular ticket: $20                               │
│                                                              │
│ Total: $40 for 3 sessions                                    │
│                                                              │
│                                     [Proceed to Checkout →] │
└──────────────────────────────────────────────────────────────┘
```

---

## Registration & Attendance

### Registration Flow

**For One-Time & Multi-Day Events:**

```
User selects ticket
       ↓
Proceeds to checkout
       ↓
Payment processed
       ↓
Registration created
       ↓
Ticket issued
       ↓
Confirmation email sent
       ↓
User can view ticket in "My Events"
```

**For Recurring Events:**

```
User selects session(s) and ticket type(s)
       ↓
First purchase?
       ↓
   ┌───┴────┐
  YES      NO
   │        │
   ↓        ↓
Create    Already
Series    registered
Registration
   │        │
   └───┬────┘
       ↓
Payment processed
       ↓
Session ticket(s) issued
       ↓
Confirmation email sent
       ↓
User can:
• View registered series
• See owned session tickets
• Purchase more sessions
```

### Registration Data Tracking

**One-Time Event Registration:**
- User ID
- Event ID
- Ticket Type ID
- Payment status
- Registration date/time
- Ticket unique code/QR
- Attendance status (for check-in)

**Multi-Day Event Registration:**
- User ID
- Event ID
- Ticket Type ID
- Payment status
- Registration date/time
- Ticket unique code/QR
- Attendance per day (optional tracking):
  - Day 1: Attended/Not attended
  - Day 2: Attended/Not attended
  - Day 3: Attended/Not attended

**Recurring Event Registration:**

**Series Level:**
- User ID
- Series ID
- Registration date (first purchase date)
- Status: Active/Cancelled
- Total sessions owned

**Session Level:**
- User ID
- Session ID
- Ticket Type ID
- Payment status
- Purchase date/time
- Ticket unique code/QR
- Attendance status

### Attendance Tracking

**Check-in Methods:**
1. QR code scan
2. Manual check-in by organizer
3. Email verification
4. Unique ticket code entry

**For Recurring Events:**
- Track attendance per session
- User can have tickets for sessions 1, 3, 5 but not 2, 4
- Each session = separate check-in

**Attendance Reports:**
- Who registered vs who attended
- No-show rate
- For recurring: attendance patterns across sessions

---

## User Roles & Permissions

### Role Definitions

**1. Event Organizer (Creator)**
- Creates events
- Manages event details
- Creates/modifies ticket types
- Manages invitations (for private events)
- Views registrations and attendance
- Can edit event before it starts
- Can cancel event
- Receives payments (event revenue)

**2. Attendee (Regular User)**
- Browses public/unlisted events
- Registers for events
- Purchases tickets
- Receives invitations (for private events)
- Views owned tickets
- Can cancel registration (based on refund policy)

**3. Platform Administrator**
- Manages all events
- Can modify/delete any event
- Views all registrations
- Manages users
- Handles disputes
- Platform-level reporting

### Organizer Capabilities

**Event Management:**
- Create new events (all types)
- Edit unpublished events (full edit)
- Edit published events (limited - can't change past dates, can modify future details)
- Cancel events (with attendee notifications)
- Duplicate events

**Ticket Management:**
- Create ticket types
- Modify ticket quantities
- Modify ticket prices (before sales start)
- Enable/disable ticket types
- Set sales periods

**Recurring Event Specific:**
- Customize individual sessions
- Cancel specific sessions
- Reschedule sessions (with attendee notifications)
- Modify session-specific ticket pricing

**Registration Management:**
- View all registrations
- Export attendee lists
- Send messages to attendees
- Manually add attendees (comp tickets)
- Issue refunds
- Check-in attendees

**For Private Events:**
- Send invitations
- Approve/reject registration requests
- Regenerate invite links
- View invitation status

### Attendee Capabilities

**Event Discovery:**
- Browse public events
- Search events by category, date, location
- Filter by event type
- View event details

**Registration:**
- Register for public events
- Access unlisted events via link
- Accept invitations for private events
- Select ticket types
- Purchase multiple tickets/sessions

**Account Management:**
- View "My Events" (upcoming, past, cancelled)
- View tickets/QR codes
- Download tickets
- Cancel registration (if allowed)
- Rate/review events (after attendance)

**For Recurring Events:**
- View registered series
- See which sessions owned
- Purchase additional sessions
- View attendance history

---

## Business Rules

### Event Creation Rules

1. **Required Information:**
   - Event name (3-200 characters)
   - Start date/time (must be in future)
   - End date/time (must be after start)
   - Location details (based on type)
   - At least one ticket type OR mark as free

2. **Date Validation:**
   - Start date must be in future (at event creation)
   - End date must be after start date
   - For multi-day: Each day's dates must be sequential or specified
   - For recurring: End date must be after start date OR specify number of occurrences

3. **Location Validation:**
   - In-person: Address required
   - Online: Meeting link OR provider integration required
   - Hybrid: Both in-person AND online details required

4. **Ticket Validation:**
   - At least one ticket type OR mark event as free
   - Ticket quantity must be positive integer or unlimited
   - Price must be >= 0
   - Sales end date must be before or on event start date
   - Sales start date must be before sales end date

### Registration Rules

1. **Capacity Management:**
   - Cannot register if event/session is at capacity
   - Cannot register if ticket type is sold out
   - For recurring: Each session has independent capacity

2. **Time Restrictions:**
   - Cannot register after event starts
   - Cannot register before ticket sales start
   - Cannot register after ticket sales end
   - For recurring: Can register for future sessions even if past sessions occurred

3. **User Restrictions:**
   - One registration per user per event (one-time/multi-day)
   - One ticket per user per session (recurring)
   - Cannot purchase same ticket type twice for same session
   - Can purchase different ticket types across different sessions

4. **Private Event Rules:**
   - Must have valid invitation
   - Invitation must not be expired
   - User email must match invitation email (or logged-in account)

5. **Payment Rules:**
   - Payment required before ticket issued (except free tickets)
   - Payment amount must match ticket price at time of purchase
   - For recurring: Can pay for multiple sessions in single transaction

### Cancellation & Refund Rules

**Event Cancellation (by Organizer):**
- Can cancel event at any time
- Must notify all registered attendees
- Automatic full refund to all attendees
- For recurring: Can cancel entire series OR individual sessions

**Registration Cancellation (by Attendee):**
- Depends on organizer's refund policy
- Common policies:
  - Full refund until X days before event
  - Partial refund until Y days before event
  - No refund after Z days before event
- For recurring:
  - Can cancel individual session tickets
  - If all sessions cancelled, series registration remains (can buy more sessions later)

**Automated Actions:**
- Send cancellation notifications
- Process refunds
- Update capacities
- Mark tickets as cancelled

### Recurring Event Specific Rules

1. **Session Generation:**
   - Sessions auto-generated based on recurrence pattern
   - Each session gets copy of default ticket types
   - Sessions created in "scheduled" status

2. **Session Customization:**
   - Organizer can modify any session independently
   - Changes to one session don't affect others
   - Can cancel individual sessions

3. **Registration Requirements:**
   - Must purchase at least one session to register for series
   - First purchase = automatic series registration
   - Can purchase more sessions anytime before session starts

4. **Session Attendance:**
   - Each session = separate attendance record
   - User can own tickets for non-consecutive sessions
   - Missing a session doesn't affect future session tickets

5. **Series Management:**
   - Cannot delete series if any session has registrations
   - Can cancel future sessions
   - Past sessions remain in history

---

## Data Relationships

### Core Entities

```
┌─────────────────────────────────────────────────────────────┐
│ User                                                        │
├─────────────────────────────────────────────────────────────┤
│ • User ID (PK)                                              │
│ • Name, Email, Phone                                        │
│ • Zoom access token (optional)                              │
│ • Account created date                                      │
│ • Role (Organizer, Attendee, Admin)                         │
└──────────────┬──────────────────────────────────────────────┘
               │
               │ creates
               ↓
┌─────────────────────────────────────────────────────────────┐
│ Event (One-Time or Multi-Day)                               │
├─────────────────────────────────────────────────────────────┤
│ • Event ID (PK)                                             │
│ • Organizer ID (FK → User)                                  │
│ • Name, Description, Category                               │
│ • Event Type (ONE_TIME, MULTI_DAY)                          │
│ • Visibility (PUBLIC, PRIVATE, UNLISTED)                    │
│ • Location Type (IN_PERSON, ONLINE, HYBRID)                 │
│ • Start Date/Time, End Date/Time                            │
│ • Venue/Address (if in-person)                              │
│ • Meeting URL/Platform (if online)                          │
│ • Access Token (if unlisted)                                │
│ • Status (DRAFT, PUBLISHED, CANCELLED, COMPLETED)           │
│ • Created/Updated timestamps                                │
└──────────────┬──────────────────────────────────────────────┘
               │
               │ has many
               ↓
┌─────────────────────────────────────────────────────────────┐
│ Ticket Type                                                 │
├─────────────────────────────────────────────────────────────┤
│ • Ticket Type ID (PK)                                       │
│ • Event ID (FK → Event)                                     │
│ • Name (e.g., "Early Bird", "VIP")                          │
│ • Price                                                     │
│ • Quantity Available                                        │
│ • Quantity Sold                                             │
│ • Description, Benefits                                     │
│ • Sales Start Date, Sales End Date                          │
│ • Status (ACTIVE, SOLD_OUT, EXPIRED)                        │
└──────────────┬──────────────────────────────────────────────┘
               │
               │ purchased via
               ↓
┌─────────────────────────────────────────────────────────────┐
│ Event Registration                                          │
├─────────────────────────────────────────────────────────────┤
│ • Registration ID (PK)                                      │
│ • Event ID (FK → Event)                                     │
│ • User ID (FK → User)                                       │
│ • Ticket Type ID (FK → Ticket Type)                         │
│ • Unique Ticket Code / QR Code                              │
│ • Payment Status (PENDING, PAID, REFUNDED)                  │
│ • Registration Date/Time                                    │
│ • Attendance Status (NOT_ATTENDED, ATTENDED)                │
│ • Check-in Time (if attended)                               │
│ • Attendance Mode (IN_PERSON, ONLINE) - for hybrid events   │
└─────────────────────────────────────────────────────────────┘


For Multi-Day Events:
┌─────────────────────────────────────────────────────────────┐
│ Event Day Schedule                                          │
├─────────────────────────────────────────────────────────────┤
│ • Day Schedule ID (PK)                                      │
│ • Event ID (FK → Event)                                     │
│ • Day Number (1, 2, 3...)                                   │
│ • Date                                                      │
│ • Start Time, End Time                                      │
│ • Location (if different from main)                         │
│ • Description                                               │
└─────────────────────────────────────────────────────────────┘

For Private Events:
┌─────────────────────────────────────────────────────────────┐
│ Event Invitation                                            │
├─────────────────────────────────────────────────────────────┤
│ • Invitation ID (PK)                                        │
│ • Event ID (FK → Event)                                     │
│ • Invited User ID (FK → User, nullable)                     │
│ • Invited Email (if user doesn't exist)                     │
│ • Invite Token (unique)                                     │
│ • Status (PENDING, ACCEPTED, DECLINED, EXPIRED)             │
│ • Sent At, Expires At                                       │
│ • Responded At                                              │
└─────────────────────────────────────────────────────────────┘
```

### Recurring Event Relationships

```
┌─────────────────────────────────────────────────────────────┐
│ Recurring Event Series                                      │
├─────────────────────────────────────────────────────────────┤
│ • Series ID (PK)                                            │
│ • Organizer ID (FK → User)                                  │
│ • Series Name, Description                                  │
│ • Visibility, Location Type                                 │
│ • Recurrence Pattern (DAILY, WEEKLY, MONTHLY, YEARLY)       │
│ • Recurrence Interval (e.g., every 2 weeks)                 │
│ • Days of Week (if weekly)                                  │
│ • Day of Month (if monthly)                                 │
│ • Series Start Date, Series End Date                        │
│ • Default Session Duration                                  │
│ • Default Session Time                                      │
│ • Total Sessions Generated                                  │
│ • Status (DRAFT, PUBLISHED, CANCELLED, COMPLETED)           │
└──────────────┬──────────────────────────────────────────────┘
               │
               │ has many
               ↓
┌─────────────────────────────────────────────────────────────┐
│ Series Session (Individual Occurrence)                      │
├─────────────────────────────────────────────────────────────┤
│ • Session ID (PK)                                           │
│ • Series ID (FK → Recurring Event Series)                   │
│ • Session Number (1, 2, 3...)                               │
│ • Session Date                                              │
│ • Start Time, End Time                                      │
│ • Location (can differ from default)                        │
│ • Meeting URL (if online)                                   │
│ • Status (SCHEDULED, CANCELLED, COMPLETED)                  │
│ • Is Customized (boolean - if differs from defaults)        │
└──────────────┬──────────────────────────────────────────────┘
               │
               │ has many
               ↓
┌─────────────────────────────────────────────────────────────┐
│ Session Ticket Type                                         │
├─────────────────────────────────────────────────────────────┤
│ • Session Ticket Type ID (PK)                               │
│ • Session ID (FK → Series Session)                          │
│ • Name (e.g., "Regular", "Student")                         │
│ • Price (can differ per session)                            │
│ • Quantity Available                                        │
│ • Quantity Sold                                             │
│ • Description                                               │
│ • Requires Verification (boolean)                           │
└──────────────┬──────────────────────────────────────────────┘
               │
               │ purchased via
               ↓
┌─────────────────────────────────────────────────────────────┐
│ Series Registration (User enrolled in series)               │
├─────────────────────────────────────────────────────────────┤
│ • Series Registration ID (PK)                               │
│ • Series ID (FK → Recurring Event Series)                   │
│ • User ID (FK → User)                                       │
│ • Registration Date (first purchase date)                   │
│ • Status (ACTIVE, CANCELLED)                                │
│ • Total Sessions Owned                                      │
└──────────────┬──────────────────────────────────────────────┘
               │
               │ owns
               ↓
┌─────────────────────────────────────────────────────────────┐
│ Session Ticket (User's ticket for specific session)        │
├─────────────────────────────────────────────────────────────┤
│ • Session Ticket ID (PK)                                    │
│ • Series Registration ID (FK → Series Registration)         │
│ • Session ID (FK → Series Session)                          │
│ • Session Ticket Type ID (FK → Session Ticket Type)         │
│ • User ID (FK → User)                                       │
│ • Unique Ticket Code / QR Code                              │
│ • Payment Status (PENDING, PAID, REFUNDED)                  │
│ • Purchase Date/Time                                        │
│ • Attendance Status (NOT_ATTENDED, ATTENDED)                │
│ • Check-in Time (if attended)                               │
└─────────────────────────────────────────────────────────────┘
```

### Relationship Summary

**One-to-Many Relationships:**
- User → Events (user creates many events)
- Event → Ticket Types (event has many ticket types)
- Event → Registrations (event has many registrations)
- User → Registrations (user has many registrations)
- Event → Event Invitations (private event has many invitations)

**For Recurring Events:**
- Recurring Series → Sessions (series has many sessions)
- Session → Session Ticket Types (each session has many ticket types)
- User → Series Registrations (user registered for many series)
- Series Registration → Session Tickets (registration owns many session tickets)

**For Multi-Day Events:**
- Event → Day Schedules (event has schedule for each day)

---

## Key Technical Considerations

### Performance Optimization

1. **Capacity Checks:**
   - Cache available tickets count
   - Use optimistic locking for ticket purchases
   - Handle race conditions (multiple users buying last ticket)

2. **Recurring Event Sessions:**
   - Generate sessions in batches
   - Index sessions by date for quick lookups
   - Lazy load past sessions

3. **Search & Discovery:**
   - Index events by: date, category, location, visibility
   - Full-text search on event name/description
   - Filter by event type, price range, location type

### Security Considerations

1. **Access Control:**
   - Verify user owns event before allowing edits
   - Validate invitation tokens
   - Rate limit invitation sends
   - Sanitize all user inputs

2. **Payment Security:**
   - Never store credit card details
   - Use payment gateway webhooks for status updates
   - Verify payment before issuing tickets
   - Handle failed payments gracefully

3. **Online Meeting Links:**
   - Don't expose links before access time
   - Validate user has valid ticket before showing link
   - Log link access for security auditing
   - Support link regeneration for compromised links

### Edge Cases to Handle

1. **Event Modifications:**
   - Event date changed after registrations exist → Notify all attendees
   - Event cancelled → Auto-refund + notifications
   - Ticket quantity reduced below sold amount → Prevent or handle gracefully
   - Event visibility changed from Public to Private → Handle existing registrations

2. **Recurring Events:**
   - Session cancelled → Refund that session only, keep other tickets
   - Series cancelled → Refund all future sessions
   - User wants to change ticket type for purchased session → Depends on policy
   - Session time conflicts with another event user registered for → User's problem to manage

3. **Capacity:**
   - Event at capacity but user in checkout process → Reserve temporarily or first-come-first-served
   - Refund issued → Increase available capacity
   - Organizer increases capacity mid-sale → Allow more registrations

4. **Payment:**
   - Payment pending during checkout → Hold temporarily, expire after X minutes
   - Payment fails → Release reserved ticket, notify user
   - Refund requested → Verify eligibility, process, update capacity

---

## User Experience Flows

### Attendee: Discovering & Registering for One-Time Event

```
Homepage / Event Listing
       ↓
Browse or Search Events
       ↓
Filter by Category/Date/Location
       ↓
Click on Event
       ↓
View Event Details Page
• Description, Date, Location
• Available Tickets
• Organizer Info
       ↓
Select Ticket Type & Quantity
       ↓
Click "Register" or "Buy Ticket"
       ↓
Login / Sign Up (if not logged in)
       ↓
Review Order
• Ticket details
• Price breakdown
• Terms & conditions
       ↓
Enter Payment Information
       ↓
Complete Purchase
       ↓
Receive Confirmation
• Email with ticket
• QR code for check-in
       ↓
View in "My Events"
• Access ticket anytime
• Add to calendar
• Get event updates
       ↓
Day of Event
• Show QR code for check-in
• Access online meeting link (if applicable)
```

### Attendee: Registering for Recurring Event

```
Browse Events
       ↓
Discover Recurring Series
       ↓
View Series Details
• Pattern (every Monday)
• Dates covered
• Location & time
       ↓
View All Sessions
• Upcoming sessions listed
• Each with ticket options
       ↓
Select Session(s) & Ticket Type(s)
• Can select multiple sessions
• Choose appropriate ticket type per session
       ↓
Review Selection
• Jan 6 - Student: $10
• Jan 13 - Student: $10
• Jan 20 - Regular: $20
• Total: $40
       ↓
Checkout & Pay
       ↓
First Purchase?
   ↓
  YES → Create Series Registration
  NO → Add to existing registration
       ↓
Receive Confirmation
• Email with tickets for purchased sessions
• Series enrollment confirmed
       ↓
View in "My Events"
• See series enrollment
• View owned session tickets
• See upcoming sessions
       ↓
Later: Want to Attend More Sessions
       ↓
Go to Series Page
       ↓
Select Additional Sessions
       ↓
Purchase & Receive New Tickets
       ↓
Day of Session
• Show session-specific QR code
• Check in for that session only
```

### Organizer: Creating One-Time Event

```
Dashboard
       ↓
Click "Create New Event"
       ↓
Select Event Type: One-Time
       ↓
Step 1: Basic Info
• Name, description, category
• Upload cover image
• Select visibility
       ↓
Step 2: Date & Time
• Start date/time
• End date/time
• Timezone
       ↓
Step 3: Location
• Select type (in-person/online/hybrid)
• Enter details based on type
• If online + Zoom: Connect account or manual link
       ↓
Step 4: Tickets
• Add ticket types
• For each: name, price, quantity, description
• Set sales periods
       ↓
Step 5: Review
• Preview how event looks
• Check all details
       ↓
Save as Draft OR Publish
       ↓
If Published:
• Event goes live
• Appears in listings (if public)
• Tickets available for purchase
       ↓
Monitor Event
• View registrations
• Track ticket sales
• Send updates to attendees
       ↓
Day of Event
• Check in attendees
• View attendance list
       ↓
After Event
• View final attendance
• Download reports
• Close event
```

### Organizer: Creating Recurring Event Series

```
Dashboard
       ↓
Click "Create New Event"
       ↓
Select Event Type: Recurring
       ↓
Step 1: Series Info
• Series name & description
• Cover image
• Visibility
       ↓
Step 2: Recurrence Pattern
• Frequency (daily/weekly/monthly/yearly)
• Interval (every X weeks)
• Days of week (if weekly)
• Start & end date OR # of occurrences
       ↓
Step 3: Session Details
• Default session time
• Default duration
• Location type & details
       ↓
Step 4: Default Tickets
• Create ticket type templates
• These apply to all sessions by default
• Name, price, quantity per session
       ↓
Review Pattern & Generate Sessions
• Preview: "This will create 12 sessions"
• Show first few sessions as examples
       ↓
Confirm Generation
       ↓
System Creates All Sessions
• Each session = copy of defaults
• All sessions in "scheduled" status
       ↓
Optional: Customize Individual Sessions
• Click on any session
• Modify price, add ticket types, change time
• Example: Special guest session - increase price
       ↓
Publish Series
• All sessions go live
• Users can start registering
       ↓
Ongoing Management
• Monitor registrations per session
• Can still customize future sessions
• Cancel individual sessions if needed
• View attendance per session
       ↓
Each Session Day
• Check in attendees for that specific session
• Track attendance per session
       ↓
After Series Completes
• View overall series analytics
• Attendance patterns
• Revenue per session
• Download reports
```

---

## Additional Features & Considerations

### Waitlist Management

**When Event/Session is at Capacity:**

```
User tries to register
       ↓
Event is full
       ↓
Option to "Join Waitlist"
       ↓
User added to waitlist
       ↓
If spot opens (cancellation/refund)
       ↓
First person on waitlist notified
       ↓
Limited time to claim spot (e.g., 24 hours)
       ↓
If claimed: Registration processed
If not claimed: Offer to next person
```

**Waitlist Properties:**
- Order (first-come, first-served)
- Expiration time for offers
- Notifications when spots available
- User can leave waitlist

### Event Updates & Notifications

**Notify Attendees When:**
- Event details changed (date, time, location)
- Event cancelled
- New announcement from organizer
- Reminder before event (24 hours, 1 hour)
- Event starts soon (for online events - show link)

**For Recurring Events:**
- Notify about upcoming session (24 hours before)
- Notify if specific session cancelled
- Notify if session time/location changed

### Analytics & Reporting

**For Organizers:**
- Total registrations
- Revenue by ticket type
- Sales over time (graph)
- Attendance rate
- Demographics (if collected)
- For recurring: Per-session breakdown

**For Platform:**
- Total events created
- Event types distribution
- Popular categories
- Revenue metrics
- User engagement

### Social Features

**Event Sharing:**
- Share on social media
- Generate shareable link
- Embed event widget

**Reviews & Ratings:**
- After event, attendees can rate/review
- Displayed on event page
- Builds organizer reputation

**Following:**
- Users can follow organizers
- Get notified of new events

---

## Implementation Priority

### Phase 1: MVP (Core Features)
1. One-time event creation & management
2. Basic ticket types (free & paid)
3. Simple registration flow
4. Public event visibility
5. In-person and manual online link support
6. Basic attendee management

### Phase 2: Enhanced Features
1. Multi-day events
2. Recurring events (simple - uniform pricing)
3. Private events with invitation system
4. Unlisted events
5. Multiple ticket types per event
6. Waitlist functionality

### Phase 3: Advanced Features
1. Recurring events with variable pricing per session
2. Zoom/provider integration
3. Hybrid events with attendance mode selection
4. Advanced analytics
5. Event series customization (per-session modifications)
6. Refund automation

### Phase 4: Premium Features
1. Social features (reviews, following)
2. Event recommendations
3. Advanced reporting
4. API for third-party integrations
5. White-label options
6. Mobile app

---

## Conclusion

This document provides comprehensive requirements for an event management system supporting three distinct event types with flexible ticketing and access control. The system is designed to scale from simple one-time events to complex recurring series with variable pricing.

**Key Differentiators:**
- Support for recurring events with per-session ticket management
- Flexible visibility options (public, private, unlisted)
- Multiple location modes including hybrid
- Integration with online meeting providers
- Granular ticket type control

**Success Metrics:**
- Number of events created
- Registration conversion rate
- User satisfaction (organizers & attendees)
- Platform revenue
- Event completion rate

This system empowers organizers to create professional events while providing attendees with a smooth discovery and registration experience.

---

**Document Version:** 1.0  
**Last Updated:** November 23, 2025  
**Status:** Requirements Approved - Ready for Development