# LIVE NAVIGATION - Quick Reference

**Real-time session-based navigation with GPS tracking, chat, and emergency features**

---

## Status

| Metric | Value |
|--------|-------|
| Phase | ✅ Production Ready |
| Total Code | ~6,600 lines (frontend + backend + types) |
| Components | 5 Vue components |
| API Endpoints | 21 REST routes |
| Last Updated | November 9, 2025 |

---

## File Structure (Actual Line Counts)

### Backend

| File | Path | Lines | Purpose |
|------|------|-------|---------|
| Routes | `apps/api/src/modules/live/live.routes.ts` | 221 | 21 REST endpoints |
| Controller | `apps/api/src/modules/live/liveNavigation.controller.ts` | 436 | HTTP handlers |
| Service | `apps/api/src/modules/live/liveNavigation.service.ts` | 713 | Business logic |
| Types | `packages/types/src/live.types.ts` | 478 | TypeScript interfaces |

### Frontend

| File | Path | Lines | Purpose |
|------|------|-------|---------|
| Store | `apps/web/src/modules/live/stores/liveNavigationStore.ts` | 615 | Pinia state |
| Service | `apps/web/src/modules/live/services/liveNavigationService.ts` | 550 | API client |
| Geolocation | `apps/web/src/modules/live/services/geolocationService.ts` | 403 | GPS wrapper |
| CreateDialog | `apps/web/src/modules/live/components/CreateSessionDialog.vue` | 588 | Session creation |
| JoinDialog | `apps/web/src/modules/live/components/JoinSessionDialog.vue` | 634 | Session join |
| Participants | `apps/web/src/modules/live/components/LiveParticipantsList.vue` | 638 | Participants list |
| Chat | `apps/web/src/modules/live/components/LiveChat.vue` | 957 | Chat system |
| Emergency | `apps/web/src/modules/live/components/EmergencyButton.vue` | 335 | Emergency alerts |
| MapPage | `apps/web/src/modules/map/pages/MapPage.mobile.vue` | 3341 | UI integration |

---

## 🎯 Key Features

| Feature | Status | Description |
|---------|--------|-------------|
| **Session Types** | ✅ | Casual, Rally, Track Day, Convoy, Group Ride |
| **GPS Tracking** | ✅ | 3-5s updates, battery optimized |
| **Participant Overlay** | ✅ | Real-time markers on map |
| **Chat System** | ✅ | Text + voice messages |
| **Emergency Alerts** | ✅ | One-tap SOS with hold-to-trigger |
| **Roles** | ✅ | Host, Lead Rider, Tail Rider, Participant |
| **Stopped Detection** | ✅ | Auto-detect stopped > 30s |
| **Tier Limits** | ✅ | Free: 2, Premium: 5, Pro: 15, Group: 100 |
| **Session Export** | ✅ | GPX, CSV, JSON |
| **Telemetry** | ⏳ | UI pending (backend ready) |
| **Leaderboard** | ⏳ | UI pending (backend ready) |
| **Replay Viewer** | ⏳ | Not started |

---

## API Endpoints (21 Routes)

| Method | Route | Purpose | Rate Limit |
|--------|-------|---------|------------|
| GET | `/api/live/friends` | List friends locations (legacy) | - |
| GET | `/api/live/clans/:clanId` | Get clan locations (legacy) | - |
| POST | `/api/live/sessions` | Create session | - |
| GET | `/api/live/sessions/:sessionId` | Get session details | - |
| GET | `/api/live/sessions` | List sessions (nearby/public) | - |
| POST | `/api/live/sessions/:sessionId/end` | End session (host only) | - |
| POST | `/api/live/sessions/:sessionId/join` | Join session | - |
| POST | `/api/live/sessions/:sessionId/leave` | Leave session | - |
| POST | `/api/live/position` | Update position | 20/min |
| POST | `/api/live/role` | Change participant role | - |
| DELETE | `/api/live/participants/:userId` | Remove participant | - |
| POST | `/api/live/chat` | Send message | 10/min |
| GET | `/api/live/chat/:sessionId` | Get chat history | - |
| POST | `/api/live/emergency` | Send emergency alert | 5/hour |
| DELETE | `/api/live/emergency/:sessionId` | Clear emergency | - |
| POST | `/api/live/telemetry` | Record telemetry | 20/min |
| POST | `/api/live/laps` | Complete lap | - |
| GET | `/api/live/leaderboard/:sessionId` | Get leaderboard | - |
| GET | `/api/live/sessions/:sessionId/replay` | Get session replay | - |
| GET | `/api/live/sessions/:sessionId/export` | Export data (GPX/CSV/JSON) | - |
| GET | `/api/live/sessions/:sessionId/stats` | Get session stats | - |

---

## 📊 Type Definitions

