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
+8 -3
View File
@@ -20,7 +20,8 @@ import type {
StageEnv,
StandaloneProxy,
ValidationResult,
Volume
Volume,
VolumeScopeInfo
} from './types';
// ── Helpers ─────────────────────────────────────────────────────────
@@ -327,7 +328,7 @@ export function listVolumes(projectId: string): Promise<Volume[]> {
export function createVolume(
projectId: string,
data: { source: string; target: string; mode?: string }
data: { source: string; target: string; scope: string; name?: string; mode?: string }
): Promise<Volume> {
return post<Volume>(`/api/projects/${projectId}/volumes`, data);
}
@@ -335,11 +336,15 @@ export function createVolume(
export function updateVolume(
projectId: string,
volId: string,
data: { source?: string; target?: string; mode?: string }
data: { source?: string; target?: string; scope?: string; name?: string; mode?: string }
): Promise<Volume> {
return put<Volume>(`/api/projects/${projectId}/volumes/${volId}`, data);
}
export function listVolumeScopes(): Promise<VolumeScopeInfo[]> {
return get<VolumeScopeInfo[]>('/api/volumes/scopes');
}
export function deleteVolume(
projectId: string,
volId: string