# BadNote Server (Self-hosted companion)

Optional FastAPI backend for multi-device vault assist and deferred OCR.
The Flutter app stays local-first: notes work fully offline. This server is
for **your NAS / VPS**, not a hosted cloud product.

## Architecture (v2 / API v1)

```
Client vault (files + *.badnote.json)
        │
        ├─ WebDAV (NAS) ───────────── file sync (existing)
        │
        └─ BadNote Server /api/v1 ─── assist layer
              ├─ /auth     JWT register/login
              ├─ /vault    manifest + PUT/GET/DELETE (tombstones)
              └─ /ocr      upload ink PNG → job queue → EasyOCR worker
```

**Source of truth = vault files**, not the legacy `notes.strokes_json` tables.
Legacy routers remain under `/api/legacy/*` (and old `/api/notes` paths) for
experiments only — new clients must use `/api/v1`.

### Storage layout

```
data/
  badnote_server.db          # users
  .jwt_secret                # if BADNOTE_JWT_SECRET unset
  vaults/<user_id>/files/    # mirrors client vault
  storage/ocr_blobs/…        # uploaded ink rasters
  queue/{pending,processing,done,failed}/
```

## Run

```bash
cd server
python -m venv .venv
source .venv/bin/activate   # Windows: .venv\Scripts\activate
pip install -r requirements.txt
uvicorn badnote_server.main:app --host 0.0.0.0 --port 8080
```

- Health: `GET /api/v1/health`
- OpenAPI: http://localhost:8080/docs

### OCR worker (optional, heavy)

```bash
pip install -r requirements-ocr.txt
python -m badnote_server.ocr.worker
```

### Security

- Set `BADNOTE_JWT_SECRET` in production.
- Restrict CORS with `BADNOTE_CORS_ORIGINS`.
- Prefer HTTPS reverse proxy (Caddy/Nginx) in front of uvicorn.

### Env

| Variable | Default | Meaning |
|----------|---------|---------|
| `BADNOTE_HOST` / `PORT` | `0.0.0.0` / `8080` | Bind |
| `BADNOTE_DB_PATH` | `./data/badnote_server.db` | Users DB |
| `BADNOTE_VAULT_PATH` | `./data/vaults` | Per-user vault trees |
| `BADNOTE_STORAGE_PATH` | `./data/storage` | Blobs |
| `BADNOTE_QUEUE_PATH` | `./data/queue` | OCR jobs |
| `BADNOTE_JWT_SECRET` | persisted file | Signing key |
| `BADNOTE_CORS_ORIGINS` | `*` | Allowed origins |

## Client

In BadNote → Settings → **BadNote Server**, set base URL (e.g.
`http://192.168.1.10:8080`), register/login, then **Test connection**.
Vault file sync via the API is additive to WebDAV; OCR upload is opt-in when
online/charging (future client job).

## Status

- **v1 vault + health + OCR enqueue**: implemented
- **Wiki / semantic search**: stubbed for later (`501` reserved)
- Legacy notes push/pull: deprecated, not used by current Flutter app
