# Admin Seat Details Endpoint - Data Relationships Diagram

## Entity Relationship Overview

```
┌─────────────────────────────────────────────────────────────────────────┐
│                        ADMIN SEAT DETAILS ENDPOINT                       │
│                   GET /api/admin/seats/{seat_id}/details                 │
└─────────────────────────────────────────────────────────────────────────┘
                                    │
                                    ↓
        ┌───────────────────────────────────────────────────┐
        │              PRIMARY DATA: SEAT                    │
        │  ┌─────────────────────────────────────────────┐  │
        │  │  seats                                       │  │
        │  │  - seat_id (PK)                             │  │
        │  │  - event_id (FK)                            │  │
        │  │  - row_letter, seat_number                  │  │
        │  │  - price, zone, section_id                  │  │
        │  │  - seat_type, is_accessible                 │  │
        │  │  - position, parent_table_id                │  │
        │  └─────────────────────────────────────────────┘  │
        └───────────────────────────────────────────────────┘
                    │                           │
                    ↓                           ↓
    ┌──────────────────────────┐   ┌──────────────────────────┐
    │   EVENT CONTEXT          │   │   RESERVATION STATUS      │
    │  ┌────────────────────┐  │   │  ┌────────────────────┐  │
    │  │  events            │  │   │  │  seat_reservations │  │
    │  │  - id (PK)         │  │   │  │  - id (PK)         │  │
    │  │  - name            │  │   │  │  - seat_id (FK)    │  │
    │  │  - slug            │  │   │  │  - event_id (FK)   │  │
    │  │  - start_date      │  │   │  │  - status          │  │
    │  │  - venue_id        │  │   │  │  - hold_token      │  │
    │  │  - status          │  │   │  │  - session_id      │  │
    │  └────────────────────┘  │   │  │  - user_id         │  │
    └──────────────────────────┘   │  │  - expires_at      │  │
                                   │  │  - price_snapshot  │  │
                                   │  └────────────────────┘  │
                                   └──────────────────────────┘
                                              │
                                              ↓
                ┌─────────────────────────────────────────────────────┐
                │                  BOOKING DATA                        │
                │  ┌───────────────────────────────────────────────┐  │
                │  │  orders                                        │  │
                │  │  - id (PK)                                     │  │
                │  │  - session_id (matches seat_reservations)     │  │
                │  │  - event_id (FK)                               │  │
                │  │  - customer_name, customer_email ⭐            │  │
                │  │  - customer_phone                              │  │
                │  │  - total_amount                                │  │
                │  │  - status, payment_status, payment_method     │  │
                │  │  - payment_mode, idempotency_key              │  │
                │  │  - created_by_admin_id, admin_notes           │  │
                │  └───────────────────────────────────────────────┘  │
                └─────────────────────────────────────────────────────┘
                            │                           │
                            ↓                           ↓
        ┌───────────────────────────┐   ┌───────────────────────────┐
        │   PAYMENT DETAILS         │   │   LINE ITEMS BREAKDOWN     │
        │  ┌─────────────────────┐  │   │  ┌─────────────────────┐  │
        │  │  payment_transactions│  │   │  │  order_line_items   │  │
        │  │  - id (PK)          │  │   │  │  - id (PK)          │  │
        │  │  - order_id (FK)    │  │   │  │  - order_id (FK)    │  │
        │  │  - payment_gateway  │  │   │  │  - item_type        │  │
        │  │  - transaction_id   │  │   │  │  - description      │  │
        │  │  - amount, currency │  │   │  │  - quantity         │  │
        │  │  - status           │  │   │  │  - unit_price       │  │
        │  │  - initiated_at     │  │   │  │  - line_total       │  │
        │  │  - completed_at     │  │   │  │  - tax_rate         │  │
        │  │  - metadata         │  │   │  │  - seat_id (FK) ⭐  │  │
        │  └─────────────────────┘  │   │  └─────────────────────┘  │
        └───────────────────────────┘   └───────────────────────────┘


                        ┌─────────────────────────────┐
                        │   OPTIONAL: HISTORY         │
                        │  ┌───────────────────────┐  │
                        │  │  seat_reservations    │  │
                        │  │  (previous records)   │  │
                        │  │  - status transitions │  │
                        │  │  - timestamps         │  │
                        │  │  - hold tokens        │  │
                        │  └───────────────────────┘  │
                        └─────────────────────────────┘

                        ┌─────────────────────────────┐
                        │   OPTIONAL: AUDIT LOGS      │
                        │  ┌───────────────────────┐  │
                        │  │  mbs_activity_logs    │  │
                        │  │  - action_type        │  │
                        │  │  - performed_by       │  │
                        │  │  - seat_id (FK)       │  │
                        │  │  - metadata           │  │
                        │  └───────────────────────┘  │
                        └─────────────────────────────┘
```

