Skip to content

Commit

Permalink
Merge pull request #53 from Black-Sirius69/master
Browse files Browse the repository at this point in the history
feat: feat
  • Loading branch information
Mr-Emerald-Wolf authored Mar 17, 2024
2 parents 3f4e326 + 7ecab3c commit 314d9bd
Show file tree
Hide file tree
Showing 13 changed files with 470 additions and 8 deletions.
4 changes: 2 additions & 2 deletions db/migrations/001_users.sql
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,5 @@ CREATE TABLE vit_details (
);

-- +goose Down
DROP TABLE vit_details;
DROP TABLE users;
DROP TABLE IF EXISTS vit_details;
DROP TABLE IF EXISTS users;
3 changes: 1 addition & 2 deletions db/migrations/002_teams.sql
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,4 @@ CREATE TABLE IF NOT EXISTS teams (
);

-- +goose Down

DROP TABLE teams;
DROP TABLE IF EXISTS teams;
3 changes: 1 addition & 2 deletions db/migrations/003_ideas.sql
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,4 @@ CREATE TABLE IF NOT EXISTS ideas (
);

-- +goose Down

DROP TABLE ideas;
DROP TABLE IF EXISTS ideas;
17 changes: 17 additions & 0 deletions db/migrations/006_reviews.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
-- +goose Up
CREATE TABLE IF NOT EXISTS reviews (
id UUID PRIMARY KEY,
team_id UUID NOT NULL,
reviewer TEXT NOT NULL,
innovation_score DOUBLE PRECISION NOT NULL,
functionality_score DOUBLE PRECISION NOT NULL,
design_score DOUBLE PRECISION NOT NULL,
tech_score DOUBLE PRECISION NOT NULL,
presentation_score DOUBLE PRECISION NOT NULL,
comments TEXT NOT NULL,
total_score DOUBLE PRECISION NOT NULL,
review_round INTEGER NOT NULL
);

-- +goose Down
DROP TABLE IF EXISTS reviews;
10 changes: 10 additions & 0 deletions db/migrations/007_reviews_foreign_keys.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
-- +goose Up
ALTER TABLE reviews
ADD CONSTRAINT fk_reviews
FOREIGN KEY (team_id)
REFERENCES teams(id)
ON UPDATE CASCADE;

-- +goose Down
ALTER TABLE reviews
DROP CONSTRAINT fk_reviews;
228 changes: 228 additions & 0 deletions internal/controllers/admin_review_controller.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
package controllers

import (
"database/sql"
"errors"
"net/http"
"strconv"
"strings"

"github.com/CodeChefVIT/devsoc-backend-24/internal/models"
services "github.com/CodeChefVIT/devsoc-backend-24/internal/services/admin"
"github.com/google/uuid"
"github.com/labstack/echo/v4"
)

func ReviewTeam(ctx echo.Context) error {
var payload models.TeamReviewRequest

if err := ctx.Bind(&payload); err != nil {
return ctx.JSON(http.StatusBadRequest, map[string]interface{}{
"message": "invalid request payload",
"status": "fail",
"data": nil,
})
}

if err := ctx.Validate(&payload); err != nil {
return ctx.JSON(http.StatusBadRequest, map[string]interface{}{
"message": err.Error(),
"status": "fail",
"data": nil,
})
}

totalScore := payload.InnovationScore + payload.FunctionalityScore + payload.DesignScore + payload.TechScore + payload.PresentationScore

review := models.TeamReview{
ID: uuid.New(),
TeamID: payload.TeamID,
Reviewer: payload.Reviewer,
InnovationScore: payload.InnovationScore,
FunctionalityScore: payload.FunctionalityScore,
DesignScore: payload.DesignScore,
TechScore: payload.TechScore,
PresentationScore: payload.PresentationScore,
ReviewRound: payload.ReviewRound,
Comments: payload.Comments,
TotalScore: totalScore,
}

if err := services.InsertReview(review); err != nil {
return ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"message": err.Error(),
"status": "fail",
"data": nil,
})
}

