diff --git a/internal/storage/sqlite.go b/internal/storage/sqlite.go index e67c646..e491e8a 100644 --- a/internal/storage/sqlite.go +++ b/internal/storage/sqlite.go @@ -1,6 +1,7 @@ package storage import ( + "context" "database/sql" "encoding/json" "errors" @@ -168,11 +169,10 @@ func (s *Store) migrate() error { CREATE TABLE IF NOT EXISTS teams ( id TEXT PRIMARY KEY, - org_id TEXT NOT NULL, + org_id TEXT NOT NULL DEFAULT 'default', name TEXT NOT NULL, description TEXT NOT NULL DEFAULT '', - created_at TEXT NOT NULL, - FOREIGN KEY(org_id) REFERENCES organizations(id) ON DELETE CASCADE + created_at TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS team_members ( @@ -349,6 +349,32 @@ func (s *Store) migrate() error { ('smtp_from', ''), ('smtp_tls', 'true')`) + // Migrate existing teams table if it still has a legacy FOREIGN KEY to organizations + var teamsTableSQL string + _ = s.db.QueryRow(`SELECT sql FROM sqlite_master WHERE type='table' AND name='teams'`).Scan(&teamsTableSQL) + if strings.Contains(strings.ToUpper(teamsTableSQL), "ORGANIZATIONS") { + if conn, err := s.db.Conn(context.Background()); err == nil { + _, _ = conn.ExecContext(context.Background(), `PRAGMA foreign_keys = OFF;`) + _, _ = conn.ExecContext(context.Background(), ` + BEGIN TRANSACTION; + CREATE TABLE IF NOT EXISTS teams_migrated ( + id TEXT PRIMARY KEY, + org_id TEXT NOT NULL DEFAULT 'default', + name TEXT NOT NULL, + description TEXT NOT NULL DEFAULT '', + created_at TEXT NOT NULL + ); + INSERT OR IGNORE INTO teams_migrated (id, org_id, name, description, created_at) + SELECT id, COALESCE(NULLIF(org_id, ''), 'default'), name, COALESCE(description, ''), created_at FROM teams; + DROP TABLE teams; + ALTER TABLE teams_migrated RENAME TO teams; + COMMIT; + `) + _, _ = conn.ExecContext(context.Background(), `PRAGMA foreign_keys = ON;`) + _ = conn.Close() + } + } + // Reindex block tags if table is newly added or empty var tagCount int _ = s.db.QueryRow(`SELECT COUNT(*) FROM doc_block_tags`).Scan(&tagCount) @@ -3007,6 +3033,18 @@ func (s *Store) CreateTeam(orgID, name, description string) (*domain.Team, error `INSERT INTO teams (id, org_id, name, description, created_at) VALUES (?, ?, ?, ?, ?)`, team.ID, team.OrgID, team.Name, team.Description, team.CreatedAt, ) + if err != nil && strings.Contains(strings.ToUpper(err.Error()), "FOREIGN KEY") { + if conn, connErr := s.db.Conn(context.Background()); connErr == nil { + _, _ = conn.ExecContext(context.Background(), `PRAGMA foreign_keys = OFF;`) + _, err = conn.ExecContext( + context.Background(), + `INSERT INTO teams (id, org_id, name, description, created_at) VALUES (?, ?, ?, ?, ?)`, + team.ID, team.OrgID, team.Name, team.Description, team.CreatedAt, + ) + _, _ = conn.ExecContext(context.Background(), `PRAGMA foreign_keys = ON;`) + _ = conn.Close() + } + } if err != nil { return nil, err }