backend api, swagger, tooling, frontend skeleton
This commit is contained in:
@@ -0,0 +1,269 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
"gitea.maison43.duckdns.org/gilles/matosbox/internal/data/ent"
|
||||
"gitea.maison43.duckdns.org/gilles/matosbox/internal/data/ent/lienobjetemplacement"
|
||||
)
|
||||
|
||||
type lienObjetEmplacementRequest struct {
|
||||
EmplacementID *string `json:"emplacement_id"`
|
||||
Type *string `json:"type"`
|
||||
}
|
||||
|
||||
type lienObjetEmplacementUpdateRequest struct {
|
||||
EmplacementID *string `json:"emplacement_id"`
|
||||
Type *string `json:"type"`
|
||||
}
|
||||
|
||||
// @Summary Lister les liens objet/emplacement
|
||||
// @Tags LiensEmplacements
|
||||
// @Produce json
|
||||
// @Param id path string true "ID objet"
|
||||
// @Param page query int false "Page"
|
||||
// @Param limit query int false "Limite"
|
||||
// @Success 200 {object} map[string]any
|
||||
// @Failure 400 {object} map[string]string
|
||||
// @Failure 500 {object} map[string]string
|
||||
// @Router /objets/{id}/liens_emplacements [get]
|
||||
func (h *Handler) ListLiensEmplacements(c *gin.Context) {
|
||||
objetID, err := uuid.Parse(c.Param("id"))
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"erreur": "identifiant invalide"})
|
||||
return
|
||||
}
|
||||
|
||||
limit, offset, page := parsePagination(c.Query("page"), c.Query("limit"))
|
||||
query := h.client.LienObjetEmplacement.Query().
|
||||
Where(lienobjetemplacement.ObjetID(objetID))
|
||||
total, err := query.Count(c.Request.Context())
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"erreur": "impossible de compter les liens"})
|
||||
return
|
||||
}
|
||||
|
||||
items, err := query.
|
||||
Order(ent.Desc(lienobjetemplacement.FieldCreatedAt)).
|
||||
Limit(limit).
|
||||
Offset(offset).
|
||||
All(c.Request.Context())
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"erreur": "impossible de lister les liens"})
|
||||
return
|
||||
}
|
||||
respondPaginated(c, items, total, page, limit)
|
||||
}
|
||||
|
||||
// @Summary Creer un lien objet/emplacement
|
||||
// @Tags LiensEmplacements
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path string true "ID objet"
|
||||
// @Param body body lienObjetEmplacementRequest true "Lien"
|
||||
// @Success 201 {object} ent.LienObjetEmplacement
|
||||
// @Failure 400 {object} map[string]string
|
||||
// @Failure 404 {object} map[string]string
|
||||
// @Failure 409 {object} map[string]string
|
||||
// @Failure 500 {object} map[string]string
|
||||
// @Router /objets/{id}/liens_emplacements [post]
|
||||
func (h *Handler) CreateLienEmplacement(c *gin.Context) {
|
||||
objetID, err := uuid.Parse(c.Param("id"))
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"erreur": "identifiant invalide"})
|
||||
return
|
||||
}
|
||||
|
||||
var req lienObjetEmplacementRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"erreur": "donnees invalides"})
|
||||
return
|
||||
}
|
||||
if req.EmplacementID == nil || *req.EmplacementID == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"erreur": "emplacement_id obligatoire"})
|
||||
return
|
||||
}
|
||||
|
||||
emplacementID, err := uuid.Parse(*req.EmplacementID)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"erreur": "emplacement_id invalide"})
|
||||
return
|
||||
}
|
||||
|
||||
if _, err := h.client.Emplacement.Get(c.Request.Context(), emplacementID); err != nil {
|
||||
if ent.IsNotFound(err) {
|
||||
c.JSON(http.StatusNotFound, gin.H{"erreur": "emplacement introuvable"})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"erreur": "impossible de charger l'emplacement"})
|
||||
return
|
||||
}
|
||||
|
||||
create := h.client.LienObjetEmplacement.Create().
|
||||
SetObjetID(objetID).
|
||||
SetEmplacementID(emplacementID)
|
||||
|
||||
typeValeur := lienobjetemplacement.TypeStocke
|
||||
if req.Type != nil && *req.Type != "" {
|
||||
parsed, ok := parseLienType(*req.Type)
|
||||
if !ok {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"erreur": "type invalide"})
|
||||
return
|
||||
}
|
||||
typeValeur = parsed
|
||||
}
|
||||
create.SetType(typeValeur)
|
||||
|
||||
exists, err := h.client.LienObjetEmplacement.Query().
|
||||
Where(
|
||||
lienobjetemplacement.ObjetID(objetID),
|
||||
lienobjetemplacement.EmplacementID(emplacementID),
|
||||
lienobjetemplacement.TypeEQ(typeValeur),
|
||||
).
|
||||
Exist(c.Request.Context())
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"erreur": "impossible de verifier le lien"})
|
||||
return
|
||||
}
|
||||
if exists {
|
||||
c.JSON(http.StatusConflict, gin.H{"erreur": "lien deja existant"})
|
||||
return
|
||||
}
|
||||
|
||||
created, err := create.Save(c.Request.Context())
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"erreur": "impossible de creer le lien"})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusCreated, created)
|
||||
}
|
||||
|
||||
// @Summary Supprimer un lien objet/emplacement
|
||||
// @Tags LiensEmplacements
|
||||
// @Param id path string true "ID lien"
|
||||
// @Success 204 {string} string "No Content"
|
||||
// @Failure 400 {object} map[string]string
|
||||
// @Failure 404 {object} map[string]string
|
||||
// @Failure 500 {object} map[string]string
|
||||
// @Router /liens_emplacements/{id} [delete]
|
||||
func (h *Handler) DeleteLienEmplacement(c *gin.Context) {
|
||||
lienID, err := uuid.Parse(c.Param("id"))
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"erreur": "identifiant invalide"})
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.client.LienObjetEmplacement.DeleteOneID(lienID).Exec(c.Request.Context()); err != nil {
|
||||
if ent.IsNotFound(err) {
|
||||
c.JSON(http.StatusNotFound, gin.H{"erreur": "lien introuvable"})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"erreur": "impossible de supprimer le lien"})
|
||||
return
|
||||
}
|
||||
c.Status(http.StatusNoContent)
|
||||
}
|
||||
|
||||
// @Summary Mettre a jour un lien objet/emplacement
|
||||
// @Tags LiensEmplacements
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path string true "ID lien"
|
||||
// @Param body body lienObjetEmplacementUpdateRequest true "Mise a jour"
|
||||
// @Success 200 {object} ent.LienObjetEmplacement
|
||||
// @Failure 400 {object} map[string]string
|
||||
// @Failure 404 {object} map[string]string
|
||||
// @Failure 409 {object} map[string]string
|
||||
// @Failure 500 {object} map[string]string
|
||||
// @Router /liens_emplacements/{id} [put]
|
||||
func (h *Handler) UpdateLienEmplacement(c *gin.Context) {
|
||||
lienID, err := uuid.Parse(c.Param("id"))
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"erreur": "identifiant invalide"})
|
||||
return
|
||||
}
|
||||
|
||||
var req lienObjetEmplacementUpdateRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"erreur": "donnees invalides"})
|
||||
return
|
||||
}
|
||||
|
||||
existant, err := h.client.LienObjetEmplacement.Get(c.Request.Context(), lienID)
|
||||
if err != nil {
|
||||
if ent.IsNotFound(err) {
|
||||
c.JSON(http.StatusNotFound, gin.H{"erreur": "lien introuvable"})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"erreur": "impossible de charger le lien"})
|
||||
return
|
||||
}
|
||||
|
||||
nouveauEmplacementID := existant.EmplacementID
|
||||
if req.EmplacementID != nil && *req.EmplacementID != "" {
|
||||
parsed, err := uuid.Parse(*req.EmplacementID)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"erreur": "emplacement_id invalide"})
|
||||
return
|
||||
}
|
||||
if _, err := h.client.Emplacement.Get(c.Request.Context(), parsed); err != nil {
|
||||
if ent.IsNotFound(err) {
|
||||
c.JSON(http.StatusNotFound, gin.H{"erreur": "emplacement introuvable"})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"erreur": "impossible de charger l'emplacement"})
|
||||
return
|
||||
}
|
||||
nouveauEmplacementID = parsed
|
||||
}
|
||||
|
||||
nouveauType := existant.Type
|
||||
if req.Type != nil && *req.Type != "" {
|
||||
parsed, ok := parseLienType(*req.Type)
|
||||
if !ok {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"erreur": "type invalide"})
|
||||
return
|
||||
}
|
||||
nouveauType = parsed
|
||||
}
|
||||
|
||||
dupe, err := h.client.LienObjetEmplacement.Query().
|
||||
Where(
|
||||
lienobjetemplacement.ObjetID(existant.ObjetID),
|
||||
lienobjetemplacement.EmplacementID(nouveauEmplacementID),
|
||||
lienobjetemplacement.TypeEQ(nouveauType),
|
||||
lienobjetemplacement.IDNEQ(lienID),
|
||||
).
|
||||
Exist(c.Request.Context())
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"erreur": "impossible de verifier le lien"})
|
||||
return
|
||||
}
|
||||
if dupe {
|
||||
c.JSON(http.StatusConflict, gin.H{"erreur": "lien deja existant"})
|
||||
return
|
||||
}
|
||||
|
||||
updated, err := h.client.LienObjetEmplacement.UpdateOneID(lienID).
|
||||
SetEmplacementID(nouveauEmplacementID).
|
||||
SetType(nouveauType).
|
||||
Save(c.Request.Context())
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"erreur": "impossible de mettre a jour le lien"})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, updated)
|
||||
}
|
||||
|
||||
func parseLienType(value string) (lienobjetemplacement.Type, bool) {
|
||||
switch value {
|
||||
case "stocke":
|
||||
return lienobjetemplacement.TypeStocke, true
|
||||
case "utilise_dans":
|
||||
return lienobjetemplacement.TypeUtiliseDans, true
|
||||
default:
|
||||
return "", false
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user