This commit is contained in:
Bashy 2026-05-03 20:56:15 +03:00
commit 60ca58f5ba
80 changed files with 9458 additions and 0 deletions

29
sql/001_initial.sql Normal file
View file

@ -0,0 +1,29 @@
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT NOT NULL UNIQUE,
password_hash TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS projects (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
path TEXT NOT NULL UNIQUE,
type TEXT NOT NULL DEFAULT 'generic',
url TEXT,
is_active INTEGER NOT NULL DEFAULT 1,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS scan_paths (
id INTEGER PRIMARY KEY AUTOINCREMENT,
path TEXT NOT NULL UNIQUE,
depth INTEGER NOT NULL DEFAULT 2,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS settings (
key TEXT PRIMARY KEY,
value TEXT
);

46
sql/002_milestone4.sql Normal file
View file

@ -0,0 +1,46 @@
ALTER TABLE projects ADD COLUMN is_pinned INTEGER NOT NULL DEFAULT 0;
CREATE TABLE IF NOT EXISTS command_history (
id INTEGER PRIMARY KEY AUTOINCREMENT,
project_id INTEGER NOT NULL REFERENCES projects(id),
cmd_id TEXT NOT NULL,
cmd TEXT NOT NULL,
output TEXT,
exit_code INTEGER,
run_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS audit_log (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER,
project_id INTEGER,
action TEXT NOT NULL,
detail TEXT,
ip TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS post_templates (
id INTEGER PRIMARY KEY AUTOINCREMENT,
project_id INTEGER NOT NULL REFERENCES projects(id),
name TEXT NOT NULL,
type TEXT NOT NULL DEFAULT 'post',
content TEXT NOT NULL DEFAULT '',
is_default INTEGER NOT NULL DEFAULT 0,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS snippets (
id INTEGER PRIMARY KEY AUTOINCREMENT,
project_id INTEGER NOT NULL REFERENCES projects(id),
name TEXT NOT NULL,
content TEXT NOT NULL DEFAULT '',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS project_settings (
project_id INTEGER NOT NULL REFERENCES projects(id),
key TEXT NOT NULL,
value TEXT,
PRIMARY KEY (project_id, key)
);

11
sql/003_db_drafts.sql Normal file
View file

@ -0,0 +1,11 @@
CREATE TABLE IF NOT EXISTS drafts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
project_id INTEGER NOT NULL REFERENCES projects(id),
title TEXT NOT NULL DEFAULT '',
slug TEXT NOT NULL DEFAULT '',
folder TEXT NOT NULL DEFAULT '',
frontmatter TEXT NOT NULL DEFAULT '',
body TEXT NOT NULL DEFAULT '',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

1
sql/004_scratchpad.sql Normal file
View file

@ -0,0 +1 @@
ALTER TABLE projects ADD COLUMN scratchpad TEXT NOT NULL DEFAULT '';

44
sql/005_milestone5.sql Normal file
View file

@ -0,0 +1,44 @@
CREATE TABLE IF NOT EXISTS recent_files (
id INTEGER PRIMARY KEY AUTOINCREMENT,
project_id INTEGER NOT NULL REFERENCES projects(id),
path TEXT NOT NULL,
opened_at DATETIME DEFAULT CURRENT_TIMESTAMP,
UNIQUE(project_id, path)
);
CREATE INDEX IF NOT EXISTS idx_recent_files_project ON recent_files(project_id, opened_at DESC);
CREATE TABLE IF NOT EXISTS scheduled_builds (
id INTEGER PRIMARY KEY AUTOINCREMENT,
project_id INTEGER NOT NULL REFERENCES projects(id),
cmd_id TEXT NOT NULL,
cron TEXT NOT NULL,
is_enabled INTEGER NOT NULL DEFAULT 1,
last_run_at DATETIME,
last_status TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX IF NOT EXISTS idx_scheduled_builds_project ON scheduled_builds(project_id);
CREATE TABLE IF NOT EXISTS link_check_runs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
project_id INTEGER NOT NULL REFERENCES projects(id),
started_at DATETIME DEFAULT CURRENT_TIMESTAMP,
finished_at DATETIME,
total_links INTEGER DEFAULT 0,
broken INTEGER DEFAULT 0
);
CREATE TABLE IF NOT EXISTS link_check_results (
id INTEGER PRIMARY KEY AUTOINCREMENT,
run_id INTEGER NOT NULL REFERENCES link_check_runs(id) ON DELETE CASCADE,
project_id INTEGER NOT NULL REFERENCES projects(id),
url TEXT NOT NULL,
source TEXT NOT NULL,
status_code INTEGER,
error TEXT,
checked_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX IF NOT EXISTS idx_link_results_run ON link_check_results(run_id);

15
sql/006_analytics.sql Normal file
View file

@ -0,0 +1,15 @@
CREATE TABLE IF NOT EXISTS site_visits (
id INTEGER PRIMARY KEY AUTOINCREMENT,
project_id INTEGER NOT NULL REFERENCES projects(id),
path TEXT NOT NULL,
referrer TEXT,
ua_hash TEXT,
ip_hash TEXT,
visited_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX IF NOT EXISTS idx_visits_project_time
ON site_visits(project_id, visited_at DESC);
CREATE INDEX IF NOT EXISTS idx_visits_project_path
ON site_visits(project_id, path);

View file

@ -0,0 +1,5 @@
-- Track HTTP status on each visit so analytics can split 200s from 404s.
ALTER TABLE site_visits ADD COLUMN status INTEGER NOT NULL DEFAULT 200;
CREATE INDEX IF NOT EXISTS idx_visits_project_status
ON site_visits(project_id, status);

View file

@ -0,0 +1,37 @@
-- Hourly rollup: views + uniques per (project, hour, path, status, referrer).
CREATE TABLE IF NOT EXISTS site_visits_hourly (
id INTEGER PRIMARY KEY AUTOINCREMENT,
project_id INTEGER NOT NULL REFERENCES projects(id),
bucket_at DATETIME NOT NULL,
path TEXT NOT NULL,
status INTEGER NOT NULL DEFAULT 200,
referrer TEXT NOT NULL DEFAULT '',
views INTEGER NOT NULL DEFAULT 0,
uniques INTEGER NOT NULL DEFAULT 0,
UNIQUE(project_id, bucket_at, path, status, referrer)
);
CREATE INDEX IF NOT EXISTS idx_visits_hourly_project_time
ON site_visits_hourly(project_id, bucket_at);
CREATE INDEX IF NOT EXISTS idx_visits_hourly_project_status
ON site_visits_hourly(project_id, status);
-- Daily rollup: views + uniques per (project, day, path, status, referrer).
-- "Uniques" here is "distinct ip_hash within the day" — and since the salt
-- rotates daily, that hash is meaningful only within the bucket's day.
CREATE TABLE IF NOT EXISTS site_visits_daily (
id INTEGER PRIMARY KEY AUTOINCREMENT,
project_id INTEGER NOT NULL REFERENCES projects(id),
bucket_at DATE NOT NULL,
path TEXT NOT NULL,
status INTEGER NOT NULL DEFAULT 200,
referrer TEXT NOT NULL DEFAULT '',
views INTEGER NOT NULL DEFAULT 0,
uniques INTEGER NOT NULL DEFAULT 0,
UNIQUE(project_id, bucket_at, path, status, referrer)
);
CREATE INDEX IF NOT EXISTS idx_visits_daily_project_time
ON site_visits_daily(project_id, bucket_at);
CREATE INDEX IF NOT EXISTS idx_visits_daily_project_status
ON site_visits_daily(project_id, status);