# NextChair NextChair is a multi-tenant, white-label booking platform for barbershops. The application is being rebuilt as a conventional Laravel web application using PHP, MySQL, Blade, Tailwind CSS, Alpine.js, and Vite. The audited Next.js implementation is preserved in [`legacy-nextjs`](legacy-nextjs) as the functional and visual migration reference. The Laravel application has its own deployment-neutral Docker option at the repository root; files inside `legacy-nextjs` are not used by it. ## Local development ```bash composer install cp .env.example .env php artisan key:generate npm install npm run build php artisan serve ``` Configure the MySQL connection in `.env` before running migrations. The application resolves a business only from the request hostname through the `business_domains` table; it never guesses a tenant from the first business in the database. For local multi-tenant work, map each configured hostname to 127.0.0.1 in `/etc/hosts`. ## Platform and tenant setup Migrations create schema only. They do not create a demo business or a business owner. After migrating, open `/install` once and create the platform administrator. That account can sign in at `/manager/sign-in`, create businesses, edit their primary domains, and share the one-time owner setup link generated during provisioning. For an existing installation created before this platform/tenant split, the recorded `initialAdminUserId` account is allowed to sign in once and is promoted to the platform administrator. No other business owner can use that upgrade path. Business provisioning creates the tenant domain, settings, booking rules, opening hours, system roles, owner staff profile, and seven-day owner invitation in one transaction. The owner chooses a password through that invitation; platform administrators and business owners are separate account types. If demo data is useful for local development, opt into the existing seeder explicitly: ```bash NEXTCHAIR_SEED_DEMO=true php artisan db:seed ``` ## Docker deployment The root `compose.yaml` runs Laravel with PHP 8.4 FPM, Nginx, MySQL 8, the database-backed queue worker, and the scheduler. It does not include or configure Caddy; an existing reverse proxy can forward traffic to Nginx on `127.0.0.1:8085`. First run: ```bash cp .env.example .env ``` Set private values in `.env`, including: ```dotenv APP_URL=http://localhost:8085 APP_KEY= DB_HOST=db DB_DATABASE=nextchair DB_USERNAME=nextchair DB_PASSWORD=replace-with-a-private-password DB_ROOT_PASSWORD=replace-with-a-private-root-password ``` Then build and start the stack: ```bash docker compose build docker compose up -d docker compose exec app php artisan key:generate docker compose exec app php artisan migrate ``` Then visit `http://localhost:8085/install` to create the first platform administrator. Do not run migrations or create tenants from container startup; the tenant owner is provisioned manually from Manager. Migrations are intentionally not run by container startup. To inspect the application logs: ```bash docker compose logs -f app nginx queue scheduler db ``` The default host binding is `127.0.0.1:8085:80`. Override it with `NEXTCHAIR_HTTP_BIND` and `NEXTCHAIR_HTTP_PORT` in `.env` when needed. MySQL has no published host port and is reachable only as `db:3306` inside Compose. ## Verification ```bash php artisan test npm run build ```