# 3D Virtual Tour Map - Architecture Diagram

## Technology Stack

### Backend
- **Runtime**: Node.js
- **Framework**: Express.js
- **Database**: MongoDB (Mongoose ODM)
- **Authentication**: JWT (jsonwebtoken) + bcrypt
- **Image Processing**: Sharp (resize), exifr (read EXIF), piexifjs (write EXIF)
- **File Upload**: Multer
- **Security**: CORS, referer verification, no-cache headers

### Frontend
- **Map**: Leaflet.js (OpenStreetMap tiles)
- **3D Viewer**: Pannellum.js (360° panorama viewer)
- **UI**: Vanilla HTML/CSS/JavaScript
- **State**: localStorage for JWT tokens

## Architecture Diagram

```mermaid
graph TB
    subgraph "Client (Browser)"
        UI[HTML/CSS UI]
        MAP[Leaflet Map]
        VIEWER[Pannellum 3D Viewer]
        AUTH[Auth Panel]
        MODAL[Scene Creation Modal]
    end

    subgraph "Backend (Node.js/Express)"
        SERVER[server.js]
        ROUTES[API Routes]
        MIDDLEWARES[Security & Auth Middlewares]
        UTILS[Image & EXIF Utils]
        MODELS[Mongoose Models]
    end

    subgraph "Database (MongoDB)"
        USERS[Users Collection]
        SCENES[Scenes Collection]
        ASSETS[Assets Collection]
    end

    subgraph "File System"
        UPLOADS[uploads/ Directory]
        TEMP[temp/ Directory]
    end

    UI --> MAP
    UI --> AUTH
    UI --> MODAL
    UI --> VIEWER
    
    MAP -->|Right-click| MODAL
    MAP -->|Load Scenes| ROUTES
    MAP -->|Click Marker| VIEWER
    
    AUTH -->|Login/Register| ROUTES
    AUTH -->|Store JWT| UI
    
    MODAL -->|Upload Image| ROUTES
    
    VIEWER -->|Request Image| ROUTES
    
    ROUTES --> MIDDLEWARES
    MIDDLEWARES -->|Verify JWT| AUTH
    MIDDLEWARES -->|Verify Referer| UI
    MIDDLEWARES -->|Privacy Check| SCENES
    
    ROUTES --> MODELS
    MODELS --> USERS
    MODELS --> SCENES
    MODELS --> ASSETS
    
    ROUTES --> UTILS
    UTILS -->|Resize| UPLOADS
    UTILS -->|Read/Write EXIF| UPLOADS
    UTILS -->|Temp Storage| TEMP
    
    SCENES --> ASSETS
    ASSETS --> UPLOADS
    
    SERVER --> ROUTES
    SERVER -->|Serve Static| UI
```

## Data Flow

### 1. User Registration/Login
```
Client → POST /api/auth/register or /api/auth/login
  → authRoutes.js
  → User model (bcrypt hash/compare)
  → JWT generation
  → Response with token
  → Client stores token in localStorage
```

### 2. Scene Creation (Upload 360° Image)
```
Client → Right-click on map → Open modal with lat/lng
  → POST /api/scenes (with multipart/form-data)
  → authMiddleware.protect (verify JWT)
  → Multer saves to temp/
  → imageHelper.resizeTo8K (resize to 8192x4096)
  → exifHelper.getGPSCoordinates (read original GPS)
  → exifHelper.injectGPSCoordinates (inject map lat/lng)
  → Asset model saved to DB
  → Scene model saved to DB (with privacy settings)
  → Delete temp file
  → Response with scene data
```

### 3. Load Scenes on Map
```
Client → GET /api/scenes (with optional JWT)
  → authMiddleware.optionalAuth
  → Scene.find() with privacy filter:
    - Guests: public + shared scenes
    - Logged-in: public + member + owned + shared-with-me
  → Populate owner and asset data
  → Response with scene list
  → Client adds markers to Leaflet map
```

