package store import ( "database/sql" "errors" "fmt" "github.com/google/uuid" ) // CreateStandaloneProxy inserts a new standalone proxy record. func (s *Store) CreateStandaloneProxy(p StandaloneProxy) (StandaloneProxy, error) { p.ID = uuid.New().String() p.CreatedAt = Now() p.UpdatedAt = p.CreatedAt if p.HealthStatus == "" { p.HealthStatus = "unknown" } _, err := s.db.Exec( `INSERT INTO standalone_proxies (id, domain, destination_url, destination_port, ssl_certificate_id, npm_proxy_id, health_status, health_checked_at, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, p.ID, p.Domain, p.DestinationURL, p.DestinationPort, p.SSLCertificateID, p.NpmProxyID, p.HealthStatus, p.HealthCheckedAt, p.CreatedAt, p.UpdatedAt, ) if err != nil { return StandaloneProxy{}, fmt.Errorf("insert standalone proxy: %w", err) } return p, nil } // GetStandaloneProxy returns a standalone proxy by ID. func (s *Store) GetStandaloneProxy(id string) (StandaloneProxy, error) { var p StandaloneProxy err := s.db.QueryRow( `SELECT id, domain, destination_url, destination_port, ssl_certificate_id, npm_proxy_id, health_status, health_checked_at, created_at, updated_at FROM standalone_proxies WHERE id = ?`, id, ).Scan(&p.ID, &p.Domain, &p.DestinationURL, &p.DestinationPort, &p.SSLCertificateID, &p.NpmProxyID, &p.HealthStatus, &p.HealthCheckedAt, &p.CreatedAt, &p.UpdatedAt) if errors.Is(err, sql.ErrNoRows) { return StandaloneProxy{}, fmt.Errorf("standalone proxy %s: %w", id, ErrNotFound) } if err != nil { return StandaloneProxy{}, fmt.Errorf("query standalone proxy: %w", err) } return p, nil } // ListStandaloneProxies returns all standalone proxy records ordered by creation time. func (s *Store) ListStandaloneProxies() ([]StandaloneProxy, error) { rows, err := s.db.Query( `SELECT id, domain, destination_url, destination_port, ssl_certificate_id, npm_proxy_id, health_status, health_checked_at, created_at, updated_at FROM standalone_proxies ORDER BY created_at DESC`, ) if err != nil { return nil, fmt.Errorf("query standalone proxies: %w", err) } defer rows.Close() proxies := []StandaloneProxy{} for rows.Next() { var p StandaloneProxy if err := rows.Scan(&p.ID, &p.Domain, &p.DestinationURL, &p.DestinationPort, &p.SSLCertificateID, &p.NpmProxyID, &p.HealthStatus, &p.HealthCheckedAt, &p.CreatedAt, &p.UpdatedAt); err != nil { return nil, fmt.Errorf("scan standalone proxy: %w", err) } proxies = append(proxies, p) } return proxies, rows.Err() } // UpdateStandaloneProxy updates an existing standalone proxy's mutable fields. func (s *Store) UpdateStandaloneProxy(p StandaloneProxy) error { p.UpdatedAt = Now() result, err := s.db.Exec( `UPDATE standalone_proxies SET domain=?, destination_url=?, destination_port=?, ssl_certificate_id=?, npm_proxy_id=?, health_status=?, health_checked_at=?, updated_at=? WHERE id=?`, p.Domain, p.DestinationURL, p.DestinationPort, p.SSLCertificateID, p.NpmProxyID, p.HealthStatus, p.HealthCheckedAt, p.UpdatedAt, p.ID, ) if err != nil { return fmt.Errorf("update standalone proxy: %w", err) } n, _ := result.RowsAffected() if n == 0 { return fmt.Errorf("standalone proxy %s: %w", p.ID, ErrNotFound) } return nil } // DeleteStandaloneProxy removes a standalone proxy by ID. func (s *Store) DeleteStandaloneProxy(id string) error { result, err := s.db.Exec(`DELETE FROM standalone_proxies WHERE id = ?`, id) if err != nil { return fmt.Errorf("delete standalone proxy: %w", err) } n, _ := result.RowsAffected() if n == 0 { return fmt.Errorf("standalone proxy %s: %w", id, ErrNotFound) } return nil } // UpdateProxyHealth updates the health status and check timestamp for a standalone proxy. func (s *Store) UpdateProxyHealth(id string, status string) error { ts := Now() result, err := s.db.Exec( `UPDATE standalone_proxies SET health_status=?, health_checked_at=?, updated_at=? WHERE id=?`, status, ts, ts, id, ) if err != nil { return fmt.Errorf("update proxy health: %w", err) } n, _ := result.RowsAffected() if n == 0 { return fmt.Errorf("standalone proxy %s: %w", id, ErrNotFound) } return nil }