```typescript
// Session
interface LiveSession {
  id: string
  name: string
  type: 'casual' | 'rally' | 'trackday' | 'convoy' | 'group_ride'
  hostId: string
  participantIds: string[]
  maxParticipants: number
  status: 'waiting' | 'active' | 'ended'
  startTime: Date
  endTime?: Date
  privacy: 'public' | 'private'
  inviteCode?: string
  features: LiveFeatures
  stats: LiveSessionStats
}

// Participant
interface LiveParticipant {
  userId: string
  userName: string
  position: DetailedPosition
  status: 'moving' | 'stopped' | 'emergency' | 'disconnected'
  role: 'host' | 'lead_rider' | 'tail_rider' | 'participant'
  vehicleIcon: 'car' | 'moto' | 'van' | 'truck' | 'suv' | 'sports_car'
  hasEmergency: boolean
  isOnline: boolean
}

// Position
interface DetailedPosition {
  lat: number
  lng: number
  accuracy?: number
  altitude?: number
  heading?: number  // 0-360°
  speed?: number    // km/h
  timestamp: Date
}

// Chat
interface ChatMessage {
  id: string
  userId: string
  userName: string
  type: 'text' | 'voice' | 'system' | 'alert'
  content: string
  timestamp: Date
  readBy?: string[]
  duration?: number  // For voice messages
}
```

---

## 🎨 Pinia Store Usage

```typescript
import { useLiveNavigationStore } from '@/modules/live/stores/liveNavigationStore'

const liveStore = useLiveNavigationStore()

// Create session
await liveStore.createSession({
  name: 'Weekend Raid',
  type: 'casual',
  maxParticipants: 5,
  privacy: 'private',
  vehicle: { type: 'car', name: 'Porsche 911' },
  features: { chat: true, emergencyAlerts: true }
})

// Join session
await liveStore.joinSession('ABC123', { type: 'moto', name: 'R1' })

// Start GPS tracking
await liveStore.startPositionTracking()

// Send message
await liveStore.sendMessage('Hello!', 'text')

// Emergency
await liveStore.sendEmergencyAlert('Accident!')

// Leave
await liveStore.leaveSession()

// Getters
const isInSession = liveStore.isInSession
const participantCount = liveStore.participantCount
const unreadMessages = liveStore.unreadMessagesCount
```

---

## 🗺️ MapPage Integration

### Changes Made

1. **Session button** added to `liveSocialButtons`
2. **Participant markers** overlay on map
3. **Auto-start GPS** when joining session
4. **Real-time listeners** auto-connect
5. **5 UI components** integrated (dialogs, drawers, button)
6. **10 handler functions** for session events

### Key Computed Properties

```typescript
// Session button state
const liveSocialButtons = computed(() => [
  { id: 'friends', label: 'Amis', ... },
  { id: 'clan', label: 'Club', ... },
  { 
    id: 'session',
    label: liveNavigationStore.isInSession 
      ? `Session (${liveNavigationStore.participantCount})` 
      : 'Session Live',
    active: liveNavigationStore.isInSession
  }
])

// Participant markers
const sessionParticipantsMarkers = computed(() => {
  return liveNavigationStore.activeParticipants
    .filter(p => p.userId !== currentUserId)
    .map(p => ({
      id: `session-${p.userId}`,
      coordinates: { lat: p.position.lat, lng: p.position.lng },
      displayName: p.userName,
      kind: 'friend',
      status: p.isOnline ? 'online' : 'idle',
      speedKmh: p.position.speed,
      heading: p.position.heading
    }))
})

// Combined markers (3 systems)
const liveMapMarkers = computed(() => {
  const markers = []
  if (friendsOverlayEnabled.value) markers.push(...friendLiveMarkers.value)
  if (clanOverlayEnabled.value) markers.push(...clanLiveMarkers.value)
  if (liveNavigationStore.isInSession) markers.push(...sessionParticipantsMarkers.value)
  return markers
})
```

### Watchers

```typescript
// Auto-start GPS tracking
watch(
  () => liveNavigationStore.isInSession,
  async (isInSession) => {
    if (isInSession) {
      await liveNavigationStore.startPositionTracking()
    } else {
      liveNavigationStore.stopPositionTracking()
    }
  }
)

// Auto-connect Firebase listeners
watch(
  () => liveNavigationStore.isInSession,
  (isInSession) => {
    if (isInSession) {
      liveNavigationStore.startRealtimeListeners()
    } else {
      liveNavigationStore.stopRealtimeListeners()
    }
  },
  { immediate: true }
)
```

---

## 🔥 Firebase Structure

