refactor: Remove database migrations for clean dev-phase bootstrap (#176)

This commit is contained in:
João Salavisa
2026-02-04 10:43:14 +00:00
committed by GitHub
parent e5cd199447
commit 604401aaf4
6 changed files with 4 additions and 198 deletions
-1
View File
@@ -188,7 +188,6 @@ kandev/
│ │ └── Makefile
│ └── web/ # Frontend application
├── docs/ # Architecture and planning docs
├── migrations/ # Database migrations (future)
├── deployments/ # Deployment configs
└── scripts/ # Utility scripts (including e2e-test.sh)
```
@@ -58,6 +58,7 @@ func (r *sqliteRepository) initSchema() error {
auto_approve INTEGER NOT NULL DEFAULT 0,
dangerously_skip_permissions INTEGER NOT NULL DEFAULT 0,
allow_indexing INTEGER NOT NULL DEFAULT 1,
cli_passthrough INTEGER NOT NULL DEFAULT 0,
plan TEXT DEFAULT '',
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
@@ -80,19 +81,7 @@ func (r *sqliteRepository) initSchema() error {
CREATE INDEX IF NOT EXISTS idx_agent_profiles_agent_id ON agent_profiles(agent_id);
`
_, err := r.db.Exec(schema)
if err != nil {
return err
}
if err := sqlite.EnsureColumn(r.db, "agent_profiles", "deleted_at", "DATETIME"); err != nil {
return err
}
if err := sqlite.EnsureColumn(r.db, "agent_profiles", "agent_display_name", "TEXT NOT NULL DEFAULT ''"); err != nil {
return err
}
if err := sqlite.EnsureColumn(r.db, "agent_profiles", "cli_passthrough", "INTEGER NOT NULL DEFAULT 0"); err != nil {
return err
}
return nil
return err
}
func (r *sqliteRepository) Close() error {
+1 -56
View File
@@ -72,21 +72,7 @@ func (r *sqliteRepository) initSchema() error {
);
`
_, err := r.db.Exec(schema)
if err != nil {
return err
}
columns := []columnDef{
{name: "name", typ: "TEXT", defaultValue: "''"},
{name: "kind", typ: "TEXT", defaultValue: "'built_in'"},
{name: "config", typ: "TEXT", defaultValue: "NULL"},
{name: "installed", typ: "INTEGER", defaultValue: "0"},
}
for _, column := range columns {
if err := ensureColumn(r.db, "editors", column); err != nil {
return err
}
}
return nil
return err
}
func (r *sqliteRepository) ensureDefaults(ctx context.Context) error {
@@ -319,47 +305,6 @@ func scanEditor(scanner interface{ Scan(dest ...any) error }) (*models.Editor, e
return editor, nil
}
type columnDef struct {
name string
typ string
defaultValue string
}
func ensureColumn(db *sql.DB, table string, column columnDef) error {
rows, err := db.Query(fmt.Sprintf("PRAGMA table_info(%s)", table))
if err != nil {
return err
}
defer func() {
_ = rows.Close()
}()
for rows.Next() {
var (
cid int
name string
typ string
notNull int
defaultVal sql.NullString
pk int
)
if err := rows.Scan(&cid, &name, &typ, &notNull, &defaultVal, &pk); err != nil {
return err
}
if name == column.name {
return nil
}
}
alter := fmt.Sprintf(
"ALTER TABLE %s ADD COLUMN %s %s DEFAULT %s",
table,
column.name,
column.typ,
column.defaultValue,
)
_, err = db.Exec(alter)
return err
}
func marshalConfig(config json.RawMessage) (string, error) {
if len(config) == 0 {
return "", nil
@@ -4,8 +4,6 @@ package sqlite
import (
"database/sql"
"fmt"
commonsqlite "github.com/kandev/kandev/internal/common/sqlite"
)
// Repository provides SQLite-based task storage operations.
@@ -45,11 +43,6 @@ func (r *Repository) DB() *sql.DB {
return r.db
}
// ensureColumn adds a column to a table if it doesn't exist
func (r *Repository) ensureColumn(table, column, definition string) error {
return commonsqlite.EnsureColumn(r.db, table, column, definition)
}
// ensureWorkspaceIndexes creates workspace-related indexes
func (r *Repository) ensureWorkspaceIndexes() error {
if _, err := r.db.Exec(`CREATE INDEX IF NOT EXISTS idx_tasks_workspace_id ON tasks(workspace_id)`); err != nil {
@@ -129,6 +122,7 @@ func (r *Repository) initSchema() error {
CREATE TABLE IF NOT EXISTS boards (
id TEXT PRIMARY KEY,
workspace_id TEXT NOT NULL DEFAULT '',
workflow_template_id TEXT DEFAULT '',
name TEXT NOT NULL,
description TEXT DEFAULT '',
created_at DATETIME NOT NULL,
@@ -372,88 +366,6 @@ func (r *Repository) initSchema() error {
return err
}
// Ensure columns exist for schema migrations
if err := r.ensureColumn("boards", "workspace_id", "TEXT NOT NULL DEFAULT ''"); err != nil {
return err
}
if err := r.ensureColumn("boards", "workflow_template_id", "TEXT DEFAULT ''"); err != nil {
return err
}
if err := r.ensureColumn("tasks", "workspace_id", "TEXT NOT NULL DEFAULT ''"); err != nil {
return err
}
if err := r.ensureColumn("workspaces", "default_executor_id", "TEXT DEFAULT ''"); err != nil {
return err
}
if err := r.ensureColumn("workspaces", "default_environment_id", "TEXT DEFAULT ''"); err != nil {
return err
}
if err := r.ensureColumn("workspaces", "default_agent_profile_id", "TEXT DEFAULT ''"); err != nil {
return err
}
if err := r.ensureColumn("environments", "is_system", "INTEGER NOT NULL DEFAULT 0"); err != nil {
return err
}
if err := r.ensureColumn("repositories", "deleted_at", "DATETIME"); err != nil {
return err
}
if err := r.ensureColumn("repositories", "worktree_branch_prefix", "TEXT DEFAULT 'feature/'"); err != nil {
return err
}
if err := r.ensureColumn("repositories", "pull_before_worktree", "INTEGER NOT NULL DEFAULT 1"); err != nil {
return err
}
if err := r.ensureColumn("repositories", "dev_script", "TEXT DEFAULT ''"); err != nil {
return err
}
if err := r.ensureColumn("executors", "deleted_at", "DATETIME"); err != nil {
return err
}
if err := r.ensureColumn("executors", "resumable", "INTEGER NOT NULL DEFAULT 1"); err != nil {
return err
}
if err := r.ensureColumn("environments", "deleted_at", "DATETIME"); err != nil {
return err
}
// Ensure new message columns exist for existing databases
if err := r.ensureColumn("task_session_messages", "type", "TEXT NOT NULL DEFAULT 'message'"); err != nil {
return err
}
if err := r.ensureColumn("task_session_messages", "metadata", "TEXT DEFAULT '{}'"); err != nil {
return err
}
if err := r.ensureColumn("task_session_messages", "task_session_id", "TEXT NOT NULL DEFAULT ''"); err != nil {
return err
}
if err := r.ensureColumn("task_session_messages", "turn_id", "TEXT DEFAULT ''"); err != nil {
return err
}
// Ensure container_id column exists for existing databases
if err := r.ensureColumn("task_sessions", "container_id", "TEXT NOT NULL DEFAULT ''"); err != nil {
return err
}
if err := r.ensureColumn("task_sessions", "executor_id", "TEXT DEFAULT ''"); err != nil {
return err
}
if err := r.ensureColumn("task_sessions", "environment_id", "TEXT DEFAULT ''"); err != nil {
return err
}
if err := r.ensureColumn("task_sessions", "state", "TEXT NOT NULL DEFAULT 'CREATED'"); err != nil {
return err
}
if err := r.ensureColumn("task_sessions", "is_primary", "INTEGER DEFAULT 0"); err != nil {
return err
}
if err := r.ensureColumn("task_sessions", "workflow_step_id", "TEXT DEFAULT ''"); err != nil {
return err
}
if err := r.ensureColumn("task_sessions", "review_status", "TEXT DEFAULT ''"); err != nil {
return err
}
if err := r.ensureDefaultWorkspace(); err != nil {
return err
}
@@ -7,7 +7,6 @@ import (
"fmt"
"time"
"github.com/kandev/kandev/internal/common/sqlite"
"github.com/kandev/kandev/internal/user/models"
)
@@ -53,17 +52,10 @@ func (r *sqliteRepository) initSchema() error {
if _, err := r.db.Exec(schema); err != nil {
return err
}
if err := r.ensureUserSettingsColumn(); err != nil {
return err
}
return r.ensureDefaultUser()
}
func (r *sqliteRepository) ensureUserSettingsColumn() error {
return sqlite.EnsureColumn(r.db, "users", "settings", "TEXT NOT NULL DEFAULT '{}'")
}
func (r *sqliteRepository) ensureDefaultUser() error {
ctx := context.Background()
var count int
@@ -33,11 +33,6 @@ func (r *Repository) DB() *sql.DB {
return r.db
}
// ensureColumn adds a column to a table if it doesn't exist.
func (r *Repository) ensureColumn(table, column, definition string) error {
return sqlite.EnsureColumn(r.db, table, column, definition)
}
// initSchema creates the database tables if they don't exist.
func (r *Repository) initSchema() error {
// Create workflow_templates table
@@ -102,11 +97,6 @@ func (r *Repository) initSchema() error {
return fmt.Errorf("failed to create session_step_history table: %w", err)
}
// Run migrations for existing tables
if err := r.runMigrations(); err != nil {
return fmt.Errorf("failed to run migrations: %w", err)
}
// Seed system templates
if err := r.seedSystemTemplates(); err != nil {
return fmt.Errorf("failed to seed system templates: %w", err)
@@ -120,27 +110,6 @@ func (r *Repository) initSchema() error {
return nil
}
// runMigrations adds columns to existing tables.
func (r *Repository) runMigrations() error {
// Add workflow_template_id to boards table
if err := r.ensureColumn("boards", "workflow_template_id", "TEXT"); err != nil {
return fmt.Errorf("failed to add workflow_template_id to boards: %w", err)
}
// Add workflow-related columns to task_sessions table
if err := r.ensureColumn("task_sessions", "is_primary", "INTEGER DEFAULT 0"); err != nil {
return fmt.Errorf("failed to add is_primary to task_sessions: %w", err)
}
if err := r.ensureColumn("task_sessions", "workflow_step_id", "TEXT"); err != nil {
return fmt.Errorf("failed to add workflow_step_id to task_sessions: %w", err)
}
if err := r.ensureColumn("task_sessions", "review_status", "TEXT"); err != nil {
return fmt.Errorf("failed to add review_status to task_sessions: %w", err)
}
return nil
}
// seedDefaultWorkflowSteps creates default workflow steps for boards that don't have any.
// Uses the simple template as the default workflow.
func (r *Repository) seedDefaultWorkflowSteps() error {