aboutsummaryrefslogtreecommitdiff
path: root/internal/admin/api_techs.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/admin/api_techs.go')
-rw-r--r--internal/admin/api_techs.go138
1 files changed, 138 insertions, 0 deletions
diff --git a/internal/admin/api_techs.go b/internal/admin/api_techs.go
new file mode 100644
index 0000000..9b29647
--- /dev/null
+++ b/internal/admin/api_techs.go
@@ -0,0 +1,138 @@
+package admin
+
+import (
+ "net/http"
+ "os"
+ "path/filepath"
+ "strings"
+)
+
+func (s *AdminServer) handleTechs(w http.ResponseWriter, r *http.Request) {
+ switch r.Method {
+ case http.MethodGet:
+ ids, err := listYAMLFiles(s.dataDir, "techs")
+ if err != nil {
+ writeJSON(w, map[string]any{"error": err.Error()})
+ return
+ }
+ if ids == nil {
+ ids = []string{}
+ }
+ writeJSON(w, ids)
+ case http.MethodPost:
+ var m map[string]any
+ if err := readJSON(r, &m); err != nil {
+ writeJSON(w, map[string]any{"error": "invalid json"})
+ return
+ }
+ id, _ := m["id"].(string)
+ if strings.TrimSpace(id) == "" {
+ writeJSON(w, map[string]any{"error": "missing id"})
+ return
+ }
+ delete(m, "id")
+ path := filepath.Join(s.dataDir, "techs", id+".yaml")
+ if _, err := os.Stat(path); err == nil {
+ writeJSON(w, map[string]any{"error": "tech already exists"})
+ return
+ }
+ newContent, err := writeMapAsYAML(path, m)
+ if err != nil {
+ writeJSON(w, map[string]any{"error": "write error: " + err.Error()})
+ return
+ }
+ s.undoStack.Push(ChangeDesc{
+ Description: "Created tech " + id,
+ FilePath: path,
+ NewContent: newContent,
+ IsCreate: true,
+ })
+ writeJSON(w, map[string]any{"ok": true, "id": id})
+ default:
+ http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
+ }
+}
+
+func (s *AdminServer) handleTechByID(w http.ResponseWriter, r *http.Request) {
+ id := strings.TrimPrefix(r.URL.Path, "/api/techs/")
+ if id == "" {
+ http.Error(w, `{"error":"missing id"}`, http.StatusBadRequest)
+ return
+ }
+
+ switch r.Method {
+ case http.MethodGet:
+ data, path, err := findYAMLFileInSubdirs(s.dataDir, "techs", id)
+ if err != nil {
+ writeJSON(w, map[string]any{"error": "not found: " + id})
+ return
+ }
+ raw, err := yamlToMap(data)
+ if err != nil {
+ writeJSON(w, map[string]any{"error": "parse error: " + err.Error()})
+ return
+ }
+ raw["id"] = id
+ raw["_path"] = path
+ raw["_raw"] = string(data)
+ writeJSON(w, raw)
+
+ case http.MethodPost, http.MethodPut:
+ var body map[string]any
+ if err := readJSON(r, &body); err != nil {
+ writeJSON(w, map[string]any{"error": "invalid JSON: " + err.Error()})
+ return
+ }
+ delete(body, "id")
+ delete(body, "_path")
+ delete(body, "_raw")
+
+ path := filepath.Join(s.dataDir, "techs", id+".yaml")
+ var oldContent []byte
+ if existing, err := snapshotFile(path); err == nil {
+ oldContent = existing
+ }
+
+ newContent, err := writeMapAsYAML(path, body)
+ if err != nil {
+ writeJSON(w, map[string]any{"error": "write error: " + err.Error()})
+ return
+ }
+
+ isCreate := oldContent == nil
+ desc := "Updated tech " + id
+ if isCreate {
+ desc = "Created tech " + id
+ }
+ s.undoStack.Push(ChangeDesc{
+ Description: desc,
+ FilePath: path,
+ OldContent: oldContent,
+ NewContent: newContent,
+ IsCreate: isCreate,
+ })
+ writeJSON(w, map[string]any{"ok": true, "id": id})
+
+ case http.MethodDelete:
+ _, path, err := findYAMLFileInSubdirs(s.dataDir, "techs", id)
+ if err != nil {
+ writeJSON(w, map[string]any{"error": "not found: " + id})
+ return
+ }
+ oldContent, _ := snapshotFile(path)
+ if err := os.Remove(path); err != nil {
+ writeJSON(w, map[string]any{"error": "delete error: " + err.Error()})
+ return
+ }
+ s.undoStack.Push(ChangeDesc{
+ Description: "Deleted tech " + id,
+ FilePath: path,
+ OldContent: oldContent,
+ IsDelete: true,
+ })
+ writeJSON(w, map[string]any{"ok": true, "id": id})
+
+ default:
+ http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
+ }
+}