Changeset 0.21.1 (#86)

This commit is contained in:
2026-03-01 14:44:55 +00:00
parent 817062e5fc
commit 70aa78e486
18 changed files with 3778 additions and 29 deletions

View 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';

View 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;