feat(07-01): add quick-add HTTP handlers and route registration

- Add ListQuickAddItems, CreateQuickAddItem, UpdateQuickAddItem, DeleteQuickAddItem handler methods
- Register GET/POST /api/quick-add and PUT/DELETE /api/quick-add/{itemId} in authenticated route group
- Validate name non-empty on create and update; return 404 on update when item not found
This commit is contained in:
2026-03-12 13:34:19 +01:00
parent 84d5b76a8a
commit b42f7b13bb
2 changed files with 89 additions and 0 deletions

View File

@@ -636,6 +636,88 @@ func (h *Handlers) GenerateBudget(w http.ResponseWriter, r *http.Request) {
writeJSON(w, http.StatusCreated, detail)
}
// Quick Add Item Handlers
func (h *Handlers) ListQuickAddItems(w http.ResponseWriter, r *http.Request) {
userID := auth.UserIDFromContext(r.Context())
items, err := h.queries.ListQuickAddItems(r.Context(), userID)
if err != nil {
writeError(w, http.StatusInternalServerError, "failed to list quick add items")
return
}
writeJSON(w, http.StatusOK, items)
}
func (h *Handlers) CreateQuickAddItem(w http.ResponseWriter, r *http.Request) {
userID := auth.UserIDFromContext(r.Context())
var req struct {
Name string `json:"name"`
Icon string `json:"icon"`
}
if err := decodeJSON(r, &req); err != nil {
writeError(w, http.StatusBadRequest, "invalid request body")
return
}
if req.Name == "" {
writeError(w, http.StatusBadRequest, "name is required")
return
}
item, err := h.queries.CreateQuickAddItem(r.Context(), userID, req.Name, req.Icon)
if err != nil {
writeError(w, http.StatusInternalServerError, "failed to create quick add item")
return
}
writeJSON(w, http.StatusCreated, item)
}
func (h *Handlers) UpdateQuickAddItem(w http.ResponseWriter, r *http.Request) {
userID := auth.UserIDFromContext(r.Context())
itemID, err := parseUUID(chi.URLParam(r, "itemId"))
if err != nil {
writeError(w, http.StatusBadRequest, "invalid item id")
return
}
var req struct {
Name string `json:"name"`
Icon string `json:"icon"`
SortOrder int `json:"sort_order"`
}
if err := decodeJSON(r, &req); err != nil {
writeError(w, http.StatusBadRequest, "invalid request body")
return
}
if req.Name == "" {
writeError(w, http.StatusBadRequest, "name is required")
return
}
item, err := h.queries.UpdateQuickAddItem(r.Context(), itemID, userID, req.Name, req.Icon, req.SortOrder)
if err != nil {
writeError(w, http.StatusNotFound, "quick add item not found")
return
}
writeJSON(w, http.StatusOK, item)
}
func (h *Handlers) DeleteQuickAddItem(w http.ResponseWriter, r *http.Request) {
userID := auth.UserIDFromContext(r.Context())
itemID, err := parseUUID(chi.URLParam(r, "itemId"))
if err != nil {
writeError(w, http.StatusBadRequest, "invalid item id")
return
}
if err := h.queries.DeleteQuickAddItem(r.Context(), itemID, userID); err != nil {
writeError(w, http.StatusInternalServerError, "failed to delete quick add item")
return
}
w.WriteHeader(http.StatusNoContent)
}
// Settings Handlers
func (h *Handlers) GetSettings(w http.ResponseWriter, r *http.Request) {

View File

@@ -70,6 +70,13 @@ func NewRouter(queries *db.Queries, sessionSecret string, frontendFS fs.FS) http
r.Delete("/items/{itemId}", h.DeleteTemplateItem)
})
r.Route("/api/quick-add", func(r chi.Router) {
r.Get("/", h.ListQuickAddItems)
r.Post("/", h.CreateQuickAddItem)
r.Put("/{itemId}", h.UpdateQuickAddItem)
r.Delete("/{itemId}", h.DeleteQuickAddItem)
})
r.Get("/api/settings", h.GetSettings)
r.Put("/api/settings", h.UpdateSettings)
})