return ctx.JSON(http.StatusOK, map[string]interface{}{
"message": "review inserted",
"status": "success",
"data": review,
})
}

func GetReviewsByTeamID(ctx echo.Context) error {
teamIDStr := ctx.Param("id")

teamID, err := uuid.Parse(teamIDStr)
if err != nil {
return ctx.JSON(http.StatusBadRequest, map[string]interface{}{
"message": "invalid team id",
"status": "fail",
"data": nil,
})
}

reviews, err := services.GetReviewsByTeamID(teamID)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return ctx.JSON(http.StatusNotFound, map[string]interface{}{
"message": "no reviews found",
"status": "fail",
"data": nil,
})
}
return ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"message": err.Error(),
"status": "fail",
"data": nil,
})
}

return ctx.JSON(http.StatusOK, map[string]interface{}{
"message": "reviews found",
"status": "success",
"data": reviews,
})
}

func GetReviewsByRound(ctx echo.Context) error {
roundStr := ctx.Param("round")

round, err := strconv.Atoi(roundStr)
if err != nil {
return ctx.JSON(http.StatusBadRequest, map[string]interface{}{
"message": "invalid round id",
"status": "fail",
"data": nil,
})
}

reviews, err := services.GetReviewsByRound(round)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return ctx.JSON(http.StatusNotFound, map[string]interface{}{
"message": "no reviews found",
"status": "fail",
"data": nil,
})
}
return ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"message": err.Error(),
"status": "fail",
"data": nil,
})
}

return ctx.JSON(http.StatusOK, map[string]interface{}{
"message": "reviews found",
"status": "success",
"data": reviews,
})
}

func UpdateReview(ctx echo.Context) error {
var payload models.UpdateTeamReviewRequest

if err := ctx.Bind(&payload); err != nil {
return ctx.JSON(http.StatusBadRequest, map[string]interface{}{
"message": err.Error(),
"status": "fail",
"data": nil,
})
}

if err := ctx.Validate(&payload); err != nil {
return ctx.JSON(http.StatusBadRequest, map[string]interface{}{
"message": err.Error(),
"status": "fail",
"data": nil,
})
}

review, err := services.GetReviewByID(payload.ID)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return ctx.JSON(http.StatusNotFound, map[string]interface{}{
"message": "review not found",
"status": "fail",
"data": nil,
})
}
return ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"message": err.Error(),
"status": "fail",
"data": nil,
})
}

payload.Reviewer = strings.TrimSpace(payload.Reviewer)
payload.Comments = strings.TrimSpace(payload.Comments)

if payload.Reviewer != "" {
review.Reviewer = payload.Reviewer
}

if payload.FunctionalityScore != nil {
review.TotalScore -= review.FunctionalityScore
review.TotalScore += *payload.FunctionalityScore
review.FunctionalityScore = *payload.FunctionalityScore
}

if payload.DesignScore != nil {
review.TotalScore -= review.DesignScore
review.TotalScore += *payload.DesignScore
review.DesignScore = *payload.DesignScore
}

if payload.InnovationScore != nil {
review.TotalScore -= review.InnovationScore
review.TotalScore += *payload.InnovationScore
review.InnovationScore = *payload.InnovationScore
}

if payload.PresentationScore != nil {
review.TotalScore -= review.PresentationScore
review.TotalScore += *payload.PresentationScore
review.PresentationScore = *payload.PresentationScore
}

if payload.TechScore != nil {
review.TotalScore -= review.TechScore
review.TotalScore += *payload.TechScore
review.TechScore = *payload.TechScore
}

if payload.ReviewRound != nil {
review.ReviewRound = *payload.ReviewRound
}

if payload.Comments != "" {
review.Comments = payload.Comments
}

if err := services.UpdateReview(review); err != nil {
return ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"message": err.Error(),
"status": "fail",
"data": nil,
})
}

