Initial commit: Phase 1+2 prototype
- Go backend with SQLite, JWT auth, file CRUD - Vue 3 frontend with split/raw/WYSIWYG editor modes - Markdown preview (marked, GFM) - Formatting toolbar + keyboard shortcuts - File tree with search, create, delete - Light/dark theme toggle - Admin panel (user management) - Preferences (timezone, theme, default mode) - Shared documents section (placeholder) - Export: PDF, HTML, MD - Build daemon (Python, stdlib only) - Build job queue API - Docker deployment
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
_ "modernc.org/sqlite"
|
||||
)
|
||||
|
||||
type DB = sql.DB
|
||||
|
||||
func Open(path string) (*DB, error) {
|
||||
dir := filepath.Dir(path)
|
||||
if err := os.MkdirAll(dir, 0755); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
database, err := sql.Open("sqlite", path+"?_journal_mode=WAL&_busy_timeout=5000")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := database.Ping(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return database, nil
|
||||
}
|
||||
|
||||
func Migrate(database *DB) error {
|
||||
_, err := database.Exec(schema)
|
||||
return err
|
||||
}
|
||||
|
||||
var schema = `
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id TEXT PRIMARY KEY,
|
||||
username TEXT UNIQUE NOT NULL,
|
||||
email TEXT UNIQUE NOT NULL,
|
||||
password_hash TEXT NOT NULL,
|
||||
totp_secret TEXT,
|
||||
encryption_enabled INTEGER DEFAULT 0,
|
||||
encryption_salt BLOB,
|
||||
recovery_key_hash TEXT,
|
||||
is_admin INTEGER DEFAULT 0,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS files (
|
||||
id TEXT PRIMARY KEY,
|
||||
owner_id TEXT NOT NULL REFERENCES users(id),
|
||||
path TEXT NOT NULL,
|
||||
title TEXT,
|
||||
encrypted INTEGER DEFAULT 0,
|
||||
encrypted_content BLOB,
|
||||
encrypted_file_key BLOB,
|
||||
sync_flagged INTEGER DEFAULT 0,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
UNIQUE(owner_id, path)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS virtual_tree (
|
||||
id TEXT PRIMARY KEY,
|
||||
user_id TEXT NOT NULL REFERENCES users(id),
|
||||
parent_id TEXT REFERENCES virtual_tree(id),
|
||||
name TEXT NOT NULL,
|
||||
type TEXT NOT NULL,
|
||||
target_file_id TEXT REFERENCES files(id),
|
||||
sort_order INTEGER DEFAULT 0,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS permissions (
|
||||
id TEXT PRIMARY KEY,
|
||||
file_id TEXT NOT NULL REFERENCES files(id),
|
||||
user_id TEXT NOT NULL REFERENCES users(id),
|
||||
level TEXT NOT NULL,
|
||||
granted_by TEXT NOT NULL REFERENCES users(id),
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
UNIQUE(file_id, user_id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS git_remotes (
|
||||
id TEXT PRIMARY KEY,
|
||||
user_id TEXT NOT NULL REFERENCES users(id),
|
||||
name TEXT NOT NULL,
|
||||
url TEXT NOT NULL,
|
||||
auth_token TEXT,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
UNIQUE(user_id, name)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS collab_state (
|
||||
file_id TEXT PRIMARY KEY REFERENCES files(id),
|
||||
yjs_state BLOB,
|
||||
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS sessions (
|
||||
id TEXT PRIMARY KEY,
|
||||
user_id TEXT NOT NULL REFERENCES users(id),
|
||||
token_hash TEXT NOT NULL,
|
||||
expires_at TEXT NOT NULL,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS api_tokens (
|
||||
id TEXT PRIMARY KEY,
|
||||
user_id TEXT NOT NULL REFERENCES users(id),
|
||||
name TEXT NOT NULL,
|
||||
token_hash TEXT NOT NULL,
|
||||
last_used_at TEXT,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS build_jobs (
|
||||
id TEXT PRIMARY KEY,
|
||||
user_id TEXT NOT NULL REFERENCES users(id),
|
||||
status TEXT NOT NULL DEFAULT 'pending',
|
||||
spec_content TEXT NOT NULL,
|
||||
gitea_url TEXT,
|
||||
gitea_token TEXT,
|
||||
gitea_org TEXT,
|
||||
repo_name TEXT NOT NULL,
|
||||
model TEXT,
|
||||
log TEXT DEFAULT '',
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS daemon_state (
|
||||
id TEXT PRIMARY KEY DEFAULT 'singleton',
|
||||
last_heartbeat TEXT,
|
||||
status TEXT DEFAULT 'offline'
|
||||
);
|
||||
`
|
||||
Reference in New Issue
Block a user