Changeset 0.22.8 (#150)
This commit is contained in:
123
server/database/migrations/009_workspaces.sql
Normal file
123
server/database/migrations/009_workspaces.sql
Normal file
@@ -0,0 +1,123 @@
|
||||
-- ==========================================
|
||||
-- Chat Switchboard — 009 Workspaces & Git
|
||||
-- ==========================================
|
||||
-- File workspaces, workspace file index, semantic chunks, git credentials.
|
||||
-- ICD §7 (Workspaces & Git)
|
||||
-- ==========================================
|
||||
|
||||
-- =========================================
|
||||
-- WORKSPACES
|
||||
-- =========================================
|
||||
|
||||
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,
|
||||
max_bytes BIGINT,
|
||||
status VARCHAR(20) NOT NULL DEFAULT 'active'
|
||||
CHECK (status IN ('active', 'archived', 'deleting')),
|
||||
indexing_enabled BOOLEAN NOT NULL DEFAULT true,
|
||||
-- Git integration (v0.21.4)
|
||||
git_remote_url TEXT,
|
||||
git_branch TEXT,
|
||||
git_credential_id UUID,
|
||||
git_last_sync TIMESTAMPTZ,
|
||||
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.root_path IS 'PVC-relative path to workspace root directory';
|
||||
|
||||
|
||||
-- =========================================
|
||||
-- WORKSPACE FILES
|
||||
-- =========================================
|
||||
|
||||
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,
|
||||
is_directory BOOLEAN NOT NULL DEFAULT false,
|
||||
content_type VARCHAR(100),
|
||||
size_bytes BIGINT NOT NULL DEFAULT 0,
|
||||
sha256 VARCHAR(64),
|
||||
index_status VARCHAR(20) DEFAULT 'pending'
|
||||
CHECK (index_status IN ('pending', 'indexing', 'ready', 'error', 'skipped')),
|
||||
chunk_count INT NOT NULL DEFAULT 0,
|
||||
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;
|
||||
CREATE INDEX IF NOT EXISTS idx_workspace_files_index_status
|
||||
ON workspace_files(workspace_id, index_status)
|
||||
WHERE index_status IN ('pending', 'indexing');
|
||||
|
||||
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';
|
||||
|
||||
|
||||
-- =========================================
|
||||
-- WORKSPACE CHUNKS (v0.21.2)
|
||||
-- =========================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS workspace_chunks (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
workspace_id UUID NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
|
||||
file_id UUID NOT NULL REFERENCES workspace_files(id) ON DELETE CASCADE,
|
||||
chunk_index INT NOT NULL,
|
||||
content TEXT NOT NULL,
|
||||
token_count INT NOT NULL DEFAULT 0,
|
||||
embedding vector(3072),
|
||||
metadata JSONB DEFAULT '{}',
|
||||
created_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_workspace_chunks_file ON workspace_chunks(file_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_workspace_chunks_workspace ON workspace_chunks(workspace_id);
|
||||
|
||||
COMMENT ON TABLE workspace_chunks IS 'Text chunks with vector embeddings for workspace file semantic search';
|
||||
|
||||
|
||||
-- =========================================
|
||||
-- GIT CREDENTIALS (v0.21.4)
|
||||
-- =========================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS git_credentials (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
name TEXT NOT NULL DEFAULT '',
|
||||
auth_type TEXT NOT NULL DEFAULT 'https_pat',
|
||||
encrypted_data BYTEA NOT NULL DEFAULT '',
|
||||
nonce BYTEA NOT NULL DEFAULT '',
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_git_credentials_user ON git_credentials(user_id);
|
||||
|
||||
-- Deferred FK: workspaces.git_credential_id → git_credentials.id
|
||||
DO $$ BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM pg_constraint WHERE conname = 'fk_workspaces_git_credential'
|
||||
) THEN
|
||||
ALTER TABLE workspaces ADD CONSTRAINT fk_workspaces_git_credential
|
||||
FOREIGN KEY (git_credential_id) REFERENCES git_credentials(id) ON DELETE SET NULL;
|
||||
END IF;
|
||||
END $$;
|
||||
Reference in New Issue
Block a user