Phase 1: Go backend scaffold

- Project structure: cmd/boosapi, internal/, pkg/
- Config loader (all env vars from Node.js original)
- Database layer with SQLite/MySQL/Postgres support
- Migration runner (sequential SQL files)
- Health check endpoint (GET /healthz)
- HTTP middleware: logger, auth, CORS, panic recovery
- chi router with /admin, /v1, /api route groups
- Graceful shutdown (SIGINT/SIGTERM)
- Multi-stage Dockerfile (alpine, ~20MB image)
- Initial schema migration (users, api_keys, sites, usage_logs)

Signed-off-by: Boos4721 <boos4721@icloud.com>
This commit is contained in:
boos
2026-05-16 01:07:02 +08:00
parent f0188d3f68
commit b6ecd613d4
9 changed files with 686 additions and 88 deletions
+50
View File
@@ -0,0 +1,50 @@
-- Initial schema
-- Compatible with SQLite, MySQL, and PostgreSQL
CREATE TABLE IF NOT EXISTS users (
id TEXT PRIMARY KEY,
username TEXT NOT NULL UNIQUE,
email TEXT,
role TEXT NOT NULL DEFAULT 'user',
created_at TEXT NOT NULL DEFAULT (datetime('now')),
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE TABLE IF NOT EXISTS api_keys (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL REFERENCES users(id),
key_hash TEXT NOT NULL,
name TEXT NOT NULL DEFAULT '',
enabled INTEGER NOT NULL DEFAULT 1,
created_at TEXT NOT NULL DEFAULT (datetime('now')),
expires_at TEXT
);
CREATE TABLE IF NOT EXISTS sites (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
type TEXT NOT NULL DEFAULT 'openai',
base_url TEXT NOT NULL,
api_key TEXT NOT NULL DEFAULT '',
priority INTEGER NOT NULL DEFAULT 0,
weight REAL NOT NULL DEFAULT 1.0,
enabled INTEGER NOT NULL DEFAULT 1,
created_at TEXT NOT NULL DEFAULT (datetime('now')),
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE TABLE IF NOT EXISTS usage_logs (
id TEXT PRIMARY KEY,
user_id TEXT REFERENCES users(id),
site_id TEXT REFERENCES sites(id),
model TEXT NOT NULL,
prompt_tokens INTEGER NOT NULL DEFAULT 0,
completion_tokens INTEGER NOT NULL DEFAULT 0,
total_tokens INTEGER NOT NULL DEFAULT 0,
cost REAL NOT NULL DEFAULT 0,
request_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE INDEX IF NOT EXISTS idx_usage_logs_user_id ON usage_logs(user_id);
CREATE INDEX IF NOT EXISTS idx_usage_logs_request_at ON usage_logs(request_at);
CREATE INDEX IF NOT EXISTS idx_api_keys_user_id ON api_keys(user_id);