```
/live-sessions/
  /{sessionId}/
    /session
      - id, name, type, hostId, status, startTime, maxParticipants, features
      
    /participants/
      /{userId}
        - userId, position: { lat, lng, speed, heading, timestamp }
        - status, role, vehicleIcon, lastUpdate, hasEmergency
        
    /chat/
      /{messageId}
        - userId, content, type, timestamp, readBy
        
    /events/
      /{eventId}
        - type: 'participant_joined' | 'emergency' | 'lap_completed'
        - userId, timestamp, data
        
    /telemetry/
      /{userId}/
        /{timestamp}
          - speed, acceleration: { x, y, z }, lap, sector
```

---

## 💡 Usage Examples

### Create & Join Flow

```typescript
// Host creates session
const session = await liveStore.createSession({
  name: 'Sunday Ride',
  type: 'group_ride',
  maxParticipants: 10,
  privacy: 'public',
  vehicle: { type: 'moto', name: 'Ducati V4' },
  features: {
    chat: true,
    voiceChat: false,
    emergencyAlerts: true,
    telemetry: false
  }
})

console.log('Invite code:', session.inviteCode)  // "X8K9P2"

// Friend joins by code
await liveStore.joinSession('X8K9P2', {
  type: 'moto',
  name: 'Yamaha R1'
})

// GPS tracking starts automatically (watcher)
// Firebase listeners start automatically (watcher)
```

### Chat

```typescript
// Send text message
await liveStore.sendMessage('Meeting at gas station in 5 min', 'text')

// Send voice (with duration)
await liveStore.sendMessage('base64_audio_data', 'voice')

// Mark messages as read
liveStore.markMessagesAsRead()

// Check unread count
const unread = liveStore.unreadMessagesCount
```

### Emergency

```typescript
// Quick emergency (no message)
await liveStore.sendEmergencyAlert()

// Emergency with message
await liveStore.sendEmergencyAlert('Flat tire, need help')

// All participants receive:
// - participant.hasEmergency = true
// - participant.status = 'emergency'
// - Red pulsing marker on map
// - Chat alert message

// Clear emergency
await liveStore.clearEmergencyAlert()
```

### Roles & Permissions

```typescript
// Change participant role (host only)
await liveStore.updateParticipantRole('user123', 'lead_rider')

// Remove participant (host only)
await liveStore.removeParticipant('user456')

// Check permissions
const canManage = liveStore.canManageSession
const isHost = liveStore.isHost
```

---

## 🔋 Battery Optimization

GeolocationService automatically adjusts based on speed:

| Speed | Accuracy | Update Interval | Battery Impact |
|-------|----------|-----------------|----------------|
| > 20 km/h | High | 3s | High |
| 5-20 km/h | High | 5s | Medium |
| < 5 km/h | Low | 10s | Low |

```typescript
// Manual optimization
geolocationService.optimizeBattery(currentSpeed)

// Check stopped
const isStopped = geolocationService.detectStopped()
```

---

## 🐛 Common Issues

### GPS Not Working
```typescript
// Check permission
const permission = await geolocationService.checkPermission()
if (permission !== 'granted') {
  // Show instructions to enable in settings
}

// Check support
if (!geolocationService.isSupported()) {
  toast.error('Geolocation not supported')
}
```

### Firebase Not Syncing
```typescript
// Check connection state
import { getDatabase, onValue, ref } from 'firebase/database'

const db = getDatabase()
const connectedRef = ref(db, '.info/connected')

onValue(connectedRef, (snap) => {
  if (snap.val() === true) {
    console.log('Firebase connected')
  } else {
    console.log('Firebase disconnected')
  }
})
```

### Participants Not Showing
```typescript
// Debug markers
console.log('Is in session:', liveStore.isInSession)
console.log('Participants:', liveStore.participants)
console.log('Session markers:', sessionParticipantsMarkers.value)
console.log('All markers:', liveMapMarkers.value)
```

---

## 📊 Tier Limits

```typescript
const TIER_LIMITS = {
  free: 2,       // 1 host + 1 guest
  premium: 5,    // Small groups
  pro: 15,       // Medium events
  group: 100     // Large rallies
}

// Enforced at session creation
// Displayed in CreateSessionDialog slider
// Checked when joining (maxParticipantsReached)
```

---

## 📝 TODO / Future Features

- [x] Session types (5 types)
- [x] GPS tracking (battery optimized)
- [x] Chat (text + voice)
- [x] Emergency alerts
- [x] Participant roles
- [x] Stopped detection
- [x] Map overlay
- [ ] Telemetry UI (track days)
- [ ] Leaderboard UI
- [ ] Session replay viewer
- [ ] Voice chat (WebRTC)
- [ ] Route following
- [ ] Photo sharing
- [ ] Weather alerts

---

## 🔗 Related Docs

- **Full Documentation:** `LIVE_NAVIGATION_SYSTEM.md` (35+ pages)
- **Systems Comparison:** `SYSTEMS_COEXISTENCE.md`
- **Product Roadmap:** `PRODUCT_VISION.md` (Phase 3-4)

---

**Status:** ✅ Production Ready  
**Last Updated:** November 8, 2025