---

## Query Flow & Join Strategy

### Primary Query (Single Database Call with Eager Loading)

```sql
SELECT
    -- Seat base data
    seats.*,

    -- Event context
    events.id, events.name, events.slug, events.start_date, events.venue_id, events.status,

    -- Reservation status
    sr.id AS reservation_id, sr.status, sr.hold_token, sr.session_id, sr.user_id,
    sr.expires_at, sr.price_snapshot, sr.created_at AS reserved_at,

    -- Order details (if booked)
    orders.id AS order_id, orders.customer_name, orders.customer_email, orders.customer_phone,
    orders.total_amount, orders.status AS order_status, orders.payment_status, orders.payment_method,
    orders.payment_mode, orders.idempotency_key, orders.created_by_admin_id, orders.admin_notes,

    -- Payment transaction (if exists)
    pt.id AS payment_transaction_id, pt.payment_gateway, pt.transaction_id,
    pt.amount AS payment_amount, pt.currency, pt.status AS payment_status_detail,
    pt.initiated_at, pt.completed_at, pt.metadata AS payment_metadata

FROM seats

-- Join event (always present)
INNER JOIN events ON events.id = seats.event_id

-- Join reservation (may not exist if seat never reserved)
LEFT JOIN seat_reservations sr ON sr.seat_id = seats.seat_id
    AND sr.event_id = seats.event_id
    AND sr.id = (
        SELECT id FROM seat_reservations
        WHERE seat_id = seats.seat_id
        AND event_id = seats.event_id
        ORDER BY created_at DESC
        LIMIT 1
    )

-- Join order (only if reservation status = 'booked')
LEFT JOIN orders ON orders.session_id = sr.session_id
    AND orders.event_id = seats.event_id

-- Join payment transaction (only if order exists)
LEFT JOIN payment_transactions pt ON pt.order_id = orders.id
    AND pt.id = (
        SELECT id FROM payment_transactions
        WHERE order_id = orders.id
        ORDER BY created_at DESC
        LIMIT 1
    )

WHERE seats.seat_id = :seat_id
  AND seats.event_id = :event_id (optional but recommended)
```

### Line Items Query (Separate Query, Conditional)

```sql
SELECT
    oli.*
FROM order_line_items oli
WHERE oli.order_id = :order_id
ORDER BY
    FIELD(oli.item_type, 'ticket', 'booking_fee', 'tax', 'discount'),
    oli.created_at ASC
```

### History Query (Optional, `?include_history=true`)

```sql
SELECT
    sr.id, sr.status, sr.hold_token, sr.session_id, sr.expires_at, sr.created_at
FROM seat_reservations sr
WHERE sr.seat_id = :seat_id
  AND sr.event_id = :event_id
ORDER BY sr.created_at DESC
LIMIT 50
```

### Audit Logs Query (Optional, `?include_audit_logs=true`)

```sql
SELECT
    mal.id, mal.action_type, mal.action_category, mal.action_description,
    mal.performed_by_type, mal.performed_by_id, mal.performed_by_name,
    mal.performed_at, mal.metadata
FROM mbs_activity_logs mal
WHERE mal.seat_id = :seat_id
  AND mal.event_id = :event_id
ORDER BY mal.performed_at DESC
LIMIT 100
```

### Related Seats Section Stats Query (Optional)

```sql
SELECT
    COUNT(*) AS total_seats,
    SUM(CASE WHEN sr.status IS NULL THEN 1 ELSE 0 END) AS available_seats,
    SUM(CASE WHEN sr.status = 'held' AND sr.expires_at > NOW() THEN 1 ELSE 0 END) AS held_seats,
    SUM(CASE WHEN sr.status = 'booked' THEN 1 ELSE 0 END) AS booked_seats,
    SUM(CASE WHEN sr.status = 'shadow_sold' THEN 1 ELSE 0 END) AS shadow_sold_seats,
    SUM(CASE WHEN sr.status = 'blocked' THEN 1 ELSE 0 END) AS blocked_seats
FROM seats s
LEFT JOIN seat_reservations sr ON sr.seat_id = s.seat_id
    AND sr.event_id = s.event_id
    AND sr.id = (
        SELECT id FROM seat_reservations
        WHERE seat_id = s.seat_id
        AND event_id = s.event_id
        ORDER BY created_at DESC
        LIMIT 1
    )
WHERE s.section_id = :section_id
  AND s.event_id = :event_id
  AND s.seat_type != 'table'  -- Exclude parent tables
  AND s.is_active = 1
```

---

## Key Relationships Explained

### 1. **Seat → Reservation** (1:many, but use latest)
```
seats.seat_id + seats.event_id → seat_reservations.seat_id + seat_reservations.event_id
```
**Key**: A seat can have multiple reservations over time (held → expired → held again → booked).
**Solution**: Always fetch the **latest** reservation by `created_at DESC`.

