fix: quick deploy duplicate detection, logout UX, backup toggle, CSP, SSE guard, and migration

- Detect existing projects with same image on quick deploy; show conflict dialog with options
- Move logout button to sidebar header as icon-only
- Replace backup checkbox with ToggleSwitch component
- Allow unsafe-inline in CSP script-src for SvelteKit hydration
- Guard SSE connection behind isAuthenticated() check
- Add notification_url ALTER TABLE migration for existing databases
- Restore RegisterPersistentLogger on event bus
This commit is contained in:
2026-04-04 14:40:59 +03:00
parent 205a5a36c6
commit 6667abf03c
11 changed files with 259 additions and 35 deletions
+22
View File
@@ -63,6 +63,28 @@ func (s *Store) GetAllProjects() ([]Project, error) {
return projects, rows.Err()
}
// GetProjectsByImage returns all projects using the given image, newest first.
func (s *Store) GetProjectsByImage(image string) ([]Project, error) {
rows, err := s.db.Query(
`SELECT id, name, registry, image, port, healthcheck, env, volumes, created_at, updated_at
FROM projects WHERE image = ? ORDER BY created_at DESC`, image,
)
if err != nil {
return nil, fmt.Errorf("query projects by image: %w", err)
}
defer rows.Close()
projects := []Project{}
for rows.Next() {
var p Project
if err := rows.Scan(&p.ID, &p.Name, &p.Registry, &p.Image, &p.Port, &p.Healthcheck, &p.Env, &p.Volumes, &p.CreatedAt, &p.UpdatedAt); err != nil {
return nil, fmt.Errorf("scan project: %w", err)
}
projects = append(projects, p)
}
return projects, rows.Err()
}
// UpdateProject updates an existing project's mutable fields.
func (s *Store) UpdateProject(p Project) error {
p.UpdatedAt = Now()