Skip to content

Commit 82f7e93

Browse files
authored
Merge branch 'master' into language-options
2 parents 839988e + 40cd12a commit 82f7e93

File tree

60 files changed

+3025
-544
lines changed

Some content is hidden

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

60 files changed

+3025
-544
lines changed

.credo.exs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@
8383
{Credo.Check.Readability.ModuleNames},
8484
{Credo.Check.Readability.ParenthesesOnZeroArityDefs},
8585
{Credo.Check.Readability.ParenthesesInCondition},
86-
{Credo.Check.Readability.PredicateFunctionNames},
86+
{Credo.Check.Readability.PredicateFunctionNames, exit_status: 0},
8787
{Credo.Check.Readability.PreferImplicitTry},
8888
{Credo.Check.Readability.RedundantBlankLines},
8989
{Credo.Check.Readability.StringSigils},
@@ -94,7 +94,7 @@
9494
{Credo.Check.Readability.SpaceAfterCommas},
9595
{Credo.Check.Refactor.DoubleBooleanNegation},
9696
{Credo.Check.Refactor.CondStatements},
97-
{Credo.Check.Refactor.CyclomaticComplexity, max_complexity: 10},
97+
{Credo.Check.Refactor.CyclomaticComplexity, max_complexity: 11},
9898
{Credo.Check.Refactor.FunctionArity},
9999
{Credo.Check.Refactor.LongQuoteBlocks},
100100
{Credo.Check.Refactor.MatchInCondition},

.github/workflows/ci.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@ jobs:
2323
env:
2424
MIX_ENV: test
2525
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
26-
ELIXIR_VERSION: 1.13.4
27-
OTP_VERSION: 25.3.2
26+
ELIXIR_VERSION: 1.18.3
27+
OTP_VERSION: 27.3.3
2828
services:
2929
postgres:
30-
image: postgres:14.2
30+
image: postgres:17.4
3131
env:
3232
POSTGRES_USER: postgres
3333
POSTGRES_PASSWORD: postgres

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ Cadet is the web application powering Source Academy.
1414

1515
### System requirements
1616

17-
1. Elixir 1.13.3+ (current version: 1.13.4)
18-
2. Erlang/OTP 23.2.1+ (current version: 25.3.2)
19-
3. PostgreSQL 12+ (tested to be working up to 14.5)
17+
1. Elixir 1.18+ (current version: 1.18.3)
18+
2. Erlang/OTP 27+ (current version: 27.3.3)
19+
3. PostgreSQL 12+ (tested to be working up to 17)
2020

2121
It is probably okay to use a different version of PostgreSQL or Erlang/OTP, but using a different version of Elixir may result in differences in e.g. `mix format`.
2222

config/prod.exs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,17 @@ import Config
33
# Do not print debug messages in production
44
config :logger, level: :info
55

6+
# Add the CloudWatch logger backend in production
7+
config :logger, backends: [:console, {Cadet.Logger.CloudWatchLogger, :cloudwatch_logger}]
8+
9+
# Configure CloudWatch Logger
10+
config :logger, :cloudwatch_logger,
11+
level: :info,
12+
format: "$time $metadata[$level] $message\n",
13+
metadata: [:request_id],
14+
log_group: "cadet-logs",
15+
log_stream: "#{node()}-#{:os.system_time(:second)}"
16+
617
# ## SSL Support
718
#
819
# To get SSL working, you will need to add the `https` key

config/test.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ config :cadet, CadetWeb.Endpoint,
99
config :cadet, environment: :test
1010

1111
# Print only warnings and errors during test
12-
config :logger, level: :warn, compile_time_purge_matching: [[level_lower_than: :warn]]
12+
config :logger, level: :warning, compile_time_purge_matching: [[level_lower_than: :warning]]
1313

1414
config :ex_aws,
1515
access_key_id: "hello",

lib/cadet/accounts/accounts.ex

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ defmodule Cadet.Accounts do
55
use Cadet, [:context, :display]
66

77
import Ecto.Query
8+
require Logger
89

910
alias Cadet.Accounts.{Query, User, CourseRegistration}
1011
alias Cadet.Auth.Provider
@@ -101,23 +102,29 @@ defmodule Cadet.Accounts do
101102

102103
def update_latest_viewed(user = %User{id: user_id}, latest_viewed_course_id)
103104
when is_ecto_id(latest_viewed_course_id) do
105+
Logger.info("Updating latest viewed course for user #{user_id} to #{latest_viewed_course_id}")
106+
104107
CourseRegistration
105108
|> where(user_id: ^user_id)
106109
|> where(course_id: ^latest_viewed_course_id)
107110
|> Repo.one()
108111
|> case do
109112
nil ->
113+
Logger.error("User #{user_id} is not enrolled in course #{latest_viewed_course_id}")
110114
{:error, {:bad_request, "user is not in the course"}}
111115

112116
_ ->
113117
case user
114118
|> User.changeset(%{latest_viewed_course_id: latest_viewed_course_id})
115119
|> Repo.update() do
116120
result = {:ok, _} ->
121+
Logger.info("Successfully updated latest viewed course for user")
117122
result
118123

