From 9805eddf936e43e530034d7262c59e2c51a802b4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pedro=20Andr=C3=A9s=20Chaparro=20Quintero?=
 <pedro.chaparro.2020@upb.edu.co>
Date: Thu, 18 Jan 2024 14:03:52 -0500
Subject: [PATCH 1/6] docs(openapi): Update spec

Add new endpoint to the spec and fix typo
---
 docs/openapi/spec.openapi.yaml | 57 ++++++++++++++++++++++++++++++----
 1 file changed, 51 insertions(+), 6 deletions(-)

diff --git a/docs/openapi/spec.openapi.yaml b/docs/openapi/spec.openapi.yaml
index eafcf04..d839a18 100644
--- a/docs/openapi/spec.openapi.yaml
+++ b/docs/openapi/spec.openapi.yaml
@@ -2176,7 +2176,7 @@ paths:
               schema:
                 $ref: "#/components/schemas/default_error_response"
   
-  /grades/laboratory/{laboratory_uuid}: 
+  /grades/laboratories/{laboratory_uuid}: 
     get: 
       tags: 
         - Grades
@@ -2216,6 +2216,56 @@ paths:
               schema:
                 $ref: "#/components/schemas/default_error_response"
     
+  /grades/laboratories/{laboratory_uuid}/students/{student_uuid}/comment: 
+    put:
+      tags: 
+        - Grades
+      security:
+        - cookieAuth: []
+      parameters:
+        - in: path
+          name: student_uuid
+          schema:
+            type: string
+            example: "b0c553b3-ddb2-4392-9d94-b31d8c9c4a84"
+          required: true
+        - in: path
+          name: laboratory_uuid
+          schema:
+            type: string
+            example: "a9be2f1e-e0e9-4b8d-9f72-6ed55ea5b1b8"
+          required: true
+      description: Add / update the comment given by the teacher to the given student in the given laboratory. 
+      requestBody:
+        content:
+          application/json:
+            schema:
+              type: object
+              properties:
+                comment: 
+                  type: string
+                  example: "This is a comment made by the teacher :D"
+      responses: 
+        "204": 
+          description: The comment was updated.
+        "400":
+          description: Required fields were missed or doesn't fulfill the required format.
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/default_error_response"
+        "403":
+          description: The session token isn't valid or the user doesn't have enough permissions.
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/default_error_response"
+        "500":
+          description: There was an unexpected error in the server side.
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/default_error_response"
   
 components:
   securitySchemes:
@@ -2357,11 +2407,6 @@ components:
     select_criteria_to_grade_req:
       allOf:
         - $ref: "#/components/schemas/selected_criteria_in_grade"
-      type: object
-      properties: 
-        rubric_uuid:
-          type: string
-          example: "3fc29baf-9517-430c-9048-0f85599b61b7"
 
     # Responses
     default_error_response:

From 266dad32c19d4b90a2c5f3c491fa90056c3ed847 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pedro=20Andr=C3=A9s=20Chaparro=20Quintero?=
 <pedro.chaparro.2020@upb.edu.co>
Date: Thu, 18 Jan 2024 14:04:29 -0500
Subject: [PATCH 2/6] chore: Remove logging message

---
 src/blocks/infrastructure/implementations/blocks_repository.go | 2 --
 1 file changed, 2 deletions(-)