return ctx.JSON(http.StatusOK, map[string]interface{}{
"message": "review updated",
"status": "success",
})
}
2 changes: 1 addition & 1 deletion internal/controllers/user_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ func CompleteProfile(ctx echo.Context) error {
if errors.As(err, &pgerr) {
if pgerr.Code == "23505" {
return ctx.JSON(http.StatusExpectationFailed, map[string]string{
"message": "team name already exists",
"message": "vit email already exists",
"status": "failed to update team",
})
}
Expand Down
41 changes: 41 additions & 0 deletions internal/models/review_model.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package models

import "github.com/google/uuid"

type TeamReview struct {
ID uuid.UUID `json:"id"`
TeamID uuid.UUID `json:"team_id"`
Reviewer string `json:"reviewer"`
InnovationScore float64 `json:"innovation_and_creativity"`
FunctionalityScore float64 `json:"functionality_and_completeness"`
DesignScore float64 `json:"ui_and_design"`
TechScore float64 `json:"techincal_implementation"`
PresentationScore float64 `json:"presentation_and_communication"`
ReviewRound int `json:"review_round"`
Comments string `json:"comments"`
TotalScore float64 `json:"total_score"`
}

type TeamReviewRequest struct {
TeamID uuid.UUID `json:"team_id" validate:"required,uuid"`
Reviewer string `json:"reviewer" validate:"required"`
InnovationScore float64 `json:"innovation_and_creativity" validate:"required"`
FunctionalityScore float64 `json:"functionality_and_completeness" validate:"required"`
DesignScore float64 `json:"ui_and_design" validate:"required"`
TechScore float64 `json:"techincal_implementation" validate:"required"`
PresentationScore float64 `json:"presentation_and_communication" validate:"required"`
ReviewRound int `json:"review_round" validate:"required"`
Comments string `json:"comments"`
}

type UpdateTeamReviewRequest struct {
ID uuid.UUID `json:"id" validate:"required,uuid"`
Reviewer string `json:"reviewer"`
InnovationScore *float64 `json:"innovation_and_creativity,omitempty"`
FunctionalityScore *float64 `json:"functionality_and_completeness,omitempty"`
DesignScore *float64 `json:"ui_and_design,omitempty"`
TechScore *float64 `json:"techincal_implementation,omitempty"`
PresentationScore *float64 `json:"presentation_and_communication,omitempty"`
ReviewRound *int `json:"review_round,omitempty"`
Comments string `json:"comments"`
}
5 changes: 5 additions & 0 deletions internal/models/user_model.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,11 @@ type GetUser struct {
ID uuid.UUID `json:"id"`
IsLeader bool `json:"is_leader"`
}

type GetAdminUser struct {
GetUser
Email string `json:"email"`
}
type ResendOTPRequest struct {
Email string `json:"email" validate:"required,email"`
Type string `json:"type" validate:"required,oneof=verification resetpass"`
Expand Down
6 changes: 5 additions & 1 deletion internal/routes/admin_routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,12 @@ func AdminRoutes(incomingRoutes *echo.Echo) {

admin.GET("/projects/all", controllers.GetAllProject)
admin.GET("/ideas/all", controllers.GetAllIdeas)
admin.POST("/idea/shortlist", controllers.ShortList, middleware.EditOnly)

admin.POST("/idea/shortlist", controllers.ShortList)
admin.GET("/reviews/:round", controllers.GetReviewsByRound)
admin.GET("/reviews/team/:id", controllers.GetReviewsByTeamID)
admin.POST("/review", controllers.ReviewTeam, middleware.EditOnly)
admin.PATCH("/review", controllers.UpdateReview, middleware.EditOnly)

//admin.GET("/team/freshers", controllers.GetAllFresherTeams)
//admin.GET("/team/females", controllers.GetAllFemaleTeams)
Expand Down
Loading

0 comments on commit 314d9bd

Please sign in to comment.