mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-09-25 09:53:08 +02:00
191 lines
7.0 KiB
Markdown
191 lines
7.0 KiB
Markdown
# 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.
|
|
|
|
### APP_KEY and the app/.env file
|
|
|
|
The app derives DB/storage paths from the filesystem layout, so the public site
|
|
and admin panel run without any env file. But `Crypto` (decrypting the SMTP
|
|
password, PeerTube credentials, and Nextcloud WebDAV sync) requires an
|
|
`app/.env` containing an `APP_KEY`:
|
|
|
|
```
|
|
APP_KEY=<base64-encoded 32 random bytes>
|
|
```
|
|
|
|
Generate one with:
|
|
|
|
```bash
|
|
php -r 'echo "APP_KEY=" . base64_encode(random_bytes(32)) . PHP_EOL;' > app/.env
|
|
chmod 600 app/.env
|
|
```
|
|
|
|
`app/.env` must **never** be committed. If the file is missing, the public site
|
|
still runs but any path that reads encrypted credentials throws
|
|
`RuntimeException: APP_KEY not found`. On a fresh clone, create it before
|
|
relying on SMTP/PeerTube/Nextcloud features.
|
|
|
|
### First admin login
|
|
|
|
A brand-new DB seeds `site_settings.admin_password_hash` as an **empty string**,
|
|
which makes `AdminAuth::requireLogin()` a pass-through — i.e. `/admin/` starts
|
|
**unauthenticated** until a password is set. To secure it, open
|
|
`http://127.0.0.1:8000/admin/account` (or the production admin) and set the
|
|
admin password, which stores the bcrypt hash in `site_settings`.
|
|
|
|
## 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_<timestamp>.sql
|
|
just backup-snapshot # WAL-safe hot backup + gzip into storage/backups/
|
|
just cleanup-drafts [--no-dry-run] # remove orphaned drafts > 7 days (default)
|
|
# OLDER_THAN_HOURS=24 to change the threshold
|
|
```
|
|
|
|
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`).
|