- Add MacroFile type to internal/kc and extract silo/macros/* files
from .kc ZIP archives on commit
- Create ItemMacroRepository with ReplaceForItem, ListByItem, and
GetByFilename methods
- Add GET /{partNumber}/macros (list) and
GET /{partNumber}/macros/{filename} (source content) endpoints
- Index macros in extractKCMetadata with SSE broadcast
- List endpoint omits content for lightweight responses
Closes #144
96 lines
2.7 KiB
Go
96 lines
2.7 KiB
Go
package api
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"github.com/go-chi/chi/v5"
|
|
)
|
|
|
|
// MacroListItem is the JSON representation for GET /macros list entries.
|
|
type MacroListItem struct {
|
|
Filename string `json:"filename"`
|
|
Trigger string `json:"trigger"`
|
|
RevisionNumber int `json:"revision_number"`
|
|
}
|
|
|
|
// MacroResponse is the JSON representation for GET /macros/{filename}.
|
|
type MacroResponse struct {
|
|
Filename string `json:"filename"`
|
|
Trigger string `json:"trigger"`
|
|
Content string `json:"content"`
|
|
RevisionNumber int `json:"revision_number"`
|
|
}
|
|
|
|
// HandleGetMacros returns the list of registered macros for an item.
|
|
// GET /api/items/{partNumber}/macros
|
|
func (s *Server) HandleGetMacros(w http.ResponseWriter, r *http.Request) {
|
|
ctx := r.Context()
|
|
partNumber := chi.URLParam(r, "partNumber")
|
|
|
|
item, err := s.items.GetByPartNumber(ctx, partNumber)
|
|
if err != nil {
|
|
s.logger.Error().Err(err).Msg("failed to get item")
|
|
writeError(w, http.StatusInternalServerError, "internal_error", "Failed to get item")
|
|
return
|
|
}
|
|
if item == nil {
|
|
writeError(w, http.StatusNotFound, "not_found", "Item not found")
|
|
return
|
|
}
|
|
|
|
macros, err := s.macros.ListByItem(ctx, item.ID)
|
|
if err != nil {
|
|
s.logger.Error().Err(err).Msg("failed to list macros")
|
|
writeError(w, http.StatusInternalServerError, "internal_error", "Failed to list macros")
|
|
return
|
|
}
|
|
|
|
resp := make([]MacroListItem, len(macros))
|
|
for i, m := range macros {
|
|
resp[i] = MacroListItem{
|
|
Filename: m.Filename,
|
|
Trigger: m.Trigger,
|
|
RevisionNumber: m.RevisionNumber,
|
|
}
|
|
}
|
|
|
|
writeJSON(w, http.StatusOK, resp)
|
|
}
|
|
|
|
// HandleGetMacro returns a single macro's source content.
|
|
// GET /api/items/{partNumber}/macros/{filename}
|
|
func (s *Server) HandleGetMacro(w http.ResponseWriter, r *http.Request) {
|
|
ctx := r.Context()
|
|
partNumber := chi.URLParam(r, "partNumber")
|
|
filename := chi.URLParam(r, "filename")
|
|
|
|
item, err := s.items.GetByPartNumber(ctx, partNumber)
|
|
if err != nil {
|
|
s.logger.Error().Err(err).Msg("failed to get item")
|
|
writeError(w, http.StatusInternalServerError, "internal_error", "Failed to get item")
|
|
return
|
|
}
|
|
if item == nil {
|
|
writeError(w, http.StatusNotFound, "not_found", "Item not found")
|
|
return
|
|
}
|
|
|
|
macro, err := s.macros.GetByFilename(ctx, item.ID, filename)
|
|
if err != nil {
|
|
s.logger.Error().Err(err).Msg("failed to get macro")
|
|
writeError(w, http.StatusInternalServerError, "internal_error", "Failed to get macro")
|
|
return
|
|
}
|
|
if macro == nil {
|
|
writeError(w, http.StatusNotFound, "not_found", "Macro not found")
|
|
return
|
|
}
|
|
|
|
writeJSON(w, http.StatusOK, MacroResponse{
|
|
Filename: macro.Filename,
|
|
Trigger: macro.Trigger,
|
|
Content: macro.Content,
|
|
RevisionNumber: macro.RevisionNumber,
|
|
})
|
|
}
|