package vault import ( "fmt" "os" "path/filepath" "verstak/internal/core/config" "verstak/internal/core/storage" "verstak/internal/core/util" ) const currentVaultVersion = 1 // Init creates a vault directory structure at vaultRoot. // Calling Init on an already-initialized vault is safe. func Init(vaultRoot string) error { vaultRoot = filepath.Clean(vaultRoot) dirs := []string{ filepath.Join(vaultRoot, ".verstak"), filepath.Join(vaultRoot, ".verstak", "trash"), filepath.Join(vaultRoot, ".verstak", "history"), filepath.Join(vaultRoot, ".verstak", "originals"), filepath.Join(vaultRoot, ".verstak", "thumbnails"), filepath.Join(vaultRoot, ".verstak", "blobs"), filepath.Join(vaultRoot, "spaces"), } for _, d := range dirs { if err := os.MkdirAll(d, 0o750); err != nil { return fmt.Errorf("create %s: %w", d, err) } } cfgPath := filepath.Join(vaultRoot, ".verstak", "config.yml") if _, err := os.Stat(cfgPath); os.IsNotExist(err) { cfg := &config.Config{ Engine: config.EngineConfig{ Version: currentVaultVersion, VaultID: util.UUID7(), }, Sync: config.SyncConfig{ AutoSync: false, }, Browser: config.BrowserConfig{ Enabled: false, LocalPort: 47731, }, } if err := config.Save(vaultRoot, cfg); err != nil { return fmt.Errorf("write config: %w", err) } } dbPath := filepath.Join(vaultRoot, ".verstak", "index.db") if _, err := os.Stat(dbPath); os.IsNotExist(err) { db, err := storage.Open(dbPath) if err != nil { return fmt.Errorf("create db: %w", err) } db.Close() } return nil }