fn register_user(ctx: context.Context, req: wisp.Request) {
use json <- wisp.require_json(req)
let result = {
use input <- result.try(
decode.run(json, register_decoder())
|> result.replace_error(errors.BadRequest(
"missing email, username, or password",
)),
)
let validation = {
validator.new()
|> users.validate_username(input.username)
|> users.validate_email(input.email)
|> users.validate_password(input.password)
}
use _ <- result.try(validator.valid(validation))
use password_bits <- result.try(users.hash_password(input.password))
users.create_user(ctx, input.username, input.email, password_bits)
}
case result {
Ok(_) -> helpers.message_response("user created", 201)
Error(err) -> errors.handle_error(req, err)
}
}
pub fn create_user(ctx: context.Context, username, email, password) {
sql.create_user(username, email, password, helpers.current_time())
|> db.exec(ctx.db, _)
|> result.map_error(errors.DatabaseError)
}
pub fn exec(db: Connection, b: #(String, List(dev.Param))) {
let query_string = b.0
let params = b.1
case db {
Pog(conn) -> {
query_string
|> pog.query()
|> list.fold(params, _, fn(acc, param) {
let param = parrot_to_pog(param)
pog.parameter(acc, param)
})
|> pog.execute(conn)
}
Mock(handler) -> {
case handler(query_string, params) {
Ok(returned) -> Ok(pog.Returned(returned.count, []))
Error(err) -> Error(err)
}
}
}
}
INFO 2026-02-11T18:23:45.812875652+07:00 201 POST /api/register
EROR 2026-02-11T18:23:45.850050641+07:00 POST /api/register constraint violated: { message:duplicate key value violates unique constraint "users_username_key" constraint: users_username_key detail: Key (username)=(test3) already exists. }