···77//// All requests are processed through the web middleware pipeline before routing.
88//// Unmatched routes return a 404 Not Found response.
991010-import app/routes/get_brigade_members
1111-import app/routes/get_crew_members
1212-import app/routes/get_ocurrences_by_applicant
1313-import app/routes/login
1414-import app/routes/register_new_occurrence
1515-import app/routes/signup
1010+import app/routes/brigade/get_brigade_members
1111+import app/routes/occurrence/register_new_occurrence
1212+import app/routes/user/get_crew_members
1313+import app/routes/user/get_ocurrences_by_applicant
1414+import app/routes/user/login
1515+import app/routes/user/signup
1616import app/web.{type Context}
1717import gleam/http
1818import wisp
+112
src/app/routes/brigade/sql.gleam
···11+//// This module contains the code to run the sql queries defined in
22+//// `./src/app/routes/brigade/sql`.
33+//// > 🐿️ This module was generated automatically using v4.4.1 of
44+//// > the [squirrel package](https://github.com/giacomocavalieri/squirrel).
55+////
66+77+import gleam/dynamic/decode
88+import gleam/option.{type Option}
99+import pog
1010+import youid/uuid.{type Uuid}
1111+1212+/// A row you get from running the `count_active_brigades` query
1313+/// defined in `./src/app/routes/brigade/sql/count_active_brigades.sql`.
1414+///
1515+/// > 🐿️ This type definition was generated automatically using v4.4.1 of the
1616+/// > [squirrel package](https://github.com/giacomocavalieri/squirrel).
1717+///
1818+pub type CountActiveBrigadesRow {
1919+ CountActiveBrigadesRow(count: Int)
2020+}
2121+2222+/// Counts the number of active brigades in the database.
2323+///
2424+/// > 🐿️ This function was generated automatically using v4.4.1 of
2525+/// > the [squirrel package](https://github.com/giacomocavalieri/squirrel).
2626+///
2727+pub fn count_active_brigades(
2828+ db: pog.Connection,
2929+) -> Result(pog.Returned(CountActiveBrigadesRow), pog.QueryError) {
3030+ let decoder = {
3131+ use count <- decode.field(0, decode.int)
3232+ decode.success(CountActiveBrigadesRow(count:))
3333+ }
3434+3535+ "-- Counts the number of active brigades in the database.
3636+SELECT COUNT(id)
3737+FROM public.brigade
3838+WHERE is_active = TRUE;
3939+"
4040+ |> pog.query
4141+ |> pog.returning(decoder)
4242+ |> pog.execute(db)
4343+}
4444+4545+/// A row you get from running the `get_brigade_members` query
4646+/// defined in `./src/app/routes/brigade/sql/get_brigade_members.sql`.
4747+///
4848+/// > 🐿️ This type definition was generated automatically using v4.4.1 of the
4949+/// > [squirrel package](https://github.com/giacomocavalieri/squirrel).
5050+///
5151+pub type GetBrigadeMembersRow {
5252+ GetBrigadeMembersRow(
5353+ id: Uuid,
5454+ full_name: String,
5555+ role_name: Option(String),
5656+ description: Option(String),
5757+ )
5858+}
5959+6060+/// Find all members of a brigade
6161+///
6262+/// > 🐿️ This function was generated automatically using v4.4.1 of
6363+/// > the [squirrel package](https://github.com/giacomocavalieri/squirrel).
6464+///
6565+pub fn get_brigade_members(
6666+ db: pog.Connection,
6767+ arg_1: Uuid,
6868+) -> Result(pog.Returned(GetBrigadeMembersRow), pog.QueryError) {
6969+ let decoder = {
7070+ use id <- decode.field(0, uuid_decoder())
7171+ use full_name <- decode.field(1, decode.string)
7272+ use role_name <- decode.field(2, decode.optional(decode.string))
7373+ use description <- decode.field(3, decode.optional(decode.string))
7474+ decode.success(GetBrigadeMembersRow(
7575+ id:,
7676+ full_name:,
7777+ role_name:,
7878+ description:,
7979+ ))
8080+ }
8181+8282+ "-- Find all members of a brigade
8383+SELECT
8484+ u.id,
8585+ u.full_name,
8686+ r.role_name,
8787+ r.description
8888+FROM public.user_account AS u
8989+LEFT JOIN
9090+ public.user_role AS r
9191+ ON u.role_id = r.id
9292+INNER JOIN
9393+ public.query_brigade_members_id($1) AS brigade_members (id)
9494+ ON u.id = brigade_members.id;
9595+"
9696+ |> pog.query
9797+ |> pog.parameter(pog.text(uuid.to_string(arg_1)))
9898+ |> pog.returning(decoder)
9999+ |> pog.execute(db)
100100+}
101101+102102+// --- Encoding/decoding utils -------------------------------------------------
103103+104104+/// A decoder to decode `Uuid`s coming from a Postgres query.
105105+///
106106+fn uuid_decoder() {
107107+ use bit_array <- decode.then(decode.bit_array)
108108+ case uuid.from_bit_array(bit_array) {
109109+ Ok(uuid) -> decode.success(uuid)
110110+ Error(_) -> decode.failure(uuid.v7(), "Uuid")
111111+ }
112112+}
···33//// It returns a list of members belonging to the specified brigade, including
44//// their id, full name, role, and description.
5566-import app/sql
66+import app/routes/brigade/sql
77import app/web.{type Context}
88import gleam/http
99import gleam/json
···11//// Handler for retrieving members from the same brigade as a given user.
2233-import app/sql
33+import app/routes/user/sql
44import app/web.{type Context}
55import gleam/http
66import gleam/json
···33//// It returns a list of occurrences (incidents/reports) that were submitted
44//// by the specified user, including detailed information about each occurrence.
5566-import app/sql
66+import app/routes/user/sql
77import app/web
88import gleam/float
99import gleam/http
···22////
33//// Uses signed cookies to prevent tampering and logs all login attempts.
4455-import app/sql
55+import app/routes/user/sql
66import app/web.{type Context}
77import argus
88import formal/form
+16
src/app/routes/occurrence.gleam
···11+import youid/uuid
22+33+/// Validated occurrence data with all IDs converted to UUIDs,
44+/// ready for database insertion
55+pub type Occurrence {
66+ Occurrence(
77+ applicant_id: uuid.Uuid,
88+ category_id: uuid.Uuid,
99+ subcategory_id: uuid.Uuid,
1010+ description: String,
1111+ location: List(Float),
1212+ reference_point: String,
1313+ vehicle_code: String,
1414+ participants_id: List(uuid.Uuid),
1515+ )
1616+}
···66//// Passwords are hashed using Argon2 before storage and all sensitive
77//// operations are logged for audit purposes.
8899-import app/sql
99+import app/routes/user/sql
1010import app/web.{type Context}
1111import argus
1212import formal/form
+6-141
src/app/sql.gleam
src/app/routes/user/sql.gleam
···11//// This module contains the code to run the sql queries defined in
22-//// `./src/app/sql`.
22+//// `./src/app/routes/user/sql`.
33//// > 🐿️ This module was generated automatically using v4.4.1 of
44//// > the [squirrel package](https://github.com/giacomocavalieri/squirrel).
55////
···1010import pog
1111import youid/uuid.{type Uuid}
12121313-/// A row you get from running the `count_active_brigades` query
1414-/// defined in `./src/app/sql/count_active_brigades.sql`.
1515-///
1616-/// > 🐿️ This type definition was generated automatically using v4.4.1 of the
1717-/// > [squirrel package](https://github.com/giacomocavalieri/squirrel).
1818-///
1919-pub type CountActiveBrigadesRow {
2020- CountActiveBrigadesRow(count: Int)
2121-}
2222-2323-/// Counts the number of active brigades in the database.
2424-///
2525-/// > 🐿️ This function was generated automatically using v4.4.1 of
2626-/// > the [squirrel package](https://github.com/giacomocavalieri/squirrel).
2727-///
2828-pub fn count_active_brigades(
2929- db: pog.Connection,
3030-) -> Result(pog.Returned(CountActiveBrigadesRow), pog.QueryError) {
3131- let decoder = {
3232- use count <- decode.field(0, decode.int)
3333- decode.success(CountActiveBrigadesRow(count:))
3434- }
3535-3636- "-- Counts the number of active brigades in the database.
3737-SELECT COUNT(id)
3838-FROM public.brigade
3939-WHERE is_active = TRUE;
4040-"
4141- |> pog.query
4242- |> pog.returning(decoder)
4343- |> pog.execute(db)
4444-}
4545-4646-/// A row you get from running the `get_brigade_members` query
4747-/// defined in `./src/app/sql/get_brigade_members.sql`.
4848-///
4949-/// > 🐿️ This type definition was generated automatically using v4.4.1 of the
5050-/// > [squirrel package](https://github.com/giacomocavalieri/squirrel).
5151-///
5252-pub type GetBrigadeMembersRow {
5353- GetBrigadeMembersRow(
5454- id: Uuid,
5555- full_name: String,
5656- role_name: Option(String),
5757- description: Option(String),
5858- )
5959-}
6060-6161-/// Find all members of a brigade
6262-///
6363-/// > 🐿️ This function was generated automatically using v4.4.1 of
6464-/// > the [squirrel package](https://github.com/giacomocavalieri/squirrel).
6565-///
6666-pub fn get_brigade_members(
6767- db: pog.Connection,
6868- arg_1: Uuid,
6969-) -> Result(pog.Returned(GetBrigadeMembersRow), pog.QueryError) {
7070- let decoder = {
7171- use id <- decode.field(0, uuid_decoder())
7272- use full_name <- decode.field(1, decode.string)
7373- use role_name <- decode.field(2, decode.optional(decode.string))
7474- use description <- decode.field(3, decode.optional(decode.string))
7575- decode.success(GetBrigadeMembersRow(
7676- id:,
7777- full_name:,
7878- role_name:,
7979- description:,
8080- ))
8181- }
8282-8383- "-- Find all members of a brigade
8484-SELECT
8585- u.id,
8686- u.full_name,
8787- r.role_name,
8888- r.description
8989-FROM public.user_account AS u
9090-LEFT JOIN
9191- public.user_role AS r
9292- ON u.role_id = r.id
9393-INNER JOIN
9494- public.query_brigade_members_id($1) AS brigade_members (id)
9595- ON u.id = brigade_members.id;
9696-"
9797- |> pog.query
9898- |> pog.parameter(pog.text(uuid.to_string(arg_1)))
9999- |> pog.returning(decoder)
100100- |> pog.execute(db)
101101-}
102102-10313/// A row you get from running the `get_crew_members` query
104104-/// defined in `./src/app/sql/get_crew_members.sql`.
1414+/// defined in `./src/app/routes/user/sql/get_crew_members.sql`.
10515///
10616/// > 🐿️ This type definition was generated automatically using v4.4.1 of the
10717/// > [squirrel package](https://github.com/giacomocavalieri/squirrel).
···15565}
1566615767/// A row you get from running the `get_login_token` query
158158-/// defined in `./src/app/sql/get_login_token.sql`.
6868+/// defined in `./src/app/routes/user/sql/get_login_token.sql`.
15969///
16070/// > 🐿️ This type definition was generated automatically using v4.4.1 of the
16171/// > [squirrel package](https://github.com/giacomocavalieri/squirrel).
···195105}
196106197107/// A row you get from running the `get_occurences_by_applicant` query
198198-/// defined in `./src/app/sql/get_occurences_by_applicant.sql`.
108108+/// defined in `./src/app/routes/user/sql/get_occurences_by_applicant.sql`.
199109///
200110/// > 🐿️ This type definition was generated automatically using v4.4.1 of the
201111/// > [squirrel package](https://github.com/giacomocavalieri/squirrel).
···270180}
271181272182/// A row you get from running the `get_user_id_by_registration` query
273273-/// defined in `./src/app/sql/get_user_id_by_registration.sql`.
183183+/// defined in `./src/app/routes/user/sql/get_user_id_by_registration.sql`.
274184///
275185/// > 🐿️ This type definition was generated automatically using v4.4.1 of the
276186/// > [squirrel package](https://github.com/giacomocavalieri/squirrel).
···305215}
306216307217/// A row you get from running the `get_user_name` query
308308-/// defined in `./src/app/sql/get_user_name.sql`.
218218+/// defined in `./src/app/routes/user/sql/get_user_name.sql`.
309219///
310220/// > 🐿️ This type definition was generated automatically using v4.4.1 of the
311221/// > [squirrel package](https://github.com/giacomocavalieri/squirrel).
···335245"
336246 |> pog.query
337247 |> pog.parameter(pog.text(uuid.to_string(arg_1)))
338338- |> pog.returning(decoder)
339339- |> pog.execute(db)
340340-}
341341-342342-/// Inserts a new occurrence into the database
343343-///
344344-/// > 🐿️ This function was generated automatically using v4.4.1 of
345345-/// > the [squirrel package](https://github.com/giacomocavalieri/squirrel).
346346-///
347347-pub fn insert_new_occurence(
348348- db: pog.Connection,
349349- arg_1: Uuid,
350350- arg_2: Uuid,
351351- arg_3: Uuid,
352352- arg_4: String,
353353- arg_5: List(Float),
354354- arg_6: String,
355355- arg_7: String,
356356- arg_8: List(Uuid),
357357-) -> Result(pog.Returned(Nil), pog.QueryError) {
358358- let decoder = decode.map(decode.dynamic, fn(_) { Nil })
359359-360360- "-- Inserts a new occurrence into the database
361361-INSERT INTO public.occurrence (
362362- applicant_id,
363363- category_id,
364364- subcategory_id,
365365- description,
366366- location,
367367- reference_point,
368368- vehicle_code,
369369- participants_id
370370-) VALUES ($1, $2, $3, $4, $5, $6, $7, $8);
371371-"
372372- |> pog.query
373373- |> pog.parameter(pog.text(uuid.to_string(arg_1)))
374374- |> pog.parameter(pog.text(uuid.to_string(arg_2)))
375375- |> pog.parameter(pog.text(uuid.to_string(arg_3)))
376376- |> pog.parameter(pog.text(arg_4))
377377- |> pog.parameter(pog.array(fn(value) { pog.float(value) }, arg_5))
378378- |> pog.parameter(pog.text(arg_6))
379379- |> pog.parameter(pog.text(arg_7))
380380- |> pog.parameter(
381381- pog.array(fn(value) { pog.text(uuid.to_string(value)) }, arg_8),
382382- )
383248 |> pog.returning(decoder)
384249 |> pog.execute(db)
385250}
-4
src/app/sql/count_active_brigades.sql
···11--- Counts the number of active brigades in the database.
22-SELECT COUNT(id)
33-FROM public.brigade
44-WHERE is_active = TRUE;