server: implement channels
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-chi/render"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
func GetChannel(w http.ResponseWriter, r *http.Request) {
|
||||
slog.Debug("channel: entering GetChannel handler")
|
||||
|
||||
channelID := chi.URLParam(r, "channelID")
|
||||
parsed, err := uuid.Parse(channelID)
|
||||
if err != nil {
|
||||
render.Render(w, r, ErrInvalidRequest(err))
|
||||
return
|
||||
}
|
||||
|
||||
channel, err := dbGetChannel(parsed.String())
|
||||
if err != nil {
|
||||
if errors.Is(err, ErrChannelNotFound) {
|
||||
render.Render(w, r, ErrNotFound)
|
||||
} else {
|
||||
slog.Error("channel: failed to fetch channel", "channelid", parsed.String(), "error", err)
|
||||
render.Render(w, r, ErrInternal(err))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
slog.Debug("channel: rendering channel", "channelid", channel.ID, "channelname", channel.Name)
|
||||
if err := render.Render(w, r, NewChannelPayloadResponse(channel)); err != nil {
|
||||
slog.Error("channel: failed to render channel", "channelid", parsed.String(), "error", err)
|
||||
render.Render(w, r, ErrInternal(err))
|
||||
}
|
||||
}
|
||||
|
||||
func ListChannels(w http.ResponseWriter, r *http.Request) {
|
||||
slog.Debug("channel: entering ListChannels handler")
|
||||
dbChannels, err := dbGetAllChannels()
|
||||
if err != nil {
|
||||
if errors.Is(err, ErrChannelNotFound) {
|
||||
render.Render(w, r, ErrNotFound)
|
||||
} else {
|
||||
slog.Error("channel: failed to fetch channels", "error", err)
|
||||
render.Render(w, r, ErrInternal(err))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
slog.Debug("channel: successfully fetched channels", "count", len(dbChannels))
|
||||
if err := render.RenderList(w, r, NewChannelListResponse(dbChannels)); err != nil {
|
||||
slog.Error("channel: failed to render channel list response", "error", err)
|
||||
render.Render(w, r, ErrInternal(err))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func newChannelID() uuid.UUID {
|
||||
return uuid.New()
|
||||
}
|
||||
|
||||
func NewChannel(w http.ResponseWriter, r *http.Request) {
|
||||
slog.Debug("channel: entering NewChannel handler")
|
||||
err := r.ParseMultipartForm(64 << 10)
|
||||
if err != nil {
|
||||
slog.Error("user: failed to parse multipartform", "error", err)
|
||||
http.Error(w, "Unable to parse form", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
newChannelName := r.FormValue("name")
|
||||
newChannelType := r.FormValue("type")
|
||||
newChannelLocation := r.FormValue("location")
|
||||
newChannelNotes := r.FormValue("notes")
|
||||
if newChannelName == "" {
|
||||
slog.Error("channel: channelname is empty")
|
||||
http.Error(w, "Channel name cannot be empty", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
newChannel := Channel{
|
||||
ID: newChannelID(),
|
||||
Name: newChannelName,
|
||||
Created: time.Now(),
|
||||
Type: newChannelType,
|
||||
Location: newChannelLocation,
|
||||
Notes: newChannelNotes,
|
||||
}
|
||||
|
||||
slog.Debug("channel: adding new channel to database", "channelid", newChannel.ID, "channelname", newChannel.Name)
|
||||
err = dbAddChannel(&newChannel)
|
||||
if err != nil {
|
||||
slog.Error("channel: failed to add new channel", "channelid", newChannel.ID, "channelname", newChannel.Name)
|
||||
render.Render(w, r, ErrInternal(err))
|
||||
return
|
||||
}
|
||||
|
||||
slog.Debug("channel: successfully added new channel", "channelid", newChannel.ID, "channelname", newChannel.Name)
|
||||
render.Render(w, r, NewChannelPayloadResponse(&newChannel))
|
||||
|
||||
}
|
||||
|
||||
func DeleteChannel(w http.ResponseWriter, r *http.Request) {
|
||||
slog.Debug("channel: entering DeleteChannel handler")
|
||||
|
||||
channelID := chi.URLParam(r, "channelID")
|
||||
parsed, err := uuid.Parse(channelID)
|
||||
if err != nil {
|
||||
render.Render(w, r, ErrInvalidRequest(err))
|
||||
return
|
||||
}
|
||||
|
||||
err = dbDeleteChannel(parsed.String())
|
||||
if err != nil {
|
||||
if errors.Is(err, ErrChannelNotFound) {
|
||||
render.Render(w, r, ErrNotFound)
|
||||
} else {
|
||||
slog.Error("channel: failed to delete channel", "channelid", parsed.String(), "error", err)
|
||||
render.Render(w, r, ErrInternal(err))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
slog.Debug("channel: deleted channel", "channelid", parsed.String())
|
||||
w.Write([]byte("Channel deleted successfully"))
|
||||
}
|
||||
|
||||
type Channel struct {
|
||||
ID uuid.UUID
|
||||
Name string
|
||||
Created time.Time
|
||||
Type string
|
||||
Location string
|
||||
Notes string
|
||||
}
|
||||
|
||||
type channelKey struct{}
|
||||
|
||||
type ChannelPayload struct {
|
||||
*Channel
|
||||
}
|
||||
Reference in New Issue
Block a user