feat: vault-aligned server v1 + UX polish
All checks were successful
CI / Windows build (push) Successful in 7m47s
All checks were successful
CI / Windows build (push) Successful in 7m47s
Redesign the optional FastAPI companion around vault files (manifest / PUT/GET/DELETE + OCR jobs) instead of legacy strokes_json notes. Wire a client Server settings panel for health/login. Polish shell UX: l10n for settings/home/board, sticky-board empty state, and a narrow-screen diagnostics FAB. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,24 +1,38 @@
|
||||
# BadNote Server (Optional)
|
||||
# BadNote Server (Self-hosted companion)
|
||||
|
||||
This directory contains an **optional** Python/FastAPI backend. The BadNote desktop app does **not** depend on it.
|
||||
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.
|
||||
|
||||
The Flutter client is local-first:
|
||||
## Architecture (v2 / API v1)
|
||||
|
||||
- Notes and documents are stored in SQLite on device
|
||||
- OCR runs locally via Windows built-in OCR
|
||||
- Full-text search uses on-device FTS5
|
||||
```
|
||||
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
|
||||
```
|
||||
|
||||
## Why this exists
|
||||
**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`.
|
||||
|
||||
This server was an early experiment for:
|
||||
### Storage layout
|
||||
|
||||
- Multi-device note sync (push/pull)
|
||||
- Server-side OCR with EasyOCR
|
||||
- JWT authentication
|
||||
```
|
||||
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}/
|
||||
```
|
||||
|
||||
These features are **not wired into the current client**. The client previously had incomplete sync/OCR scaffolding that has been removed in favor of local processing.
|
||||
|
||||
## Running (if you want to experiment)
|
||||
## Run
|
||||
|
||||
```bash
|
||||
cd server
|
||||
@@ -28,25 +42,43 @@ pip install -r requirements.txt
|
||||
uvicorn badnote_server.main:app --host 0.0.0.0 --port 8080
|
||||
```
|
||||
|
||||
API docs: http://localhost:8080/docs
|
||||
- Health: `GET /api/v1/health`
|
||||
- OpenAPI: http://localhost:8080/docs
|
||||
|
||||
The OCR worker has heavy extra dependencies (EasyOCR + torch). Install them only
|
||||
if you want to run it:
|
||||
### OCR worker (optional, heavy)
|
||||
|
||||
```bash
|
||||
pip install -r requirements-ocr.txt
|
||||
python -m badnote_server.ocr.worker
|
||||
```
|
||||
|
||||
### Security notes
|
||||
### Security
|
||||
|
||||
- Set `BADNOTE_JWT_SECRET` in production. If unset, a secret is generated once
|
||||
and persisted to `<data>/.jwt_secret` so tokens survive restarts.
|
||||
- Restrict origins with `BADNOTE_CORS_ORIGINS` (comma-separated). The default is
|
||||
permissive (`*`, without credentials) for local development.
|
||||
- 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
|
||||
|
||||
- Kept for reference and future optional sync work
|
||||
- Not part of the primary development path
|
||||
- No guarantee of API compatibility with future client versions
|
||||
- **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
|
||||
|
||||
Reference in New Issue
Block a user