This document is intended for the engineering team taking over the Phase Connect website and its supporting APIs. It assumes the reader is already familiar with Node.js, Vue/Nuxt, PHP Laravel, Nginx/PHP-FPM, queues, and common frontend/backend separated deployment patterns. The document therefore focuses only on project-specific structure, runtime behavior, deployment notes, and handoff checks.
Frontend branch notice: production development and handoff for the frontend must use the new_dev branch, not the main branch. Before debugging, development, builds, acceptance testing, or production comparison, first confirm that the frontend repository is checked out to new_dev.
This document does not cover the documentation site project and does not include any real local or server absolute paths.
Phase Connect is a content-driven official website. It includes public content pages and in-page content editing after login. The frontend is a Nuxt 3 SPA responsible for website pages, content display, in-page admin entry points, and admin login. The backend is a Laravel API-only project responsible for public content APIs, Admin CRUD APIs, third-party data synchronization, and background workers.
Main business areas:
The backend includes Owl Admin, but the project has been customized on top of it. In production, only the /api/* and /admin-api/* API layers are deployed. The project mainly reuses Slowlyo\OwlAdmin\Services\AdminService, Admin Controllers, and routing conventions to provide CRUD APIs quickly. It does not use the Owl Admin view layer and does not deploy a Laravel Web/view layer.
Recommended production topology:
/api/* and /admin-api/* from the same origin to the backend API service.phase-front| Path | Description |
|---|---|
nuxt.config.ts | Nuxt configuration. Uses ssr: false, runtime environment variables, and dev proxy settings. |
app.vue | Root component. Initializes global configuration and shows Logout / Edit Mode floating entries after login. |
middleware/route-link.global.js | Global login middleware. All routes except /login check login state. |
api/allApi.js | Public API $fetch wrapper. In practice, requests same-origin /api/*. |
service/request/* | Admin API axios wrapper. Automatically attaches the Bearer token. |
pages/index.vue | Home page vertical Swiper container. |
pages/login.vue | Admin login page. |
pages/generation.vue, pages/talent/[id].vue | Main Talent / Generation pages. |
pages/live-schedule.vue, pages/schedule.vue | Full schedule page and home schedule module. |
pages/music.vue, pages/shop.vue, pages/newslist.vue, pages/posts/[id].vue | Main content pages. |
pages/auditions.vue, pages/jointheteam.vue, pages/letstalk.vue | Work With Us related pages. |
components/Admin/* | Embedded editing, shared CRUD, forms, upload, and rich-text components. |
components/Navbar, components/FooterNavbar | Public navigation and footer. |
assets/* | Styles, images, videos, and font assets. |
phase-back-admin| Path | Description |
|---|---|
routes/api.php | Public /api/* routes. |
routes/admin.php | /admin-api/* CRUD resource routes based on Owl Admin AdminService. |
app/Admin/routes.php | Admin API extension routes, such as sync buttons and rich-text upload. |
app/Http/Controllers/Api/* | Public API controllers. |
app/Admin/Controllers/* | Admin CRUD controllers. |
app/Services/Stream/* | Core YouTube / Twitch live-stream synchronization services. |
app/Jobs/* | Queue jobs, synchronization jobs, and asynchronous Webhook handling. |
routes/console.php | Laravel scheduler task definitions. |
app/Console/Commands/* | Manual synchronization commands, such as music and Shopify synchronization. |
app/Http/Resources/Api/* | Public API response resources. |
config/admin.php | Admin API prefix and login-related configuration. |
config/livestream.php | YouTube / Twitch synchronization configuration. |
config/shopify.php | Shopify API configuration. |
ecosystem.config.cjs | PM2 worker example configuration. |
The frontend only needs the following two variables:
Notes:
NUXT_DEV_BASE_URL is used as the Nuxt dev proxy target for /api and is also exposed as runtimeConfig.public.apiBase.ADMIN_BASE_URL is used as the Nuxt dev proxy target for /admin-api and is also exposed as runtimeConfig.public.adminApiBase.api/allApi.js effectively builds requests against same-origin /api/*. In production, configure same-origin routing/proxying for /api, or refactor the API base URL logic first./admin-api/*, so they depend on same-origin routing/proxying or the Nuxt dev proxy.The backend .env follows standard Laravel configuration. Focus on the following groups:
| Group | Required items | Notes |
|---|---|---|
| App | APP_KEY, APP_ENV, APP_DEBUG, APP_URL | For production, use APP_ENV=production and APP_DEBUG=false after confirming logging and troubleshooting procedures. |
| Database | DB_CONNECTION, DB_HOST, DB_DATABASE, DB_USERNAME, DB_PASSWORD | A full database SQL export will be provided for handoff. New environments should initialize from that SQL. Migrations are mainly a reference for later schema changes. |
| Queue / Cache / Session | QUEUE_CONNECTION, CACHE_STORE, SESSION_DRIVER | Database drivers are currently preferred. Make sure the required tables exist and workers are running. |
| Storage | FILESYSTEM_DISK, AWS_* | Local disk is the default. If uploaded files must be public, configure static file serving, object storage, or CDN according to the target environment. |
| YouTube | YOUTUBE_API_KEY | The receiving team must use its own Google/YouTube developer account, create a project, enable YouTube Data API, and generate its own API Key. Live, music, and program synchronization depend on this key. |
| Twitch / Webhook | TWITCH_CLIENT_ID, TWITCH_CLIENT_SECRET, TWITCH_WEBHOOK_SECRET, TWITCH_WEBHOOK_CALLBACK_URL | The receiving team must use its own Twitch developer account, create an application, configure the EventSub callback, and generate its own Client ID, Client Secret, and Webhook Secret. |
| Shopify | SHOPIFY_API_KEY, SHOPIFY_API_SECRET, SHOPIFY_API_ACCESS_TOKEN, SHOPIFY_DOMAIN | The receiving team must use its own Shopify developer account, create an app, and generate its own API Key, API Secret, and Access Token. SHOPIFY_DOMAIN is fixed as official-phase-connect-store.myshopify.com. |
| Admin | ADMIN_LOGIN_CAPTCHA | Login captcha can currently be disabled. The Admin API prefix comes from config/admin.php by default. |
| Fetch cache | FETCH_* | Controls cache TTL for third-party synchronization. |
Backend .env example:
Third-party credential ownership:
YOUTUBE_API_KEY.SHOPIFY_DOMAIN is fixed as official-phase-connect-store.myshopify.com.nuxt.config.ts, .env, .env.development.env, config/admin.php, config/livestream.php, config/shopify.php, config/cors.phproutes/console.php, ecosystem.config.cjs/api/* and /admin-api/* to the backend API service. The backend is not deployed as a Laravel Web site.This starts the Nuxt dev server. During development, browser requests to /api/* and /admin-api/* are forwarded to the backend by the Nuxt dev proxy.
Note: the frontend has a global login middleware. Except for /login, unauthenticated visits redirect to the login page. For local acceptance testing, log in first as in production, or configure route allow rules according to the target environment access policy.
To validate synchronization tasks, Webhooks, or asynchronous processing during development, also start:
The backend has no Web/view layer and no frontend asset build step. Local backend development does not require npm install, npm run build, or Vite.
Optional static generation:
Choose one deployment mode:
.output/public, with Nginx using try_files to fall back to index.html..output/server, with Nginx proxying page requests to the Nuxt server.In either mode, production must ensure:
/api/* routes to the backend public content API./admin-api/* routes to the backend Admin API.Backend deployment boundaries:
npm run build, and do not run php artisan view:cache.public./api and /admin-api should be exposed to the frontend same-origin entry as backend API upstreams.The following only shows how the frontend same-origin entry dispatches pages and APIs. It is not a Laravel Web site configuration.
In production, add HTTPS, cache rules, security headers, upload size limits, timeouts, and logs according to the team's gateway standards.
This is a key deployment area. The backend only exposes API and admin-API externally, but live status, music, programs, Shopify, and Twitch Webhooks all depend on internal workers.
Required long-running processes:
The repository provides a PM2 example:
It includes:
php artisan schedule:workphp artisan queue:work --sleep=3 --tries=3 --max-time=3600If the team's standard is Supervisor + Cron, the queue worker can be run as:
And system cron can run:
Do not run multiple scheduler strategies at the same time, or synchronization tasks may be triggered repeatedly.
Main scheduled tasks:
| Task | Frequency | Purpose |
|---|---|---|
SyncYouTubeRssJob | Every 5 minutes | Fetch YouTube RSS and discover new live streams or videos. |
SyncYouTubeStatusJob | Every 15 minutes | Update YouTube live-stream status. |
SyncYouTubeCompletedViewersJob | Hourly | Backfill viewer count and timing for completed live streams. |
SyncTwitchStreamsJob | Every 5 minutes | Query online Twitch streams. |
EnsureTwitchSubscriptionsJob | Hourly | Ensure Twitch EventSub subscriptions. |
CleanExpiredTwitchSchedulesJob | Every 5 minutes | Clean expired Twitch schedules. |
SyncTwitchVodsJob | Every 30 minutes | Match Twitch VODs. |
Recommended production monitoring:
jobs table is accumulating backlog.failed_jobs keeps increasing.The home page is organized by the vertical Swiper in pages/index.vue. It includes Main Banner, News, Schedule, Talents, About, Music, Shop, and other major sections.
Navigation is mainly controlled by components/Navbar/index.vue:
/api/generations/index./auditions and /jointheteam.The backend resource is news. The public site uses:
/api/news/index/api/news/show/api/news/filtersPages include the home module, list page, and detail page. After login, content can be edited in page through AdminNewsCrud and AdminNewsEdit.
Core resources include generations, talents, talent_profiles, talent_models, talent_galleries, and talent_rec_vids. The frontend uses cname as the main public route identifier:
/generation?name={generation.cname}/talent/{talent.cname}The Talent detail page shows profile data, model images, recommended videos, music, and gallery content, and provides in-page Admin editing entry points.
The core model is Schedule. Public APIs include:
/api/schedule/index/api/schedule/now_liveThe backend synchronizes YouTube and Twitch and maintains UPCOMING, LIVE, and COMPLETED states. The frontend uses Unix timestamp fields such as scheduled_start_time.
Music uses music, music_categories, and fetch_music_links. It can be triggered manually with:
Programs reuse the YouTube playlist synchronization logic. Categories come from program_categories, and content comes from programs. The page remains an independent content page and can be exposed according to operational needs.
Product data comes from Shopify synchronization. Main APIs:
/api/shopify/collections/api/shopify/productsIt can be triggered manually with:
/auditions and /jointheteam remain the main flow entry points. FAQ, positions, and team members all support in-page editing after login.
Contact submission is provided by backend /api/customer_message/send. Whether the frontend entry is enabled depends on the operational page configuration. If an independent contact form is enabled, submit category, name, email, message_subject, and message according to the business field requirements.
The frontend includes embedded in-page Admin editing:
/login writes a token into localStorage after login./admin-api/*.AdminWrapper controls edit button visibility based on login state and Edit Mode.BaseCrud handles list resource CRUD.BaseEdit + BaseForm handles single-record editing./admin-api/upload_rich.Frontend:
Backend:
Key regression areas:
cname routing./login, Edit Mode, CRUD, upload, and rich-text images./api/*; production and acceptance environments must configure same-origin routing/proxying./admin-api/*; login, CRUD, and upload all depend on this routing/proxying.YOUTUBE_API_KEY, Shopify API Key, API Secret, and Access Token. SHOPIFY_DOMAIN is fixed as official-phase-connect-store.myshopify.com. YouTube / Twitch / Shopify API quota should be monitored.routes/admin.php. For new management resources, prefer maintaining Admin Controllers / Services and add extension APIs through app/Admin/routes.php when necessary.npm install, npm run build, or php artisan view:cache, and Nginx document root should not be pointed to Laravel public.Before going live, confirm the following:
/api and /admin-api works..env is configured for DB, Queue, Storage, YouTube, Twitch/Webhook, and Shopify.YOUTUBE_API_KEY.SHOPIFY_DOMAIN=official-phase-connect-store.myshopify.com.APP_KEY has been generated and debug is disabled in production.php artisan test and frontend npm run build pass. The backend does not run npm builds.