Files
core/internal/api/assets_components.go

162 lines
4.3 KiB
Go

package api
import (
"net/http"
"strings"
"reanimator/internal/history"
"reanimator/internal/repository/registry"
"reanimator/internal/repository/timeline"
)
type AssetComponentDependencies struct {
Assets *registry.AssetRepository
Components *registry.ComponentRepository
Installations *registry.InstallationRepository
Timeline *timeline.EventRepository
History *history.Service
}
type assetComponentHandlers struct {
deps AssetComponentDependencies
}
func RegisterAssetComponentRoutes(mux *http.ServeMux, deps AssetComponentDependencies) {
h := assetComponentHandlers{deps: deps}
mux.HandleFunc("/api/assets/", h.handleAssetAPI)
mux.HandleFunc("/api/components/search-lite", h.handleComponentSearchLite)
mux.HandleFunc("/assets/", h.handleAsset)
mux.HandleFunc("/components/", h.handleComponent)
}
func (h assetComponentHandlers) handleAsset(w http.ResponseWriter, r *http.Request) {
if strings.HasSuffix(r.URL.Path, "/timeline") {
if r.Method != http.MethodGet {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
if h.deps.Timeline == nil {
if h.deps.History == nil {
writeError(w, http.StatusInternalServerError, "timeline unavailable")
return
}
}
if h.deps.History != nil {
id := parseTimelineID(r.URL.Path, "/assets/")
if id == "" {
writeError(w, http.StatusNotFound, "asset timeline not found")
return
}
historyHandlers{deps: HistoryDependencies{Service: h.deps.History}}.handleTimeline(w, r, "asset", id)
return
}
id := parseTimelineID(r.URL.Path, "/assets/")
if id == "" {
writeError(w, http.StatusNotFound, "asset timeline not found")
return
}
writeTimelineResponse(w, r, h.deps.Timeline, "asset", id)
return
}
if strings.HasSuffix(r.URL.Path, "/components") {
if r.Method != http.MethodGet {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
if h.deps.Installations == nil {
writeError(w, http.StatusInternalServerError, "installations unavailable")
return
}
id, ok := parseSubresourceID(r.URL.Path, "/assets/", "/components")
if !ok {
writeError(w, http.StatusNotFound, "asset components not found")
return
}
items, err := h.deps.Installations.ListCurrentComponentsByAsset(r.Context(), id)
if err != nil {
writeError(w, http.StatusInternalServerError, "list components failed")
return
}
writeJSON(w, http.StatusOK, map[string]any{"items": items})
return
}
if r.Method != http.MethodGet {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
id, ok := parseID(r.URL.Path, "/assets/")
if !ok {
writeError(w, http.StatusNotFound, "asset not found")
return
}
item, err := h.deps.Assets.Get(r.Context(), id)
if err != nil {
switch err {
case registry.ErrNotFound:
writeError(w, http.StatusNotFound, "asset not found")
default:
writeError(w, http.StatusInternalServerError, "get asset failed")
}
return
}
writeJSON(w, http.StatusOK, item)
}
func (h assetComponentHandlers) handleComponent(w http.ResponseWriter, r *http.Request) {
if strings.HasSuffix(r.URL.Path, "/timeline") {
if r.Method != http.MethodGet {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
if h.deps.Timeline == nil {
if h.deps.History == nil {
writeError(w, http.StatusInternalServerError, "timeline unavailable")
return
}
}
if h.deps.History != nil {
id := parseTimelineID(r.URL.Path, "/components/")
if id == "" {
writeError(w, http.StatusNotFound, "component timeline not found")
return
}
historyHandlers{deps: HistoryDependencies{Service: h.deps.History}}.handleTimeline(w, r, "component", id)
return
}
id := parseTimelineID(r.URL.Path, "/components/")
if id == "" {
writeError(w, http.StatusNotFound, "component timeline not found")
return
}
writeTimelineResponse(w, r, h.deps.Timeline, "component", id)
return
}
if r.Method != http.MethodGet {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
id, ok := parseID(r.URL.Path, "/components/")
if !ok {
writeError(w, http.StatusNotFound, "component not found")
return
}
item, err := h.deps.Components.Get(r.Context(), id)
if err != nil {
switch err {
case registry.ErrNotFound:
writeError(w, http.StatusNotFound, "component not found")
default:
writeError(w, http.StatusInternalServerError, "get component failed")
}
return
}
writeJSON(w, http.StatusOK, item)
}