Skip to content

Commit 5bf61d9

Browse files
CheongYeeMingLuYiting0913RichDom2185YaleChen299
authored
Add Team Assessments (#968)
* Update assessment schema and add max_team_size as a required field * Update assessment schema and add max_team_size as a required field * Add max team size to assessment controller payload * Update mix.exs * Create migrations for team assessments * Add Team Formation Models * Fix line endings * Fix line endings * Establish connection with Frontend * Generate seeds for team and team_member * Fix line endings * Add API call to retrieve team formation students * Add Validation for Create Team * Update response for Create and Delete Team API * Add Update Teams API call * Modify helper function * Update seeds * Modify TeamMember migration * Update AlterSubmissionsTable migration * Add API to retrieve TeamFormationOverview for students * Add Delete Team * Refactor SQL chunk to fetch both Team and Individual submissions * Add retrieve Team Submission * Add create empty submission for Team submission * Add cascade delete answer when Team is deleted * Update XOR validation in Submission * Remove bulk_upload API call and doc * Add retrieve of team submission answers * Add unsubmit for team submission * Add retrieval of team submissions for grading * Add handle team submission notifications * Remove io inspect statement * Remove io inspect statement * Revert seeds * Revert seeds * Revert seeds * Add last_modified_at field for Answer * Add Save-Safe * Add documentation for models * Minor refactoring of Teams * Add Swagger Documentation for AdminTeamsController * Write Function Documentation for Teams * Add documentation and minor refactoring * Minor changes to existing tests * Cascade delete notification for submission * Update error message for team creation * Update assessments Team retrieval * Add cascading delete for notifications * Fix Team Delete Bug * Fix save answer bug when no team * Raise exception when mass team imports violates constraints * remove test file * Fix bug of importing duplicate students through excel * Refactor default max team size to 1 * Check size of the team before insertion * Fix format * Fix unsubmit handle notifications bug * Fix end of line issue * Fix end of line issue * Fix end of line issue * Raise exception when some of the students in mass team import are not enrolled in the course * Update docs * Fix Submission Grading Bug * Update docs * Fix team deletion bug when there is a submitted assessment * Send proper error msg to frontend when delete team fails * Resolve merge conflict from upstream * Merge conflict * Retrieve Team Submission Details * Fix failed test cases * Add test cases * Team Member Factory * add team tests * Modify Submission Factory to include Team Submission * Write test for Team Members * Increase COV for Notification Test * Prepend unused variable with underscore * Answer View Test * Team View Test * Update Admin Teams Controller * Admin Teams Controller Test * Clean up test cases * Improve test coverage for teams * Improve test coverage for team controller * Improve submission test coverage * Remove unrecheable code * Empty Guardian Test * Answer Controller Test * Notification Test * improve test coverage for assessments * Improve test coverage for assessments * Clean up test cases * Update Swagger Documentation * Modify AddMaxTeamSizeToAssessments migration file * Remove unused variable in notification test * Fix format * Fix credo errors * Fix casing (code quality) * Fix other miscellaneous code quality issues * Revert credo dependency version update * Fix credo configuration * Fix failing tests * Remove unused variables * Fix failing tests * Remove IO.inspect * Fix dialyzer CI * Run mix format * Fix format * Simplify code * Group multiple aliases together * Remove unnecesary newlines * Reorder/revert/reformat unnecessary changes to simplify diff * Revert file permission changes * Remove commented code * Revert status code changes * Fix tests following status code change revert * Remove redundant conversion * Add comment to notifications * Add validation for max team size * Update assessment changeset testcase * Abstract out find teams * Remove repeated code * Abstraction of XOR logic * Fix format * Fix failing tests * Run format * Fix format * Redate migrations To ensure proper ordering * Fix format post-merge * Remove typo * Revert dependency downgrades * Revert incorrect merge conflict resolution * Fix tests * Update status code for not found * Fix test for not found status code --------- Co-authored-by: Lu Yiting <[email protected]> Co-authored-by: LuYiting0913 <[email protected]> Co-authored-by: Richard Dominick <[email protected]> Co-authored-by: Chen Yanyu <[email protected]>
1 parent bba4b1a commit 5bf61d9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+3113
-105
lines changed

.credo.exs

+1-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@
9494
{Credo.Check.Readability.SpaceAfterCommas},
9595
{Credo.Check.Refactor.DoubleBooleanNegation},
9696
{Credo.Check.Refactor.CondStatements},
97-
{Credo.Check.Refactor.CyclomaticComplexity},
97+
{Credo.Check.Refactor.CyclomaticComplexity, max_complexity: 10},
9898
{Credo.Check.Refactor.FunctionArity},
9999
{Credo.Check.Refactor.LongQuoteBlocks},
100100
{Credo.Check.Refactor.MatchInCondition},

.iex.exs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import Ecto.Query
22
alias Cadet.Repo
3-
alias Cadet.Accounts.User
3+
alias Cadet.Accounts.{User, Team, TeamMember}
44
alias Cadet.Assessments.{Answer, Assessment, Question, Submission}
55
alias Cadet.Courses.Group

lib/cadet/accounts/notifications.ex

+64-12
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ defmodule Cadet.Accounts.Notifications do
88
import Ecto.Query
99

1010
alias Cadet.Repo
11-
alias Cadet.Accounts.{Notification, CourseRegistration, CourseRegistration}
11+
alias Cadet.Accounts.{Notification, CourseRegistration, CourseRegistration, Team, TeamMember}
1212
alias Cadet.Assessments.Submission
1313
alias Ecto.Multi
1414

@@ -169,17 +169,47 @@ defmodule Cadet.Accounts.Notifications do
169169
@spec write_notification_when_graded(integer(), any()) ::
170170
{:ok, Ecto.Schema.t()} | {:error, Ecto.Changeset.t()}
171171
def write_notification_when_graded(submission_id, type) when type in [:graded, :autograded] do
172-
submission =
173-
Submission
174-
|> Repo.get_by(id: submission_id)
172+
case Repo.get(Submission, submission_id) do
173+
nil ->
174+
{:error, %Ecto.Changeset{}}
175175

176-
write(%{
177-
type: type,
178-
read: false,
179-
role: :student,
180-
course_reg_id: submission.student_id,
181-
assessment_id: submission.assessment_id
182-
})
176+
submission ->
177+
case submission.student_id do
178+
nil ->
179+
team = Repo.get(Team, submission.team_id)
180+
181+
query =
182+
from(t in Team,
183+
join: tm in TeamMember,
184+
on: t.id == tm.team_id,
185+
join: cr in CourseRegistration,
186+
on: tm.student_id == cr.id,
187+
where: t.id == ^team.id,
188+
select: cr.id
189+
)
190+
191+
team_members = Repo.all(query)
192+
193+
Enum.each(team_members, fn tm_id ->
194+
write(%{
195+
type: type,
196+
read: false,
197+
role: :student,
198+
course_reg_id: tm_id,
199+
assessment_id: submission.assessment_id
200+
})
201+
end)
202+
203+
student_id ->
204+
write(%{
205+
type: type,
206+
read: false,
207+
role: :student,
208+
course_reg_id: student_id,
209+
assessment_id: submission.assessment_id
210+
})
211+
end
212+
end
183213
end
184214

185215
@doc """
@@ -223,7 +253,29 @@ defmodule Cadet.Accounts.Notifications do
223253
@spec write_notification_when_student_submits(Submission.t()) ::
224254
{:ok, Ecto.Schema.t()} | {:error, Ecto.Changeset.t()}
225255
def write_notification_when_student_submits(submission = %Submission{}) do
226-
avenger_id = get_avenger_id_of(submission.student_id)
256+
id =
257+
case submission.student_id do
258+
nil ->
259+
team_id = submission.team_id
260+
261+
team =
262+
Repo.one(
263+
from(t in Team,
264+
where: t.id == ^team_id,
265+
preload: [:team_members]
266+
)
267+
)
268+
269+
# Does not matter if team members have different Avengers
270+
# Just require one of them to be notified of the submission
271+
s_id = team.team_members |> hd() |> Map.get(:student_id)
272+
s_id
273+
274+
_ ->
275+
submission.student_id
276+
end
277+
278+
avenger_id = get_avenger_id_of(id)
227279

228280
if is_nil(avenger_id) do
229281
{:ok, nil}

lib/cadet/accounts/team.ex

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
defmodule Cadet.Accounts.Team do
2+
@moduledoc """
3+
This module defines the Ecto schema and changeset for teams in the Cadet.Accounts context.
4+
Teams represent groups of students collaborating on an assessment within a course.
5+
"""
6+
7+
use Cadet, :model
8+
9+
alias Cadet.Accounts.TeamMember
10+
alias Cadet.Assessments.{Assessment, Submission}
11+
12+
@doc """
13+
Ecto schema definition for teams.
14+
This schema represents a group of students collaborating on a specific assessment within a course.
15+
Fields:
16+
- `assessment`: A reference to the assessment associated with the team.
17+
- `submission`: A reference to the team's submission for the assessment.
18+
- `team_members`: A list of team members associated with the team.
19+
"""
20+
schema "teams" do
21+
belongs_to(:assessment, Assessment)
22+
has_one(:submission, Submission, on_delete: :delete_all)
23+
has_many(:team_members, TeamMember, on_delete: :delete_all)
24+
25+
timestamps()
26+
end
27+
28+
@required_fields ~w(assessment_id)a
29+
30+
@doc """
31+
Builds an Ecto changeset for a team.
32+
This function is used to create or update a team record based on the provided attributes.
33+
Args:
34+
- `team`: The existing team struct.
35+
- `attrs`: The attributes to be cast and validated for the changeset.
36+
Returns:
37+
A changeset struct with cast and validated attributes.
38+
"""
39+
def changeset(team, attrs) do
40+
team
41+
|> cast(attrs, @required_fields)
42+
|> validate_required(@required_fields)
43+
|> foreign_key_constraint(:assessment_id)
44+
end
45+
end

lib/cadet/accounts/team_member.ex

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
defmodule Cadet.Accounts.TeamMember do
2+
@moduledoc """
3+
This module defines the Ecto schema and changeset for team members in the Cadet.Accounts context.
4+
Team members represent the association between a student and a team within a course.
5+
"""
6+
7+
use Ecto.Schema
8+
9+
import Ecto.Changeset
10+
11+
alias Cadet.Accounts.{CourseRegistration, Team}
12+
13+
@doc """
14+
Ecto schema definition for team members.
15+
This schema represents the relationship between a student and a team within a course.
16+
Fields:
17+
- `student`: A reference to the student's course registration.
18+
- `team`: A reference to the team associated with the student.
19+
"""
20+
schema "team_members" do
21+
belongs_to(:student, CourseRegistration)
22+
belongs_to(:team, Team)
23+
24+
timestamps()
25+
end
26+
27+
@required_fields ~w(student_id team_id)a
28+
29+
@doc """
30+
Builds an Ecto changeset for a team member.
31+
This function is used to create or update a team member record based on the provided attributes.
32+
Args:
33+
- `team_member`: The existing team member struct.
34+
- `attrs`: The attributes to be cast and validated for the changeset.
35+
Returns:
36+
A changeset struct with cast and validated attributes.
37+
"""
38+
def changeset(team_member, attrs) do
39+
team_member
40+
|> cast(attrs, @required_fields)
41+
|> validate_required(@required_fields)
42+
|> foreign_key_constraint(:team_id)
43+
|> foreign_key_constraint(:student_id)
44+
end
45+
end

0 commit comments

Comments
 (0)