448 lines
32 KiB
Markdown
448 lines
32 KiB
Markdown
# AGENTS.md
|
|
|
|
This file provides guidance to CODEX when working with code in this repository.
|
|
|
|
**MAIN RULE:** DON'T MADE UP ANYTHING!!! IF YOU NOT SURE - DOUBLECHECK IT VIA PROJECT DOCUMENTATION, TOOL DOCUMENTATION, APPROPRIATE MCP, WEB SEARCH OR JUST ASK FOR ME TO CLARIFY.
|
|
|
|
## Project Overview
|
|
|
|
Tour Builder Platform - a web application for building and managing interactive virtual tours. Built with:
|
|
- **Frontend**: Next.js 15 with React 19, TypeScript, Redux Toolkit, Tailwind CSS
|
|
- **Backend**: Node.js/Express with Sequelize ORM
|
|
- **Database**: PostgreSQL
|
|
|
|
## System Requirements
|
|
|
|
### Required Software
|
|
- **Node.js** 24.x for backend runtime and TypeScript migration work
|
|
- **PostgreSQL** 14+
|
|
|
|
### FFmpeg
|
|
|
|
FFmpeg is bundled with the backend via `ffmpeg-static` and `ffprobe-static` npm packages. No manual installation is required.
|
|
|
|
**How it works:**
|
|
- Pre-compiled binaries are downloaded during `npm install`
|
|
- `fluent-ffmpeg` is configured to use bundled binaries in `backend/src/services/videoProcessing.js`
|
|
- Works across all platforms (Linux, macOS, Windows) and Docker environments
|
|
|
|
**Supported use case:**
|
|
- Reversed video generation for back navigation transitions
|
|
|
|
## Important Rules
|
|
|
|
- **Never change global app configs casually** - Do not modify `.env` or database configuration without verifying the target environment. These configs are shared across environments and incorrect changes can break production.
|
|
- **Centralize environment variables** - Do not read new app/runtime environment variables directly from services, routes, components, hooks, or feature modules. Backend app env vars must be added to `backend/src/utils/env-validation.ts`, typed in `backend/src/types/env.ts` / `backend/src/types/config.ts`, exposed through `backend/src/config.ts`, and consumed via `config`. Frontend public env vars must be centralized in `frontend/src/config.ts`. Direct `process.env` access is acceptable only in bootstrap/config entrypoints (`load-env`, logger bootstrap, DB/Umzug config, Next config), scripts, migrations, seeders, and tests.
|
|
- **Backend async handlers** must be wrapped with `wrapAsync` helper for error propagation.
|
|
- **Use Passport JWT** for protected routes: `passport.authenticate('jwt', { session: false })`. Secure routes must read the authenticated user through `getCurrentUser(req)` from `backend/src/utils/request-context.ts`; if absent, return `ForbiddenError`.
|
|
- **Access model** - Keep the current permission model: effective permissions are `app_role.permissions + user.custom_permissions`. `Administrator`, `Platform Owner`, and `Account Manager` are platform-wide internal roles. Other internal users currently have all-project scope by default unless a future explicit override system is implemented. `Public` users must not have admin API permissions and can only access public production pages plus explicitly granted private production presentations.
|
|
- **Public role hardening** - Do not grant RBAC permissions or custom permissions to `Public` users. Do not represent private production presentation grants as `READ_PROJECTS`, `READ_TOUR_PAGES`, or other admin permissions; use `production_presentation_access`.
|
|
- **Centralize access decisions** - New authorization logic must go through an `AccessPolicy`-style helper/service rather than ad hoc checks in routes/components. Keep admin API permissions separate from runtime presentation access.
|
|
|
|
## Mandatory Rules For New Code
|
|
|
|
These rules are required for new code and for touched code when practical.
|
|
|
|
### Backend Boundaries
|
|
- **Routes/controllers**: only authenticate, read runtime context, validate request input, call a service, and map the response. Do not put business logic in routes.
|
|
- **Services/domain**: own business logic, transactions, permission decisions, and orchestration.
|
|
- **DB API/repository**: only data access, filters, includes, pagination, and persistence mapping.
|
|
- **Policy**: all role/permission/runtime access decisions belong in policy/helper services, not scattered across routes.
|
|
- **Validation**: all new external `body`, `query`, and `params` inputs must be validated before service calls. `Joi` is already available in backend and should be preferred unless there is a clear reason to use another validator.
|
|
- **ID handling**: route params are canonical. For `PUT/PATCH/DELETE /:id`, use `req.params.id`; reject mismatched body ids.
|
|
- **Query safety**: new list/autocomplete endpoints must define max `limit`, default pagination, allowed sort fields, and allowed sort directions.
|
|
- **Service contracts**: new service/DB API methods should use object/options signatures, e.g. `Service.update({ id, data, currentUser, transaction, runtimeContext })` and `DBApi.findAll(filter, { currentUser, transaction, runtimeContext })`.
|
|
- **Logging**: use the project logger in runtime backend code (`services`, `routes`, `middlewares`, `db/api`, `utils`, app/bootstrap/config). Do not add new `console.*` calls outside migrations, seeders, scripts, or explicit debug-only CLI tooling.
|
|
|
|
### Backend Typing
|
|
- New backend pure helpers, validators, and policy modules should use TypeScript or JSDoc/checkJs-compatible types.
|
|
- Define shared shapes for `currentUser`, `runtimeContext`, service options, and validation results when touching related code.
|
|
- Do not add global `Express.Request` augmentation for project request fields. Use `backend/src/utils/request-context.ts` helpers for request-scoped `currentUser`, `runtimeContext`, logging, runtime-public flags, and permission overrides.
|
|
- Keep active backend source in strict TypeScript/ESM.
|
|
|
|
### Frontend State And API
|
|
- **Redux is for client/app state only**: auth/session UI, theme/style, layout/sidebar, constructor UI state, and app preferences.
|
|
- **TanStack Query is for server state**: API reads, entity lists/details, mutations, invalidation, and background refetch.
|
|
- Do not create new entity CRUD Redux slices or new Redux thunks for server reads/mutations.
|
|
- Centralize API access through query hooks or a shared API client. Avoid direct `axios` calls inside feature UI components unless there is a clear existing local pattern.
|
|
- New feature-specific code should live near the feature/domain it belongs to. Do not put feature logic into generic `components`, `hooks`, or `lib` folders when a feature-local module is clearer.
|
|
|
|
### Frontend TypeScript And React
|
|
- Do not add new `any` without a specific reason. Prefer existing domain types or add a narrow local type.
|
|
- Avoid new `eslint-disable`, `@ts-ignore`, and hook dependency suppressions. If unavoidable, add a short reason.
|
|
- New hooks must follow React hook rules and should be structured so `react-hooks/exhaustive-deps` can be enabled.
|
|
- Do not add new client usage of `jsonwebtoken`; use `jwt-decode` or `/auth/me` for client-side identity.
|
|
|
|
### Database And Migrations
|
|
- Do not add indexes speculatively. Add indexes after checking query patterns or explaining the expected query.
|
|
- Migrations must be reversible or include an explicit rollback/backup plan.
|
|
- Do not drop columns/tables in the same change that stops using them unless explicitly requested and production data safety is covered.
|
|
- Do not normalize `ui_schema_json` into new tables unless there is a concrete current need; prefer validation/extraction helpers first.
|
|
- Do not rewrite, rename, or reformat already applied backend migration files. Add new migrations only for new schema changes.
|
|
|
|
## Disabled Features
|
|
|
|
The following features are implemented but currently disabled with `false &&` conditions:
|
|
|
|
- **Navigation blocking while preloading** - Navigation buttons can be disabled until neighbor page backgrounds are preloaded. Currently disabled to allow instant navigation response. To re-enable, remove `false &&` in:
|
|
- `frontend/src/components/RuntimePresentation.tsx` (isForwardNavDisabled, handleElementClick)
|
|
- `frontend/src/pages/constructor.tsx` (handleElementClick, isNavDisabled calculation)
|
|
|
|
## Documentation Workflow
|
|
|
|
- **Before each task**: Research relevant documentation in `documentation/` to understand existing implementations, patterns, and conventions.
|
|
- **After each task**: Update affected documentation to reflect changes (API changes, new fields, modified workflows).
|
|
- **After implementing new features/modules**: Create new documentation file in `documentation/` following the existing format, and add reference to the Feature Documentation table in this file.
|
|
|
|
## Quick Start
|
|
```bash
|
|
# Terminal 1 - Backend (port 3000)
|
|
cd backend && npm run start-dev
|
|
|
|
# Terminal 2 - Frontend (port 3001)
|
|
cd frontend && npm run dev
|
|
```
|
|
|
|
## Common Commands
|
|
|
|
### Backend (run from `backend/` directory, runs on port 3000 in the default dev_stage flow)
|
|
```bash
|
|
npm install # Install dependencies
|
|
npm run start-dev # Start server (loads .env, migrates, seeds, watches)
|
|
npm run lint # ESLint check
|
|
npm run typecheck # Strict TypeScript check for migrated backend scope
|
|
npm run test # Unit tests (Node test runner)
|
|
npm run test:integration # Integration tests; DB tests skip when Postgres is unavailable
|
|
npm run test:e2e # E2E HTTP tests with a local listener
|
|
npm run test:all # Unit, integration, and e2e suites
|
|
npm run build # Compile migrated TypeScript files
|
|
npm run db:migrate # Run migrations only
|
|
npm run db:migrate:undo # Undo last migration
|
|
npm run db:seed # Seed database only
|
|
npm run db:reset # Drop, create, migrate, and seed
|
|
```
|
|
|
|
**Creating new migrations:** Add new migration files deliberately under `backend/src/db/migrations/` only when a schema change is required. Keep them reversible and preserve already applied migration files unchanged.
|
|
|
|
**Note:** Backend `.env` is loaded centrally by `backend/src/load-env.ts` for app and DB entrypoints. If `NODE_ENV` is absent, it defaults to `dev_stage`, matching the standard VM backend flow and using the `.env` DB settings. Do not add `NODE_ENV=production` to local startup unless a task explicitly requires the production config.
|
|
The backend defaults to port `3000` in `dev_stage` and `8080` otherwise; set `PORT` explicitly when a task needs a different port.
|
|
|
|
### Frontend (run from `frontend/` directory)
|
|
```bash
|
|
npm install # Install dependencies
|
|
npm run dev # Start dev server with Turbopack (port 3001)
|
|
npm run typecheck # TypeScript check without production build
|
|
npm run verify # Typecheck, lint, and production build
|
|
npm run build # Production build
|
|
npm run lint # ESLint check (.ts, .tsx files)
|
|
npm run format # Format code with Prettier
|
|
```
|
|
|
|
### Standard VM Environment
|
|
|
|
The standard VM port split is:
|
|
- **Frontend PM2 app `frontend-dev`**: Next.js production server on port `3001`
|
|
- **Backend PM2 app `backend-dev`**: `npm run start` with `NODE_ENV=dev_stage` on port `3000`
|
|
- **Apache**: public entrypoint and reverse proxy on port `80`
|
|
|
|
Direct VM backend health checks should target `http://127.0.0.1:3000/api/...`. A protected endpoint returning `401 Unauthorized` without JWT means the backend is reachable.
|
|
|
|
### Docker (run from `docker/` directory)
|
|
```bash
|
|
chmod +x start-backend.sh && chmod +x wait-for-it.sh # First time setup
|
|
docker-compose up # Start all services
|
|
rm -rf data && docker-compose up # Start with fresh database
|
|
```
|
|
|
|
## Architecture
|
|
|
|
### Backend Structure (`backend/src/`)
|
|
- **routes/**: Express route handlers (RESTful endpoints)
|
|
- **db/api/**: Database access layer (CRUD operations per model)
|
|
- **db/models/**: Sequelize model definitions
|
|
- **db/migrations/**: Database migrations
|
|
- **db/seeders/**: Seed data
|
|
- **auth/**: Passport.js authentication (JWT, Google OAuth, Microsoft OAuth)
|
|
- **services/**: Business logic services (emails, notifications, publishing, file storage)
|
|
- **factories/**: Router and service generation (`router.factory.js`, `service.factory.js`)
|
|
- **middlewares/**: Permission checking, runtime context handling
|
|
- **helpers/**: Utility functions (e.g., `wrapAsync` for async error handling)
|
|
|
|
### Frontend Structure (`frontend/src/`)
|
|
- **pages/**: Next.js pages (each entity has `-list`, `-edit`, `-new`, `-view`, `-table` variants)
|
|
- **components/**: React components (PascalCase naming)
|
|
- **stores/**: Redux Toolkit slices (per entity + auth, main, style slices)
|
|
- **layouts/**: Page layouts (Authenticated, Guest)
|
|
- **hooks/**: Global custom hooks (`usePreloadOrchestrator`, `useNeighborGraph`, etc.)
|
|
- **lib/**: Utility libraries (`elementStyles`, `imagePreDecode`, `mediaDuration`, `parseJson`)
|
|
- **types/**: TypeScript type definitions (`constructor.ts`, `runtime.ts`, `preload.ts`)
|
|
- **helpers/**: Utility functions
|
|
- **styles/**: Global CSS with Tailwind (`_theme.css` uses `@apply`)
|
|
|
|
### Key Domain Models
|
|
Projects, Tour Pages, Assets, Asset Variants, Permissions, Roles, Users, Publish Events, PWA Caches, Element Type Defaults, Project Element Defaults
|
|
|
|
**Note:** Page elements, navigation links, and transitions are stored directly in `tour_pages.ui_schema_json`.
|
|
|
|
### Element Defaults Hierarchy
|
|
The system has a two-level defaults cascade for UI elements:
|
|
1. **element_type_defaults** - Global platform-wide defaults (11 predefined types)
|
|
2. **project_element_defaults** - Project-specific overrides (auto-snapshotted from global on project creation)
|
|
|
|
When creating new elements, defaults cascade: global → project. Instance-specific settings are stored in `tour_pages.ui_schema_json`.
|
|
|
|
### Special Pages
|
|
- **`constructor.tsx`**: Tour builder/editor with drag-drop, element positioning, page management
|
|
- **`runtime.tsx`**: Tour playback with transitions, preloading, navigation
|
|
- **`p/[slug].tsx`**: Public tour pages with PWA offline support
|
|
|
|
### State Management
|
|
- **Redux Toolkit is the default only for client/app state** (auth/session UI, style/theme, layout/sidebar, constructor UI state, app preferences)
|
|
- **TanStack Query is the default for server state** (API reads, entity lists/details, mutations, invalidation, background refetch)
|
|
- Do not create new entity CRUD Redux slices in `stores/[entity]/[entity]Slice.ts`.
|
|
- Core slices: `authSlice.ts` (auth), `mainSlice.ts` (UI), `styleSlice.ts` (theming), `constructorSlice.ts` (editor)
|
|
- Use `useAppSelector` and `useAppDispatch` hooks from `stores/hooks.ts`
|
|
- **Local hooks acceptable** for ephemeral, component-scoped state (e.g., `usePageNavigation` for session-scoped page history)
|
|
- See [stores-module.md](frontend/docs/stores-module.md#state-management-guidelines) for decision tree
|
|
|
|
## Code Conventions
|
|
|
|
### Backend
|
|
- ES6+ with arrow functions, const/let
|
|
- Document endpoints with Swagger JSDoc comments
|
|
- Lowercase filenames (e.g., `auth.js`, `projects.js`)
|
|
|
|
### Frontend
|
|
- Functional components with TypeScript
|
|
- PascalCase for components and types, camelCase for variables/functions
|
|
- Custom hooks prefixed with `use` (e.g., `useAuth`)
|
|
- Tailwind CSS with theme customization in `_theme.css`
|
|
|
|
### Styling
|
|
- Theme customization uses `@apply` directive in `_theme.css`
|
|
- **Sidebar styles**: Target `#asideMenu` (defined in `AsideMenuLayer.tsx`) for sidebar overrides
|
|
- Use highly specific selectors when overriding Tailwind utilities to avoid conflicts
|
|
- Themed blocks (`.theme-pink`, `.theme-green`) standardize UI appearance - ensure custom overrides integrate cleanly
|
|
|
|
### Error Handling
|
|
- Backend: Use centralized `commonErrorHandler` middleware for uniform error responses
|
|
- Frontend: Use React error boundaries for runtime errors
|
|
|
|
## API Patterns
|
|
|
|
Routes follow pattern: `/api/[entity]/` with standard CRUD operations
|
|
- `POST /api/auth/signin/local` - Login
|
|
- `GET /api/auth/me` - Current user (requires JWT)
|
|
- Self-registration is disabled. New users are created by Administrator, Platform Owner, or Account Manager through the Users flow and receive an invitation/setup link.
|
|
|
|
All entity routes support: list, findOne, create, update, destroy operations with pagination and filtering.
|
|
|
|
## Backend Factory Patterns
|
|
|
|
### Router Factory (`factories/router.factory.js`)
|
|
Generates standard CRUD routes for entities:
|
|
```javascript
|
|
module.exports = createEntityRouter('assets', AssetsService, AssetsDBApi, {
|
|
permissionEntity: 'assets',
|
|
});
|
|
```
|
|
|
|
### Service Factory (`factories/service.factory.js`)
|
|
Generates service classes with transaction handling:
|
|
```javascript
|
|
module.exports = createEntityService('assets', AssetsDBApi);
|
|
```
|
|
|
|
### Base DB API (`db/api/base.api.js`)
|
|
All entity APIs extend `GenericDBApi` and override:
|
|
- `MODEL` - Sequelize model reference
|
|
- `SEARCHABLE_FIELDS` - Fields for text search
|
|
- `RANGE_FIELDS` - Fields for range filtering
|
|
- `ENUM_FIELDS` - Fields for exact match filtering
|
|
- `getFieldMapping(data)` - Transform input data before save
|
|
|
|
## File Storage
|
|
|
|
Controlled by `FILE_STORAGE_PROVIDER` env var or auto-detected from credentials:
|
|
- `s3` - AWS S3 (requires `S3_BUCKET`, `S3_REGION`, `S3_ACCESS_KEY_ID`, `S3_SECRET_ACCESS_KEY`)
|
|
- `gcloud` - Google Cloud Storage
|
|
- `local` - Local filesystem (default)
|
|
|
|
## Publishing Workflow
|
|
|
|
Three-tier **content environment** model (distinct from `NODE_ENV` server environment):
|
|
- **Dev** (constructor editing) → **Stage** (preview) → **Production** (public)
|
|
|
|
**Route-based environment access:**
|
|
- `/p/[slug]` - Production presentation
|
|
- `/p/[slug]/stage` - Stage presentation
|
|
- `/constructor?projectId=` - Dev editing (always dev environment)
|
|
|
|
Key endpoints:
|
|
- `POST /api/publish/save-to-stage` - Dev → Stage (body: `{ projectId }`)
|
|
- `POST /api/publish` - Stage → Production (body: `{ projectId }`)
|
|
|
|
**Environment isolation:** Pages have `environment` field (`dev`, `stage`, `production`). The `X-Runtime-Environment` header (set by frontend) determines which content environment to query. Both frontend (`RuntimePresentation.tsx`) and backend (`runtime-context.js`) filter by this field.
|
|
|
|
**Server Environment vs Content Environment:**
|
|
- `NODE_ENV` controls database config (production/dev_stage/development)
|
|
- `tour_pages.environment` controls content visibility (dev/stage/production)
|
|
|
|
### Private Production Presentations
|
|
|
|
Production presentations are public by default at `/p/[slug]`. Each project can switch production runtime visibility through `projects.production_presentation_visibility` (`public` default, `private` optional).
|
|
|
|
- Platform staff users with any RBAC permission can visit every private production presentation
|
|
- Customer users with `Public` role can visit only private production presentations granted in `production_presentation_access`
|
|
- `Administrator`, `Platform Owner`, and `Account Manager` can create users
|
|
- When creating or editing a `Public` user, the form shows a selector for private production presentations and saves DB access grants
|
|
- Do not use config files or env vars for customer allowlists
|
|
- Do not grant customer viewer users broad permissions such as `READ_PROJECTS` or `READ_TOUR_PAGES`; any RBAC permission makes the user platform staff for private presentation access
|
|
|
|
See [private-production-presentations.md](documentation/private-production-presentations.md).
|
|
|
|
## PWA & Offline Support
|
|
|
|
- **Service Worker**: Generated by Serwist from `frontend/src/sw.ts` → `public/sw.js`
|
|
- **Offline Caching**: PWA_Caches model tracks cached assets per project
|
|
- **Runtime Mode**: Middleware distinguishes public vs authenticated access for offline tours
|
|
|
|
## Asset Preloading Architecture
|
|
|
|
Runtime presentations use direct S3 downloads via presigned URLs for instant page navigation:
|
|
|
|
```
|
|
1. Request presigned URLs (max 50 per batch, 1-hour expiry)
|
|
POST /api/file/presign { urls: ["assets/img.jpg", ...] }
|
|
|
|
2. Download directly from S3 → Store in Cache API (< 5MB) or IndexedDB (≥ 5MB)
|
|
|
|
3. Create blob URL → Decode image → Store in readyBlobUrlsRef
|
|
|
|
4. Instant lookup during navigation (O(1))
|
|
const blobUrl = preloadOrchestrator.getReadyBlobUrl(originalUrl);
|
|
```
|
|
|
|
**Preload Priority:** Transition videos (+150) > Images (+100) > Audio (+50) > Video (+30)
|
|
|
|
**Storage Layers:**
|
|
| Layer | Size Limit | Purpose |
|
|
|-------|------------|---------|
|
|
| Cache API | < 5MB | Fast asset storage |
|
|
| IndexedDB (Dexie) | ≥ 5MB | Large assets, offline data |
|
|
| Blob URLs | Memory | Pre-decoded for instant display |
|
|
|
|
## Frontend Patterns
|
|
|
|
### MUI X Data Grid v7
|
|
Use new `valueGetter` signature:
|
|
```typescript
|
|
// For value transformation
|
|
valueGetter: (value) => value?.id ?? value
|
|
|
|
// For row access
|
|
valueGetter: (_value, row) => new Date(row.created_at)
|
|
```
|
|
|
|
### Custom Hooks
|
|
Hooks are located in three places:
|
|
- **`src/hooks/`**: Global hooks (`usePreloadOrchestrator`, `usePageNavigationState`, `useTransitionPlayback`, `usePageNavigation`)
|
|
- **`src/hooks/video/`**: Video playback primitives (8 composable hooks for video playback scenarios)
|
|
- **Component directories**: Domain-specific hooks (`components/Assets/useAssetUploader.ts`)
|
|
|
|
Key runtime hooks:
|
|
| Hook | Purpose |
|
|
|------|---------|
|
|
| `usePreloadOrchestrator` | Stream-first asset preloading (current page + transitions only) |
|
|
| `usePageNavigationState` | Unified navigation state machine (replaces 6+ hooks) |
|
|
| `useTransitionPlayback` | Video transition playback coordination |
|
|
| `usePageNavigation` | Page history tracking with browser-like back behavior |
|
|
| `useCanvasScale` | Responsive canvas scaling with letterbox mode |
|
|
| `useNetworkAware` | Network condition monitoring for adaptive transitions |
|
|
| `useBackgroundDimensionSuggestion` | Detect background media dimensions for canvas size suggestions |
|
|
|
|
**Video Hooks (`src/hooks/video/`):**
|
|
| Hook | Purpose |
|
|
|------|---------|
|
|
| `useVideoBlobUrl` | Resolve video URLs to blob URLs from preload cache |
|
|
| `useVideoPlaybackCore` | Core playback logic combining multiple primitives |
|
|
| `useVideoPlayer` | Complete UI video player hook |
|
|
|
|
### Redux Entity Pattern
|
|
Use this pattern only when maintaining an existing Redux entity flow; new server-state code should use TanStack Query hooks instead.
|
|
```typescript
|
|
import { fetch, deleteItem } from '../../stores/assets/assetsSlice';
|
|
const dispatch = useAppDispatch();
|
|
dispatch(fetch({ query: '?limit=100' }));
|
|
```
|
|
|
|
## Feature Documentation
|
|
|
|
Detailed feature documentation is available in `documentation/`:
|
|
|
|
| Document | Description |
|
|
|----------|-------------|
|
|
| [project-architecture.md](documentation/project-architecture.md) | Overall project structure and architecture |
|
|
| [api-reference.md](documentation/api-reference.md) | API endpoints reference |
|
|
| [authentication-system.md](documentation/authentication-system.md) | JWT, OAuth (Google, Microsoft) authentication |
|
|
| [rbac-system.md](documentation/rbac-system.md) | Role-based access control system |
|
|
| [user-management.md](documentation/user-management.md) | User CRUD, roles assignment, account management |
|
|
| [project-memberships.md](documentation/project-memberships.md) | Team collaboration, per-project access control |
|
|
| [asset-upload-variants.md](documentation/asset-upload-variants.md) | Asset upload pipeline and variant generation |
|
|
| [ui-elements.md](documentation/ui-elements.md) | UI Elements stored in `ui_schema_json` (buttons, hotspots, galleries, tooltips, media players) |
|
|
| [page-transitions.md](documentation/page-transitions.md) | Video transitions stored on navigation elements |
|
|
| [project-transition-settings.md](documentation/project-transition-settings.md) | Environment-aware CSS transition settings (fade, duration, easing) |
|
|
| [video-playback.md](documentation/video-playback.md) | Video player implementation, iOS autoplay compatibility |
|
|
| [assets-preloading.md](documentation/assets-preloading.md) | Asset preloading and caching strategy |
|
|
| [publishing-workflow.md](documentation/publishing-workflow.md) | Dev → Stage → Production publishing |
|
|
| [private-production-presentations.md](documentation/private-production-presentations.md) | Private production presentation allowlist, viewer users, and runtime access flow |
|
|
| [offline-pwa-mode.md](documentation/offline-pwa-mode.md) | PWA offline capabilities and caching |
|
|
| [email-notification-service.md](documentation/email-notification-service.md) | Nodemailer/SES integration, verification emails, invitations |
|
|
| [search-system.md](documentation/search-system.md) | Global full-text search, permission-based filtering |
|
|
| [deployment-vm.md](documentation/deployment-vm.md) | Standard VM deployment topology, PM2 recovery, ports, OOM/ffmpeg diagnostics |
|
|
| [custom-domains-apache.md](documentation/custom-domains-apache.md) | Customer-owned presentation domains via Apache, DNS A records, Certbot, and host/path routing |
|
|
| [page-links-navigation.md](documentation/page-links-navigation.md) | Page navigation using `targetPageSlug` in elements |
|
|
| [access-logs-audit-trail.md](documentation/access-logs-audit-trail.md) | Access logging, audit trail, activity tracking |
|
|
| [db-cleanup-audit.md](documentation/db-cleanup-audit.md) | Non-destructive DB cleanup audit, orphan checks, legacy schema checks, and soft-delete retention policy |
|
|
| [global-ui-controls.md](documentation/global-ui-controls.md) | Configurable fullscreen, sound, and offline system controls with global/project/page cascade |
|
|
| [backend/database-schema.md](backend/docs/database-schema.md) | Complete database schema - all models, fields, relationships, indexes, constraints |
|
|
| [backend/backend-architecture.md](backend/docs/backend-architecture.md) | Backend architecture - layers, design patterns, middleware, factories, file storage |
|
|
| [backend/api-endpoints.md](backend/docs/api-endpoints.md) | Complete API reference - all endpoints, request/response formats, authentication, rate limits |
|
|
| [backend/modules/core.md](backend/docs/modules/core.md) | Core module - index.js (entry), config.ts (configuration), helpers.js/utilities |
|
|
| [backend/modules/auth.md](backend/docs/modules/auth.md) | Auth module - Passport.js strategies (JWT, Google, Microsoft), login, invitation setup, password reset, email verification |
|
|
| [backend/modules/middleware.md](backend/docs/modules/middleware.md) | Middleware module - rate limiting, permissions, runtime context, public access control, file uploads |
|
|
| [backend/modules/routes.md](backend/docs/modules/routes.md) | Routes module - 22 route files, factory pattern, CRUD endpoints, Swagger docs, auth/file/search/sql routes |
|
|
| [backend/modules/services.md](backend/docs/modules/services.md) | Services module - business logic layer, 34 service files, factory pattern, file storage (S3/GCloud/Local), email, notifications, publishing |
|
|
| [backend/modules/email.md](backend/docs/modules/email.md) | Email module - Nodemailer/AWS SES, transactional emails, HTML templates, token management, email verification, password reset, invitations |
|
|
| [backend/modules/notifications.md](backend/docs/modules/notifications.md) | Notifications module - error classes (ValidationError, ForbiddenError), i18n message catalog, helper functions |
|
|
| [backend/modules/factories.md](backend/docs/modules/factories.md) | Factories module - createEntityRouter and createEntityService functions, code generation patterns for CRUD operations, boilerplate elimination |
|
|
| [backend/modules/db-models.md](backend/docs/modules/db-models.md) | DB Models module - 16 Sequelize models, entity definitions, associations, validations, lifecycle hooks, soft delete patterns |
|
|
| [backend/modules/db-api.md](backend/docs/modules/db-api.md) | DB API module - GenericDBApi base class, 18 entity APIs, declarative configuration, query filtering, runtime context helpers |
|
|
| [backend/modules/db-migrations.md](backend/docs/modules/db-migrations.md) | DB Migrations module - Umzug runner, migration safety rules, schema evolution, data backfill |
|
|
| [backend/modules/db-seeders.md](backend/docs/modules/db-seeders.md) | DB Seeders module - Umzug seeders, RBAC setup (7 roles, 54 permissions), sample data opt-in |
|
|
| [backend/modules/db-config.md](backend/docs/modules/db-config.md) | DB Config module - typed DB config, environment validation (Joi), Umzug commands, sync/reset scripts |
|
|
| [backend/modules/utilities.md](backend/docs/modules/utilities.md) | Utilities module - error classes, Pino logging, env validation, request helpers (wrapAsync, commonErrorHandler), DB utils, i18n messages |
|
|
| [backend/testing.md](backend/docs/testing.md) | Backend test strategy - unit, integration, and e2e coverage, helpers, commands, and environment notes |
|
|
| [frontend/hooks-reference.md](frontend/docs/hooks-reference.md) | React hooks reference (useFormSync, useEntityTable, useOfflineMode, etc.) |
|
|
| [frontend/video-hooks-module.md](frontend/docs/video-hooks-module.md) | Video playback primitive hooks (8 composable hooks for video scenarios) |
|
|
| [frontend/constructor-page-editor.md](frontend/docs/constructor-page-editor.md) | Constructor page editor - visual tour builder with drag-drop elements |
|
|
| [frontend/runtime-presentation.md](frontend/docs/runtime-presentation.md) | Runtime presentation viewer - full-screen tour playback with transitions |
|
|
| [frontend/navigation-smooth-transitions.md](frontend/docs/navigation-smooth-transitions.md) | Navigation & smooth transitions - page switching, transition video playback, last frame preservation, online/offline modes |
|
|
| [frontend/ui-adaptivity-system.md](frontend/docs/ui-adaptivity-system.md) | UI Adaptivity System - canvas units (--cu), responsive scaling, letterbox mode, element styling |
|
|
| [frontend/ui-element-preloading-analysis.md](frontend/docs/ui-element-preloading-analysis.md) | UI element processing & neighbor preloading - deep analysis of asset extraction, preload flow, offline caching |
|
|
| [frontend/asset-upload-preloading-pwa-analysis.md](frontend/docs/asset-upload-preloading-pwa-analysis.md) | Deep analysis of asset upload, preload orchestrator, PWA/offline mode, storage layers, network awareness |
|
|
| [frontend/frontend-architecture.md](frontend/docs/frontend-architecture.md) | Frontend architecture - 386 files, 14 modules, factories, hooks, Redux, PWA/offline, design patterns |
|
|
| [frontend/pages-module.md](frontend/docs/pages-module.md) | Pages module - 99 pages, _app.tsx entry, entity CRUD pattern, constructor, runtime presentations, layouts |
|
|
| [frontend/components-module.md](frontend/docs/components-module.md) | Components module - 183 files, entity tables, factories, constructor, element settings, runtime, PWA/offline |
|
|
| [frontend/hooks-module.md](frontend/docs/hooks-module.md) | Hooks module - 52 custom hooks, runtime/preloading, PWA/offline, constructor, tables/forms, UI utilities |
|
|
| [frontend/stores-module.md](frontend/docs/stores-module.md) | Stores module - Redux Toolkit, 17 slices (4 core + 13 entity), createEntitySlice factory, typed hooks |
|
|
| [frontend/lib-module.md](frontend/docs/lib-module.md) | Lib module - 19 utility files, asset URL management, element defaults/styles/effects, offline storage (Cache API + IndexedDB), download queue |
|
|
| [frontend/types-module.md](frontend/docs/types-module.md) | Types module - 18 TypeScript definition files, entity types, constructor/runtime types, API/Redux types, permissions enum, offline/preload types |
|
|
| [frontend/factories-module.md](frontend/docs/factories-module.md) | Factories module - 5 factory files (~1,285 LOC), createListPage, createFormPage, createTableComponent, configBuilderFactory, createEntitySlice for 91% boilerplate reduction |
|
|
| [frontend/schemas-module.md](frontend/docs/schemas-module.md) | Schemas module - 6 Zod validation schema files (~257 LOC), form validation for User, Asset, Project, TourPage, Role entities with type inference |
|
|
| [frontend/helpers-module.md](frontend/docs/helpers-module.md) | Helpers module - 6 utility files (~304 LOC), dataFormatter (entity display), hasPermission (RBAC), notifyStateHandler (Redux), text formatters, file saver |
|
|
| [frontend/layouts-module.md](frontend/docs/layouts-module.md) | Layouts module - 2 layout files (~262 LOC), LayoutAuthenticated (JWT auth, permissions, UI chrome), LayoutGuest (public pages), getLayout pattern |
|
|
| [frontend/config-module.md](frontend/docs/config-module.md) | Config module - 12 config files (~523 LOC), Next.js/Tailwind/TypeScript build config, runtime settings (config.ts), menu configs, offline/preload configs, ESLint rules |
|
|
| [frontend/context-module.md](frontend/docs/context-module.md) | Context module - DownloadContext (~256 LOC) for PWA download progress state, DownloadEventBus integration, useDownloadContext/useDownloadContextOptional hooks |
|
|
| [frontend/interfaces-module.md](frontend/docs/interfaces-module.md) | Interfaces module - ~15 type definition files (~2,200+ LOC), entity types, API contracts, Redux state shapes, permissions enum, constructor/runtime/offline/preload interfaces |
|