# Packing Slip Extractor API

Minimal single-file PHP API that scans a string and returns every standalone
digit-run of **4–8 digits**, formatted as `XXXXX/DDT<YY>` where `<YY>` is the
last two digits of the current year (e.g. `26` in 2026).

## Files

| File           | Purpose                                                          |
| -------------- | ---------------------------------------------------------------- |
| `api.php`      | The API endpoint.                                                |
| `.env`         | Real secrets. **Do not commit.** Loaded automatically.           |
| `.env.example` | Template for the `.env` file. Safe to commit.                    |
| `.htaccess`    | Apache rule that blocks public access to `.env` / dotfiles.      |
| `.gitignore`   | Keeps `.env` and editor/OS cruft out of git.                     |

## Setup

1. Copy `.env.example` to `.env`.
2. Set a strong password in `.env`:

   ```env
   API_PASSWORD="your-strong-secret-here"
   ```

3. Upload **everything except `.env.example`** to your PHP host (PHP 7.4+).
   The API is reachable at the URL of `api.php`,
   e.g. `https://yourdomain.tld/api.php`.

> The loader respects real environment variables first. If your host lets you
> set `API_PASSWORD` via the control panel / php-fpm pool / `SetEnv`, that
> takes precedence over `.env` — you can then skip the `.env` file entirely.

### Nginx note

`.htaccess` is Apache-only. On Nginx, add this to your server block to deny
direct access to `.env`:

```nginx
location ~ /\.env { deny all; return 404; }
location ~ /\.    { deny all; return 404; }  # all dotfiles
```

## Use

`POST` JSON or form-encoded data:

```bash
curl -X POST https://yourdomain.tld/api.php \
  -H "Content-Type: application/json" \
  -d '{
        "password": "your-strong-secret-here",
        "text": "Order 12345 / ref 9876543, item 12, code AB-0001234X end 99999999"
      }'
```

### Response

```json
{
  "ok": true,
  "count": 4,
  "results": [
    "12345/DDT26",
    "9876543/DDT26",
    "0001234/DDT26",
    "99999999/DDT26"
  ]
}
```

### Matching rules

- A digit-run only matches if its **total** length is 4–8 (e.g. `123` and
  `123456789` are ignored; `1234567` is matched).
- Letters touching the digits are fine: `AB-0001234X` yields `0001234`.
- Leading zeros are preserved.

### Error responses

| Status | Meaning                                              |
| ------ | ---------------------------------------------------- |
| 400    | Missing/empty `text`, or bad JSON                    |
| 401    | Wrong or missing `password`                          |
| 405    | Method other than POST                               |
| 500    | `API_PASSWORD` not configured on the server          |
