package api import ( "encoding/json" "errors" "net/http" "net/mail" "github.com/alchemistkay/guestguard/internal/domain" "github.com/alchemistkay/guestguard/internal/storage" ) type userHandler struct { repo *storage.UserRepo } type upsertUserRequest struct { Email string `json:"email"` Name string `json:"name"` } // POST /users — idempotent: returns the existing user if the email already // exists, creates one otherwise. This keeps the demo flow simple without // requiring real auth. func (h *userHandler) upsert(w http.ResponseWriter, r *http.Request) { var req upsertUserRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { writeError(w, http.StatusBadRequest, "invalid json") return } if _, err := mail.ParseAddress(req.Email); err != nil { writeError(w, http.StatusBadRequest, "email is invalid") return } if req.Name == "" { writeError(w, http.StatusBadRequest, "name is required") return } u, err := h.repo.Create(r.Context(), req.Email, req.Name) if err == nil { writeJSON(w, http.StatusCreated, u) return } if errors.Is(err, domain.ErrEmailTaken) { existing, getErr := h.repo.GetByEmail(r.Context(), req.Email) if getErr != nil { writeError(w, http.StatusInternalServerError, "failed to load user") return } writeJSON(w, http.StatusOK, existing) return } writeError(w, http.StatusInternalServerError, "failed to create user") }