From: Alexander Goussas Date: Fri, 31 Oct 2025 03:57:11 +0000 (-0500) Subject: feat: add API endpoints to list and create squad members X-Git-Url: http://git.frustrated-labs.net/?a=commitdiff_plain;h=d215944b226ca7103fb8c407e97e0bc1ebf6b9be;p=squad-rotation-bot.git feat: add API endpoints to list and create squad members --- diff --git a/api/routes.go b/api/routes.go new file mode 100644 index 0000000..bf52164 --- /dev/null +++ b/api/routes.go @@ -0,0 +1,74 @@ +package api + +import ( + "encoding/json" + "log" + "net/http" + + "github.com/aloussase/squad-rotation-bot/services" +) + +func ListMembers( + memberService services.MemberService, + w http.ResponseWriter, + r *http.Request, +) { + members, err := memberService.ListMembers() + if err != nil { + log.Printf("Failed to list members: %v", err) + w.WriteHeader(400) + return + } + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(members) +} + +func CreateMember( + memberService services.MemberService, + w http.ResponseWriter, + r *http.Request, +) { + var body struct { + FullName string + AvatarUrl string + } + + err := json.NewDecoder(r.Body).Decode(&body) + if err != nil { + w.WriteHeader(400) + return + } + + err = memberService.CreateMember(body.FullName, body.AvatarUrl) + if err != nil { + log.Printf("Failed to create member: %v", err) + w.WriteHeader(400) + return + } + + w.WriteHeader(201) +} + +func TriggerBot( + memberService services.MemberService, + rotationService services.RotationService, + messagingService services.MessagingService, +) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + members, err := memberService.ListMembers() + if err != nil { + log.Fatalf("There was an error while trying to list members: %s", err) + } + + chosenOne, err := rotationService.ChooseNextInRotation(members) + if err != nil { + log.Fatalf("There was an error while trying to choose next in rotation: %s", err) + } + + if messagingService.SendRotationNotification(chosenOne) != nil { + log.Fatalf("There was an error while trying to send a rotation: %s", err) + } + + log.Printf("Succesfully sent rotation update: %s", chosenOne.FullName) + } +} diff --git a/main.go b/main.go index f2b5a21..0c76f26 100644 --- a/main.go +++ b/main.go @@ -6,6 +6,7 @@ import ( "net/http" "time" + "github.com/aloussase/squad-rotation-bot/api" "github.com/aloussase/squad-rotation-bot/config" "github.com/aloussase/squad-rotation-bot/services" "github.com/jackc/pgx/v5" @@ -45,22 +46,14 @@ func main() { rotationService := services.CreateRotationService(conn) messagingService := services.CreateMessagingService(config) - http.HandleFunc("/api/v1/rotation/trigger", func(w http.ResponseWriter, r *http.Request) { - members, err := memberService.ListMembers() - if err != nil { - log.Fatalf("There was an error while trying to list members: %s", err) + http.HandleFunc("/api/v1/rotation/trigger", api.TriggerBot(memberService, rotationService, messagingService)) + http.HandleFunc("/api/v1/rotation/members", func(w http.ResponseWriter, r *http.Request) { + switch r.Method { + case http.MethodGet: + api.ListMembers(memberService, w, r) + case http.MethodPost: + api.CreateMember(memberService, w, r) } - - chosenOne, err := rotationService.ChooseNextInRotation(members) - if err != nil { - log.Fatalf("There was an error while trying to choose next in rotation: %s", err) - } - - if messagingService.SendRotationNotification(chosenOne) != nil { - log.Fatalf("There was an error while trying to send a rotation: %s", err) - } - - log.Printf("Succesfully sent rotation update: %s", chosenOne.FullName) }) http.ListenAndServe(":8080", nil) diff --git a/services/member_service.go b/services/member_service.go index 7f3a70d..087f480 100644 --- a/services/member_service.go +++ b/services/member_service.go @@ -10,6 +10,9 @@ import ( type MemberService interface { // ListMembers / List all members of the squad. ListMembers() ([]entities.SquadMember, error) + + // Create a new member. + CreateMember(name, avatarUrl string) error } type memberServiceImpl struct { @@ -23,6 +26,12 @@ func Create(conn *pgx.Conn) MemberService { } } +func (ms *memberServiceImpl) CreateMember(name, avatarUrl string) error { + query := "insert into squad_members (full_name, avatar_url) values ($1, $2)" + _, err := ms.conn.Exec(context.Background(), query, name, avatarUrl) + return err +} + func (ms *memberServiceImpl) ListMembers() ([]entities.SquadMember, error) { query := "select (id, full_name, avatar_url) from squad_members" rows, err := ms.conn.Query(context.Background(), query)