### 4. View 3D Panorama
```
Client → Click marker → GET /api/scenes/:id (with token if shared)
  → authMiddleware.optionalAuth
  → Privacy verification
  → Response with scene details
  → Client constructs secure image URL: /api/assets/view/:assetId?token=...
  → GET /api/assets/view/:assetId
  → securityMiddleware.verifyReferer (anti-hotlinking)
  → securityMiddleware.setNoCacheHeaders
  → Privacy verification again
  → Stream image file from disk
  → Pannellum viewer displays 360° panorama
  → Client-side security: block right-click, drag, keyboard shortcuts
```

## Security Layers

### Backend Security
1. **JWT Authentication**: Required for creating scenes, optional for viewing
2. **Privacy Model**: Four levels (public, private, member, shared)
3. **Referer Verification**: Prevents direct URL access to images
4. **No-Cache Headers**: Prevents browser caching of protected images
5. **Share Tokens**: For shared scenes, token required for access

### Frontend Security
1. **Right-click Blocking**: Prevents image saving in viewer
2. **Drag Prevention**: Blocks drag-and-drop of images
3. **Keyboard Restrictions**: Blocks F12, Ctrl+S, Ctrl+U, Ctrl+Shift+I
4. **Token-based Access**: Share tokens passed in URLs for shared content

## Database Schema

### User Model
```javascript
{
  username: String (unique, required),
  password: String (bcrypt hashed),
  role: Enum ['Chủ sở hữu', 'Thành viên'],
  timestamps: true
}
```

### Scene Model
```javascript
{
  title: String (required),
  assetId: ObjectId (ref: Asset),
  lat: Number (required),
  lng: Number (required),
  owner: ObjectId (ref: User),
  privacy: Enum ['public', 'private', 'shared', 'member'],
  shareToken: String (unique, sparse),
  sharedWith: [ObjectId] (ref: User),
  timestamps: true
}
```

### Asset Model
```javascript
{
  filePath: String (required),
  uploadedBy: ObjectId (ref: User),
  coordinates: { lat: Number, lng: Number },
  timestamps: true
}
```

## File Structure

```
3dtours/
├── backend/
│   ├── config/
│   │   └── db.js              # MongoDB connection
│   ├── middlewares/
│   │   ├── authMiddleware.js  # JWT verification
│   │   └── securityMiddleware.js  # Referer check, cache control
│   ├── models/
│   │   ├── User.js            # User schema
│   │   ├── Scene.js           # Scene schema
│   │   └── Asset.js           # Asset schema
│   ├── routes/
│   │   ├── authRoutes.js      # Login/register endpoints
│   │   └── apiRoutes.js       # Scenes/assets endpoints
│   ├── utils/
│   │   ├── imageHelper.js     # Sharp resize to 8K
│   │   └── exifHelper.js      # GPS read/write
│   ├── uploads/               # Processed images
│   │   └── temp/              # Temporary upload storage
│   ├── server.js              # Express app entry point
│   ├── package.json
│   └── .env                   # Environment variables
└── frontend/
    ├── css/
    │   └── style.css          # UI styling
    ├── js/
    │   ├── main_map.js        # Map logic, auth, scene loading
    │   └── viewer360.js       # Pannellum viewer + security
    └── index.html             # Main UI
```

## Key Features

1. **Interactive Map**: Leaflet-based map with scene markers
2. **3D Panorama Viewer**: Pannellum for 360° image viewing
3. **User Authentication**: Registration, login with role-based access
4. **Privacy Controls**: Public, private, member-only, and shared scenes
5. **Image Processing**: Automatic resize to 8K (8192x4096) for consistency
6. **GPS Handling**: Extract original EXIF GPS, inject map coordinates
7. **Security**: Multi-layer protection against unauthorized access
8. **Share Links**: Token-based sharing for restricted content
