Changeset 0.21.1 (#86)
This commit is contained in:
74
server/database/migrations/009_v0210_workspaces.sql
Normal file
74
server/database/migrations/009_v0210_workspaces.sql
Normal file
@@ -0,0 +1,74 @@
|
||||
-- v0.21.0: Workspaces (platform storage primitive)
|
||||
--
|
||||
-- New: workspaces table (polymorphic owner: user, project, channel, team)
|
||||
-- New: workspace_files table (metadata index — filesystem is source of truth)
|
||||
|
||||
-- =========================================
|
||||
-- 1. Workspaces Table
|
||||
-- =========================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS workspaces (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
owner_type VARCHAR(20) NOT NULL
|
||||
CHECK (owner_type IN ('user', 'project', 'channel', 'team')),
|
||||
owner_id UUID NOT NULL,
|
||||
name VARCHAR(200) NOT NULL,
|
||||
root_path TEXT NOT NULL, -- PVC-relative: workspaces/{id}
|
||||
max_bytes BIGINT, -- quota (NULL = system default)
|
||||
status VARCHAR(20) NOT NULL DEFAULT 'active'
|
||||
CHECK (status IN ('active', 'archived', 'deleting')),
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_workspaces_owner
|
||||
ON workspaces(owner_type, owner_id);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_workspaces_status
|
||||
ON workspaces(status) WHERE status != 'deleting';
|
||||
|
||||
DROP TRIGGER IF EXISTS workspaces_updated_at ON workspaces;
|
||||
CREATE TRIGGER workspaces_updated_at BEFORE UPDATE ON workspaces
|
||||
FOR EACH ROW EXECUTE FUNCTION update_updated_at();
|
||||
|
||||
COMMENT ON TABLE workspaces IS 'File workspaces bound to users, projects, channels, or teams';
|
||||
COMMENT ON COLUMN workspaces.owner_type IS 'Polymorphic owner: user, project, channel, team';
|
||||
COMMENT ON COLUMN workspaces.root_path IS 'PVC-relative path to workspace root directory';
|
||||
COMMENT ON COLUMN workspaces.max_bytes IS 'Storage quota in bytes (NULL = system default)';
|
||||
|
||||
-- =========================================
|
||||
-- 2. Workspace Files Table
|
||||
-- =========================================
|
||||
-- Metadata index for workspace files. The PVC filesystem is the source
|
||||
-- of truth; this table enables fast queries (list, filter by type, etc.)
|
||||
-- and will hold embedding references in v0.21.2.
|
||||
|
||||
CREATE TABLE IF NOT EXISTS workspace_files (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
workspace_id UUID NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
|
||||
path TEXT NOT NULL, -- relative path: src/main.go
|
||||
is_directory BOOLEAN NOT NULL DEFAULT false,
|
||||
content_type VARCHAR(100), -- MIME type
|
||||
size_bytes BIGINT NOT NULL DEFAULT 0,
|
||||
sha256 VARCHAR(64), -- content hash (NULL for dirs)
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_workspace_files_path
|
||||
ON workspace_files(workspace_id, path);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_workspace_files_workspace
|
||||
ON workspace_files(workspace_id);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_workspace_files_type
|
||||
ON workspace_files(workspace_id, content_type)
|
||||
WHERE content_type IS NOT NULL;
|
||||
|
||||
DROP TRIGGER IF EXISTS workspace_files_updated_at ON workspace_files;
|
||||
CREATE TRIGGER workspace_files_updated_at BEFORE UPDATE ON workspace_files
|
||||
FOR EACH ROW EXECUTE FUNCTION update_updated_at();
|
||||
|
||||
COMMENT ON TABLE workspace_files IS 'Metadata index for workspace files — filesystem is source of truth';
|
||||
COMMENT ON COLUMN workspace_files.path IS 'Relative path from workspace files/ root';
|
||||
COMMENT ON COLUMN workspace_files.sha256 IS 'Content hash for change detection and dedup';
|
||||
62
server/database/migrations/sqlite/008_v0210_workspaces.sql
Normal file
62
server/database/migrations/sqlite/008_v0210_workspaces.sql
Normal file
@@ -0,0 +1,62 @@
|
||||
-- v0.21.0: Workspaces (platform storage primitive) — SQLite
|
||||
|
||||
-- =========================================
|
||||
-- 1. Workspaces Table
|
||||
-- =========================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS workspaces (
|
||||
id TEXT PRIMARY KEY,
|
||||
owner_type TEXT NOT NULL
|
||||
CHECK (owner_type IN ('user', 'project', 'channel', 'team')),
|
||||
owner_id TEXT NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
root_path TEXT NOT NULL,
|
||||
max_bytes INTEGER,
|
||||
status TEXT NOT NULL DEFAULT 'active'
|
||||
CHECK (status IN ('active', 'archived', 'deleting')),
|
||||
created_at TEXT DEFAULT (datetime('now')),
|
||||
updated_at TEXT DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_workspaces_owner
|
||||
ON workspaces(owner_type, owner_id);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_workspaces_status
|
||||
ON workspaces(status);
|
||||
|
||||
CREATE TRIGGER IF NOT EXISTS workspaces_updated_at AFTER UPDATE ON workspaces
|
||||
FOR EACH ROW WHEN NEW.updated_at = OLD.updated_at
|
||||
BEGIN
|
||||
UPDATE workspaces SET updated_at = datetime('now') WHERE id = NEW.id;
|
||||
END;
|
||||
|
||||
-- =========================================
|
||||
-- 2. Workspace Files Table
|
||||
-- =========================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS workspace_files (
|
||||
id TEXT PRIMARY KEY,
|
||||
workspace_id TEXT NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
|
||||
path TEXT NOT NULL,
|
||||
is_directory INTEGER NOT NULL DEFAULT 0,
|
||||
content_type TEXT,
|
||||
size_bytes INTEGER NOT NULL DEFAULT 0,
|
||||
sha256 TEXT,
|
||||
created_at TEXT DEFAULT (datetime('now')),
|
||||
updated_at TEXT DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_workspace_files_path
|
||||
ON workspace_files(workspace_id, path);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_workspace_files_workspace
|
||||
ON workspace_files(workspace_id);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_workspace_files_type
|
||||
ON workspace_files(workspace_id, content_type);
|
||||
|
||||
CREATE TRIGGER IF NOT EXISTS workspace_files_updated_at AFTER UPDATE ON workspace_files
|
||||
FOR EACH ROW WHEN NEW.updated_at = OLD.updated_at
|
||||
BEGIN
|
||||
UPDATE workspace_files SET updated_at = datetime('now') WHERE id = NEW.id;
|
||||
END;
|
||||
Reference in New Issue
Block a user