Replace the empty dynamic canvas placeholder with a gallery showing saved canvases, snapshots and Vue components. Users can create new canvases, restore snapshots, load components, and manage canvas toolbar/archive settings from the gallery. - Backend: soft delete (archive) instead of hard delete, status column - Frontend: CanvasGallery component with grid, search, settings popover - Show canvas name in global header when viewing a project canvas - Remove ProjectsPage (replaced by gallery), clean all references - MCP tools: project category available on canvas page, update handlers
134 lines
3.3 KiB
TypeScript
134 lines
3.3 KiB
TypeScript
import type { Database } from 'bun:sqlite'
|
|
|
|
export function runMigrations(db: Database) {
|
|
// History table
|
|
db.run(`
|
|
CREATE TABLE IF NOT EXISTS history (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
timestamp TEXT DEFAULT CURRENT_TIMESTAMP,
|
|
tool_name TEXT NOT NULL,
|
|
args TEXT,
|
|
result TEXT
|
|
)
|
|
`)
|
|
|
|
// Config table
|
|
db.run(`
|
|
CREATE TABLE IF NOT EXISTS config (
|
|
key TEXT PRIMARY KEY,
|
|
value TEXT
|
|
)
|
|
`)
|
|
|
|
// Vue components table
|
|
db.run(`
|
|
CREATE TABLE IF NOT EXISTS vue_components (
|
|
id TEXT PRIMARY KEY,
|
|
name TEXT NOT NULL,
|
|
template TEXT NOT NULL,
|
|
setup TEXT,
|
|
style TEXT,
|
|
props TEXT,
|
|
imports TEXT,
|
|
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TEXT DEFAULT CURRENT_TIMESTAMP
|
|
)
|
|
`)
|
|
|
|
// Themes table
|
|
db.run(`
|
|
CREATE TABLE IF NOT EXISTS themes (
|
|
id TEXT PRIMARY KEY,
|
|
name TEXT NOT NULL,
|
|
description TEXT,
|
|
is_default INTEGER DEFAULT 0,
|
|
is_system INTEGER DEFAULT 0,
|
|
variables TEXT NOT NULL,
|
|
metadata TEXT,
|
|
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TEXT DEFAULT CURRENT_TIMESTAMP
|
|
)
|
|
`)
|
|
|
|
// Project canvas table
|
|
db.run(`
|
|
CREATE TABLE IF NOT EXISTS project_canvas (
|
|
id TEXT PRIMARY KEY,
|
|
name TEXT NOT NULL,
|
|
description TEXT,
|
|
type TEXT NOT NULL DEFAULT 'project',
|
|
theme_id TEXT,
|
|
config TEXT,
|
|
tools TEXT,
|
|
is_default INTEGER DEFAULT 0,
|
|
is_system INTEGER DEFAULT 0,
|
|
show_in_toolbar INTEGER DEFAULT 0,
|
|
toolbar_icon TEXT,
|
|
toolbar_order INTEGER DEFAULT 99,
|
|
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TEXT DEFAULT CURRENT_TIMESTAMP
|
|
)
|
|
`)
|
|
|
|
// Canvas-components relation table
|
|
db.run(`
|
|
CREATE TABLE IF NOT EXISTS canvas_components (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
canvas_id TEXT NOT NULL,
|
|
component_id TEXT NOT NULL,
|
|
position INTEGER DEFAULT 0,
|
|
props TEXT,
|
|
layout TEXT,
|
|
is_visible INTEGER DEFAULT 1,
|
|
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
|
|
UNIQUE(canvas_id, component_id)
|
|
)
|
|
`)
|
|
|
|
// Canvas snapshots table
|
|
db.run(`
|
|
CREATE TABLE IF NOT EXISTS canvas_snapshots (
|
|
id TEXT PRIMARY KEY,
|
|
name TEXT NOT NULL,
|
|
data TEXT NOT NULL,
|
|
thumbnail TEXT,
|
|
created_at INTEGER NOT NULL
|
|
)
|
|
`)
|
|
|
|
// Voice recordings table (for training custom speech models)
|
|
db.run(`
|
|
CREATE TABLE IF NOT EXISTS voice_recordings (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
filename TEXT NOT NULL,
|
|
transcription TEXT,
|
|
duration_ms INTEGER,
|
|
microphone TEXT,
|
|
sample_rate INTEGER,
|
|
file_size INTEGER,
|
|
created_at TEXT DEFAULT CURRENT_TIMESTAMP
|
|
)
|
|
`)
|
|
|
|
// Run column migrations for existing tables
|
|
runColumnMigrations(db)
|
|
}
|
|
|
|
function runColumnMigrations(db: Database) {
|
|
// Add toolbar columns to project_canvas if missing
|
|
const alterStatements = [
|
|
'ALTER TABLE project_canvas ADD COLUMN show_in_toolbar INTEGER DEFAULT 0',
|
|
'ALTER TABLE project_canvas ADD COLUMN toolbar_icon TEXT',
|
|
'ALTER TABLE project_canvas ADD COLUMN toolbar_order INTEGER DEFAULT 99',
|
|
'ALTER TABLE project_canvas ADD COLUMN status TEXT DEFAULT \'active\''
|
|
]
|
|
|
|
for (const sql of alterStatements) {
|
|
try {
|
|
db.run(sql)
|
|
} catch {
|
|
// Column already exists
|
|
}
|
|
}
|
|
}
|