]> git.frustrated-labs.net Git - squad-rotation-bot.git/commitdiff
feat: add API endpoints to list and create squad members
authorAlexander Goussas <[email protected]>
Fri, 31 Oct 2025 03:57:11 +0000 (22:57 -0500)
committerAlexander Goussas <[email protected]>
Sun, 2 Nov 2025 00:42:31 +0000 (19:42 -0500)
api/routes.go [new file with mode: 0644]
main.go
services/member_service.go

diff --git a/api/routes.go b/api/routes.go
new file mode 100644 (file)
index 0000000..bf52164
--- /dev/null
@@ -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 f2b5a21c5986d8dc69525bf8576d766896a7d8fe..0c76f26bd92b287c9cc5a1021488a8a91179a4b3 100644 (file)
--- 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)
index 7f3a70d2514e763289a2c10c5cc3b10483e838b8..087f480eccab9d8ebda9fc5e08c08111e8b89d8c 100644 (file)
@@ -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)