# Deploying autotrade-server on Corsair

This is a NEW, independent service. It does not touch, replace, or
restart the existing `tradesimulator` (tsvalid) or `td-params-server`
processes - both keep running exactly as they are, on their existing
URLs/ports, for existing license holders. Everything below is purely
additive.

## 1. Copy the code

```bash
mkdir -p /wd/autotrade-server
# copy all the .py files + requirements.txt into it
cd /wd/autotrade-server
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
mkdir -p data/params
echo '{"_comment": "alias -> canonical"}' > data/symbol_synonyms.json
```

## 2. Create the database user

Run on Corsair (adjust the password):

```sql
CREATE USER 'autotrade'@'127.0.0.1' IDENTIFIED BY 'CHANGE_ME_REAL_PASSWORD';
GRANT SELECT, INSERT, UPDATE, DELETE ON TradeSimulatorLicense.licenses TO 'autotrade'@'127.0.0.1';
GRANT SELECT, INSERT, DELETE ON TradeSimulatorLicense.license_products TO 'autotrade'@'127.0.0.1';
GRANT SELECT, INSERT ON TradeSimulatorLicense.audit_log TO 'autotrade'@'127.0.0.1';
FLUSH PRIVILEGES;
```

Distinct from `tsvalid`'s own DB user and the old `td-params-server`'s
read-only `paramsreader` - if this user's credentials are ever
compromised, it can't touch anything those two processes weren't already
able to touch, and vice versa. `@'127.0.0.1'` because this service
connects to MariaDB locally, same as the other two - no networking
changes needed here, this is unrelated to the earlier port/firewall saga.

## 3. Generate real secrets

```bash
python3 -c "import secrets; print(secrets.token_urlsafe(32))"   # run twice
```

Use one for `AUTOTRADE_EA_HMAC_SECRET`, a different one for
`AUTOTRADE_ADMIN_API_KEY`. Write the real values into an env file:

```bash
mkdir -p /etc/autotrade
cat > /etc/autotrade/env << 'ENVEOF'
AUTOTRADE_DB_HOST=127.0.0.1
AUTOTRADE_DB_PORT=3306
AUTOTRADE_DB_USER=autotrade
AUTOTRADE_DB_PASS=CHANGE_ME_REAL_PASSWORD
AUTOTRADE_DB_NAME=TradeSimulatorLicense
AUTOTRADE_EA_HMAC_SECRET=CHANGE_ME_REAL_SECRET_1
AUTOTRADE_ADMIN_API_KEY=CHANGE_ME_REAL_SECRET_2
AUTOTRADE_PARAMS_DATA_DIR=/wd/autotrade-server/data/params
AUTOTRADE_SYMBOLS_PATH=/wd/autotrade-server/data/symbol_synonyms.json
ENVEOF
chmod 600 /etc/autotrade/env
```

`AUTOTRADE_ADMIN_API_KEY` needs to match `CORSAIR_ADMIN_KEY` in Lightning's
`corsair_env.sh` exactly.

## 4. systemd unit

```bash
cat > /etc/systemd/system/autotrade.service << 'EOF'
[Unit]
Description=Autotrade consolidated license/params/admin server
After=network.target mariadb.service

[Service]
Type=simple
WorkingDirectory=/wd/autotrade-server
EnvironmentFile=/etc/autotrade/env
ExecStart=/wd/autotrade-server/venv/bin/uvicorn main:app --host 127.0.0.1 --port 8300
Restart=always
RestartSec=5
User=root

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable autotrade
systemctl start autotrade
systemctl status autotrade
```

Bound to `127.0.0.1:8300` deliberately - not exposed directly to the
internet. nginx (next step) is what the outside world actually talks to;
it terminates TLS and proxies to this local port. Pick a different port
if 8300 collides with something else already running.

Verify it's alive:
```bash
curl http://127.0.0.1:8300/healthz
```

## 5. DNS

Add an A record: `autotrade.stellarexhorizons.com` -> Corsair's public IP
(`172.105.24.88`), wherever `stellarexhorizons.com`'s DNS is managed.

## 6. nginx + TLS

If nginx isn't already installed:
```bash
apt-get install -y nginx
```

New site config:
```bash
cat > /etc/nginx/sites-available/autotrade << 'EOF'
server {
    listen 80;
    server_name autotrade.stellarexhorizons.com;

    location / {
        proxy_pass http://127.0.0.1:8300;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
EOF
ln -s /etc/nginx/sites-available/autotrade /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx
```

Then get a real cert (certbot's nginx plugin edits the config above
in-place to add the TLS/443 block and redirect):
```bash
apt-get install -y certbot python3-certbot-nginx
certbot --nginx -d autotrade.stellarexhorizons.com
```

Verify from Lightning:
```bash
curl https://autotrade.stellarexhorizons.com/healthz
```

This should just work over 443 - no port-blocking, no IP-rotation
sensitivity, none of the issues the raw-3306 approach ran into.

## 7. Point Lightning at it

Fill in the real values in `corsair_env.sh`:
```bash
export CORSAIR_API_URL="https://autotrade.stellarexhorizons.com"
export CORSAIR_ADMIN_KEY="CHANGE_ME_REAL_SECRET_2"   # same value as AUTOTRADE_ADMIN_API_KEY above
```

Then `source corsair_env.sh` and start the suite as usual. The Licensing
tab should show whatever's actually in `TradeSimulatorLicense` (empty at
first, since this is a fresh start for new licenses - old licenses stay
on the old server, not visible here, by design).

## What's NOT done yet / decisions still open

- **Old services stay running as-is** - nothing about this deployment
  touches `tradesimulator` or the old `td-params-server`. Decide later
  when/whether to retire them once all real license holders have
  migrated to new licenses.
- **`registered_machine`** (the confirmed-dead column) isn't referenced
  anywhere in the new code, deliberately.
- **No machine-unregister admin action** exists yet (e.g. "let this
  customer transfer immediately, skip the cooldown") - straightforward to
  add to `admin_routes.py` if you want it; wasn't part of the original ask.
- **Rate limiting** on `/validate` and `/params` isn't implemented -
  `tsvalid` didn't have it either as far as I've seen, so this isn't a
  regression, just worth knowing it's still open.