119124
{:error, changeset} ->
120-
{:error, {:internal_server_error, full_error_messages(changeset)}}
125+
error_msg = full_error_messages(changeset)
126+
Logger.error("Failed to update latest viewed course for user: #{error_msg}")
127+
{:error, {:internal_server_error, error_msg}}
121128
end
122129
end
123130
end

lib/cadet/accounts/course_registrations.ex

Lines changed: 66 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ defmodule Cadet.Accounts.CourseRegistrations do
55
use Cadet, [:context, :display]
66

77
import Ecto.Query
8+
require Logger
89

910
alias Cadet.{Repo, Accounts}
1011
alias Cadet.Accounts.{User, CourseRegistration}
@@ -18,33 +19,69 @@ defmodule Cadet.Accounts.CourseRegistrations do
1819
# otherwise just use CourseRegistration
1920

2021
def get_user_record(user_id, course_id) when is_ecto_id(user_id) and is_ecto_id(course_id) do
21-
CourseRegistration
22-
|> where([cr], cr.user_id == ^user_id)
23-
|> where([cr], cr.course_id == ^course_id)
24-
|> preload(:course)
25-
|> preload(:group)
26-
|> Repo.one()
22+
Logger.info("Retrieving user record for user #{user_id} in course #{course_id}")
23+
24+
result =
25+
CourseRegistration
26+
|> where([cr], cr.user_id == ^user_id)
27+
|> where([cr], cr.course_id == ^course_id)
28+
|> preload(:course)
29+
|> preload(:group)
30+
|> Repo.one()
31+
32+
case result do
33+
nil ->
34+
Logger.error("User record not found for user #{user_id} in course #{course_id}")
35+
36+
_ ->
37+
Logger.info(
38+
"Successfully retrieved user record for user #{user_id} in course #{course_id}"
39+
)
40+
end
41+
42+
result
2743
end
2844

2945
def get_user_course(user_id, course_id) when is_ecto_id(user_id) and is_ecto_id(course_id) do
30-
CourseRegistration
31-
|> where([cr], cr.user_id == ^user_id)
32-
|> where([cr], cr.course_id == ^course_id)
33-
|> join(:inner, [cr], c in assoc(cr, :course))
34-
|> join(:left, [cr, c], ac in assoc(c, :assessment_config))
35-
|> preload([cr, c, ac],
36-
course: {c, assessment_config: ^from(ac in AssessmentConfig, order_by: [asc: ac.order])}
37-
)
38-
|> preload(:group)
39-
|> Repo.one()
46+
Logger.info("Retrieving course details for user #{user_id} in course #{course_id}")
47+
48+
result =
49+
CourseRegistration
50+
|> where([cr], cr.user_id == ^user_id)
51+
|> where([cr], cr.course_id == ^course_id)
52+
|> join(:inner, [cr], c in assoc(cr, :course))
53+
|> join(:left, [cr, c], ac in assoc(c, :assessment_config))
54+
|> preload([cr, c, ac],
55+
course: {c, assessment_config: ^from(ac in AssessmentConfig, order_by: [asc: ac.order])}
56+
)
57+
|> preload(:group)
58+
|> Repo.one()
59+
60+
case result do
61+
nil ->
62+
Logger.error("Course details not found for user #{user_id} in course #{course_id}")
63+
64+
_ ->
65+
Logger.info(
66+
"Successfully retrieved course details for user #{user_id} in course #{course_id}"
67+
)
68+
end
69+
70+
result
4071
end
4172

4273
def get_courses(%User{id: id}) do
43-
CourseRegistration
44-
|> where([cr], cr.user_id == ^id)
45-
|> join(:inner, [cr], c in assoc(cr, :course))
46-
|> preload(:course)
47-
|> Repo.all()
74+
Logger.info("Retrieving all courses for user #{id}")
75+
76+
courses =
77+
CourseRegistration
78+
|> where([cr], cr.user_id == ^id)
79+
|> join(:inner, [cr], c in assoc(cr, :course))
80+
|> preload(:course)
81+
|> Repo.all()
82+
83+
Logger.info("Retrieved #{length(courses)} courses for user #{id}")
84+
courses
4885
end
4986

5087
def get_admin_courses_count(%User{id: id}) do
@@ -118,6 +155,8 @@ defmodule Cadet.Accounts.CourseRegistrations do
118155
"""
119156
def enroll_course(params = %{user_id: user_id, course_id: course_id, role: _role})
120157
when is_ecto_id(user_id) and is_ecto_id(course_id) do
158+
Logger.info("Enrolling user #{user_id} in course #{course_id}")
159+
121160
case params |> insert_or_update_course_registration() do
122161
{:ok, _course_reg} = ok ->
123162
# Ensures that the user has a latest_viewed_course
@@ -127,9 +166,14 @@ defmodule Cadet.Accounts.CourseRegistrations do
127166
|> User.changeset(%{latest_viewed_course_id: course_id})
128167
|> Repo.update()
129168

169+
Logger.info("Successfully enrolled user #{user_id} in course #{course_id}")
130170
ok
131171

132-
{:error, _} = error ->
172+
{:error, changeset} = error ->
173+
Logger.error(
174+
"Failed to enroll user #{user_id} in course #{course_id}: #{full_error_messages(changeset)}"
175+
)
176+
133177
error
134178
end
135179
end

0 commit comments

Comments
 (0)