Skip to content

Commit

Permalink
Merge branch 'rolevents' of https://github.com/STUD-IT-team/bmstu-stu…
Browse files Browse the repository at this point in the history
…d-web-backend into rolevents
  • Loading branch information
pai0id committed Jul 17, 2024
2 parents b3562e4 + c350ab8 commit f4e1e0b
Show file tree
Hide file tree
Showing 7 changed files with 215 additions and 6 deletions.
19 changes: 19 additions & 0 deletions internal/app/club.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type clubStorage interface {
AddClubPhotos(ctx context.Context, p []domain.ClubPhoto) error
DeleteClubPhoto(ctx context.Context, ids int) error
GetPhotoClubID(ctx context.Context, photoID int) (int, error)
UpdateClubPhotos(ctx context.Context, clubID int, photos []domain.ClubPhoto) error
}

type ClubService struct {
Expand Down Expand Up @@ -312,6 +313,24 @@ func (s *ClubService) DeleteClubPhoto(ctx context.Context, req *requests.DeleteC
return nil
}

func (s *ClubService) UpdateClubPhoto(ctx context.Context, req *requests.UpdateClubPhoto) error {
clubID := req.ClubID
photos := make([]domain.ClubPhoto, 0, len(req.Photos))
for _, p := range req.Photos {
photos = append(photos, domain.ClubPhoto{
ClubID: clubID,
MediaID: p.MediaID,
RefNumber: p.RefNumber,
})
}
err := s.storage.UpdateClubPhotos(ctx, clubID, photos)
if err != nil {
return fmt.Errorf("can't storage.UpdateClubPhotos: %w", err)
}
return err

}

func (s *ClubService) GetClearancePost(ctx context.Context, resp *responses.CheckResponse) (*responses.GetClearance, error) {
if resp.IsAdmin {
return &responses.GetClearance{Access: true, Comment: ""}, nil
Expand Down
1 change: 0 additions & 1 deletion internal/domain/requests/post-club-photo.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ func (c *PostClubPhoto) Bind(req *http.Request) error {
Photos: pc.Photos,
}
return c.validate()

}

func (c *PostClubPhoto) validate() error {
Expand Down
48 changes: 48 additions & 0 deletions internal/domain/requests/update-club-photo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package requests

import (
"encoding/json"
"fmt"
"net/http"
"strconv"

"github.com/STUD-IT-team/bmstu-stud-web-backend/internal/domain"
"github.com/go-chi/chi"
)

type UpdateClubPhoto struct {
PostClubPhoto
}

type UpdateClubPhotoPointer struct {
PostClubPhotoPointer
}

func (c *UpdateClubPhoto) Bind(req *http.Request) error {
id, err := strconv.Atoi(chi.URLParam(req, "club_id"))
if err != nil {
return fmt.Errorf("can't Atoi on club_id in request: %w", err)
}
pc := PostClubPhotoPointer{}

decoder := json.NewDecoder(req.Body)
decoder.DisallowUnknownFields()
err = decoder.Decode(&pc)

if err != nil {
return fmt.Errorf("can't json decoder on updateClubPhoto: %v", err)
}

if decoder.More() {
return fmt.Errorf("updateClubPhoto Bind: extraneous data after JSON object")
}

err = pc.validate()
if err != nil {
return fmt.Errorf("%v: %v", domain.ErrIncorrectRequest, err)
}
c.ClubID = id
c.Photos = pc.Photos

return c.validate()
}
5 changes: 0 additions & 5 deletions internal/domain/responses/delete-club-photo.go

This file was deleted.

61 changes: 61 additions & 0 deletions internal/infrastructure/postgres/club.go
Original file line number Diff line number Diff line change
Expand Up @@ -752,6 +752,67 @@ func (s *Postgres) AddClubPhotos(_ context.Context, p []domain.ClubPhoto) error
return wrapPostgresError(tx.Commit())
}

const getClubPhoto = "SELECT id, ref_num, club_id, media_id FROM club_photo WHERE club_id = $1"
const upsertClubPhoto = `
INSERT INTO club_photo (ref_num, club_id, media_id) VALUES ($1, $2, $3)
ON CONFLICT (media_id, club_id) DO UPDATE SET ref_num=$1
`

func (s *Postgres) UpdateClubPhotos(_ context.Context, clubID int, p []domain.ClubPhoto) error {
tx, err := s.db.Begin()
if err != nil {
return wrapPostgresError(err)
}

dbPhotos := []domain.ClubPhoto{}
rows, err := tx.Query(getClubPhoto, p[0].ClubID)
if err != nil {
tx.Rollback()
return wrapPostgresError(err)
}
for rows.Next() {
dbPhoto := domain.ClubPhoto{}
err := rows.Scan(&dbPhoto.ID, &dbPhoto.RefNumber, &dbPhoto.ClubID, &dbPhoto.MediaID)
if err != nil {
tx.Rollback()
return wrapPostgresError(err)
}
dbPhotos = append(dbPhotos, dbPhoto)
}

toDelete := make([]int, 0, len(dbPhotos))

for _, dbPhoto := range dbPhotos {
found := false
for _, photo := range p {
if dbPhoto.MediaID == photo.MediaID {
found = true
break
}
}
if !found {
toDelete = append(toDelete, dbPhoto.ID)
}
}

for _, id := range toDelete {
_, err := tx.Exec(deleteClubPhoto, id)
if err != nil {
tx.Rollback()
return wrapPostgresError(err)
}
}

for _, photo := range p {
_, err := tx.Exec(upsertClubPhoto, photo.RefNumber, clubID, photo.MediaID)
if err != nil {
tx.Rollback()
return wrapPostgresError(err)
}
}
return wrapPostgresError(tx.Commit())
}

const deleteClubPhoto = "DELETE FROM club_photo WHERE id = $1"

func (s *Postgres) DeleteClubPhoto(_ context.Context, id int) error {
Expand Down
82 changes: 82 additions & 0 deletions internal/ports/clubs.go
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,21 @@ func (h *ClubsHandler) UpdateClub(w http.ResponseWriter, req *http.Request) hand
return handler.OkResponse(nil)
}

// PostClubPhoto
//
// @Summary Добавляет в клуб фотографии клуба в базу данных
// @Description Добавляет в клуб фотографии клуба в базу данных
// @Tags auth.club
// @Produce json
// @Param club_id path int true "club id"
// @Param request body requests.PostClubPhoto true "post club photo data"
// @Success 200
// @Failure 400
// @Failure 401
// @Failure 409
// @Failure 500
// @Router /clubs/media/{club_id} [post]
// @Security Authorized
func (h *ClubsHandler) PostClubMedia(w http.ResponseWriter, req *http.Request) handler.Response {
h.logger.Info("ClubsHandler: got PostClubMedia request")

Expand Down Expand Up @@ -529,6 +544,21 @@ func (h *ClubsHandler) PostClubMedia(w http.ResponseWriter, req *http.Request) h
return handler.OkResponse(nil)
}

// DeleteClubPhoto
//
// @Summary Удаляет фотографию из фотографий клуба
// @Description Удаляет фотографию из фотографий клуба
// @Tags auth.club
// @Produce json
// @Param club_id path int true "club id"
// @Param request body requests.DeleteClubPhoto true "post club photo data"
// @Success 200
// @Failure 400
// @Failure 401
// @Failure 404
// @Failure 500
// @Router /clubs/media/{club_id} [delete]
// @Security Authorized
func (h *ClubsHandler) DeleteClubMedia(w http.ResponseWriter, req *http.Request) handler.Response {
h.logger.Info("ClubsHandler: got DeleteClubMedia request")

Expand Down Expand Up @@ -568,6 +598,58 @@ func (h *ClubsHandler) DeleteClubMedia(w http.ResponseWriter, req *http.Request)
return handler.OkResponse(nil)
}

// UpdateClubPhoto
//
// @Summary Обновляет все фотографии клуба
// @Description Обновляет все фотографии клуба
// @Tags auth.club
// @Produce json
// @Param club_id path int true "club id"
// @Param request body requests.UpdateClubPhoto true "post club photo data"
// @Success 200
// @Failure 400
// @Failure 401
// @Failure 409
// @Failure 500
// @Router /clubs/media/{club_id} [put]
// @Security Authorized
func (h *ClubsHandler) UpdateClubMedia(w http.ResponseWriter, req *http.Request) handler.Response {
h.logger.Info("ClubsHandler: got UpdateClubMedia request")

access, err := getAccessToken(req)
if err != nil {
h.logger.Warnf("can't get access token: %v", err)
return handler.UnauthorizedResponse()
}

resp, err := h.guard.Check(context.Background(), &requests.CheckRequest{AccessToken: access})
if err != nil || !resp.Valid {
h.logger.Warnf("Unauthorized request: %v", err)
return handler.UnauthorizedResponse()
}

h.logger.Infof("ClubsHandler: UpdateClubMedia Authenticated: %v", resp.MemberID)

photo := &requests.UpdateClubPhoto{}

err = photo.Bind(req)

if err != nil {
h.logger.Warnf("can't parse UpdateClubMedia %v", err)
return handler.BadRequestResponse()
}
h.logger.Infof("ClubsHandler: parse request.")

err = h.clubs.UpdateClubPhoto(context.Background(), photo)
if err != nil {
h.logger.Warnf("can't service.UpdateClubMedia %v", err)
if errors.Is(err, postgres.ErrPostgresForeignKeyViolation) {
return handler.BadRequestResponse()
} else if errors.Is(err, postgres.ErrPostgresNotFoundError) {
return handler.NotFoundResponse()
}
return handler.InternalServerErrorResponse()
}

return handler.OkResponse(nil)
}
5 changes: 5 additions & 0 deletions internal/storage/club.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type clubStorage interface {
AddClubPhotos(ctx context.Context, p []domain.ClubPhoto) error
DeleteClubPhoto(ctx context.Context, id int) error
GetPhotoClubID(ctx context.Context, photoID int) (int, error)
UpdateClubPhotos(ctx context.Context, clubID int, photos []domain.ClubPhoto) error
}

func (s *storage) GetClub(ctx context.Context, id int) (*domain.Club, error) {
Expand Down Expand Up @@ -88,3 +89,7 @@ func (s *storage) DeleteClubPhoto(ctx context.Context, id int) error {
func (s *storage) GetPhotoClubID(ctx context.Context, photoID int) (int, error) {
return s.postgres.GetPhotoClubID(ctx, photoID)
}

func (s *storage) UpdateClubPhotos(ctx context.Context, clubID int, photos []domain.ClubPhoto) error {
return s.postgres.UpdateClubPhotos(ctx, clubID, photos)
}

0 comments on commit f4e1e0b

Please sign in to comment.