Ctrl K
ComunidadGuías…

api/README.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# 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