backend barebone done, big chunk of work done
CI / Go (build + vet + test) (push) Canceled after 0s
CI / Web (build + lint) (push) Canceled after 0s

This commit is contained in:
vantablackTea
2026-09-27 19:42:49 +03:00
parent 1a669c948a
commit c79a3cfe68
36 changed files with 2607 additions and 17 deletions
+93
View File
@@ -0,0 +1,93 @@
package api
import (
"encoding/json"
"errors"
"net/http"
"strconv"
"messenger/internal/store"
)
func (h *apiHandler) searchUsers(w http.ResponseWriter, r *http.Request) {
query := r.URL.Query().Get("q")
users, err := h.store.SearchUsers(r.Context(), query, 20)
if err != nil {
writeError(w, http.StatusInternalServerError, "internal server error")
return
}
out := make([]userJSON, 0, len(users))
for i := range users {
out = append(out, toUserJSON(&users[i]))
}
writeJSON(w, http.StatusOK, out)
}
type contactJSON struct {
User userJSON `json:"user"`
AddedAt string `json:"added_at"`
}
func (h *apiHandler) listContacts(w http.ResponseWriter, r *http.Request) {
userID, _ := userIDFrom(r.Context())
contacts, err := h.store.ListContacts(r.Context(), userID)
if err != nil {
writeError(w, http.StatusInternalServerError, "internal server error")
return
}
out := make([]contactJSON, 0, len(contacts))
for _, c := range contacts {
u, err := h.store.GetUserByID(r.Context(), c.ContactID)
if err != nil {
continue
}
out = append(out, contactJSON{User: toUserJSON(u), AddedAt: c.CreatedAt.Format("2006-01-02T15:04:05Z07:00")})
}
writeJSON(w, http.StatusOK, out)
}
func (h *apiHandler) addContact(w http.ResponseWriter, r *http.Request) {
userID, _ := userIDFrom(r.Context())
var req struct {
UserID int64 `json:"user_id"`
}
if err := json.NewDecoder(r.Body).Decode(&req); err != nil || req.UserID <= 0 {
writeError(w, http.StatusBadRequest, "invalid user_id")
return
}
if req.UserID == userID {
writeError(w, http.StatusBadRequest, "cannot add yourself")
return
}
if _, err := h.store.GetUserByID(r.Context(), req.UserID); err != nil {
if errors.Is(err, store.ErrNotFound) {
writeError(w, http.StatusNotFound, "user not found")
return
}
writeError(w, http.StatusInternalServerError, "internal server error")
return
}
if err := h.store.AddContact(r.Context(), userID, req.UserID); err != nil {
if errors.Is(err, store.ErrDuplicate) {
writeJSON(w, http.StatusOK, map[string]string{"status": "already a contact"})
return
}
writeError(w, http.StatusInternalServerError, "internal server error")
return
}
writeJSON(w, http.StatusCreated, map[string]string{"status": "ok"})
}
func (h *apiHandler) removeContact(w http.ResponseWriter, r *http.Request) {
userID, _ := userIDFrom(r.Context())
contactID, err := strconv.ParseInt(r.PathValue("user_id"), 10, 64)
if err != nil || contactID <= 0 {
writeError(w, http.StatusBadRequest, "invalid user_id")
return
}
if err := h.store.RemoveContact(r.Context(), userID, contactID); err != nil {
writeError(w, http.StatusInternalServerError, "internal server error")
return
}
writeJSON(w, http.StatusOK, map[string]string{"status": "ok"})
}