Skip to content

Commit 13b73f1

Browse files
committed
Merge branch 'master' into copilot/fix-1285
2 parents 1eb2cfd + 413a358 commit 13b73f1

File tree

3 files changed

+47
-55
lines changed

3 files changed

+47
-55
lines changed

lib/cadet/assessments/assessments.ex

Lines changed: 40 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -182,21 +182,24 @@ 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+
def all_user_total_xp(course_id, options \\ %{}) do
186186
Logger.info("Fetching total XP for all users in course #{course_id}")
187+
include_admin_staff_users = fn q ->
188+
if options[:include_admin_staff],
189+
do: q,
190+
else: where(q, [_, cr], cr.role == "student")
191+
end
192+
187193
# 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-
)
194+
course_userid_query =
195+
User
196+
|> join(:inner, [u], cr in CourseRegistration, on: cr.user_id == u.id)
197+
|> where([_, cr], cr.course_id == ^course_id)
198+
|> include_admin_staff_users.()
199+
|> select([u, cr], %{
200+
id: u.id,
201+
cr_id: cr.id
202+
})
200203

201204
achievements_xp_query =
202205
from(u in User,
@@ -212,7 +215,7 @@ defmodule Cadet.Assessments do
212215
a.course_id == ^course_id and p.completed and
213216
p.count == g.target_count,
214217
group_by: [u.id, u.name, u.username, cr.id],
215-
select_merge: %{
218+
select: %{
216219
user_id: u.id,
217220
achievements_xp:
218221
fragment(
@@ -225,42 +228,30 @@ defmodule Cadet.Assessments do
225228
)
226229

227230
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-
)
231+
course_userid_query
232+
|> subquery()
233+
|> join(:left, [u], tm in TeamMember, on: tm.student_id == u.cr_id)
234+
|> join(:left, [u, tm], s in Submission, on: s.student_id == u.cr_id or s.team_id == tm.id)
235+
|> join(:left, [u, tm, s], a in Answer, on: s.id == a.submission_id)
236+
|> where([_, _, s, _], s.is_grading_published == true)
237+
|> group_by([u, _, s, _], [u.id, s.id])
238+
|> select([u, _, s, a], %{
239+
user_id: u.id,
240+
submission_xp: sum(a.xp) + sum(a.xp_adjustment) + max(s.xp_bonus)
241+
})
253242

254243
total_xp_query =
255-
from(bu in subquery(base_user_query),
244+
from(cu in subquery(course_userid_query),
245+
inner_join: u in User,
246+
on: u.id == cu.id,
256247
left_join: ax in subquery(achievements_xp_query),
257-
on: bu.user_id == ax.user_id,
248+
on: u.id == ax.user_id,
258249
left_join: sx in subquery(submissions_xp_query),
259-
on: bu.user_id == sx.user_id,
250+
on: u.id == sx.user_id,
260251
select: %{
261-
user_id: bu.user_id,
262-
name: bu.name,
263-
username: bu.username,
252+
user_id: u.id,
253+
name: u.name,
254+
username: u.username,
264255
total_xp:
265256
fragment(
266257
"COALESCE(?, 0) + COALESCE(?, 0)",
@@ -274,15 +265,11 @@ defmodule Cadet.Assessments do
274265
# add rank index
275266
ranked_xp_query =
276267
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
268+
select_merge: %{
269+
rank: fragment("RANK() OVER (ORDER BY total_xp DESC)")
283270
},
284-
limit: ^limit,
285-
offset: ^offset
271+
limit: ^options[:limit],
272+
offset: ^options[:offset]
286273
)
287274

288275
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)