api/README.md
Rama main · réplica de lectura del repositorio original.
# Server API Scripts (Optional Feature)
This directory contains optional server-side PHP scripts that enable shared tournament hosting.
## Features
When deployed to a PHP-enabled web server, these scripts enable:
1. **Shared Tournament Viewing**: Browse and load tournaments uploaded to the server
2. **Tournament Upload**: Share completed tournaments by uploading them to the server
3. **Graceful Degradation**: Features appear only when server is configured; local-only usage remains fully functional
## Requirements
- PHP 7.0 or higher (PHP 8.2+ recommended)
- Write permissions to `/tournaments` directory
- Web server (Apache, Nginx, etc.)
## Quick Start with Docker (Recommended)
The easiest way to get the API running is with the official Docker image:
```bash
docker run -d \
--name newton-tournament \
-p 2020:2020 \
-v ./tournaments:/var/www/html/tournaments \
ghcr.io/skrodahl/newton:latest
```
**Benefits:**
- ✅ All API endpoints pre-configured and working
- ✅ nginx + PHP 8.2-FPM included
- ✅ No manual setup required
- ✅ Persistent tournament storage via volume mount
**Test endpoints:**
- List: `http://localhost:2020/api/list-tournaments.php`
- Upload: POST to `http://localhost:2020/api/upload-tournament.php`
See [DOCKER-QUICKSTART.md](../DOCKER-QUICKSTART.md) for complete Docker deployment guide.
## Manual Setup (Traditional Deployment)
If you prefer to deploy without Docker:
1. **Create tournaments directory:**
```bash
mkdir -p ../tournaments
chmod 755 ../tournaments
```
2. **Deploy to web server:**
- Upload entire application to web-accessible directory
- Ensure `/api` and `/tournaments` directories are accessible
- Verify PHP is enabled for `.php` files
3. **Test endpoints:**
- List: `https://yourdomain.com/api/list-tournaments.php`
- Upload: POST to `https://yourdomain.com/api/upload-tournament.php`
## Endpoints
### GET /api/list-tournaments.php
Returns list of available tournaments.
**Response:**
```json
{
"tournaments": [
{
"filename": "MyTournament_2025-10-01.json",
"name": "My Tournament",
"date": "2025-10-01",
"players": 16,
"status": "completed"
}
],
"count": 1
}
```
### POST /api/upload-tournament.php
Uploads a tournament to the server.
**Request:**
```json
{
"filename": "MyTournament_2025-10-01.json",
"data": { /* tournament data object */ }
}
```
**Response:**
```json
{
"success": true,
"filename": "MyTournament_2025-10-01.json",
"path": "/tournaments/MyTournament_2025-10-01.json",
"message": "Tournament uploaded successfully"
}
```
### GET / POST /api/corrections.php
Achievement corrections for Analytics: per tournament, per player, the difference from what was recorded. Analytics applies them when it loads; the register in each browser is never modified. Stored in `tournaments/corrections/corrections.json`.
**GET** returns every correction:
```json
{
"corrections": [
{
"tournamentId": "1790000000001",
"playerId": "2",
"playerName": "Bob",
"oneEighties": 1,
"tons": -2,
"lollipops": 0,
"highOuts": { "add": [140], "remove": [121] },
"shortLegs": { "add": [], "remove": [] },
"updatedAt": 1790540598
}
]
}
```
**POST** replaces all corrections for one tournament. An empty list removes them.
```json
{ "tournamentId": "1790000000001", "corrections": [ /* records as above */ ] }
```
Writes are made under a file lock, so simultaneous saves can't overwrite each other.
## Security
- **Filename validation**: Only alphanumeric, spaces, hyphens, underscores, and `.json` extension allowed
- **Directory traversal prevention**: `basename()` ensures files stay in tournaments directory
- **Upload limits**: Payloads over 10 MB are rejected (413); the data must minimally look like a tournament export (`id`, `name`, `players`)
- **Relay allowlist (optional)**: Set `NEWTON_RELAY_ALLOWLIST` (comma-separated hostnames) to restrict which remote hosts `relay.php` will forward to; unset allows any host
- **API kill switch**: `NEWTON_API_ENABLED` accepts `false`, `0`, `off`, `no` (any case) to disable all endpoints
- **CORS headers**: Configured for cross-origin requests (adjust as needed)
- **File permissions**: Tournaments directory requires write access (755 recommended)
- **API key for writes** (`NEWTON_API_KEY`): when set, upload, delete, corrections (POST) and relay need the `X-API-Key` header (`require_api_key()` in `api-check.php`); reading never does. Unset: no authentication — protect exposed instances at the deployment layer (reverse proxy with basic auth, VPN, or LAN-only) — see DOCKER-QUICKSTART.md § Security
## Local Development
These scripts are **not required** for local development. The application works fully offline using browser localStorage. This is a bonus feature for organizations wanting to share tournament data across users.
## Troubleshooting
**Upload button doesn't appear:**
- Server endpoint `/api/list-tournaments.php` must return valid JSON response
- Check browser console for network errors
**Upload fails:**
- Verify `/tournaments` directory exists and is writable
- Check PHP error logs for permission issues
- Ensure PHP has file write permissions
**CORS errors:**
- Adjust `Access-Control-Allow-Origin` header in PHP files
- For production, restrict to specific domains