Skip to content

Commit 4a12095

Browse files
authored
Merge branch 'master' into copilot/fix-1285
2 parents 1eb2cfd + 413a358 commit 4a12095

File tree

3 files changed

+48
-55
lines changed

3 files changed

+48
-55
lines changed

lib/cadet/assessments/assessments.ex

Lines changed: 41 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -182,21 +182,25 @@ defmodule Cadet.Assessments do
182182
total_achievement_xp + total_assessment_xp
183183
end
184184

185-
def all_user_total_xp(course_id, offset \\ nil, limit \\ nil) do
185+
186+
def all_user_total_xp(course_id, options \\ %{}) do
186187
Logger.info("Fetching total XP for all users in course #{course_id}")
188+
include_admin_staff_users = fn q ->
189+
if options[:include_admin_staff],
190+
do: q,
191+
else: where(q, [_, cr], cr.role == "student")
192+
end
193+
187194
# get all users even if they have 0 xp
188-
base_user_query =
189-
from(
190-
cr in CourseRegistration,
191-
join: u in User,
192-
on: cr.user_id == u.id,
193-
where: cr.course_id == ^course_id,
194-
select: %{
195-
user_id: u.id,
196-
name: u.name,
197-
username: u.username
198-
}
199-
)
195+
course_userid_query =
196+
User
197+
|> join(:inner, [u], cr in CourseRegistration, on: cr.user_id == u.id)
198+
|> where([_, cr], cr.course_id == ^course_id)
199+
|> include_admin_staff_users.()
200+
|> select([u, cr], %{
201+
id: u.id,
202+
cr_id: cr.id
203+
})
200204

201205
achievements_xp_query =
202206
from(u in User,
@@ -212,7 +216,7 @@ defmodule Cadet.Assessments do
212216
a.course_id == ^course_id and p.completed and
213217
p.count == g.target_count,
214218
group_by: [u.id, u.name, u.username, cr.id],
215-
select_merge: %{
219+
select: %{
216220
user_id: u.id,
217221
achievements_xp:
218222
fragment(
@@ -225,42 +229,30 @@ defmodule Cadet.Assessments do
225229
)
226230

227231
submissions_xp_query =
228-
from(
229-
sub_xp in subquery(
230-
from(cr in CourseRegistration,
231-
join: u in User,
232-
on: cr.user_id == u.id,
233-
full_join: tm in TeamMember,
234-
on: cr.id == tm.student_id,
235-
join: s in Submission,
236-
on: tm.team_id == s.team_id or s.student_id == cr.id,
237-
join: a in Answer,
238-
on: s.id == a.submission_id,
239-
where: s.is_grading_published == true and cr.course_id == ^course_id,
240-
group_by: [cr.id, u.id, u.name, u.username, s.id, a.xp, a.xp_adjustment],
241-
select: %{
242-
user_id: u.id,
243-
submission_xp: a.xp + a.xp_adjustment + max(s.xp_bonus)
244-
}
245-
)
246-
),
247-
group_by: sub_xp.user_id,
248-
select: %{
249-
user_id: sub_xp.user_id,
250-
submission_xp: sum(sub_xp.submission_xp)
251-
}
252-
)
232+
course_userid_query
233+
|> subquery()
234+
|> join(:left, [u], tm in TeamMember, on: tm.student_id == u.cr_id)
235+
|> join(:left, [u, tm], s in Submission, on: s.student_id == u.cr_id or s.team_id == tm.id)
236+
|> join(:left, [u, tm, s], a in Answer, on: s.id == a.submission_id)
237+
|> where([_, _, s, _], s.is_grading_published == true)
238+
|> group_by([u, _, s, _], [u.id, s.id])
239+
|> select([u, _, s, a], %{
240+
user_id: u.id,
241+
submission_xp: sum(a.xp) + sum(a.xp_adjustment) + max(s.xp_bonus)
242+
})
253243

254244
total_xp_query =
255-
from(bu in subquery(base_user_query),
245+
from(cu in subquery(course_userid_query),
246+
inner_join: u in User,
247+
on: u.id == cu.id,
256248
left_join: ax in subquery(achievements_xp_query),
257-
on: bu.user_id == ax.user_id,
249+
on: u.id == ax.user_id,
258250
left_join: sx in subquery(submissions_xp_query),
259-
on: bu.user_id == sx.user_id,
251+
on: u.id == sx.user_id,
260252
select: %{
261-
user_id: bu.user_id,
262-
name: bu.name,
263-
username: bu.username,
253+
user_id: u.id,
254+
name: u.name,
255+
username: u.username,
264256
total_xp:
265257
fragment(
266258
"COALESCE(?, 0) + COALESCE(?, 0)",
@@ -274,15 +266,11 @@ defmodule Cadet.Assessments do
274266
# add rank index
275267
ranked_xp_query =
276268
from(t in subquery(total_xp_query),
277-
select: %{
278-
rank: fragment("RANK() OVER (ORDER BY total_xp DESC)"),
279-
user_id: t.user_id,
280-
name: t.name,
281-
username: t.username,
282-
total_xp: t.total_xp
269+
select_merge: %{
270+
rank: fragment("RANK() OVER (ORDER BY total_xp DESC)")
283271
},
284-
limit: ^limit,
285-
offset: ^offset
272+
limit: ^options[:limit],
273+
offset: ^options[:offset]
286274
)
287275

288276
count_query =

lib/cadet_web/controllers/leaderboard_controller.ex

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ defmodule CadetWeb.LeaderboardController do
1313
def xp_paginated(conn, %{"course_id" => course_id}) do
1414
offset = String.to_integer(conn.params["offset"] || "0")
1515
page_size = String.to_integer(conn.params["page_size"] || "25")
16-
paginated_display = Assessments.all_user_total_xp(course_id, offset, page_size)
16+
17+
paginated_display =
18+
Assessments.all_user_total_xp(course_id, %{offset: offset, limit: page_size})
19+
1720
json(conn, paginated_display)
1821
end
1922

test/cadet/assessments/assessments_test.exs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3188,7 +3188,9 @@ defmodule Cadet.AssessmentsTest do
31883188
Enum.each(1..50, fn x ->
31893189
offset = Enum.random(0..49)
31903190
limit = Enum.random(1..50)
3191-
paginated_user_xp = Assessments.all_user_total_xp(course.id, offset, limit)
3191+
3192+
paginated_user_xp =
3193+
Assessments.all_user_total_xp(course.id, %{offset: offset, limit: limit})
31923194

31933195
expected_xp_list =
31943196
50..1

0 commit comments

Comments
 (0)