# Tour Builder Platform

A web application for building and managing interactive virtual tours with drag-and-drop editing, video transitions, and PWA offline support.

## Features

- **Visual Tour Builder** - Drag-and-drop editor for creating interactive tour pages
- **Video Transitions** - Smooth video-based transitions between pages with forward/reverse playback
- **Multiple Element Types** - Navigation buttons, hotspots, galleries, tooltips, video/audio players
- **Three-Tier Publishing** - Dev → Stage → Production workflow with environment isolation
- **Asset Preloading** - Direct S3 download via presigned URLs for instant page navigation
- **PWA Offline Mode** - Tours work offline with Cache API and IndexedDB storage
- **Role-Based Access Control** - Granular permissions system
- **Team Collaboration** - Project memberships with role-based access
- **Asset Management** - Upload, optimize, and manage media assets with variants
- **Multi-Language Support** - i18n ready

## Tech Stack

| Layer | Technology |
|-------|------------|
| Frontend | Next.js 15, React 19, TypeScript, Redux Toolkit, Tailwind CSS |
| Backend | Node.js, Express, Sequelize ORM |
| Database | PostgreSQL |
| Authentication | JWT, Google OAuth, Microsoft OAuth |
| File Storage | AWS S3 / Google Cloud Storage (direct presigned URL access) |
| PWA | Serwist Service Worker, Cache API, IndexedDB (Dexie) |

## Quick Start

### Prerequisites

- Node.js 24 LTS for backend
- PostgreSQL 14+
- npm for backend; frontend uses its existing package scripts

### Database Setup (First Time)

```bash
# Create database user and database
PGPASSWORD='postgres' psql -U postgres -c "CREATE USER app_39215 WITH PASSWORD 'your-password';"
PGPASSWORD='postgres' psql -U postgres -c "CREATE DATABASE app_39215 OWNER app_39215;"
```

### Start Backend (Terminal 1)

```bash
cd backend
npm install
npm run start-dev
```

Backend runs on **http://localhost:3000**

### Start Frontend (Terminal 2)

```bash
cd frontend
npm install
npm run dev
```

Frontend runs on **http://localhost:3001**

### Login

The login page does not display or prefill seeded credentials in any environment.
After seeding, use the credentials configured in backend environment/config values.

## Project Structure

```
├── backend/                 # Node.js/Express API server
│   ├── src/
│   │   ├── routes/          # REST API endpoints
│   │   ├── services/        # Business logic
│   │   ├── db/
│   │   │   ├── models/      # Sequelize models
│   │   │   ├── api/         # Database access layer
│   │   │   ├── migrations/  # Schema migrations
│   │   │   └── seeders/     # Seed data
│   │   ├── auth/            # Passport.js authentication
│   │   └── middlewares/     # Express middlewares
│   └── README.md            # Backend documentation
│
├── frontend/                # Next.js React application
│   ├── src/
│   │   ├── pages/           # Next.js pages
│   │   ├── components/      # React components
│   │   ├── stores/          # Redux Toolkit slices
│   │   ├── hooks/           # Custom React hooks
│   │   ├── types/           # TypeScript definitions
│   │   └── lib/             # Utility libraries
│   └── README.md            # Frontend documentation
│
└── docker/                  # Docker Compose setup
    ├── docker-compose.yml
    ├── start-backend.sh
    ├── wait-for-it.sh
    └── README.md            # Docker documentation
```

## Key Workflows

### Tour Creation

1. Create a new project in the dashboard
2. Open the **Constructor** (`/constructor?projectId=...`)
3. Add pages with background images/videos
4. Place interactive elements (buttons, hotspots, etc.)
5. Configure navigation targets and transitions on elements
6. Preview in **Runtime** mode
7. Publish: Dev → Stage → Production

### Publishing Flow

Three-tier environment model with separate content per environment:

```
    Dev Environment         Stage Environment       Production Environment
         │                        │                         │
  /constructor?projectId=   /p/[projectSlug]/stage    /p/[projectSlug]
    (editing mode)            (preview)              (public access)
         │                        │                         │
         └── Save to Stage ──────►└── Publish ─────────────►│
```