### 2. **Reservation → Order** (1:1 via session_id)
```
seat_reservations.session_id + seat_reservations.event_id → orders.session_id + orders.event_id
```
**Key**: When a hold is confirmed, the `session_id` links reservation to order.
**Note**: Only exists when `status = 'booked'`.

### 3. **Order → Payment Transaction** (1:many, but use latest)
```
orders.id → payment_transactions.order_id
```
**Key**: An order can have multiple payment attempts (failed → retry → success).
**Solution**: Fetch the **latest** payment transaction by `created_at DESC`.

### 4. **Order → Line Items** (1:many)
```
orders.id → order_line_items.order_id
```
**Key**: Each order has multiple line items (tickets, fees, taxes, discounts).
**Note**: Filter by `seat_id` to get seat-specific line items.

### 5. **Seat → Event** (many:1)
```
seats.event_id → events.id
```
**Key**: All seats belong to an event. Always fetch event context.

---

## Data Flow: Customer Books Seat

```
1. Customer visits booking page
   └─> Frontend calls: GET /api/venue/availability/{eventId}
   └─> Returns: Seat status, price (NO owner info)

2. Customer selects seat A1
   └─> Frontend calls: POST /api/seats/hold
   └─> Creates: seat_reservations record (status='held')
   └─> Returns: hold_token, expires_at

3. Customer enters payment details
   └─> Frontend calls: POST /api/payment/create-intent
   └─> Creates: payment_transactions record (status='pending')

4. Customer completes payment
   └─> Stripe webhook: POST /api/webhooks/stripe
   └─> Updates: payment_transactions (status='completed')
   └─> Creates: orders record
   └─> Creates: order_line_items records (ticket, fee, tax)
   └─> Updates: seat_reservations (status='booked')

5. Admin hovers over seat A1 ⭐ **NEW ENDPOINT USED HERE**
   └─> Frontend calls: GET /api/admin/seats/seat-A1-12345/details
   └─> Returns: EVERYTHING (seat, reservation, order, payment, line items)
   └─> Admin sees: "Booked by John Doe (john.doe@example.com), Order #5678"
```

---

## Performance: Query Optimization

### Before Optimization (N+1 Problem)
```
Query 1: SELECT * FROM seats WHERE seat_id = ?                    -- 1 query
Query 2: SELECT * FROM events WHERE id = ?                        -- 1 query
Query 3: SELECT * FROM seat_reservations WHERE seat_id = ?        -- 1 query
Query 4: SELECT * FROM orders WHERE session_id = ?                -- 1 query
Query 5: SELECT * FROM payment_transactions WHERE order_id = ?    -- 1 query
Query 6: SELECT * FROM order_line_items WHERE order_id = ?        -- 1 query

TOTAL: 6 queries (N+1 problem if iterating over seats)
```

### After Optimization (Eager Loading)
```
Query 1: SELECT * FROM seats
         LEFT JOIN events ON ...
         LEFT JOIN seat_reservations ON ...
         LEFT JOIN orders ON ...
         LEFT JOIN payment_transactions ON ...
         WHERE seats.seat_id = ?                                  -- 1 query

Query 2: SELECT * FROM order_line_items WHERE order_id = ?        -- 1 query

TOTAL: 2 queries (with proper indexing: < 100ms)
```

### Required Indexes
```sql
-- Already exist (from existing migrations)
CREATE INDEX idx_seat_reservations_seat_id ON seat_reservations(seat_id);
CREATE INDEX idx_seat_reservations_event_id ON seat_reservations(event_id);
CREATE INDEX idx_seats_event_id ON seats(event_id);

-- Should add (if not exist)
CREATE INDEX idx_order_line_items_order_id ON order_line_items(order_id);
CREATE INDEX idx_order_line_items_seat_id ON order_line_items(seat_id);
CREATE INDEX idx_mbs_activity_logs_seat_id ON mbs_activity_logs(seat_id);
CREATE INDEX idx_payment_transactions_order_id ON payment_transactions(order_id);
```

---

## Summary

This diagram shows how **10+ database tables** are connected to provide comprehensive seat information:

✅ **Core Path**: Seat → Reservation → Order → Payment (4 tables, 2 queries)
✅ **Supporting Data**: Event, Line Items (2 tables, 1 query)
✅ **Optional Data**: History, Audit Logs (2 tables, 2 queries)

**Total Query Count**:
- **Minimum**: 2 queries (seat with order, line items)
- **With History**: 3 queries (+1 for history)
- **With Audit Logs**: 4 queries (+1 for audit logs)
- **With Everything**: 5 queries (all data)

**Target Response Time**: < 300ms (with proper indexing and eager loading)
