feat: volume scopes redesign — replace shared/isolated with 6 scopes

Replace confusing shared/isolated volume modes with explicit scopes:
- instance: per-deploy isolated directory
- stage: shared within a stage across deploys
- project: shared across all stages
- project_named: named group within a project
- named: global named volume across projects
- ephemeral: tmpfs in-memory mount

Includes schema migration (shared→project, isolated→instance),
backward-compatible deployer resolution, scope metadata API endpoint,
and redesigned volume editor UI with scope guide cards and hints.
This commit is contained in:
2026-03-31 23:22:43 +03:00
parent 1a8dfefa77
commit 8fb959f81f
12 changed files with 424 additions and 112 deletions
+9
View File
@@ -85,6 +85,9 @@ func (s *Store) runMigrations() error {
`ALTER TABLE settings ADD COLUMN stale_threshold_days INTEGER NOT NULL DEFAULT 7`,
// Add last_alive_at to instances for stale container detection (2026-03-30).
`ALTER TABLE instances ADD COLUMN last_alive_at TEXT NOT NULL DEFAULT ''`,
// Add name column and rename mode→scope for volume scopes redesign (2026-03-31).
`ALTER TABLE volumes ADD COLUMN name TEXT NOT NULL DEFAULT ''`,
`ALTER TABLE volumes ADD COLUMN scope TEXT NOT NULL DEFAULT ''`,
}
for _, m := range migrations {
@@ -112,6 +115,12 @@ func (s *Store) runMigrations() error {
}
}
// Data migration: copy mode→scope for volumes that have scope still empty.
// shared→project, isolated→instance.
_, _ = s.db.Exec(`UPDATE volumes SET scope = 'project' WHERE scope = '' AND mode = 'shared'`)
_, _ = s.db.Exec(`UPDATE volumes SET scope = 'instance' WHERE scope = '' AND mode = 'isolated'`)
_, _ = s.db.Exec(`UPDATE volumes SET scope = 'project' WHERE scope = '' AND mode = ''`)
return nil
}