๐Ÿ‘ฉโ€๐Ÿš’ Firefighters API written in Gleam!
lustre gleam

:bug: add error type for name conflicts

kacaii.dev bb74fa07 3d2c6d7c

verified
+73 -46
+4 -3
server/src/server/auth/sql.gleam
··· 58 58 GetRoleRow(user_role: UserRoleEnum) 59 59 } 60 60 61 - /// Runs the `get_role` query 62 - /// defined in `./src/server/auth/sql/get_role.sql`. 61 + /// ๎ท‘ Find role assigned to an determined user 63 62 /// 64 63 /// > ๐Ÿฟ๏ธ This function was generated automatically using v4.6.0 of 65 64 /// > the [squirrel package](https://github.com/giacomocavalieri/squirrel). ··· 73 72 decode.success(GetRoleRow(user_role:)) 74 73 } 75 74 76 - "select u.user_role from public.user_account as u 75 + "-- ๎ท‘ Find role assigned to an determined user 76 + select u.user_role 77 + from public.user_account as u 77 78 where u.id = $1; 78 79 " 79 80 |> pog.query
+41 -22
server/src/server/crew.gleam
··· 2 2 import gleam/result 3 3 import pog 4 4 import server/crew/sql 5 - import server/user as server_user 5 + import server/user 6 6 import shared/crew.{type Crew, Crew} 7 - import shared/user.{type User, User} 7 + import shared/user.{type User, User} as _shared_user 8 8 9 9 pub type CrewError { 10 10 Database(pog.QueryError) 11 - UserError(server_user.UserError) 11 + UserError(user.UserError) 12 + 13 + /// Crew name needs to be unique 14 + NameConflict 15 + /// Crew not found 12 16 NotFound 13 17 } 14 18 19 + /// Register an new empty crew 15 20 pub fn register( 16 21 db db: pog.Connection, 17 22 leader leader: User, ··· 19 24 is_active is_active: Bool, 20 25 ) -> Result(Crew, CrewError) { 21 26 use returned <- result.try( 22 - sql.register(db, leader.uuid, crew_name, is_active) 23 - |> result.map_error(Database), 27 + case sql.register(db, leader.uuid, crew_name, is_active) { 28 + // Crew name needs to be unique 29 + Error(pog.ConstraintViolated(constraint: "crew_name_key", ..)) -> 30 + Error(NameConflict) 31 + 32 + // Other errors 33 + Error(err) -> Error(Database(err)) 34 + Ok(rows) -> Ok(rows) 35 + }, 24 36 ) 25 37 26 38 use row <- result.try( ··· 28 40 |> result.replace_error(NotFound), 29 41 ) 30 42 31 - use leader <- result.map( 32 - server_user.find(db, row.crew_leader) 43 + use leader: User <- result.map( 44 + user.find(db, row.crew_leader) 33 45 |> result.map_error(UserError), 34 46 ) 35 47 ··· 41 53 ) 42 54 } 43 55 56 + /// Assign a group of members to a crew. 57 + /// Nothing happens is a member is already assigned. 58 + /// 59 + /// Returns all successfully assigned members. 44 60 pub fn assign( 45 61 db: pog.Connection, 46 62 crew: Crew, 47 63 members: List(User), 48 64 ) -> Result(List(User), CrewError) { 49 - let id_list = list.map(members, fn(member) { member.uuid }) 65 + let id_list = { 66 + use member <- list.map(members) 67 + member.uuid 68 + } 50 69 51 70 use returned <- result.try( 52 71 sql.assign_members(db, crew.id, id_list) 53 72 |> result.map_error(Database), 54 73 ) 55 74 56 - use row <- list.try_map(returned.rows) 75 + list.try_map(returned.rows, fn(row) { 76 + use user <- result.map( 77 + user.find(db, row.user_id) 78 + |> result.map_error(UserError), 79 + ) 57 80 58 - use member <- result.map( 59 - server_user.find(db, row.user_id) 60 - |> result.map_error(UserError), 61 - ) 62 - 63 - User( 64 - uuid: member.uuid, 65 - role: member.role, 66 - full_name: member.full_name, 67 - email: member.email, 68 - phone: member.phone, 69 - is_active: member.is_active, 70 - ) 81 + User( 82 + uuid: user.uuid, 83 + role: user.role, 84 + full_name: user.full_name, 85 + email: user.email, 86 + phone: user.phone, 87 + is_active: user.is_active, 88 + ) 89 + }) 71 90 }
+12 -12
server/src/server/crew/sql.gleam
··· 18 18 AssignMembersRow(user_id: Uuid) 19 19 } 20 20 21 - /// Runs the `assign_members` query 22 - /// defined in `./src/server/crew/sql/assign_members.sql`. 21 + /// ๏ƒ€ Assign a group of members to a crew 23 22 /// 24 23 /// > ๐Ÿฟ๏ธ This function was generated automatically using v4.6.0 of 25 24 /// > the [squirrel package](https://github.com/giacomocavalieri/squirrel). ··· 34 33 decode.success(AssignMembersRow(user_id:)) 35 34 } 36 35 37 - "insert into crew_membership as cm ( 36 + "-- ๏ƒ€ Assign a group of members to a crew 37 + insert into crew_membership as cm ( 38 38 crew_id, 39 39 user_id 40 40 ) 41 - 42 41 values ($1, unnest($2::uuid [])) 42 + 43 43 on conflict do nothing 44 44 returning cm.user_id; 45 45 " ··· 68 68 ) 69 69 } 70 70 71 - /// Runs the `find_members` query 72 - /// defined in `./src/server/crew/sql/find_members.sql`. 71 + /// ๏ƒ€ Find all members assigned to a determined crew 73 72 /// 74 73 /// > ๐Ÿฟ๏ธ This function was generated automatically using v4.6.0 of 75 74 /// > the [squirrel package](https://github.com/giacomocavalieri/squirrel). ··· 87 86 decode.success(FindMembersRow(id:, role:, full_name:, email:, phone:)) 88 87 } 89 88 90 - "with member as ( 89 + "-- ๏ƒ€ Find all members assigned to a determined crew 90 + with member as ( 91 91 select cm.user_id as id 92 92 from crew_membership as cm 93 93 where cm.crew_id = $1 ··· 118 118 RegisterRow(id: Uuid, crew_leader: Uuid, crew_name: String, is_active: Bool) 119 119 } 120 120 121 - /// Runs the `register` query 122 - /// defined in `./src/server/crew/sql/register.sql`. 121 + /// ๏ƒ€ Register an new empty crew 123 122 /// 124 123 /// > ๐Ÿฟ๏ธ This function was generated automatically using v4.6.0 of 125 124 /// > the [squirrel package](https://github.com/giacomocavalieri/squirrel). ··· 138 137 decode.success(RegisterRow(id:, crew_leader:, crew_name:, is_active:)) 139 138 } 140 139 141 - "insert into crew as c ( 140 + "-- ๏ƒ€ Register an new empty crew 141 + insert into crew as c ( 142 142 crew_leader, 143 143 crew_name, 144 144 is_active 145 - ) values ($1, $2, $3) 146 - 145 + ) 146 + values ($1, $2, $3) 147 147 returning c.id, c.crew_leader, c.crew_name, c.is_active; 148 148 " 149 149 |> pog.query
+1 -1
server/src/server/crew/sql/assign_members.sql
··· 1 - -- ๏ƒ€ Assign a group of members to a crew 1 + -- ๏ƒ€ Assign a group of members to a crew 2 2 insert into crew_membership as cm ( 3 3 crew_id, 4 4 user_id
+2 -1
server/src/server/seed/sql.gleam
··· 33 33 34 34 "-- ๓ฐถš Check if the user_account table is empty 35 35 -- If it returns a least one row it means that the tables is not empty. 36 - select 1 as row_exists from public.user_account; 36 + select 1 as row_exists 37 + from public.user_account; 37 38 " 38 39 |> pog.query 39 40 |> pog.returning(decoder)
+13 -7
server/src/server/user/sql.gleam
··· 25 25 ) 26 26 } 27 27 28 - /// Runs the `find` query 29 - /// defined in `./src/server/user/sql/find.sql`. 28 + /// ๏€‡ Find details about an user 30 29 /// 31 30 /// > ๐Ÿฟ๏ธ This function was generated automatically using v4.6.0 of 32 31 /// > the [squirrel package](https://github.com/giacomocavalieri/squirrel). ··· 45 44 decode.success(FindRow(id:, role:, full_name:, email:, phone:, is_active:)) 46 45 } 47 46 48 - "select 47 + "-- ๏€‡ Find details about an user 48 + select 49 49 u.id, 50 50 u.user_role as role, 51 51 u.full_name, ··· 78 78 ) 79 79 } 80 80 81 - /// ๏ˆด register an user 81 + /// ๏ˆด Register an user 82 82 /// 83 83 /// > ๐Ÿฟ๏ธ This function was generated automatically using v4.6.0 of 84 84 /// > the [squirrel package](https://github.com/giacomocavalieri/squirrel). ··· 109 109 )) 110 110 } 111 111 112 - "-- ๏ˆด register an user 113 - insert into public.user_account as u 114 - (full_name, user_role, password_hash, email, phone, is_active) 112 + "-- ๏ˆด Register an user 113 + insert into public.user_account as u ( 114 + full_name, 115 + user_role, 116 + password_hash, 117 + email, 118 + phone, 119 + is_active 120 + ) 115 121 values ($1, $2, $3, $4, $5, $6) 116 122 returning u.id, u.full_name, u.user_role, u.email, u.phone, u.is_active; 117 123 "