# Development Guide Setup, workflow, building assets, and testing for XAMXAM development. --- ## Requirements - **PHP** ≥ 8.4 with `ext-json`, `ext-openssl`, `ext-pdo` (and `ext-sqlite3` for the local DB) - **Composer** for PHP dependencies - **Node.js / npm** for frontend asset builds (rolldown, lightningcss, biome) - **SQLite3** CLI (for `just query`, `just init-db`) ## One-time setup From the repo root, install dependencies (manually — there is no `just` recipe for these): ```bash composer install # PHP deps (vendor/) npm ci # JS build deps (node_modules/) just migrate # create/update the SQLite DB from schema + migrations ``` `just setup` exists but its backing script (`scripts/setup-dev.sh`) is **stale** — it still clones the old `php-live-reload` library and creates legacy `admin/data/` directories. Live-reload now ships inside the app (`app/public/live-reload.php`), and assets are built with rolldown/lightningcss, not the live-reload watcher. Prefer the explicit `composer install` + `npm ci` above. ## Project Structure ``` xamxam/ ├── app/ # All application code (the project root on the server) │ ├── bootstrap.php # App bootstrapping (constants, autoload, config) │ ├── router.php # Router for the PHP built-in dev server │ ├── public/ # DocumentRoot (web-accessible only) │ │ ├── index.php # Front controller / entry point │ │ ├── request-access.php │ │ ├── live-reload.php │ │ ├── admin/ # Admin panel │ │ ├── partage/ # Student submission via share links │ │ └── assets/ # Built CSS/JS, fonts, images (dist/ is generated) │ ├── src/ # PHP classes │ │ ├── Controllers/ # Request controllers (Home, Search, Tfe, Export, …) │ │ ├── Form/ # Form helper │ │ ├── Database.php # DB access + queries │ │ ├── AdminAuth.php # Session auth for admin │ │ ├── RateLimit.php │ │ ├── FilepondHandler.php │ │ ├── PeerTubeService.php │ │ └── … # (see list in src/) │ ├── templates/ # Template partials (public, admin, partials, partage) │ ├── storage/ # Database + uploads (private) │ │ ├── xamxam.db # SQLite database │ │ ├── schema.sql # Base schema │ │ ├── theses/ tfe/ # Uploaded files │ │ └── cache/ logs/ # Runtime data │ └── migrations/ # Migration runner + applied migrations ├── scripts/ # Build / deploy / utility scripts ├── tests/phpunit/ # PHPUnit tests ├── nginx/ # Server configuration + docs ├── deploy/ # Cron configs (backup, cleanup) ├── justfile # Task runner ├── composer.json / package.json └── TODO.md ``` ## Development Workflow ### Start the dev server ```bash just dev ``` This runs a one-shot asset build, applies pending migrations, opens `http://127.0.0.1:8000/` (public) and `/admin/` (admin), then starts the PHP built-in server (`php -S 127.0.0.1:8000`) with a `chokidar` watcher that rebuilds CSS/JS on change. - **Public site:** `http://127.0.0.1:8000/` - **Admin panel:** `http://127.0.0.1:8000/admin/` Stop it with `just stop`. If you only need the server without browsers/ui, run `just dev-build` first, then start the PHP built-in server manually with the `php -d … -S` command shown in the `dev` recipe (or add a `just serve` alias locally). ### Frontend assets Source CSS lives in `app/public/assets/css/`, source JS in `app/public/assets/js/app/`. They are **bundled and minified** into `app/public/assets/dist/` by `scripts/build*.mjs` (rolldown + lightningcss). ```bash just dev-build # one-shot build (quicker output than full) just build # full build just build-css # CSS only just build-js # JS only just build-check # verify build output is up to date ``` There is no live-reloading in production — `app/public/live-reload.php` only activates under the PHP built-in server. ## Testing PHPUnit is used. Configuration lives in `phpunit.xml`, tests in `tests/phpunit/` (with `tests/bootstrap.php` and `tests/TestDatabase.php` helpers). ```bash just test # run all PHPUnit tests just test-coverage # run with HTML coverage into coverage/ ``` ### Linting / formatting ```bash just lint-php # phpstan (static analysis) + php-cs-fixer (coding standards) just lint-css # biome lint on app/public/assets/css/ just lint-js # biome lint on app/public/assets/js/app/ + scripts/ just lint # all linters just fix # auto-fix (biome + php-cs-fixer) ``` ## Database Operations ```bash just migrate # run pending migrations just init-db # create/reset DB from app/storage/schema.sql just reset-db # rm DB + init-db just query # open an interactive SQLite shell just backup # SQL dump into app/storage/backup_.sql just backup-snapshot # WAL-safe hot backup + gzip into storage/backups/ just cleanup-drafts [--no-dry-run] # remove orphaned drafts > 24h ``` See [database.md](database.md) for the full schema reference. ## Deployment See [deployment.md](deployment.md). Files are pushed to the server with `just deploy` (rsync → `xamxam:/var/www/xamxam/`). There is no git repo on the remote. ## Troubleshooting ```bash just logs # tail the dev error log (error.log) just stop # kill the dev server / asset watcher ``` If the browser doesn't hot-reload, confirm the asset watcher is still running and the rebuild succeeded (`just dev-build`).