diff --git a/src/blocks/infrastructure/implementations/blocks_repository.go b/src/blocks/infrastructure/implementations/blocks_repository.go
index ca39a97..2e57e25 100644
--- a/src/blocks/infrastructure/implementations/blocks_repository.go
+++ b/src/blocks/infrastructure/implementations/blocks_repository.go
@@ -3,7 +3,6 @@ package implementations
 import (
 	"context"
 	"database/sql"
-	"fmt"
 	"log"
 	"time"
 
@@ -480,7 +479,6 @@ func (repository *BlocksPostgresRepository) SwapBlocks(firstBlockUUID, secondBlo
 	}
 
 	// Run the query
-	fmt.Println("Swapping blocks", firstBlockUUID, secondBlockUUID)
 	_, err = tx.ExecContext(ctx, query, firstBlockUUID, secondBlockUUID)
 	if err != nil {
 		return err

From b8388d0c579980e95f65de956134a5f5dae8f1c9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pedro=20Andr=C3=A9s=20Chaparro=20Quintero?=
 <pedro.chaparro.2020@upb.edu.co>
Date: Thu, 18 Jan 2024 14:05:27 -0500
Subject: [PATCH 3/6] feat(grades): Add endpoint to update the comment of an
 student's grade

---
 src/grades/application/use_cases.go           | 40 +++++++++--
 .../domain/definitions/grades_repository.go   |  1 +
 src/grades/domain/dtos/grades_dtos.go         |  9 +++
 src/grades/infrastructure/http/controllers.go | 56 +++++++++++++++-
 src/grades/infrastructure/http/routes.go      |  7 ++
 .../grades_postgres_repository.go             | 66 +++++++++++++++++++
 .../requests/grades_requests.go               | 12 +++-
 7 files changed, 184 insertions(+), 7 deletions(-)

diff --git a/src/grades/application/use_cases.go b/src/grades/application/use_cases.go
index b41ffe1..328847d 100644
--- a/src/grades/application/use_cases.go
+++ b/src/grades/application/use_cases.go
@@ -74,10 +74,8 @@ func (useCases *GradesUseCases) SetCriteriaToGrade(dto *dtos.SetCriteriaToGradeD
 		return gradesErrors.LaboratoryDoesNotHaveRubricError{}
 	}
 
-	// Validate the rubric UUID
-	if *rubricUUID != dto.RubricUUID {
-		return gradesErrors.RubricDoesNotMatchLaboratoryError{}
-	}
+	// Set the rubric UUID
+	dto.RubricUUID = *rubricUUID
 
 	// Validate the objective belongs to the rubric
 	objectiveBelongsToRubric, err := useCases.RubricsRepository.DoesRubricHaveObjective(
@@ -134,3 +132,37 @@ func (useCases *GradesUseCases) GetStudentGradeInLaboratoryWithRubric(dto *dtos.
 	grade, err := useCases.GradesRepository.GetStudentGradeInLaboratoryWithRubric(dto)
 	return grade, err
 }
+
+// SetCommentToGrade sets a comment to an student's grade
+func (useCases *GradesUseCases) SetCommentToGrade(dto *dtos.SetCommentToGradeDTO) error {
+	// Validate the teacher owns the laboratory
+	teacherOwnsLaboratory, err := useCases.LaboratoriesRepository.DoesTeacherOwnLaboratory(
+		dto.TeacherUUID,
+		dto.LaboratoryUUID,
+	)
+	if err != nil {
+		return err
+	}
+	if !teacherOwnsLaboratory {
+		return laboratoriesErrors.TeacherDoesNotOwnLaboratoryError{}
+	}
+
+	// Get the UUID of the current rubric of the laboratory
+	laboratoryUUID := dto.LaboratoryUUID
+	laboratoryInformation, err := useCases.LaboratoriesRepository.GetLaboratoryInformationByUUID(laboratoryUUID)
+	if err != nil {
+		return err
+	}
+
+	// Return an error if the laboratory does not have a rubric
+	rubricUUID := laboratoryInformation.RubricUUID
+	if rubricUUID == nil {
+		return gradesErrors.LaboratoryDoesNotHaveRubricError{}
+	}
+
+	// Set the rubric UUID
+	dto.RubricUUID = *rubricUUID
+
+	// Set the comment to the student's grade
+	return useCases.GradesRepository.SetCommentToGrade(dto)
+}
diff --git a/src/grades/domain/definitions/grades_repository.go b/src/grades/domain/definitions/grades_repository.go
index 5859cfa..5189f5d 100644
--- a/src/grades/domain/definitions/grades_repository.go
+++ b/src/grades/domain/definitions/grades_repository.go
@@ -11,6 +11,7 @@ type GradesRepository interface {
 		[]*dtos.SummarizedStudentGradeDTO, error,
 	)
 	SetCriteriaToGrade(dto *dtos.SetCriteriaToGradeDTO) error
+	SetCommentToGrade(dto *dtos.SetCommentToGradeDTO) error
 	GetStudentGradeInLaboratoryWithRubric(
 		dto *dtos.GetStudentGradeInLaboratoryWithRubricDTO,
 	) (
diff --git a/src/grades/domain/dtos/grades_dtos.go b/src/grades/domain/dtos/grades_dtos.go
index 3703020..74bc92f 100644
--- a/src/grades/domain/dtos/grades_dtos.go
+++ b/src/grades/domain/dtos/grades_dtos.go
@@ -58,3 +58,12 @@ type SelectedCriteriaInStudentGradeDTO struct {
 	ObjectiveUUID string `json:"objective_uuid"`
 	CriteriaUUID  string `json:"criteria_uuid"`
 }
+
+// SetCommentToGradeDTO data transfer object to parse the request of the endpoint
+type SetCommentToGradeDTO struct {
+	TeacherUUID    string
+	LaboratoryUUID string
+	RubricUUID     string
+	StudentUUID    string
+	Comment        string
+}
diff --git a/src/grades/infrastructure/http/controllers.go b/src/grades/infrastructure/http/controllers.go
index 425a33e..e620ca7 100644
--- a/src/grades/infrastructure/http/controllers.go
+++ b/src/grades/infrastructure/http/controllers.go
@@ -79,12 +79,11 @@ func (controller *GradesController) HandleSetCriteriaGrade(c *gin.Context) {
 		return
 	}
 
-	// Create DTO
+	// Create DTO, note that the rubric field will be populated in the use case
 	dto := &dtos.SetCriteriaToGradeDTO{
 		TeacherUUID:    teacherUUID,
 		LaboratoryUUID: laboratoryUUID,
 		StudentUUID:    studentUUID,
-		RubricUUID:     request.RubricUUID,
 		ObjectiveUUID:  request.ObjectiveUUID,
 		CriteriaUUID:   request.CriteriaUUID,
 	}
@@ -137,3 +136,56 @@ func (controller *GradesController) HandleGetStudentGradeInLaboratoryWithRubric(
 
 	c.JSON(http.StatusOK, grade)
 }
+
+// HandleSetCommentToGrade controller to set a comment to a student's grade
+func (controller *GradesController) HandleSetCommentToGrade(c *gin.Context) {
+	teacherUUID := c.GetString("session_uuid")
+	laboratoryUUID := c.Param("laboratoryUUID")
+	studentUUID := c.Param("studentUUID")
+
+	// Validate UUIDs
+	requestUUIDs := requests.SetCommentToGradeRequestUUIDs{
+		StudentUUID:    studentUUID,
+		LaboratoryUUID: laboratoryUUID,
+	}
+	if err := sharedInfrastructure.GetValidator().Struct(requestUUIDs); err != nil {
+		c.JSON(http.StatusBadRequest, gin.H{
+			"message": "Please, make sure the provided UUIDs are valid",
+		})
+		return
+	}
+
+	// Parse the request body
+	var request requests.SetCommentToGradeRequest
+	if err := c.ShouldBindJSON(&request); err != nil {
+		c.JSON(http.StatusBadRequest, gin.H{
+			"message": "Request body is not valid",
+		})
+		return
+	}
+
+	// Validate the request body
+	if err := sharedInfrastructure.GetValidator().Struct(request); err != nil {
+		c.JSON(http.StatusBadRequest, gin.H{
+			"message": "Validation error",
+			"errors":  err.Error(),
+		})
+		return
+	}
+
+	// Create DTO. Note that the rubric field will be populated in the use case
+	dto := &dtos.SetCommentToGradeDTO{
+		TeacherUUID:    teacherUUID,
+		LaboratoryUUID: laboratoryUUID,
+		StudentUUID:    studentUUID,
+		Comment:        request.Comment,
+	}
+
+	err := controller.UseCases.SetCommentToGrade(dto)
+	if err != nil {
+		c.Error(err)
+		return
+	}
+
+	c.Status(http.StatusNoContent)
+}
diff --git a/src/grades/infrastructure/http/routes.go b/src/grades/infrastructure/http/routes.go
index 7493c60..2f13533 100644
--- a/src/grades/infrastructure/http/routes.go
+++ b/src/grades/infrastructure/http/routes.go
@@ -42,4 +42,11 @@ func StartGradesRoutes(g *gin.RouterGroup) {
 		sharedInfrastructure.WithAuthorizationMiddleware([]string{"teacher"}),
 		controller.HandleSetCriteriaGrade,
 	)
+
+	gradesGroup.PUT(
+		"/laboratories/:laboratoryUUID/students/:studentUUID/comment",
+		sharedInfrastructure.WithAuthenticationMiddleware(),
+		sharedInfrastructure.WithAuthorizationMiddleware([]string{"teacher"}),
+		controller.HandleSetCommentToGrade,
+	)
 }
diff --git a/src/grades/infrastructure/implementations/grades_postgres_repository.go b/src/grades/infrastructure/implementations/grades_postgres_repository.go
index c6fe05e..33f37a3 100644
--- a/src/grades/infrastructure/implementations/grades_postgres_repository.go
+++ b/src/grades/infrastructure/implementations/grades_postgres_repository.go
@@ -279,3 +279,69 @@ func (repository *GradesPostgresRepository) GetStudentGradeInLaboratoryWithRubri
 
 	return grade, nil
 }
+
+// SetCommentToGrade sets a comment to a student's grade
+func (repository *GradesPostgresRepository) SetCommentToGrade(dto *dtos.SetCommentToGradeDTO) error {
+	ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
+	defer cancel()
+
+	// Check if the student has a grade in the laboratory
+	studentHasGrade, err := repository.doesStudentHasGrade(&dtos.CheckIfStudentHasGradeDTO{
+		StudentUUID:    dto.StudentUUID,
+		LaboratoryUUID: dto.LaboratoryUUID,
+		RubricUUID:     dto.RubricUUID,
+	})
+	if err != nil {
+		return err
+	}
+
+	// Get the UUID of the grade of the student in the laboratory with the given rubric
+	studentGradeUUID := ""
+
+	if !studentHasGrade {
+		// Create a grade for the student if they do not have one
+		studentGradeUUID, err = repository.createStudentGrade(&dtos.CreateStudentGradeDTO{
+			CheckIfStudentHasGradeDTO: dtos.CheckIfStudentHasGradeDTO{
+				StudentUUID:    dto.StudentUUID,
+				LaboratoryUUID: dto.LaboratoryUUID,
+				RubricUUID:     dto.RubricUUID,
+			},
+		})
+
+		if err != nil {
+			return err
+		}
+	} else {
+		// Get the UUID of the grade of the student in the laboratory with the given rubric
+		studentGradeUUID, err = repository.getStudentGradeUUID(&dtos.GetStudentGradeDTO{
+			CheckIfStudentHasGradeDTO: dtos.CheckIfStudentHasGradeDTO{
+				StudentUUID:    dto.StudentUUID,
+				LaboratoryUUID: dto.LaboratoryUUID,
+				RubricUUID:     dto.RubricUUID,
+			},
+		})
+
+		if err != nil {
+			return err
+		}
+	}
+
+	// Set the comment to the grade
+	query := `
+		UPDATE grades
+		SET comment = $1
+		WHERE id = $2
+	`
+
+	// Run the query
+	if _, err := repository.Connection.ExecContext(
+		ctx,
+		query,
+		dto.Comment,
+		studentGradeUUID,
+	); err != nil {
+		return err
+	}
+
+	return nil
+}
diff --git a/src/grades/infrastructure/requests/grades_requests.go b/src/grades/infrastructure/requests/grades_requests.go
index ca9db36..27d8028 100644
--- a/src/grades/infrastructure/requests/grades_requests.go
+++ b/src/grades/infrastructure/requests/grades_requests.go
@@ -4,7 +4,6 @@ package requests
 type SetCriteriaToGradeRequest struct {
 	CriteriaUUID  *string `json:"criteria_uuid" validate:"omitempty,uuid4"`
 	ObjectiveUUID string  `json:"objective_uuid" validate:"required,uuid4"`
-	RubricUUID    string  `json:"rubric_uuid" validate:"required,uuid4"`
 }
 
 type SetCriteriaToGradeRequestUUIDs struct {
@@ -19,3 +18,14 @@ type GetStudentGradeInLaboratoryWithRubricRequest struct {
 	RubricUUID     string `validate:"required,uuid4"`
 	StudentUUID    string `validate:"required,uuid4"`
 }
+
+// SetCommentToGradeRequestUUIDs
+type SetCommentToGradeRequestUUIDs struct {
+	StudentUUID    string `validate:"required,uuid4"`
+	LaboratoryUUID string `validate:"required,uuid4"`
+}
+
+// SetCommentToGradeRequest request to set a comment to an student's grade
+type SetCommentToGradeRequest struct {
+	Comment string `json:"comment" validate:"required,min=8,max=510"`
+}

From 67079468caf8bd4f3745a602e06ff8c0f3ba0f89 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pedro=20Andr=C3=A9s=20Chaparro=20Quintero?=
 <pedro.chaparro.2020@upb.edu.co>
Date: Thu, 18 Jan 2024 14:05:52 -0500
Subject: [PATCH 4/6] test(grades): Add test to ensure teachers can update the
 comment of an student's grade

---
 __tests__/integration/grades_test.go       | 20 +++++++++++------
 __tests__/integration/grades_utils_test.go | 25 ++++++++++++++++++++--
 2 files changed, 37 insertions(+), 8 deletions(-)

diff --git a/__tests__/integration/grades_test.go b/__tests__/integration/grades_test.go
index bd124ce..10cc5cc 100644
--- a/__tests__/integration/grades_test.go
+++ b/__tests__/integration/grades_test.go
@@ -7,7 +7,7 @@ import (
 	"github.com/stretchr/testify/require"
 )
 
-func TestSetCriteriaToStudentSubmission(t *testing.T) {
+func TestGradeStudentSubmission(t *testing.T) {
 	c := require.New(t)
 
 	// ## Test preparation
@@ -78,18 +78,26 @@ func TestSetCriteriaToStudentSubmission(t *testing.T) {
 	firstStudent := enrolledStudents[0].(map[string]interface{})
 	studentUUID := firstStudent["uuid"].(string)
 
-	// ## Test execution
+	// ## Test: Set criteria to student grade
 	// Select the criteria for the student grade
 	_, code := SetCriteriaToStudentGrade(&SetCriteriaToStudentGradeUtilsDTO{
 		LaboratoryUUID: laboratoryUUID,
-		RubricUUID:     rubricUUID,
 		StudentUUID:    studentUUID,
 		ObjectiveUUID:  objectiveUUID,
 		CriteriaUUID:   criteriaUUID,
 	}, cookie)
 	c.Equal(http.StatusNoContent, code)
 
-	// Get all the grades of students in the laboratory
+	// ## Test: Set comment to student grade
+	comment := "Set criteria to student grade test - comment"
+	_, code = SetCommentToStudentGrade(&SetCommentToStudentGradeUtilsDTO{
+		LaboratoryUUID: laboratoryUUID,
+		StudentUUID:    studentUUID,
+		Comment:        comment,
+	}, cookie)
+	c.Equal(http.StatusNoContent, code)
+
+	// ## Test: Get all the grades of students in the laboratory
 	studentGradeResponse, code := GetSummarizedGrades(laboratoryUUID, cookie)
 	c.Equal(http.StatusOK, code)
 
@@ -100,7 +108,7 @@ func TestSetCriteriaToStudentSubmission(t *testing.T) {
 	c.Equal(studentUUID, firstStudentGrade["student_uuid"].(string))
 	c.Equal(criteriaWeight, firstStudentGrade["grade"].(float64))
 
-	// Get the grade of the student in the laboratory
+	// ## Test: Get the grade of the student in the laboratory
 	studentGradeResponse, code = GetStudentGrade(&GetStudentGradeUtilsDTO{
 		LaboratoryUUID: laboratoryUUID,
 		RubricUUID:     rubricUUID,
@@ -112,7 +120,7 @@ func TestSetCriteriaToStudentSubmission(t *testing.T) {
 	c.Equal(criteriaWeight, studentGrade)
 
 	gradeComment := studentGradeResponse["comment"].(string)
-	c.Equal("", gradeComment)
+	c.Equal(comment, gradeComment)
 
 	selectedCriteriaList := studentGradeResponse["selected_criteria"].([]interface{})
 	c.Equal(1, len(selectedCriteriaList))
diff --git a/__tests__/integration/grades_utils_test.go b/__tests__/integration/grades_utils_test.go
index 93d7f95..c01fd5a 100644
--- a/__tests__/integration/grades_utils_test.go
+++ b/__tests__/integration/grades_utils_test.go
@@ -17,7 +17,6 @@ func GetSummarizedGrades(laboratoryUUID string, cookie *http.Cookie) (response m
 
 type SetCriteriaToStudentGradeUtilsDTO struct {
 	LaboratoryUUID string
-	RubricUUID     string
 	StudentUUID    string
 	ObjectiveUUID  string
 	CriteriaUUID   string
@@ -28,7 +27,6 @@ func SetCriteriaToStudentGrade(dto *SetCriteriaToStudentGradeUtilsDTO, cookie *h
 	w, r := PrepareRequest("PUT", endpoint, map[string]interface{}{
 		"objective_uuid": dto.ObjectiveUUID,
 		"criteria_uuid":  dto.CriteriaUUID,
-		"rubric_uuid":    dto.RubricUUID,
 	})
 	r.AddCookie(cookie)
 	router.ServeHTTP(w, r)
@@ -58,3 +56,26 @@ func GetStudentGrade(dto *GetStudentGradeUtilsDTO, cookie *http.Cookie) (respons
 	jsonResponse := ParseJsonResponse(w.Body)
 	return jsonResponse, w.Code
 }
+
+type SetCommentToStudentGradeUtilsDTO struct {
+	LaboratoryUUID string
+	StudentUUID    string
+	Comment        string
+}
+
+func SetCommentToStudentGrade(dto *SetCommentToStudentGradeUtilsDTO, cookie *http.Cookie) (response map[string]interface{}, statusCode int) {
+	endpoint := fmt.Sprintf(
+		"/api/v1/grades/laboratories/%s/students/%s/comment",
+		dto.LaboratoryUUID,
+		dto.StudentUUID,
+	)
+
+	w, r := PrepareRequest("PUT", endpoint, map[string]interface{}{
+		"comment": dto.Comment,
+	})
+	r.AddCookie(cookie)
+	router.ServeHTTP(w, r)
+
+	jsonResponse := ParseJsonResponse(w.Body)
+	return jsonResponse, w.Code
+}

From 4e4d7477ccee779ff382c5879af71da7a525a168 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pedro=20Andr=C3=A9s=20Chaparro=20Quintero?=
 <pedro.chaparro.2020@upb.edu.co>
Date: Thu, 18 Jan 2024 14:06:56 -0500
Subject: [PATCH 5/6] feat(labs): Add UUID of students' submissions to test
 blocks

---
 src/laboratories/application/use_cases.go     |  2 +-
 .../definitions/laboratories_repository.go    |  2 +-
 .../domain/dtos/laboratories_dtos.go          |  1 +
 .../domain/entities/test_block.go             | 11 ++---
 .../infrastructure/http/controllers.go        |  3 ++
 .../laboratories_respository.go               | 44 +++++++++++++++----
 src/submissions/application/use_cases.go      |  2 +-
 7 files changed, 48 insertions(+), 17 deletions(-)

diff --git a/src/laboratories/application/use_cases.go b/src/laboratories/application/use_cases.go
index d1e4efa..bfceb11 100644
--- a/src/laboratories/application/use_cases.go
+++ b/src/laboratories/application/use_cases.go
@@ -41,7 +41,7 @@ func (useCases *LaboratoriesUseCases) CreateLaboratory(dto *dtos.CreateLaborator
 
 func (useCases *LaboratoriesUseCases) GetLaboratory(dto *dtos.GetLaboratoryDTO) (laboratory *entities.Laboratory, err error) {
 	// Get the laboratory
-	laboratory, err = useCases.LaboratoriesRepository.GetLaboratoryByUUID(dto.LaboratoryUUID)
+	laboratory, err = useCases.LaboratoriesRepository.GetLaboratoryByUUID(dto)
 	if err != nil {
 		return nil, err
 	}
diff --git a/src/laboratories/domain/definitions/laboratories_repository.go b/src/laboratories/domain/definitions/laboratories_repository.go
index 9ca2382..61b1622 100644
--- a/src/laboratories/domain/definitions/laboratories_repository.go
+++ b/src/laboratories/domain/definitions/laboratories_repository.go
@@ -6,7 +6,7 @@ import (
 )
 
 type LaboratoriesRepository interface {
-	GetLaboratoryByUUID(uuid string) (laboratory *entities.Laboratory, err error)
+	GetLaboratoryByUUID(dto *dtos.GetLaboratoryDTO) (laboratory *entities.Laboratory, err error)
 	GetLaboratoryInformationByUUID(uuid string) (laboratory *dtos.LaboratoryDetailsDTO, err error)
 	SaveLaboratory(dto *dtos.CreateLaboratoryDTO) (laboratory *entities.Laboratory, err error)
 	UpdateLaboratory(dto *dtos.UpdateLaboratoryDTO) error
diff --git a/src/laboratories/domain/dtos/laboratories_dtos.go b/src/laboratories/domain/dtos/laboratories_dtos.go
index ee1a938..b727f4b 100644
--- a/src/laboratories/domain/dtos/laboratories_dtos.go
+++ b/src/laboratories/domain/dtos/laboratories_dtos.go
@@ -13,6 +13,7 @@ type CreateLaboratoryDTO struct {
 type GetLaboratoryDTO struct {
 	LaboratoryUUID string
 	UserUUID       string
+	UserRole       string
 }
 
 type UpdateLaboratoryDTO struct {
diff --git a/src/laboratories/domain/entities/test_block.go b/src/laboratories/domain/entities/test_block.go
index 50f78c0..ea25565 100644
--- a/src/laboratories/domain/entities/test_block.go
+++ b/src/laboratories/domain/entities/test_block.go
@@ -1,9 +1,10 @@
 package entities
 
 type TestBlock struct {
-	UUID            string `json:"uuid"`
-	LanguageUUID    string `json:"language_uuid"`
-	TestArchiveUUID string `json:"test_archive_uuid"`
-	Name            string `json:"name"`
-	Index           int    `json:"index"`
+	UUID            string  `json:"uuid"`
+	LanguageUUID    string  `json:"language_uuid"`
+	TestArchiveUUID *string `json:"test_archive_uuid"`
+	SubmissionUUID  *string `json:"submission_uuid"`
+	Name            string  `json:"name"`
+	Index           int     `json:"index"`
 }
diff --git a/src/laboratories/infrastructure/http/controllers.go b/src/laboratories/infrastructure/http/controllers.go
index cebeba6..f4978dd 100644
--- a/src/laboratories/infrastructure/http/controllers.go
+++ b/src/laboratories/infrastructure/http/controllers.go
@@ -68,6 +68,8 @@ func (controller *LaboratoriesController) HandleCreateLaboratory(c *gin.Context)
 
 func (controller *LaboratoriesController) HandleGetLaboratory(c *gin.Context) {
 	userUUID := c.GetString("session_uuid")
+	userRole := c.GetString("session_role")
+
 	laboratoryUUID := c.Param("laboratory_uuid")
 
 	// Validate the laboratory UUID
@@ -82,6 +84,7 @@ func (controller *LaboratoriesController) HandleGetLaboratory(c *gin.Context) {
 	dto := dtos.GetLaboratoryDTO{
 		LaboratoryUUID: laboratoryUUID,
 		UserUUID:       userUUID,
+		UserRole:       userRole,
 	}
 
 	laboratory, err := controller.UseCases.GetLaboratory(&dto)
diff --git a/src/laboratories/infrastructure/implementations/laboratories_respository.go b/src/laboratories/infrastructure/implementations/laboratories_respository.go
index 5099384..ea20954 100644
--- a/src/laboratories/infrastructure/implementations/laboratories_respository.go
+++ b/src/laboratories/infrastructure/implementations/laboratories_respository.go
@@ -28,7 +28,7 @@ func GetLaboratoriesPostgresRepositoryInstance() *LaboratoriesPostgresRepository
 	return laboratoriesPostgresRepositoryInstance
 }
 
-func (repository *LaboratoriesPostgresRepository) GetLaboratoryByUUID(uuid string) (laboratory *entities.Laboratory, err error) {
+func (repository *LaboratoriesPostgresRepository) GetLaboratoryByUUID(dto *dtos.GetLaboratoryDTO) (laboratory *entities.Laboratory, err error) {
 	ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
 	defer cancel()
 
@@ -39,7 +39,7 @@ func (repository *LaboratoriesPostgresRepository) GetLaboratoryByUUID(uuid strin
 		WHERE id = $1
 	`
 
-	row := repository.Connection.QueryRowContext(ctx, query, uuid)
+	row := repository.Connection.QueryRowContext(ctx, query, dto.LaboratoryUUID)
 	laboratory = &entities.Laboratory{}
 	rubricUUID := sql.NullString{}
 	if err := row.Scan(&laboratory.UUID, &laboratory.CourseUUID, &rubricUUID, &laboratory.Name, &laboratory.OpeningDate, &laboratory.DueDate); err != nil {
@@ -57,7 +57,7 @@ func (repository *LaboratoriesPostgresRepository) GetLaboratoryByUUID(uuid strin
 	}
 
 	// Get markdown blocks
-	markdownBlocks, err := repository.getMarkdownBlocks(uuid)
+	markdownBlocks, err := repository.getMarkdownBlocks(dto.LaboratoryUUID)
 	if err != nil {
 		return nil, err
 	}
@@ -65,7 +65,7 @@ func (repository *LaboratoriesPostgresRepository) GetLaboratoryByUUID(uuid strin
 	laboratory.MarkdownBlocks = markdownBlocks
 
 	// Get test blocks
-	testBlocks, err := repository.getTestBlocks(uuid)
+	testBlocks, err := repository.getTestBlocks(dto)
 	if err != nil {
 		return nil, err
 	}
@@ -145,19 +145,24 @@ func (repository *LaboratoriesPostgresRepository) getMarkdownBlocks(laboratoryUU
 	return markdownBlocks, nil
 }
 
-func (repository *LaboratoriesPostgresRepository) getTestBlocks(laboratoryUUID string) ([]entities.TestBlock, error) {
+func (repository *LaboratoriesPostgresRepository) getTestBlocks(dto *dtos.GetLaboratoryDTO) ([]entities.TestBlock, error) {
 	ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
 	defer cancel()
 
 	query := `
-		SELECT tb.id, tb.language_id, tb.test_archive_id, tb.name, bi.block_position
+		SELECT tb.id, tb.language_id, tb.test_archive_id, tb.name, bi.block_position, s.id
 		FROM test_blocks tb
 		RIGHT JOIN blocks_index bi ON tb.block_index_id = bi.id
+		LEFT JOIN submissions s ON tb.id = s.test_block_id AND s.student_id = $2
 		WHERE tb.laboratory_id = $1
 		ORDER BY bi.block_position ASC
 	`
 
-	rows, err := repository.Connection.QueryContext(ctx, query, laboratoryUUID)
+	rows, err := repository.Connection.QueryContext(
+		ctx,
+		query,
+		dto.LaboratoryUUID, dto.UserUUID,
+	)
 	if err != nil {
 		return nil, err
 	}
@@ -165,10 +170,27 @@ func (repository *LaboratoriesPostgresRepository) getTestBlocks(laboratoryUUID s
 	testBlocks := []entities.TestBlock{}
 	for rows.Next() {
 		testBlock := entities.TestBlock{}
-		if err := rows.Scan(&testBlock.UUID, &testBlock.LanguageUUID, &testBlock.TestArchiveUUID, &testBlock.Name, &testBlock.Index); err != nil {
+		if err := rows.Scan(
+			&testBlock.UUID,
+			&testBlock.LanguageUUID,
+			&testBlock.TestArchiveUUID,
+			&testBlock.Name,
+			&testBlock.Index,
+			&testBlock.SubmissionUUID,
+		); err != nil {
 			return nil, err
 		}
 
+		// If the user is an student, hide the test archive UUID
+		if dto.UserRole == "student" {
+			testBlock.TestArchiveUUID = nil
+		}
+
+		// If the user is a teacher, hide the submission UUID
+		if dto.UserRole == "teacher" {
+			testBlock.SubmissionUUID = nil
+		}
+
 		testBlocks = append(testBlocks, testBlock)
 	}
 
@@ -191,7 +213,11 @@ func (repository *LaboratoriesPostgresRepository) SaveLaboratory(dto *dtos.Creat
 		return nil, err
 	}
 
-	return repository.GetLaboratoryByUUID(laboratoryUUID)
+	return repository.GetLaboratoryByUUID(&dtos.GetLaboratoryDTO{
+		LaboratoryUUID: laboratoryUUID,
+		UserUUID:       dto.TeacherUUID,
+		UserRole:       "teacher",
+	})
 }
 
 func (repository *LaboratoriesPostgresRepository) UpdateLaboratory(dto *dtos.UpdateLaboratoryDTO) error {
diff --git a/src/submissions/application/use_cases.go b/src/submissions/application/use_cases.go
index 4d9c9ea..226aad9 100644
--- a/src/submissions/application/use_cases.go
+++ b/src/submissions/application/use_cases.go
@@ -108,7 +108,7 @@ func (useCases *SubmissionUseCases) isTestBlockLaboratoryOpen(testBlockUUID stri
 	}
 
 	// Get the laboratory
-	laboratory, err := useCases.LaboratoriesRepository.GetLaboratoryByUUID(laboratoryUUID)
+	laboratory, err := useCases.LaboratoriesRepository.GetLaboratoryInformationByUUID(laboratoryUUID)
 	if err != nil {
 		return false, err
 	}

From d1de7d75ceb3284786ca7303f8ddede258240933 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pedro=20Andr=C3=A9s=20Chaparro=20Quintero?=
 <pedro.chaparro.2020@upb.edu.co>
Date: Thu, 18 Jan 2024 14:07:05 -0500
Subject: [PATCH 6/6] docs(http): Update bruno collection

---
 .../grades/set-comment-to-student-grade.bru     | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)
 create mode 100644 docs/bruno/grades/set-comment-to-student-grade.bru

diff --git a/docs/bruno/grades/set-comment-to-student-grade.bru b/docs/bruno/grades/set-comment-to-student-grade.bru
new file mode 100644
index 0000000..f58bdc0
--- /dev/null
+++ b/docs/bruno/grades/set-comment-to-student-grade.bru
@@ -0,0 +1,17 @@
+meta {
+  name: set-comment-to-student-grade
+  type: http
+  seq: 4
+}
+
+put {
+  url: {{BASE_URL}}/grades/laboratories/d0ce7e95-59b4-4ac1-9238-461e9a47ce1d/students/3fd0671b-8673-4282-94f5-9bd6300d943f/comment
+  body: json
+  auth: none
+}
+
+body:json {
+  {
+    "comment": "Good job"
+  }
+}