tangled
alpha
login
or
join now
kacaii.dev
/
senac-brigade-server
0
fork
atom
wip: currently rewriting the project as a full stack application
tangled.org/kacaii.dev/sigo
gleam
0
fork
atom
overview
issues
1
pulls
pipelines
:heavy_minus_sign: remove `glight`
kacaii.dev
2 months ago
6b19f3e0
ef2d9119
+30
-138
15 changed files
expand all
collapse all
unified
split
gleam.toml
manifest.toml
src
app
domain
admin
admin_update_user.gleam
brigade
register_new_brigade.gleam
data_analysis
analysis_occurrence_volume.gleam
role.gleam
user
delete_user.gleam
get_all_user_profiles.gleam
login.gleam
signup.gleam
update_user_password.gleam
update_user_status.gleam
user.gleam
web.gleam
app.gleam
-1
gleam.toml
···
28
28
argus = ">= 1.0.3 and < 2.0.0"
29
29
cors_builder = ">= 2.0.6 and < 3.0.0"
30
30
gleam_time = ">= 1.5.0 and < 2.0.0"
31
31
-
glight = ">= 2.1.1 and < 3.0.0"
32
31
global_value = ">= 1.0.0 and < 2.0.0"
33
32
argv = ">= 1.0.2 and < 2.0.0"
34
33
simplifile = ">= 2.3.0 and < 3.0.0"
+1
-6
manifest.toml
···
5
5
{ name = "argus", version = "1.0.3", build_tools = ["gleam"], requirements = ["jargon"], otp_app = "argus", source = "hex", outer_checksum = "522A932BE147A78720A1AF95348544F604E900E788FF3D84DDF9F18DC7767819" },
6
6
{ name = "argv", version = "1.0.2", build_tools = ["gleam"], requirements = [], otp_app = "argv", source = "hex", outer_checksum = "BA1FF0929525DEBA1CE67256E5ADF77A7CDDFE729E3E3F57A5BDCAA031DED09D" },
7
7
{ name = "backoff", version = "1.1.6", build_tools = ["rebar3"], requirements = [], otp_app = "backoff", source = "hex", outer_checksum = "CF0CFFF8995FB20562F822E5CC47D8CCF664C5ECDC26A684CBE85C225F9D7C39" },
8
8
-
{ name = "birl", version = "1.8.0", build_tools = ["gleam"], requirements = ["gleam_regexp", "gleam_stdlib", "ranger"], otp_app = "birl", source = "hex", outer_checksum = "2AC7BA26F998E3DFADDB657148BD5DDFE966958AD4D6D6957DD0D22E5B56C400" },
9
8
{ name = "cors_builder", version = "2.0.6", build_tools = ["gleam"], requirements = ["gleam_http", "gleam_stdlib", "mist", "wisp"], otp_app = "cors_builder", source = "hex", outer_checksum = "DBB16790F8FBF859242812FFC74E2719AC8F8D55F0A4CB5F4A064C87109B6021" },
10
9
{ name = "directories", version = "1.2.0", build_tools = ["gleam"], requirements = ["envoy", "gleam_stdlib", "platform", "simplifile"], otp_app = "directories", source = "hex", outer_checksum = "D13090CFCDF6759B87217E8DDD73A75903A700148A82C1D33799F333E249BF9E" },
11
10
{ name = "envoy", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "envoy", source = "hex", outer_checksum = "850DA9D29D2E5987735872A2B5C81035146D7FE19EFC486129E44440D03FD832" },
···
27
26
{ name = "gleam_yielder", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_yielder", source = "hex", outer_checksum = "8E4E4ECFA7982859F430C57F549200C7749823C106759F4A19A78AEA6687717A" },
28
27
{ name = "gleeunit", version = "1.9.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "DA9553CE58B67924B3C631F96FE3370C49EB6D6DC6B384EC4862CC4AAA718F3C" },
29
28
{ name = "glexer", version = "2.3.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "splitter"], otp_app = "glexer", source = "hex", outer_checksum = "40A1FB0919FA080AD6C5809B4C7DBA545841CAAC8168FACDFA0B0667C22475CC" },
30
30
-
{ name = "glight", version = "2.2.0", build_tools = ["gleam"], requirements = ["birl", "gleam_erlang", "gleam_otp", "gleam_stdlib", "jsx", "logging"], otp_app = "glight", source = "hex", outer_checksum = "DB1FC2B770C86437A3932851AC8D7F8C32646E7CD4A8730A2B0AAA9B74E4AD90" },
31
29
{ name = "glisten", version = "8.0.1", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_otp", "gleam_stdlib", "logging", "telemetry"], otp_app = "glisten", source = "hex", outer_checksum = "534BB27C71FB9E506345A767C0D76B17A9E9199934340C975DC003C710E3692D" },
32
30
{ name = "global_value", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "global_value", source = "hex", outer_checksum = "23F74C91A7B819C43ABCCBF49DAD5BB8799D81F2A3736BA9A534BD47F309FF4F" },
33
31
{ name = "gramps", version = "6.0.0", build_tools = ["gleam"], requirements = ["gleam_crypto", "gleam_erlang", "gleam_http", "gleam_stdlib"], otp_app = "gramps", source = "hex", outer_checksum = "8B7195978FBFD30B43DF791A8A272041B81E45D245314D7A41FC57237AA882A0" },
···
35
33
{ name = "houdini", version = "1.2.0", build_tools = ["gleam"], requirements = [], otp_app = "houdini", source = "hex", outer_checksum = "5DB1053F1AF828049C2B206D4403C18970ABEF5C18671CA3C2D2ED0DD64F6385" },
36
34
{ name = "hpack_erl", version = "0.3.0", build_tools = ["rebar3"], requirements = [], otp_app = "hpack", source = "hex", outer_checksum = "D6137D7079169D8C485C6962DFE261AF5B9EF60FBC557344511C1E65E3D95FB0" },
37
35
{ name = "jargon", version = "1.0.1", build_tools = ["rebar3"], requirements = [], otp_app = "jargon", source = "hex", outer_checksum = "E969FC304BBC3F69514161DF5F9B6BA71FEF8EACB3B209784BE15FF48EC68689" },
38
38
-
{ name = "jsx", version = "3.1.0", build_tools = ["rebar3"], requirements = [], otp_app = "jsx", source = "hex", outer_checksum = "0C5CC8FDC11B53CC25CF65AC6705AD39E54ECC56D1C22E4ADB8F5A53FB9427F3" },
39
36
{ name = "justin", version = "1.0.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "justin", source = "hex", outer_checksum = "7FA0C6DB78640C6DC5FBFD59BF3456009F3F8B485BF6825E97E1EB44E9A1E2CD" },
40
37
{ name = "logging", version = "1.3.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "logging", source = "hex", outer_checksum = "1098FBF10B54B44C2C7FDF0B01C1253CAFACDACABEFB4B0D027803246753E06D" },
41
38
{ name = "marceau", version = "1.3.0", build_tools = ["gleam"], requirements = [], otp_app = "marceau", source = "hex", outer_checksum = "2D1C27504BEF45005F5DFB18591F8610FB4BFA91744878210BDC464412EC44E9" },
···
47
44
{ name = "pgo", version = "0.20.0", build_tools = ["rebar3"], requirements = ["backoff", "opentelemetry_api", "pg_types"], otp_app = "pgo", source = "hex", outer_checksum = "2F11E6649CEB38E569EF56B16BE1D04874AE5B11A02867080A2817CE423C683B" },
48
45
{ name = "platform", version = "1.0.0", build_tools = ["gleam"], requirements = [], otp_app = "platform", source = "hex", outer_checksum = "8339420A95AD89AAC0F82F4C3DB8DD401041742D6C3F46132A8739F6AEB75391" },
49
46
{ name = "pog", version = "4.1.0", build_tools = ["gleam"], requirements = ["exception", "gleam_erlang", "gleam_otp", "gleam_stdlib", "gleam_time", "pgo"], otp_app = "pog", source = "hex", outer_checksum = "E4AFBA39A5FAA2E77291836C9683ADE882E65A06AB28CA7D61AE7A3AD61EBBD5" },
50
50
-
{ name = "ranger", version = "1.4.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "gleam_yielder"], otp_app = "ranger", source = "hex", outer_checksum = "C8988E8F8CDBD3E7F4D8F2E663EF76490390899C2B2885A6432E942495B3E854" },
51
47
{ name = "simplifile", version = "2.3.1", build_tools = ["gleam"], requirements = ["filepath", "gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "957E0E5B75927659F1D2A1B7B75D7B9BA96FAA8D0C53EA71C4AD9CD0C6B848F6" },
52
48
{ name = "splitter", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "splitter", source = "hex", outer_checksum = "3DFD6B6C49E61EDAF6F7B27A42054A17CFF6CA2135FF553D0CB61C234D281DD0" },
53
49
{ name = "squirrel", version = "4.6.0", build_tools = ["gleam"], requirements = ["argv", "envoy", "eval", "filepath", "glam", "gleam_community_ansi", "gleam_crypto", "gleam_json", "gleam_regexp", "gleam_stdlib", "gleam_time", "glexer", "justin", "mug", "non_empty_list", "pog", "simplifile", "term_size", "tom", "tote", "youid"], otp_app = "squirrel", source = "hex", outer_checksum = "0ED10A868BDD1A5D4B68D99CD1C72DC3F23C6E36E16D33454C5F0C31BAC9CB1E" },
···
65
61
cors_builder = { version = ">= 2.0.6 and < 3.0.0" }
66
62
envoy = { version = ">= 1.0.2 and < 2.0.0" }
67
63
formal = { version = ">= 3.0.0 and < 4.0.0" }
64
64
+
gleam_community_ansi = { version = ">= 1.4.3 and < 2.0.0" }
68
65
gleam_crypto = { version = ">= 1.5.1 and < 2.0.0" }
69
66
gleam_erlang = { version = ">= 1.3.0 and < 2.0.0" }
70
67
gleam_http = { version = ">= 4.1.1 and < 5.0.0" }
···
73
70
gleam_stdlib = { version = ">= 0.44.0 and < 2.0.0" }
74
71
gleam_time = { version = ">= 1.5.0 and < 2.0.0" }
75
72
gleeunit = { version = ">= 1.0.0 and < 2.0.0" }
76
76
-
glight = { version = ">= 2.1.1 and < 3.0.0" }
77
73
global_value = { version = ">= 1.0.0 and < 2.0.0" }
78
74
group_registry = { version = ">= 1.0.0 and < 2.0.0" }
79
75
mist = { version = ">= 5.0.3 and < 6.0.0" }
···
82
78
squirrel = { version = ">= 4.4.1 and < 5.0.0" }
83
79
wisp = { version = ">= 2.0.0 and < 3.0.0" }
84
80
youid = { version = ">= 1.5.1 and < 2.0.0" }
85
85
-
gleam_community_ansi = { version = ">= 1.4.3 and < 2.0.0" }
+1
-2
src/app.gleam
···
12
12
import app/domain/admin/sql as admin_sql
13
13
import app/http_router
14
14
import app/supervision_tree
15
15
-
import app/web
16
15
import app/web/context.{type Context, Context}
17
16
import app/web/socket
18
17
import envoy
···
30
29
31
30
/// Application entry
32
31
pub fn main() -> Nil {
33
33
-
web.configure_logger()
32
32
+
wisp.configure_logger()
34
33
35
34
// Enviroment where the code is running on
36
35
let env = case envoy.get("SIGO_PROD") {
+3
-7
src/app/domain/admin/admin_update_user.gleam
···
51
51
) -> wisp.Response {
52
52
case query_database(req, ctx, body, user_id) {
53
53
Ok(body) -> wisp.json_response(body, 200)
54
54
-
Error(err) -> handle_error(req, body, err)
54
54
+
Error(err) -> handle_error(body, err)
55
55
}
56
56
}
57
57
···
92
92
NotFound(uuid.Uuid)
93
93
}
94
94
95
95
-
fn handle_error(
96
96
-
req: wisp.Request,
97
97
-
body: RequestBody,
98
98
-
err: AdminUpdateUserError,
99
99
-
) -> wisp.Response {
95
95
+
fn handle_error(body: RequestBody, err: AdminUpdateUserError) -> wisp.Response {
100
96
case err {
101
101
-
AccessControl(err) -> user.handle_access_control_error(req, err)
97
97
+
AccessControl(err) -> user.handle_access_control_error(err)
102
98
103
99
InvalidUuid(id) -> wisp.bad_request("Usuário possui Uuid inválido: " <> id)
104
100
+3
-3
src/app/domain/brigade/register_new_brigade.gleam
···
94
94
body body: RequestBody,
95
95
) -> wisp.Response {
96
96
case query_database(request, ctx, body) {
97
97
-
Error(err) -> handle_error(request, err)
97
97
+
Error(err) -> handle_error(err)
98
98
Ok(body) -> wisp.json_response(body, 201)
99
99
}
100
100
}
···
176
176
assigned_members
177
177
}
178
178
179
179
-
fn handle_error(request request, err err: RegisterBrigadeError) -> wisp.Response {
179
179
+
fn handle_error(err err: RegisterBrigadeError) -> wisp.Response {
180
180
case err {
181
181
InvalidUuid(id) -> wisp.bad_request("Usuário possui UUID inválido: " <> id)
182
182
DataBase(err) -> web.handle_database_error(err)
183
183
-
AccessControl(err) -> user.handle_access_control_error(request, err)
183
183
+
AccessControl(err) -> user.handle_access_control_error(err)
184
184
NotFound ->
185
185
"O Banco de Dados não retornou informações sobre a nova equipe após a inserção"
186
186
|> wisp.Text
+3
-3
src/app/domain/data_analysis/analysis_occurrence_volume.gleam
···
50
50
use <- wisp.require_method(req, http.Get)
51
51
52
52
case query_database(req, ctx) {
53
53
-
Error(err) -> handle_error(err, req)
53
53
+
Error(err) -> handle_error(err)
54
54
Ok(body) -> wisp.json_response(body, 200)
55
55
}
56
56
}
57
57
58
58
-
fn handle_error(err: AnalysisError, req: wisp.Request) -> wisp.Response {
58
58
+
fn handle_error(err: AnalysisError) -> wisp.Response {
59
59
case err {
60
60
Database(err) -> web.handle_database_error(err)
61
61
-
AccessControl(err) -> user.handle_access_control_error(req, err)
61
61
+
AccessControl(err) -> user.handle_access_control_error(err)
62
62
}
63
63
}
64
64
-25
src/app/domain/role.gleam
···
1
1
import gleam/dynamic/decode
2
2
import gleam/json
3
3
import gleam/string
4
4
-
import glight
5
5
-
import wisp
6
6
-
import youid/uuid
7
4
8
5
pub type Role {
9
6
Sargeant
···
68
65
Firefighter -> "firefighter"
69
66
Sargeant -> "sargeant"
70
67
}
71
71
-
}
72
72
-
73
73
-
/// Log when someone tries to access an endpoint that they dont have permission
74
74
-
pub fn log_unauthorized_access_attempt(
75
75
-
request request: wisp.Request,
76
76
-
user_uuid user_uuid: uuid.Uuid,
77
77
-
user_role user_role: Role,
78
78
-
required required: List(Role),
79
79
-
) -> Nil {
80
80
-
let required_roles =
81
81
-
required
82
82
-
|> json.array(to_json)
83
83
-
|> json.to_string
84
84
-
85
85
-
glight.logger()
86
86
-
|> glight.with("path", request.path)
87
87
-
|> glight.with("user", uuid.to_string(user_uuid))
88
88
-
|> glight.with("role", to_string(user_role))
89
89
-
|> glight.with("required", required_roles)
90
90
-
|> glight.notice("unauthorized_access_attempt")
91
91
-
92
92
-
Nil
93
68
}
94
69
95
70
pub fn to_json(role: Role) -> json.Json {
+3
-11
src/app/domain/user.gleam
···
135
135
}
136
136
}
137
137
138
138
-
pub fn handle_access_control_error(req: wisp.Request, err: AccessControlError) {
138
138
+
pub fn handle_access_control_error(err: AccessControlError) {
139
139
case err {
140
140
Authentication(err) -> handle_authentication_error(err)
141
141
DataBase(err) -> web.handle_database_error(err)
···
149
149
|> wisp.set_body(wisp.response(401), _)
150
150
151
151
AuthorizationError(user_uuid:, user_role:, authorized_roles:) -> {
152
152
-
role.log_unauthorized_access_attempt(
153
153
-
request: req,
154
154
-
user_uuid:,
155
155
-
user_role:,
156
156
-
required: authorized_roles,
157
157
-
)
158
158
-
159
159
-
[
152
152
+
json.object([
160
153
#("id", json.string(uuid.to_string(user_uuid))),
161
154
#("user_role", json.string(role.to_string_pt_br(user_role:))),
162
155
#("required", json.array(authorized_roles, role.to_json)),
163
163
-
]
164
164
-
|> json.object
156
156
+
])
165
157
|> json.to_string
166
158
|> wisp.json_response(403)
167
159
}
+3
-3
src/app/domain/user/delete_user.gleam
···
28
28
29
29
case query_database(req, ctx, user_id) {
30
30
Ok(deleted_user) -> wisp.json_response(deleted_user, 200)
31
31
-
Error(err) -> handle_error(req, err)
31
31
+
Error(err) -> handle_error(err)
32
32
}
33
33
}
34
34
···
46
46
CantDeleteSelf
47
47
}
48
48
49
49
-
fn handle_error(req: wisp.Request, err: DeleteUserError) -> wisp.Response {
49
49
+
fn handle_error(err: DeleteUserError) -> wisp.Response {
50
50
case err {
51
51
InvalidUserUuid(invalid_uuid) ->
52
52
wisp.bad_request("Usuário possui Uuid Inválido: " <> invalid_uuid)
53
53
UserNotFound(user_uuid) ->
54
54
wisp.bad_request("Usuário não encontrado: " <> uuid.to_string(user_uuid))
55
55
-
AccessControl(err) -> user.handle_access_control_error(req, err)
55
55
+
AccessControl(err) -> user.handle_access_control_error(err)
56
56
DataBase(err) -> web.handle_database_error(err)
57
57
CantDeleteSelf -> wisp.bad_request("Um usuário não deve remover a si mesmo")
58
58
}
+3
-3
src/app/domain/user/get_all_user_profiles.gleam
···
38
38
use <- wisp.require_method(req, http.Get)
39
39
40
40
case query_database(req, ctx) {
41
41
-
Error(err) -> handle_error(req, err)
41
41
+
Error(err) -> handle_error(err)
42
42
Ok(body) -> wisp.json_response(body, 200)
43
43
}
44
44
}
···
50
50
DataBase(pog.QueryError)
51
51
}
52
52
53
53
-
fn handle_error(req: wisp.Request, err: GetAllUsersError) -> wisp.Response {
53
53
+
fn handle_error(err: GetAllUsersError) -> wisp.Response {
54
54
case err {
55
55
-
AccessControl(err) -> user.handle_access_control_error(req, err)
55
55
+
AccessControl(err) -> user.handle_access_control_error(err)
56
56
DataBase(err) -> web.handle_database_error(err)
57
57
}
58
58
}
-12
src/app/domain/user/login.gleam
···
16
16
import gleam/list
17
17
import gleam/result
18
18
import gleam/time/duration
19
19
-
import glight
20
19
import pog
21
20
import wisp
22
21
import youid/uuid
···
131
130
}
132
131
}
133
132
134
134
-
/// Logs user registration
135
135
-
fn log_login(login: RequestBody) -> Nil {
136
136
-
glight.logger()
137
137
-
|> glight.with("registration", login.registration)
138
138
-
|> glight.info("login")
139
139
-
140
140
-
Nil
141
141
-
}
142
142
-
143
133
/// Check if the provided password matches the one inside our database
144
134
/// Returns the user's UUID if successfull.
145
135
fn query_database(
···
166
156
sql.Firefighter -> role.Firefighter
167
157
sql.Sargeant -> role.Sargeant
168
158
}
169
169
-
170
170
-
log_login(data)
171
159
172
160
json.object([
173
161
#("id", json.string(uuid.to_string(row.id))),
+4
-19
src/app/domain/user/signup.gleam
···
17
17
import gleam/json
18
18
import gleam/list
19
19
import gleam/result
20
20
-
import glight
21
20
import pog
22
21
import wisp
23
22
import youid/uuid
···
47
46
48
47
fn handle_body(req: wisp.Request, body: SignUp, ctx: Context) -> wisp.Response {
49
48
case query_database(request: req, ctx:, signup: body) {
50
50
-
Error(err) -> handle_error(req, err)
51
51
-
Ok(new_user) -> {
52
52
-
log_signup(body)
53
53
-
wisp.json_response(new_user, 201)
54
54
-
}
49
49
+
Error(err) -> handle_error(err)
50
50
+
Ok(new_user) -> wisp.json_response(new_user, 201)
55
51
}
56
52
}
57
53
···
168
164
})
169
165
}
170
166
171
171
-
fn log_signup(signup: SignUp) -> Nil {
172
172
-
glight.logger()
173
173
-
|> glight.with("name", signup.name)
174
174
-
|> glight.with("registration", signup.registration)
175
175
-
|> glight.with("phone_number", signup.phone_number)
176
176
-
|> glight.with("email", signup.email)
177
177
-
|> glight.info("signup")
178
178
-
179
179
-
Nil
180
180
-
}
181
181
-
182
167
fn handle_database_error(err: pog.QueryError) -> wisp.Response {
183
168
case err {
184
169
pog.ConstraintViolated(_, _, constraint: "user_account_registration_key") -> {
···
203
188
}
204
189
}
205
190
206
206
-
fn handle_error(req: wisp.Request, err: SignupError) {
191
191
+
fn handle_error(err: SignupError) {
207
192
case err {
208
208
-
AccessControl(err) -> user.handle_access_control_error(req, err)
193
193
+
AccessControl(err) -> user.handle_access_control_error(err)
209
194
DataBase(err) -> handle_database_error(err)
210
195
211
196
HashError -> {
+3
-18
src/app/domain/user/update_user_password.gleam
···
8
8
import gleam/http
9
9
import gleam/list
10
10
import gleam/result
11
11
-
import glight
12
11
import pog
13
12
import wisp
14
13
import youid/uuid
···
89
88
request request: wisp.Request,
90
89
ctx ctx: Context,
91
90
form_data form_data: RequestBody,
92
92
-
) -> Result(Nil, UpdatePasswordError) {
91
91
+
) -> Result(pog.Returned(Nil), UpdatePasswordError) {
93
92
use user_uuid <- result.try(
94
93
user.extract_uuid(request:, cookie_name: user.uuid_cookie_name)
95
94
|> result.map_error(AccessControl),
···
128
127
|> result.replace_error(HashError),
129
128
)
130
129
131
131
-
// Update their password
132
132
-
use _ <- result.map(
133
133
-
sql.update_user_password(ctx.db, user_uuid, hashed_password.encoded_hash)
134
134
-
|> result.map_error(DataBase),
135
135
-
)
136
136
-
137
137
-
// All done!
138
138
-
log_password_update(user_uuid)
130
130
+
sql.update_user_password(ctx.db, user_uuid, hashed_password.encoded_hash)
131
131
+
|> result.map_error(DataBase)
139
132
}
140
133
141
134
fn query_user_password(
···
201
194
/// New password must be different from the old one
202
195
MustBeDifferent
203
196
}
204
204
-
205
205
-
fn log_password_update(user_uuid: uuid.Uuid) -> Nil {
206
206
-
glight.logger()
207
207
-
|> glight.with("user_uuid", uuid.to_string(user_uuid))
208
208
-
|> glight.info("password_update")
209
209
-
210
210
-
Nil
211
211
-
}
+3
-3
src/app/domain/user/update_user_status.gleam
···
44
44
is_active: Bool,
45
45
) -> wisp.Response {
46
46
case query_database(req, ctx, user_id, is_active) {
47
47
-
Error(err) -> handle_error(req, err)
47
47
+
Error(err) -> handle_error(err)
48
48
Ok(resp) -> wisp.json_response(resp, 200)
49
49
}
50
50
}
···
99
99
|> json.to_string
100
100
}
101
101
102
102
-
fn handle_error(req: wisp.Request, err: UpdateUserStatusError) -> wisp.Response {
102
102
+
fn handle_error(err: UpdateUserStatusError) -> wisp.Response {
103
103
case err {
104
104
-
AccessControl(err) -> user.handle_access_control_error(req, err)
104
104
+
AccessControl(err) -> user.handle_access_control_error(err)
105
105
DataBase(err) -> web.handle_database_error(err)
106
106
InvalidUuid(user_id) -> {
107
107
let body = "Usuário possui UUID inválido: " <> user_id
-22
src/app/web.gleam
···
24
24
import gleam/list
25
25
import gleam/result
26
26
import gleam/string
27
27
-
import glight
28
27
import pog
29
28
import wisp
30
29
···
35
34
context ctx: context.Context,
36
35
next handler: fn(wisp.Request) -> wisp.Response,
37
36
) -> wisp.Response {
38
38
-
let path = "/static"
39
37
let request = wisp.method_override(req)
40
38
41
39
use <- wisp.log_request(request)
···
43
41
use request <- wisp.handle_head(request)
44
42
use request <- cors.wisp_middleware(request, cors_config(ctx))
45
43
46
46
-
use <- wisp.serve_static(request, under: path, from: ctx.static_directory)
47
44
handler(request)
48
48
-
}
49
49
-
50
50
-
/// Configure the Erlang logger
51
51
-
pub fn configure_logger() {
52
52
-
glight.configure([
53
53
-
glight.Console,
54
54
-
glight.File(log_directory() <> "/server.log"),
55
55
-
])
56
56
-
57
57
-
glight.set_log_level(glight.Debug)
58
58
-
glight.set_is_color(True)
59
59
-
}
60
60
-
61
61
-
/// Access to log directory
62
62
-
fn log_directory() -> String {
63
63
-
let assert Ok(priv_directory) = wisp.priv_directory("app")
64
64
-
as "Failed to access priv directory"
65
65
-
66
66
-
priv_directory <> "/log"
67
45
}
68
46
69
47
fn cors_config(ctx: context.Context) -> cors.Cors {