Phase Connect Project Handoff

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.

1. Project Overview

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:

  • News / Events
  • Talents / Generations
  • Live Schedule, including YouTube and Twitch data synchronization
  • Music / Programs, including YouTube playlist synchronization
  • Shopify product display
  • Work With Us / Audition / Join The Team
  • Embedded in-page Admin editing entry points

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.

2. Overall Architecture

Browser
  |
  |  Static SPA / Nuxt Node server
  v
Phase Frontend
  |-----------------------> /api/*        Public content API
  |-----------------------> /admin-api/*  Login + CRUD + upload API
                           |
                           v
                    Laravel Backend
                           |
       ------------------------------------------------
       |              |              |                |
     MySQL       Queue worker    Scheduler       External APIs
                                  worker         YouTube / Twitch / Shopify

Recommended production topology:

  • Serve the frontend through static hosting or a Nuxt Node server.
  • Route /api/* and /admin-api/* from the same origin to the backend API service.
  • Treat the backend only as an API/admin-API upstream. Do not configure it as a Laravel Web site entry point and do not deploy a view layer.
  • Deploy Laravel queue workers and scheduler workers as separate long-running processes.
  • MySQL is the main business storage. Queue, cache, and session configuration currently also prefer database drivers.

3. Project Structure

Frontendphase-front

PathDescription
nuxt.config.tsNuxt configuration. Uses ssr: false, runtime environment variables, and dev proxy settings.
app.vueRoot component. Initializes global configuration and shows Logout / Edit Mode floating entries after login.
middleware/route-link.global.jsGlobal login middleware. All routes except /login check login state.
api/allApi.jsPublic API $fetch wrapper. In practice, requests same-origin /api/*.
service/request/*Admin API axios wrapper. Automatically attaches the Bearer token.
pages/index.vueHome page vertical Swiper container.
pages/login.vueAdmin login page.
pages/generation.vue, pages/talent/[id].vueMain Talent / Generation pages.
pages/live-schedule.vue, pages/schedule.vueFull schedule page and home schedule module.
pages/music.vue, pages/shop.vue, pages/newslist.vue, pages/posts/[id].vueMain content pages.
pages/auditions.vue, pages/jointheteam.vue, pages/letstalk.vueWork With Us related pages.
components/Admin/*Embedded editing, shared CRUD, forms, upload, and rich-text components.
components/Navbar, components/FooterNavbarPublic navigation and footer.
assets/*Styles, images, videos, and font assets.

Backendphase-back-admin

PathDescription
routes/api.phpPublic /api/* routes.
routes/admin.php/admin-api/* CRUD resource routes based on Owl Admin AdminService.
app/Admin/routes.phpAdmin 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.phpLaravel 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.phpAdmin API prefix and login-related configuration.
config/livestream.phpYouTube / Twitch synchronization configuration.
config/shopify.phpShopify API configuration.
ecosystem.config.cjsPM2 worker example configuration.

4. Key Configuration

Frontend Environment Variables

The frontend only needs the following two variables:

NUXT_DEV_BASE_URL=<backend-public-api-base>
ADMIN_BASE_URL=<backend-admin-api-base>

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 requests are also written mostly as /admin-api/*, so they depend on same-origin routing/proxying or the Nuxt dev proxy.

Backend Environment Variables

The backend .env follows standard Laravel configuration. Focus on the following groups:

GroupRequired itemsNotes
AppAPP_KEY, APP_ENV, APP_DEBUG, APP_URLFor production, use APP_ENV=production and APP_DEBUG=false after confirming logging and troubleshooting procedures.
DatabaseDB_CONNECTION, DB_HOST, DB_DATABASE, DB_USERNAME, DB_PASSWORDA 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 / SessionQUEUE_CONNECTION, CACHE_STORE, SESSION_DRIVERDatabase drivers are currently preferred. Make sure the required tables exist and workers are running.
StorageFILESYSTEM_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.
YouTubeYOUTUBE_API_KEYThe 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 / WebhookTWITCH_CLIENT_ID, TWITCH_CLIENT_SECRET, TWITCH_WEBHOOK_SECRET, TWITCH_WEBHOOK_CALLBACK_URLThe 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.
ShopifySHOPIFY_API_KEY, SHOPIFY_API_SECRET, SHOPIFY_API_ACCESS_TOKEN, SHOPIFY_DOMAINThe 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.
AdminADMIN_LOGIN_CAPTCHALogin captcha can currently be disabled. The Admin API prefix comes from config/admin.php by default.
Fetch cacheFETCH_*Controls cache TTL for third-party synchronization.

Backend .env example:

APP_NAME=Laravel
APP_ENV=production
APP_KEY=base64:<generated-app-key>
APP_DEBUG=false
APP_URL=https://<public-api-origin>

APP_LOCALE=en
APP_FALLBACK_LOCALE=en
APP_FAKER_LOCALE=en_US

LOG_CHANNEL=stack
LOG_STACK=single
LOG_LEVEL=debug

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=<database-name>
DB_USERNAME=<database-user>
DB_PASSWORD=<database-password>

SESSION_DRIVER=database
SESSION_LIFETIME=120
SESSION_ENCRYPT=false
SESSION_PATH=/
SESSION_DOMAIN=null

BROADCAST_CONNECTION=log
FILESYSTEM_DISK=local
QUEUE_CONNECTION=database
CACHE_STORE=database

REDIS_CLIENT=phpredis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_MAILER=log
MAIL_HOST=127.0.0.1
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_FROM_ADDRESS="hello@example.com"
MAIL_FROM_NAME="${APP_NAME}"

AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
AWS_USE_PATH_STYLE_ENDPOINT=false

YOUTUBE_API_KEY=<youtube-api-key>

TWITCH_CLIENT_ID=<twitch-client-id>
TWITCH_CLIENT_SECRET=<twitch-client-secret>
TWITCH_WEBHOOK_SECRET=<twitch-webhook-secret>
TWITCH_WEBHOOK_CALLBACK_URL=https://<public-api-origin>/api/webhooks/twitch

FETCH_MUSIC_LIST_CACHE=true
FETCH_MUSIC_LIST_CACHE_TTL=3600

FETCH_LIVE_STREAM_LIST_CACHE=false
FETCH_LIVE_STREAM_LIST_CACHE_TTL=86400
FETCH_LIVE_STREAM_VIDEO_INFO_CACHE=false
FETCH_LIVE_STREAM_VIDEO_INFO_CACHE_TTL=86400
FETCH_LIVE_STREAM_TWITCH_CACHE_TTL=86400

SHOPIFY_API_KEY=<shopify-api-key>
SHOPIFY_API_SECRET=<shopify-api-secret>
SHOPIFY_API_ACCESS_TOKEN=<shopify-access-token>
SHOPIFY_DOMAIN=official-phase-connect-store.myshopify.com

ADMIN_LOGIN_CAPTCHA=false

Third-party credential ownership:

  • Webhook / Twitch EventSub: the receiving team must register its own Twitch developer account, create an application, configure the callback URL, and maintain its own Client ID, Client Secret, and Webhook Secret.
  • YouTube: the receiving team must use its own Google/YouTube developer account, create an API project, enable YouTube Data API, and maintain its own YOUTUBE_API_KEY.
  • Shopify: the receiving team must register its own Shopify developer account, create an app for the target store, and maintain its own API Key, API Secret, and Access Token. SHOPIFY_DOMAIN is fixed as official-phase-connect-store.myshopify.com.
  • When deploying to the receiving team's environment, switch to the receiving team's own credentials. The receiving team is responsible for permissions, quota, and key rotation going forward.

Important Configuration Files

  • Frontend: nuxt.config.ts, .env, .env.development
  • Backend: .env, config/admin.php, config/livestream.php, config/shopify.php, config/cors.php
  • Worker: routes/console.php, ecosystem.config.cjs
  • API entry: the gateway only needs to route /api/* and /admin-api/* to the backend API service. The backend is not deployed as a Laravel Web site.

5. Local Development

Frontend

cd phase-front
npm install
npm run dev

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.

Backend

cd phase-back-admin
composer install
cp .env.example .env
php artisan key:generate
php artisan migrate
php artisan serve --host=0.0.0.0 --port=8000

To validate synchronization tasks, Webhooks, or asynchronous processing during development, also start:

php artisan queue:work --sleep=3 --tries=3
php artisan schedule:work

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.

6. Build and Deployment

Frontend Build

cd phase-front
npm run build

Optional static generation:

npm run generate

Choose one deployment mode:

  • Static deployment of .output/public, with Nginx using try_files to fall back to index.html.
  • Node deployment of Nuxt .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.
  • SPA history fallback works.

Backend Build

cd phase-back-admin
composer install --no-dev --optimize-autoloader
php artisan migrate --force
php artisan config:cache
php artisan route:cache

Backend deployment boundaries:

  • The backend only provides API and admin-API. Do not deploy a Laravel Web/view layer.
  • Do not run backend npm run build, and do not run php artisan view:cache.
  • Do not point Nginx document root to Laravel public.
  • /api and /admin-api should be exposed to the frontend same-origin entry as backend API upstreams.

Frontend Gateway Routing Example

The following only shows how the frontend same-origin entry dispatches pages and APIs. It is not a Laravel Web site configuration.

location / {
    try_files $uri $uri/ /index.html;
}

location /api/ {
    proxy_pass http://phase-back-api-upstream/api/;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

location /admin-api/ {
    proxy_pass http://phase-back-api-upstream/admin-api/;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

In production, add HTTPS, cache rules, security headers, upload size limits, timeouts, and logs according to the team's gateway standards.

7. Workers and Scheduled Tasks

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:

  • Queue worker: executes queue jobs and asynchronous Webhook handling.
  • Scheduler worker or system cron: triggers the Laravel scheduler.

The repository provides a PM2 example:

pm2 start ecosystem.config.cjs
pm2 save

It includes:

  • php artisan schedule:work
  • php artisan queue:work --sleep=3 --tries=3 --max-time=3600

If the team's standard is Supervisor + Cron, the queue worker can be run as:

php artisan queue:work --sleep=3 --tries=3 --max-time=3600

And system cron can run:

* * * * * cd <backend-release-dir> && php artisan schedule:run >> /dev/null 2>&1

Do not run multiple scheduler strategies at the same time, or synchronization tasks may be triggered repeatedly.

Main scheduled tasks:

TaskFrequencyPurpose
SyncYouTubeRssJobEvery 5 minutesFetch YouTube RSS and discover new live streams or videos.
SyncYouTubeStatusJobEvery 15 minutesUpdate YouTube live-stream status.
SyncYouTubeCompletedViewersJobHourlyBackfill viewer count and timing for completed live streams.
SyncTwitchStreamsJobEvery 5 minutesQuery online Twitch streams.
EnsureTwitchSubscriptionsJobHourlyEnsure Twitch EventSub subscriptions.
CleanExpiredTwitchSchedulesJobEvery 5 minutesClean expired Twitch schedules.
SyncTwitchVodsJobEvery 30 minutesMatch Twitch VODs.

Recommended production monitoring:

  • Whether the jobs table is accumulating backlog.
  • Whether failed_jobs keeps increasing.
  • Whether scheduler logs are produced regularly.
  • YouTube / Twitch / Shopify API quota or authentication failures.

8. Core Business Modules

Home and Navigation

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:

  • News / Schedule / Talents / Music / Shop jump to the corresponding home slide.
  • The Talents dropdown is loaded from /api/generations/index.
  • Work With Us links to /auditions and /jointheteam.
  • The Programs page is kept as an independent content page and can be accessed through business entry points or direct routing.

News / Events

The backend resource is news. The public site uses:

  • /api/news/index
  • /api/news/show
  • /api/news/filters

Pages include the home module, list page, and detail page. After login, content can be edited in page through AdminNewsCrud and AdminNewsEdit.

Talents / Generations

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.

Live Schedule

The core model is Schedule. Public APIs include:

  • /api/schedule/index
  • /api/schedule/now_live

The backend synchronizes YouTube and Twitch and maintains UPCOMING, LIVE, and COMPLETED states. The frontend uses Unix timestamp fields such as scheduled_start_time.

Music / Programs

Music uses music, music_categories, and fetch_music_links. It can be triggered manually with:

php artisan fetch:music

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.

Shopify

Product data comes from Shopify synchronization. Main APIs:

  • /api/shopify/collections
  • /api/shopify/products

It can be triggered manually with:

php artisan fetch:shopify

Work With Us / Contact

/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.

In-Page Admin

The frontend includes embedded in-page Admin editing:

  • /login writes a token into localStorage after login.
  • Admin requests go through /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.
  • Uploads go through /admin-api/upload_rich.

9. Testing and Acceptance

Frontend:

cd phase-front
npm test
npm run build

Backend:

cd phase-back-admin
php artisan test

Key regression areas:

  • Home slide switching and navigation jumps.
  • News list, detail, and editing.
  • Generation / Talent pages and cname routing.
  • Live Schedule YouTube / Twitch cards, status, and time display.
  • Music and Shopify product display.
  • /login, Edit Mode, CRUD, upload, and rich-text images.
  • Queue worker and scheduler execution.

10. Handoff Notes

  1. Before development, confirm the frontend branch according to the branch notice at the top of this document.
  2. Public API requests are fixed to same-origin /api/*; production and acceptance environments must configure same-origin routing/proxying.
  3. Admin API requests are fixed to same-origin /admin-api/*; login, CRUD, and upload all depend on this routing/proxying.
  4. If local acceptance testing redirects to login, first confirm whether it matches the current login protection policy. Do not troubleshoot it as a fully anonymous public site by default.
  5. Database initialization should use the full SQL export provided during handoff. Migrations can be used as a reference for later schema changes, but they are not the only initialization source.
  6. Webhook / Twitch EventSub requires the receiving team to create its own developer application, configure a public HTTPS callback, and generate its own Client ID, Client Secret, and Webhook Secret.
  7. YouTube and Shopify also require the receiving team to use its own platform accounts to create an API project or app, then configure its own 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.
  8. The backend must deploy queue workers and the scheduler. Deploying only the API/admin-API entry points will prevent live, music, program, and product synchronization tasks from running.
  9. Avoid directly editing routes/admin.php. For new management resources, prefer maintaining Admin Controllers / Services and add extension APIs through app/Admin/routes.php when necessary.
  10. The backend has no Laravel Web/view layer and does not depend on the Owl Admin view layer. Do not deploy it as a traditional Laravel Blade site or a traditional Owl Admin backend page application.
  11. The backend does not require npm install, npm run build, or php artisan view:cache, and Nginx document root should not be pointed to Laravel public.

11. Deployment Checklist

Before going live, confirm the following:

  • Frontend branch, build command, and output location are clear.
  • Same-origin routing/proxying for /api and /admin-api works.
  • Laravel .env is configured for DB, Queue, Storage, YouTube, Twitch/Webhook, and Shopify.
  • The receiving team has created its own Twitch/Webhook application and configured Client ID, Client Secret, Webhook Secret, and callback URL.
  • The receiving team has created its own Google/YouTube API project, enabled YouTube Data API, and configured YOUTUBE_API_KEY.
  • The receiving team has created its own Shopify developer account and app, and configured API Key, API Secret, and Access Token. SHOPIFY_DOMAIN=official-phase-connect-store.myshopify.com.
  • APP_KEY has been generated and debug is disabled in production.
  • The upload and image access strategy is configured for the target environment. If object storage or CDN is used, follow the target environment configuration.
  • The full database SQL export has been received and the target environment has been initialized or restored from it.
  • Queue worker is running continuously.
  • Only one scheduler trigger strategy is deployed to avoid repeated execution.
  • Twitch Webhook callback is publicly reachable and passes signature verification.
  • Backend php artisan test and frontend npm run build pass. The backend does not run npm builds.
  • Login, Edit Mode, common CRUD, and upload flows have passed manual acceptance testing.