bottin-ag/apihandler/apihandler.go
2024-02-14 16:48:20 -05:00

216 lines
5.7 KiB
Go

// Package apihandler provides handlers for API routes
package apihandler
import (
"fmt"
"net/http"
"git.agecem.com/agecem/bottin-ag/apiresponse"
"git.agecem.com/agecem/bottin-ag/dbclient"
"git.agecem.com/agecem/bottin-ag/dbstruct"
bottindata "git.agecem.com/agecem/bottin/v6/data"
"github.com/labstack/echo/v4"
)
// DeclareRoutes declares the API server endpoints for the specified Group
func DeclareRoutes(e *echo.Group, h *APIHandler) {
e.GET("/health/", h.HealthGET)
e.GET("/scan/:membre_id/", h.ScanGET)
e.POST("/scan/:membre_id/", h.ScanPOST)
e.GET("/decompte/", h.DecompteGET)
e.GET("/presences/", h.PresencesGET)
}
/*
New retourne un nouveau APIHandler contenant des pointers vers les clients
nécessaires à l'exécution du API server
*/
func New(bottinAPIClient *bottindata.ApiClient, dbClient *dbclient.DBClient) APIHandler {
return APIHandler{
BottinAPIClient: bottinAPIClient,
DBClient: dbClient,
}
}
/*
APIHandler is the struct that implements the actual logic for the API server
routes
*/
type APIHandler struct {
BottinAPIClient *bottindata.ApiClient
DBClient *dbclient.DBClient
}
// HealthGET is the handler for `GET /v:version/health/ http/1.1`
func (a *APIHandler) HealthGET(c echo.Context) error {
var r apiresponse.HealthGET
r.Message = "not ok"
bottinStatus, err := a.BottinAPIClient.GetHealth()
if err != nil {
r.StatusCode = http.StatusInternalServerError
r.Data.BottinStatus = err.Error()
} else {
r.Data.BottinStatus = bottinStatus
}
switch r.Data.BottinStatus {
case "Bottin API v6 is ready":
r.Message = "ok"
r.StatusCode = http.StatusOK
default:
r.StatusCode = http.StatusInternalServerError
}
return c.JSON(r.StatusCode, r)
}
/*
ScanGET is the handler for `GET /v{version}/scan/{membre_id}/ http/1.1`
It returns the scanned status of a membre, without affecting the database.
*/
func (a *APIHandler) ScanGET(c echo.Context) error {
var r apiresponse.ScanGET
r.StatusCode = http.StatusOK
membreID := c.Param("membre_id")
membre, err := a.BottinAPIClient.GetMembre(membreID)
if err != nil {
switch err.Error() {
case "Ce numéro étudiant ne correspond à aucunE membre":
r.Message = fmt.Sprintf("%s n'est pas membre de l'AGECEM", membreID)
r.StatusCode = http.StatusNotFound
case "Veuillez fournir un numéro étudiant à rechercher":
r.Error = "membre_id ne peut pas être vide"
r.StatusCode = http.StatusBadRequest
r.Message = err.Error()
default:
r.Error = err.Error()
r.Message = "Erreur lors de BottinAPIClient.GetMembre"
r.StatusCode = http.StatusInternalServerError
return c.JSON(r.StatusCode, r)
}
}
if membre.ID == membreID && membre.ID != "" {
r.Message = fmt.Sprintf("%s est membre de l'AGECEM", membreID)
}
//TODO remplir r.Data.IsScanned
return c.JSON(r.StatusCode, r)
}
// ScanPOST is the handler for `POST /v{version}/scan/{membre_id}/ http/1.1`
func (a *APIHandler) ScanPOST(c echo.Context) error {
var r apiresponse.ScanPOST
membreID := c.Param("membre_id")
membre, err := a.BottinAPIClient.GetMembre(membreID)
if err != nil {
switch err.Error() {
case "Ce numéro étudiant ne correspond à aucunE membre":
r.Message = fmt.Sprintf("👎 %s n'est pas membre de l'AGECEM", membreID)
r.Error = err.Error()
r.StatusCode = http.StatusNotFound
return c.JSON(r.StatusCode, r)
case "Veuillez fournir un numéro étudiant à rechercher":
r.Error = "membre_id ne peut pas être vide"
r.StatusCode = http.StatusBadRequest
r.Message = err.Error()
return c.JSON(r.StatusCode, r)
default:
r.Error = err.Error()
r.Message = "Erreur lors de BottinAPIClient.GetMembre"
r.StatusCode = http.StatusInternalServerError
return c.JSON(r.StatusCode, r)
}
}
var presence dbstruct.Presence
presence.ID = membre.ID
presence.ProgrammeID = membre.ProgrammeID
switch membre.PreferedName != "" {
case true:
presence.Name = membre.PreferedName
case false:
presence.Name = fmt.Sprintf("%s, %s", membre.LastName, membre.FirstName)
}
insertedPresence, err := a.DBClient.InsertPresence(presence)
if err != nil {
r.Error = err.Error()
r.Message = "👎 Erreur lors de DBClient.InsertPresence"
r.StatusCode = http.StatusInternalServerError
return c.JSON(r.StatusCode, r)
}
if insertedPresence.ID == "" {
r.Error = "Membre déjà enregistré·e"
r.Message = fmt.Sprintf("👎 Membre '%s' (%s) déjà enregistré·e.", presence.Name, presence.ID)
r.StatusCode = http.StatusBadRequest
return c.JSON(r.StatusCode, r)
}
r.StatusCode = http.StatusOK
r.Message = fmt.Sprintf("👍 Membre '%s' (%s) enregistré·e avec succès, veuillez lui donner son carton de vote. Bonne assemblée!", insertedPresence.Name, insertedPresence.ID)
return c.JSON(r.StatusCode, r)
}
// DecompteGET is the handler for `GET /v:version/decompte/ http/1.1`
func (a *APIHandler) DecompteGET(c echo.Context) error {
var r apiresponse.DecompteGET
r.Message = "not ok"
decompte, err := a.DBClient.GetDecompte()
if err != nil {
r.Error = err.Error()
r.StatusCode = http.StatusInternalServerError
r.Message = "Error during a.DBClient.GetDecompte"
return c.JSON(r.StatusCode, r)
}
r.Data.Decompte = decompte
r.StatusCode = http.StatusOK
r.Message = "ok"
return c.JSON(r.StatusCode, r)
}
// PresencesGET is the handler for `GET /v:version/presences/ http/1.1`
func (a *APIHandler) PresencesGET(c echo.Context) error {
var r apiresponse.PresencesGET
presences, err := a.DBClient.GetPresences()
if err != nil {
r.Error = err.Error()
r.StatusCode = http.StatusInternalServerError
r.Message = "Error during a.DBClient.GetPresences"
return c.JSON(r.StatusCode, r)
}
r.Data.Presences = presences
r.StatusCode = http.StatusOK
r.Message = "ok"
return c.JSON(r.StatusCode, r)
}