# 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. 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 ```