package handler import ( "astra-events/model" "astra-events/pkg/utils" "astra-events/services" "errors" "github.com/go-playground/validator/v10" "github.com/google/uuid" "github.com/hashicorp/go-set" "github.com/labstack/echo/v4" "gorm.io/gorm" "net/http" "time" ) // swagger:route POST /events/ Events CreateEvent // // responses: // 200: Event func (h *Handler) CreateEvent(c echo.Context) (err error) { var person *model.PersonalInformationApi event := new(model.CreateEvent) authorId, err := uuid.Parse(c.Request().Header.Get("X-User-Id")) orgId, err := uuid.Parse(c.Request().Header.Get("X-User-Organization-Id")) if err != nil { return c.JSON(http.StatusUnauthorized, &utils.Error{ Type: "internal_error", Message: "User in not authorized", Code: "0002", }) } err = c.Bind(&event) err = h.Validator.Struct(event) if err != nil { var validationErrors validator.ValidationErrors errors.As(err, &validationErrors) Fields := make(map[string]string) for _, validationError := range validationErrors { Fields[validationError.Field()] = validationError.Tag() } return c.JSON(http.StatusBadRequest, &utils.ValidationError{ Type: "validation_error", Message: err.Error(), Code: "0001", Fields: Fields, }) } if event.Person.ID.ID() != 0 { person, err = services.GetPerson(event.Person.ID, c.Request().Header, c) if err != nil || person.ID != event.Person.ID { return c.JSON(http.StatusBadGateway, &utils.Error{ Type: "internal_error", Message: "Can't sen request to persons service", Code: "0003", }) } } else { newPerson := model.PersonalInformationApi{ FirstName: event.Person.FirstName, LastName: event.Person.LastName, Patronymic: event.Person.Patronymic, Contacts: []model.Contact{ { Category: "PHONE", Value: event.Person.Phone, }, }, } person, err = services.CreatePerson(newPerson, c.Request().Header, c) if err != nil || person.ID.ID() == 0 { return c.JSON(http.StatusBadGateway, &utils.Error{ Type: "internal_error", Message: "Can't sen request to persons service", Code: "0004", }) } } usersMap, err := services.GetUsers([]uuid.UUID{event.MedicId, authorId}, c.Request().Header, c) if err != nil || len(usersMap) == 0 { return c.JSON(http.StatusBadGateway, &utils.Error{ Type: "internal_error", Message: "Can't sen request to users service", Code: "0005", }) } medic := usersMap[event.MedicId] author := usersMap[authorId] newEvent, err := utils.TypeConverter[model.Event](event) newEvent.OrgId = orgId newEvent.MedicId = event.MedicId newEvent.AuthorId = authorId newEvent.PersonId = person.ID newEvent.Person = *person tx := h.DB.Create(&newEvent) if tx.RowsAffected == 0 { return c.JSON(http.StatusBadGateway, &utils.Error{ Type: "internal_error", Message: "Database error", Code: "0006", }) } newEvent.Author = author newEvent.Medic = medic return c.JSON(http.StatusCreated, newEvent) } // swagger:route GET /events/ Events GetEvents // // responses: // 200: []Event func (h *Handler) GetEvents(c echo.Context) (err error) { query := c.Request().URL.Query() orgId, err := uuid.Parse(c.Request().Header.Get("X-User-Organization-Id")) if err != nil { return c.JSON(http.StatusUnauthorized, &utils.Error{ Type: "internal_error", Message: "User in not authorized", Code: "0002", }) } tx := h.DB.Where("org_id = ?", orgId) if query.Has("start") && query.Has("end") { tx = tx.Where("start >= ?", query.Get("start")).Where("\"end\" <= ?", query.Get("end")) } return h.queryEvents(tx, c) } // swagger:route GET /events/today Events GetEventsToday // // responses: // 200: []Event func (h *Handler) GetEventsToday(c echo.Context) (err error) { orgId, err := uuid.Parse(c.Request().Header.Get("X-User-Organization-Id")) if err != nil { return c.JSON(http.StatusUnauthorized, &utils.Error{ Type: "internal_error", Message: "User in not authorized", Code: "0002", }) } tx := h.DB.Where("org_id = ?", orgId) currentDate := time.Now().Format(time.DateOnly) nextDate := time.Now().Add(24 * time.Hour).Format(time.DateOnly) tx = tx.Where("start >= ?", currentDate).Where("\"end\" < ?", nextDate) return h.queryEvents(tx, c) } // swagger:route GET /events/{uuid} Events GetEvent // // responses: // 200: Event func (h *Handler) GetEvent(c echo.Context) error { var event model.Event id := c.Param("id") orgId, err := uuid.Parse(c.Request().Header.Get("X-User-Organization-Id")) if err != nil { return c.JSON(http.StatusUnauthorized, &utils.Error{ Type: "internal_error", Message: "User in not authorized", Code: "0002", }) } tx := h.DB.Where("org_id = ?", orgId).First(&event, id) if tx.RowsAffected == 0 { return c.JSON(http.StatusNotFound, &utils.Error{ Type: "not_found_error", Message: "Event not found", Code: "0007", }) } usersMap, err := services.GetUsers([]uuid.UUID{event.MedicId, event.AuthorId}, c.Request().Header, c) if err != nil { return c.JSON(http.StatusBadGateway, &utils.Error{ Type: "internal_error", Message: "Can't sen request to persons or users service", Code: "0005", }) } medic := usersMap[event.MedicId] author := usersMap[event.AuthorId] event.Medic = medic event.Author = author return c.JSON(http.StatusOK, event) } // swagger:route DELETE /events/{uuid} Events DeleteEvent // // responses: // 200 func (h *Handler) DeleteEvent(c echo.Context) error { id := c.Param("id") orgId, err := uuid.Parse(c.Request().Header.Get("X-User-Organization-Id")) if err != nil { return c.JSON(http.StatusUnauthorized, &utils.Error{ Type: "internal_error", Message: "User in not authorized", Code: "0002", }) } tx := h.DB.Where("org_id = ?", orgId).Delete(&model.Event{}, id) if tx.RowsAffected == 0 { return c.JSON(http.StatusNotFound, &utils.Error{ Type: "not_found_error", Message: "Event not found", Code: "0007", }) } return c.NoContent(http.StatusOK) } func (h *Handler) queryEvents(tx *gorm.DB, c echo.Context) error { var events []model.Event tx.Find(&events) userIds := set.New[uuid.UUID](len(events) * 2) personIds := set.New[uuid.UUID](len(events)) for _, event := range events { userIds.Insert(event.MedicId) userIds.Insert(event.AuthorId) personIds.Insert(event.PersonId) } usersMap, err := services.GetUsers(userIds.Slice(), c.Request().Header, c) personsMap, err := services.GetPersons(personIds.Slice(), c.Request().Header, c) if err != nil { return c.JSON(http.StatusBadGateway, &utils.Error{ Type: "internal_error", Message: "Can't sen request to persons or users service", Code: "0005", }) } for i, event := range events { events[i].Author = usersMap[event.AuthorId] events[i].Medic = usersMap[event.MedicId] events[i].Person = personsMap[event.PersonId] } return c.JSON(http.StatusOK, events) }