198 lines
5.3 KiB
Go
198 lines
5.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, "/imports") {
|
|
if r.Method != http.MethodGet {
|
|
w.WriteHeader(http.StatusMethodNotAllowed)
|
|
return
|
|
}
|
|
if h.deps.Timeline == nil {
|
|
writeError(w, http.StatusInternalServerError, "import history unavailable")
|
|
return
|
|
}
|
|
id, ok := parseSubresourceID(r.URL.Path, "/assets/", "/imports")
|
|
if !ok {
|
|
writeError(w, http.StatusNotFound, "asset import history not found")
|
|
return
|
|
}
|
|
writeImportHistoryResponse(w, r, h.deps.Timeline, "asset", id)
|
|
return
|
|
}
|
|
|
|
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, "/imports") {
|
|
if r.Method != http.MethodGet {
|
|
w.WriteHeader(http.StatusMethodNotAllowed)
|
|
return
|
|
}
|
|
if h.deps.Timeline == nil {
|
|
writeError(w, http.StatusInternalServerError, "import history unavailable")
|
|
return
|
|
}
|
|
id, ok := parseSubresourceID(r.URL.Path, "/components/", "/imports")
|
|
if !ok {
|
|
writeError(w, http.StatusNotFound, "component import history not found")
|
|
return
|
|
}
|
|
writeImportHistoryResponse(w, r, h.deps.Timeline, "component", id)
|
|
return
|
|
}
|
|
|
|
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)
|
|
}
|