""" 数据库迁移脚本 - 初始化表结构 """ -- 用户表 CREATE TABLE IF NOT EXISTS users ( id VARCHAR(255) PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL, display_name VARCHAR(255) NOT NULL, username VARCHAR(255) UNIQUE, password_hash VARCHAR(255), email_verified BOOLEAN DEFAULT FALSE, email_verification_token VARCHAR(255), password_reset_token VARCHAR(255), password_reset_expires_at TIMESTAMP, last_login_at TIMESTAMP, last_login_ip VARCHAR(50), created_at TIMESTAMP NOT NULL DEFAULT NOW() ); CREATE INDEX idx_users_email ON users(email); CREATE INDEX idx_users_username ON users(username); CREATE INDEX idx_users_email_verification_token ON users(email_verification_token); CREATE INDEX idx_users_password_reset_token ON users(password_reset_token); -- 工作空间表 CREATE TABLE IF NOT EXISTS workspaces ( id VARCHAR(255) PRIMARY KEY, name VARCHAR(255) NOT NULL, owner_user_id VARCHAR(255) NOT NULL REFERENCES users(id) ON DELETE CASCADE, subscription_plan VARCHAR(50) DEFAULT 'free', subscription_status VARCHAR(50) DEFAULT 'active', subscription_expires_at TIMESTAMP, max_projects INTEGER DEFAULT 3, max_storage_gb INTEGER DEFAULT 10, used_storage_gb DECIMAL(10, 2) DEFAULT 0, created_at TIMESTAMP NOT NULL DEFAULT NOW() ); CREATE INDEX idx_workspaces_owner ON workspaces(owner_user_id); -- 工作空间成员表 CREATE TABLE IF NOT EXISTS workspace_members ( id VARCHAR(255) PRIMARY KEY, workspace_id VARCHAR(255) NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE, user_id VARCHAR(255) NOT NULL REFERENCES users(id) ON DELETE CASCADE, role VARCHAR(50) NOT NULL, invited_by VARCHAR(255) REFERENCES users(id), joined_at TIMESTAMP NOT NULL DEFAULT NOW(), UNIQUE(workspace_id, user_id) ); CREATE INDEX idx_workspace_members_workspace ON workspace_members(workspace_id); CREATE INDEX idx_workspace_members_user ON workspace_members(user_id); -- 工作空间邀请表 CREATE TABLE IF NOT EXISTS workspace_invitations ( id VARCHAR(255) PRIMARY KEY, workspace_id VARCHAR(255) NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE, inviter_user_id VARCHAR(255) NOT NULL REFERENCES users(id) ON DELETE CASCADE, invitee_email VARCHAR(255) NOT NULL, role VARCHAR(50) NOT NULL, invitation_token VARCHAR(255) UNIQUE NOT NULL, status VARCHAR(50) DEFAULT 'pending', expires_at TIMESTAMP, accepted_at TIMESTAMP, created_at TIMESTAMP NOT NULL DEFAULT NOW() ); CREATE INDEX idx_invitations_workspace ON workspace_invitations(workspace_id); CREATE INDEX idx_invitations_token ON workspace_invitations(invitation_token); CREATE INDEX idx_invitations_workspace_email ON workspace_invitations(workspace_id, invitee_email, status); -- 项目表(占位,后续 Phase 完善) CREATE TABLE IF NOT EXISTS projects ( id VARCHAR(255) PRIMARY KEY, workspace_id VARCHAR(255) NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE, name VARCHAR(255) NOT NULL, description TEXT, created_at TIMESTAMP NOT NULL DEFAULT NOW() ); CREATE INDEX idx_projects_workspace ON projects(workspace_id);