Files
core/internal/api/assets_components.go

161 lines
4.2 KiB
Go

package api
import (
"net/http"
"strings"
"reanimator/internal/repository/registry"
"reanimator/internal/repository/tickets"
"reanimator/internal/repository/timeline"
)
type AssetComponentDependencies struct {
Assets *registry.AssetRepository
Components *registry.ComponentRepository
Installations *registry.InstallationRepository
Tickets *tickets.TicketRepository
Timeline *timeline.EventRepository
}
type assetComponentHandlers struct {
deps AssetComponentDependencies
}
func RegisterAssetComponentRoutes(mux *http.ServeMux, deps AssetComponentDependencies) {
h := assetComponentHandlers{deps: deps}
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 {
writeError(w, http.StatusInternalServerError, "timeline unavailable")
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 strings.HasSuffix(r.URL.Path, "/tickets") {
if r.Method != http.MethodGet {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
if h.deps.Tickets == nil {
writeError(w, http.StatusInternalServerError, "tickets unavailable")
return
}
id, ok := parseSubresourceID(r.URL.Path, "/assets/", "/tickets")
if !ok {
writeError(w, http.StatusNotFound, "asset tickets not found")
return
}
items, err := h.deps.Tickets.ListByAsset(r.Context(), id)
if err != nil {
writeError(w, http.StatusInternalServerError, "list tickets 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 {
writeError(w, http.StatusInternalServerError, "timeline unavailable")
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)
}