mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-09-25 01:53:03 +02:00
docs: verify and refactor documentation to match current codebase
This commit is contained in:
+113
-227
@@ -1,272 +1,158 @@
|
||||
# Development Guide
|
||||
|
||||
Setup, workflow, testing, and live reload for Post-ERG development.
|
||||
Setup, workflow, building assets, and testing for XAMXAM development.
|
||||
|
||||
---
|
||||
|
||||
## Quick Start
|
||||
## 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
|
||||
just setup # One time: clone php-live-reload + setup directories
|
||||
just serve # Start dev server at http://localhost:8000
|
||||
composer install # PHP deps (vendor/)
|
||||
npm ci # JS build deps (node_modules/)
|
||||
just migrate # create/update the SQLite DB from schema + migrations
|
||||
```
|
||||
|
||||
One unified server serves both:
|
||||
- **Public site:** http://localhost:8000
|
||||
- **Admin panel:** http://localhost:8000/admin/
|
||||
|
||||
Live reload is enabled automatically — browser refreshes when you save files.
|
||||
|
||||
---
|
||||
`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
|
||||
|
||||
```
|
||||
posterg-website/
|
||||
├── public/ # DocumentRoot (web-accessible)
|
||||
│ ├── index.php # Homepage
|
||||
│ ├── search.php # Search/répertoire
|
||||
│ ├── memoire.php # Thesis detail
|
||||
│ ├── admin/ # Admin panel
|
||||
│ └── assets/ # CSS, fonts, images
|
||||
├── includes/ # Template partials (header, footer)
|
||||
├── config/ # Configuration (bootstrap.php)
|
||||
├── src/ # PHP classes (Database, AdminAuth, RateLimit)
|
||||
├── storage/ # Database + uploads (private)
|
||||
├── database/ # Schema + migrations
|
||||
├── tests/ # Test suite
|
||||
├── nginx/ # Server configuration
|
||||
├── scripts/ # Deployment/admin scripts
|
||||
└── vendor/ # Third-party (gitignored, dev only)
|
||||
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
|
||||
|
||||
### Starting Development
|
||||
### Start the dev server
|
||||
|
||||
```bash
|
||||
just serve
|
||||
just dev
|
||||
```
|
||||
|
||||
### Making Changes
|
||||
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.
|
||||
|
||||
1. Edit PHP/CSS files — browser auto-refreshes
|
||||
2. Run tests: `just test`
|
||||
3. Check syntax: `just syntax`
|
||||
4. Deploy: `just deploy`
|
||||
- **Public site:** `http://127.0.0.1:8000/`
|
||||
- **Admin panel:** `http://127.0.0.1:8000/admin/`
|
||||
|
||||
### Database Operations
|
||||
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 stats # View database stats
|
||||
just query # Open SQLite shell
|
||||
just show 42 # Show thesis by ID
|
||||
just reset-db # Reset database
|
||||
just fixtures # Create sample data
|
||||
just backup # Backup database
|
||||
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
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Live Reload
|
||||
|
||||
### What It Does
|
||||
|
||||
Automatically refreshes your browser when you save PHP/CSS/JS files. No browser extension needed.
|
||||
|
||||
### Setup (One Time)
|
||||
|
||||
```bash
|
||||
just setup
|
||||
```
|
||||
|
||||
Clones `php-live-reload` into `vendor/` (gitignored).
|
||||
|
||||
### How It Works
|
||||
|
||||
- Conditionally included in `header.php` when `php_sapi_name() === 'cli-server'`
|
||||
- JavaScript polls server for file changes → browser refreshes
|
||||
- **Never active in production** (different SAPI, vendor/ not deployed)
|
||||
|
||||
### Detection
|
||||
|
||||
```php
|
||||
<?php if (php_sapi_name() === 'cli-server'): ?>
|
||||
<script src="/vendor/php-live-reload/php-live-reload/live-reload.js"></script>
|
||||
<?php endif; ?>
|
||||
```
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
```bash
|
||||
ls -la vendor/php-live-reload/ # Check installed
|
||||
just setup # Reinstall if missing
|
||||
curl -s http://localhost:8000/ | grep live-reload # Verify script included
|
||||
```
|
||||
|
||||
---
|
||||
There is no live-reloading in production — `app/public/live-reload.php` only
|
||||
activates under the PHP built-in server.
|
||||
|
||||
## Testing
|
||||
|
||||
### Test Structure
|
||||
|
||||
```
|
||||
tests/
|
||||
├── run-tests.php # Main test runner
|
||||
├── Unit/ # Unit tests
|
||||
│ ├── DatabaseTest.php
|
||||
│ └── RateLimitTest.php
|
||||
├── Integration/ # Integration tests
|
||||
│ └── SearchTest.php
|
||||
└── Security/ # Security tests
|
||||
└── SecurityTest.php
|
||||
```
|
||||
|
||||
### Running Tests
|
||||
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 tests
|
||||
just test-unit # Unit tests only
|
||||
just test-integration # Integration tests only
|
||||
just test-security # Security tests only
|
||||
just syntax # Check PHP syntax
|
||||
just test # run all PHPUnit tests
|
||||
just test-coverage # run with HTML coverage into coverage/
|
||||
```
|
||||
|
||||
### Writing Tests
|
||||
|
||||
1. Choose type: Unit / Integration / Security
|
||||
2. Create test file in appropriate `tests/` subdirectory
|
||||
3. Follow template:
|
||||
|
||||
```php
|
||||
<?php
|
||||
require_once __DIR__ . '/../../src/Database.php';
|
||||
|
||||
echo "Test Name\n";
|
||||
echo "=========\n\n";
|
||||
|
||||
try {
|
||||
$db = Database::getInstance();
|
||||
echo "✓ PASS: Test description\n";
|
||||
return true;
|
||||
} catch (Exception $e) {
|
||||
echo "❌ FAIL: " . $e->getMessage() . "\n";
|
||||
return false;
|
||||
}
|
||||
```
|
||||
|
||||
4. Add to `tests/run-tests.php` `$testFiles` array
|
||||
5. Run: `just test`
|
||||
|
||||
---
|
||||
|
||||
## Common Tasks
|
||||
|
||||
### Create a New Page
|
||||
|
||||
```php
|
||||
<?php
|
||||
require_once __DIR__ . '/../config/bootstrap.php';
|
||||
require_once APP_ROOT . '/src/Database.php';
|
||||
$db = App::boot();
|
||||
include APP_ROOT . '/includes/header.php';
|
||||
?>
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<h1 class="title">New Page</h1>
|
||||
</div>
|
||||
</section>
|
||||
<?php include APP_ROOT . '/includes/footer.php'; ?>
|
||||
```
|
||||
|
||||
### Add a Database Method
|
||||
|
||||
1. Edit `src/Database.php`
|
||||
2. Add method to the class
|
||||
3. Write test in `tests/Unit/`
|
||||
4. Run: `just test-unit`
|
||||
|
||||
### Update CSS
|
||||
|
||||
1. Edit `public/assets/posterg.css`
|
||||
2. Browser auto-refreshes
|
||||
3. Increment cache-bust in header: `posterg.css?v=N`
|
||||
|
||||
---
|
||||
|
||||
## Justfile Commands
|
||||
|
||||
### Development
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `just setup` | Setup dev environment (one-time) |
|
||||
| `just serve` | Start dev server with live reload |
|
||||
| `just stop` | Stop dev server |
|
||||
| `just logs` | View dev logs |
|
||||
|
||||
### Testing
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `just test` | Run all tests |
|
||||
| `just test-unit` | Unit tests only |
|
||||
| `just test-integration` | Integration tests only |
|
||||
| `just test-security` | Security tests only |
|
||||
| `just syntax` | Check PHP syntax |
|
||||
|
||||
### Database
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `just stats` | Database statistics |
|
||||
| `just query` | Open SQLite shell |
|
||||
| `just show <id>` | Show thesis by ID |
|
||||
| `just reset-db` | Reset test database |
|
||||
| `just fixtures` | Create sample data |
|
||||
| `just backup` | Backup database |
|
||||
|
||||
### Deployment
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `just deploy` | Deploy complete site |
|
||||
| `just deploy-nginx` | Deploy nginx config |
|
||||
| `just deploy-db` | Deploy database |
|
||||
| `just server-status` | Check server health |
|
||||
| `just server-logs` | View server logs |
|
||||
|
||||
---
|
||||
|
||||
## Debugging
|
||||
### Linting / formatting
|
||||
|
||||
```bash
|
||||
just logs # View error logs
|
||||
tail -f error.log # Direct log monitoring
|
||||
|
||||
# PHP errors in browser (temporary):
|
||||
# Add to PHP file:
|
||||
ini_set('display_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
# Database issues:
|
||||
just stats # Check DB exists and has data
|
||||
just query # Open SQLite shell
|
||||
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)
|
||||
```
|
||||
|
||||
### Server Won't Start
|
||||
## Database Operations
|
||||
|
||||
```bash
|
||||
just stop # Kill existing process
|
||||
just setup # Reinstall php-live-reload
|
||||
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 > 24h
|
||||
```
|
||||
|
||||
### Database Errors
|
||||
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 reset-db # Reset from schema
|
||||
just fixtures # Repopulate with sample data
|
||||
just test # Verify everything works
|
||||
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`).
|
||||
|
||||
Reference in New Issue
Block a user