# Staff dashboard: deploy on cPanel

The dashboard lives at `https://shopnobookshouse.com/admin` (hidden, noindex). It talks to this PHP API with an HttpOnly session cookie and a CSRF token. No cloud services.

## Upgrade an existing install (keeps all books, orders and URLs)
1. Back up the database (cPanel → phpMyAdmin → Export).
2. Upload the new `php-api` files over the old ones (keep your `config.php`).
3. Add to `config.php` (see `config.sample.php`): `COOKIE_SAMESITE` and a long random `INSTALL_KEY`.
4. Open `https://api.shopnobookshouse.com/api/install.php?key=YOUR_INSTALL_KEY`.
   It runs `migrations/002_admin.php` (safe to run again) and, if there is no owner yet, asks you to create one.
5. Delete `install.php` from the server.
6. Sign in at `/admin/login`. Open **System check** and run "Test writing files".
7. Cron (every 5 minutes) already calling `/seo/ping/run` now also publishes scheduled books and posts.

## Update 4 upgrade
1. Back up the database, then upload the new `php-api` files (keep `config.php`).
2. Add to `config.php`: `APP_KEY` (long random, never change it) and `BACKUP_DIR` (outside `public_html` if you can). See `config.sample.php`.
3. Open `install.php?key=YOUR_INSTALL_KEY` once. It runs `migrations/003_update4.php` (safe to run again): short summaries move into the description, blank specs become empty, and tables for costs, finance, analytics, customers, emails, announcements, backups and maintenance are added. Existing books, orders and web addresses are kept. Delete `install.php` afterwards.
4. cPanel → Cron Jobs, add:
   - every minute: `php /home/USER/public_html/api/cron.php minute` (sends queued emails)
   - daily 03:15: `php /home/USER/public_html/api/cron.php daily` (keeps the last 50 activity entries, rolls up analytics, adds recurring expenses, removes old backups)
   - daily 03:30: `php /home/USER/public_html/api/cron.php backup` (weekly automatic backup)
5. Dashboard → Email: enter SMTP details and send a test email. Dashboard → Integrations: paste verification tags and pixel IDs.

## Fresh install
Create the MySQL database and user in cPanel, fill in `config.php`, then do steps 4 to 6.

## What changed for the shop
- Stock is taken when staff **confirm** an order (not at checkout) and returned on cancel or return. Older orders are marked as already counted.
- Deleted items go to Trash and disappear from the shop at once; restore brings them back with the same address.
- Public API replies carry an ETag tied to a cache version that every dashboard save bumps, so edits show on the next page view.
- Custom-print quote requests also appear under **Print requests**.
- Homepage section on/off and the header menu come from the dashboard.

## Verified
`tests/admin_smoke.py` (79 checks: sign-in, CSRF, roles, Bangla slugs, auto 301 on slug change, stale-save conflict, stock on confirm/cancel, delivered = fully paid, revenue from delivered orders only, CSV import + rollback, WebP upload, media-in-use guard, trash/restore, settings rules, quotes → order, demo delete) passed against PHP 8.4 + MariaDB 11.4. Not yet run on your cPanel host or on MySQL 5.7.