| Action | Endpoint | Description |
|--------|----------|-------------|
| Save to Stage | `POST /api/publish/save-to-stage` | Copy dev pages to stage |
| Publish | `POST /api/publish` | Copy stage pages to production |

Pages have an `environment` field (`dev`, `stage`, `production`) that determines visibility.

### Element Types

| Type | Description |
|------|-------------|
| `navigation_next` | Forward navigation button |
| `navigation_prev` | Back navigation button |
| `spot` | Clickable hotspot area |
| `description` | Text description overlay |
| `tooltip` | Hover tooltip |
| `gallery` | Image gallery |
| `carousel` | Image carousel |
| `logo` | Logo element |
| `video_player` | Embedded video player |
| `audio_player` | Audio player |
| `popup` | Modal popup |

**Element Defaults:** Each element type has configurable default settings that follow a three-tier hierarchy:
- **Global** (`element_type_defaults`) - Platform-wide defaults (auto-seeded)
- **Project** (`project_element_defaults`) - Per-project overrides (auto-snapshotted on project creation)
- **Instance** (`tour_pages.ui_schema_json`) - Page-specific element values

## API Overview

Base URL: `http://localhost:3000/api`

| Endpoint | Description |
|----------|-------------|
| `POST /auth/signin/local` | Login |
| `GET /auth/me` | Current user |
| `GET /projects` | List projects |
| `POST /publish/save-to-stage` | Copy dev → stage |
| `POST /publish` | Copy stage → production |
| `GET /tour_pages` | List tour pages |
| `GET /assets` | List assets |
| `POST /file/presign` | Get S3 presigned URLs for asset download (public) |

Full API documentation: `http://localhost:3000/api-docs` (Swagger)

## Docker Setup

```bash
cd docker
chmod +x start-backend.sh wait-for-it.sh

# Start with fresh database
rm -rf data && docker-compose up

# Or keep existing data
docker-compose up
```

Access at `http://localhost:3000`

## Environment Variables

### Backend (`backend/.env`)

```env
# Database
DB_HOST=localhost
DB_PORT=5432
DB_NAME=app_39215
DB_USER=app_39215
DB_PASSWORD=your-password

# JWT
SECRET_KEY=your-secret-key

# Admin (for seeding)
ADMIN_EMAIL=admin@example.com
ADMIN_PASS=admin-password

# AWS S3 (optional)
AWS_S3_BUCKET=your-bucket
AWS_S3_REGION=us-east-1
AWS_ACCESS_KEY_ID=your-key
AWS_SECRET_ACCESS_KEY=your-secret

# OAuth (optional)
GOOGLE_CLIENT_ID=...
GOOGLE_CLIENT_SECRET=...
MS_CLIENT_ID=...
MS_CLIENT_SECRET=...

# Email - AWS SES (optional)
EMAIL_USER=...
EMAIL_PASS=...
```

### Frontend (`frontend/.env.local`)

```env
NEXT_PUBLIC_BACK_API=http://localhost:3000/api
```

## Common Commands

### Backend

```bash
cd backend
npm run start           # Start server (migrate + seed + watch)
npm run db:migrate      # Run migrations
npm run db:seed         # Seed data
npm run db:reset        # Drop + create + migrate + seed
npm run lint            # ESLint
npm run typecheck       # Strict TypeScript check for migrated backend scope
npm run build           # Compile migrated TypeScript files
```

### Frontend

```bash
cd frontend
npm run dev             # Development server
npm run build           # Production build
npm run lint            # ESLint
npm run format          # Prettier
```

## Troubleshooting

### Connection Refused

1. Ensure PostgreSQL is running
2. Check that port 5432 (db), 3000 (backend), 3001 (frontend) are available
3. Verify database credentials in `.env`

### Database Issues

```bash
# Reset database completely
cd backend
npm run db:reset
```

### Permission Denied

Ensure the database user has proper privileges:

```sql
GRANT ALL PRIVILEGES ON DATABASE app_39215 TO app_39215;
```

## License

Proprietary - Tour Builder Platform
