Now can be powered by postgres sql
This commit is contained in:
+18
-4
@@ -1,16 +1,27 @@
|
||||
# Architecture (backend)
|
||||
|
||||
Single Bun process: `Bun.serve` handles the JSON/SSE API **and** the static
|
||||
frontend (same origin, no CORS). Persistence is SQLite via Bun's native
|
||||
`bun:sqlite` driver (`$DATA_DIR/kisassistant.db`, WAL mode).
|
||||
frontend (same origin, no CORS). Persistence is SQLite by default via Bun's
|
||||
native `bun:sqlite` driver (`$DATA_DIR/kisassistant.db`, WAL mode), or
|
||||
Postgres when `POSTGRESQL_URL` is set (Bun's native `bun:sql` driver,
|
||||
typically a docker container — see `docs/OPERATIONS.md`).
|
||||
|
||||
```
|
||||
browser ──► Bun.serve (src/index.ts)
|
||||
├─ /api/* ──► auth gate ──► routes ──► db.ts ──► kisassistant.db
|
||||
├─ /api/* ──► auth gate ──► routes ──► db.ts ──► sqlite file | postgres
|
||||
│ └─────► DriverRegistry ──► ollama / APIs
|
||||
└─ /* ──► static files + SPA fallback (index.html, covers /share/:id and /chat/:id)
|
||||
```
|
||||
|
||||
All store functions (`db.ts`, `access.ts`, `reports.ts`, `totp.ts`,
|
||||
`modelPolicy.ts`, `userProviders.ts`) are `async` and talk through the
|
||||
`DbClient` interface (`src/db/client.ts`): `get` / `all` / `run` / `exec` /
|
||||
`insertReturningId` / `transaction`. Queries are written once with `?`
|
||||
placeholders and translated to `$1, $2, …` for Postgres (quote-aware);
|
||||
Postgres `BIGINT` cells arrive as `bigint` and are normalized to `number`.
|
||||
One portable-SQL rule this forces: no bare `GROUP BY pk` with unaggregated
|
||||
columns (rejected by Postgres) — use correlated subqueries instead.
|
||||
|
||||
## Request flow: chat
|
||||
|
||||
`POST /api/chat { model: "driver:model", messages, conversationId?, stream? }`
|
||||
@@ -40,7 +51,10 @@ Streaming guarantees (ChatGPT-style, no buffering):
|
||||
|
||||
## Database schema
|
||||
|
||||
Created idempotently at boot in `getDb()` (no migration framework; keep it so).
|
||||
Created idempotently at boot in `initDb()` (no migration framework; keep it
|
||||
so). On Postgres, timestamps are `BIGINT`, auto ids `BIGSERIAL`, later
|
||||
columns arrive via `ADD COLUMN IF NOT EXISTS`, and `"window"` (model_usage)
|
||||
is quoted — `WINDOW` is reserved on Postgres.
|
||||
|
||||
| Table | Purpose |
|
||||
|---|---|
|
||||
|
||||
+30
-1
@@ -10,7 +10,8 @@ Copy `.env.example` to `.env`. Full list:
|
||||
| `PORT` / `HOST` | `3000` / `127.0.0.1` | listen address (keep localhost behind nginx) |
|
||||
| `APP_PASSWORD` | *(required)* | **admin** access key — generate with `openssl rand -base64 24` |
|
||||
| `SESSION_TTL_HOURS` | `720` | Bearer session lifetime (30 days) |
|
||||
| `DATA_DIR` | `./data` | holds `kisassistant.db` (SQLite) |
|
||||
| `DATA_DIR` | `./data` | holds `kisassistant.db` (SQLite — unused when `POSTGRESQL_URL` is set) |
|
||||
| `POSTGRESQL_URL` | *(empty)* | Postgres fallback, e.g. `postgres://kisassistant:secret@localhost:5432/kisassistant` (typically a docker container). Empty = local SQLite. Boot fails fast when unreachable. |
|
||||
| `CDN_DIR` | `./cdn` | local file CDN storage (avatars; NixOS: under state dir) |
|
||||
| `OCR_LANG` | `eng` | tesseract language(s) for the OCR tool |
|
||||
| `OCR_MAX_CHARS` | `100000` | transcription cap (longer results are truncated + flagged) |
|
||||
@@ -42,6 +43,34 @@ Smoke tests: start the backend on a **free non-3000 port** with a throwaway
|
||||
the API with curl/python: login → models → conversations → chat → share →
|
||||
unshare. See `AGENTS.md`.
|
||||
|
||||
## Postgres fallback (docker)
|
||||
|
||||
SQLite is the default. For Postgres, run a container and point the app at it:
|
||||
|
||||
```bash
|
||||
docker run -d --name kisassistant-pg --restart unless-stopped \
|
||||
-e POSTGRES_USER=kisassistant -e POSTGRES_PASSWORD=secret \
|
||||
-e POSTGRES_DB=kisassistant -p 127.0.0.1:5432:5432 \
|
||||
-v kisassistant-pgdata:/var/lib/postgresql/data \
|
||||
postgres:17-alpine
|
||||
|
||||
POSTGRESQL_URL=postgres://kisassistant:[email protected]:5432/kisassistant \
|
||||
DATA_DIR=/tmp/ka-pg-throwaway \
|
||||
bun run src/index.ts
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- The app uses Bun's native `bun:sql` driver — no extra dependency.
|
||||
- Schema is created idempotently at boot (same tables as SQLite; timestamps
|
||||
are `BIGINT`, auto ids `BIGSERIAL`). A fresh database starts empty except
|
||||
the bootstrapped `admin` row — **there is no SQLite→Postgres data
|
||||
migration** (re-create accounts or keep SQLite).
|
||||
- Switching back is just unsetting `POSTGRESQL_URL` (the SQLite file is
|
||||
untouched while Postgres is active).
|
||||
- Back up with `pg_dump` (SQLite: copy `kisassistant.db`, or
|
||||
`.backup` while running under WAL).
|
||||
|
||||
## Managing accounts
|
||||
|
||||
1. Log in as `admin` with the `APP_PASSWORD` key.
|
||||
|
||||
Reference in New Issue
Block a user