wip: currently rewriting the project as a full stack application tangled.org/kacaii.dev/sigo
gleam

:truck: rename query to occurrence_dataset

+98 -72
+73 -65
src/app/domain/data_analysis/analysis_occurrence_volume.gleam
··· 16 16 import youid/uuid 17 17 18 18 type AnalysisError { 19 + /// Failed to query the DataBase 19 20 Database(pog.QueryError) 21 + /// User does not have access to this endpoint 20 22 AccessControl(user.AccessControlError) 21 23 } 22 24 25 + /// 󰕮 Retrieve general information about occurrences and send it as JSON 26 + /// 27 + /// ## Response 28 + /// 29 + /// ```jsonc 30 + /// [ 31 + /// { 32 + /// "occurrence_id": "019b19c2-8311-799c-99db-3f777732df4a", 33 + /// "reported_timestamp": 1765652936.593211, 34 + /// "arrival_timestamp": null, 35 + /// "resolved_timestamp": null, 36 + /// "occurrence_category": "fire", 37 + /// "occurrence_subcategory": "injured_animal", 38 + /// "priority": "high", 39 + /// "applicant_name": "João Fulano", 40 + /// "applicant_role": "analyst", 41 + /// "latitude": 6.906980184619583, 42 + /// "longitude": 75.57821949630532 43 + /// } 44 + /// ] 45 + /// ``` 23 46 pub fn handle_request( 24 47 request req: wisp.Request, 25 48 ctx ctx: Context, ··· 51 74 ) 52 75 53 76 use returned <- result.map( 54 - sql.occurrence_volume(ctx.db) 77 + sql.occurrence_dataset(ctx.db) 55 78 |> result.map_error(Database), 56 79 ) 57 80 ··· 60 83 |> json.to_string 61 84 } 62 85 63 - fn row_to_json(row: sql.OccurrenceVolumeRow) -> json.Json { 86 + fn row_to_json(row: sql.OccurrenceDatasetRow) -> json.Json { 64 87 let timestamp_to_json = fn(t: timestamp.Timestamp) { 65 - timestamp.to_unix_seconds(t) |> json.float 88 + timestamp.to_unix_seconds(t) 89 + |> json.float 66 90 } 67 91 68 - let maybe_timestamp_to_json = fn(t: option.Option(timestamp.Timestamp)) { 69 - case t { 70 - option.None -> json.null() 71 - option.Some(t) -> timestamp_to_json(t) 72 - } 73 - } 74 - 75 - let cat_to_json = fn(c: sql.OccurrenceCategoryEnum) { 76 - case c { 92 + let category = { 93 + case row.occurrence_category { 77 94 sql.Fire -> category.Fire 78 95 sql.MedicEmergency -> category.MedicEmergency 79 96 sql.Other -> category.Other 80 97 sql.TrafficAccident -> category.TrafficAccident 81 98 } 82 - |> category.to_string 83 - |> json.string 84 99 } 85 100 86 - let subcat_to_json = fn(s: option.Option(sql.OccurrenceSubcategoryEnum)) -> json.Json { 87 - case s { 88 - option.None -> json.null() 89 - option.Some(value) -> 90 - case value { 91 - sql.Collision -> subcategory.Collision 92 - sql.Comercial -> subcategory.Comercial 93 - sql.Flood -> subcategory.Flood 94 - sql.HeartStop -> subcategory.HeartStop 95 - sql.InjuredAnimal -> subcategory.InjuredAnimal 96 - sql.Intoxication -> subcategory.Intoxication 97 - sql.MotorcycleCrash -> subcategory.MotorcycleCrash 98 - sql.PreHospitalCare -> subcategory.PreHospitalCare 99 - sql.Residential -> subcategory.Residential 100 - sql.Rollover -> subcategory.Rollover 101 - sql.RunOver -> subcategory.RunOver 102 - sql.Seizure -> subcategory.Seizure 103 - sql.SeriousInjury -> subcategory.SeriousInjury 104 - sql.TreeCrash -> subcategory.TreeCrash 105 - sql.Vegetation -> subcategory.Vegetation 106 - sql.Vehicle -> subcategory.Vehicle 107 - } 108 - |> subcategory.to_string 109 - |> json.string 101 + let subcategory = { 102 + use subcategory <- option.map(row.occurrence_subcategory) 103 + case subcategory { 104 + sql.Collision -> subcategory.Collision 105 + sql.Comercial -> subcategory.Comercial 106 + sql.Flood -> subcategory.Flood 107 + sql.HeartStop -> subcategory.HeartStop 108 + sql.InjuredAnimal -> subcategory.InjuredAnimal 109 + sql.Intoxication -> subcategory.Intoxication 110 + sql.MotorcycleCrash -> subcategory.MotorcycleCrash 111 + sql.PreHospitalCare -> subcategory.PreHospitalCare 112 + sql.Residential -> subcategory.Residential 113 + sql.Rollover -> subcategory.Rollover 114 + sql.RunOver -> subcategory.RunOver 115 + sql.Seizure -> subcategory.Seizure 116 + sql.SeriousInjury -> subcategory.SeriousInjury 117 + sql.TreeCrash -> subcategory.TreeCrash 118 + sql.Vegetation -> subcategory.Vegetation 119 + sql.Vehicle -> subcategory.Vehicle 110 120 } 111 121 } 112 122 113 - let maybe_role_to_json = fn(r: option.Option(sql.UserRoleEnum)) -> json.Json { 114 - case r { 115 - option.None -> json.null() 116 - option.Some(value) -> 117 - case value { 118 - sql.Admin -> role.Admin 119 - sql.Analyst -> role.Analyst 120 - sql.Captain -> role.Captain 121 - sql.Developer -> role.Developer 122 - sql.Firefighter -> role.Firefighter 123 - sql.Sargeant -> role.Sargeant 124 - } 125 - |> role.to_json 123 + let role = { 124 + use role <- option.map(row.applicant_role) 125 + case role { 126 + sql.Admin -> role.Admin 127 + sql.Analyst -> role.Analyst 128 + sql.Captain -> role.Captain 129 + sql.Developer -> role.Developer 130 + sql.Firefighter -> role.Firefighter 131 + sql.Sargeant -> role.Sargeant 126 132 } 127 133 } 128 134 129 - let priority_to_json = fn(p: sql.OccurrencePriorityEnum) -> json.Json { 130 - case p { 131 - sql.High -> priority.High 132 - sql.Low -> priority.Low 133 - sql.Medium -> priority.Medium 134 - } 135 - |> priority.to_string 136 - |> json.string 135 + let priority = case row.priority { 136 + sql.High -> priority.High 137 + sql.Low -> priority.Low 138 + sql.Medium -> priority.Medium 137 139 } 138 140 141 + let arrival_timestamp_json = 142 + json.nullable(row.arrival_timestamp, timestamp_to_json) 143 + 144 + let resolved_timestamp_json = 145 + json.nullable(row.resolved_timestamp, timestamp_to_json) 146 + 139 147 json.object([ 140 148 #("occurrence_id", json.string(row.occurrence_id |> uuid.to_string)), 141 149 #("reported_timestamp", timestamp_to_json(row.reported_timestamp)), 142 - #("arrival_timestamp", maybe_timestamp_to_json(row.arrival_timestamp)), 143 - #("resolved_timestamp", maybe_timestamp_to_json(row.resolved_timestamp)), 144 - #("occurrence_category", cat_to_json(row.occurrence_category)), 145 - #("occurrence_subcategory", subcat_to_json(row.occurrence_subcategory)), 146 - #("priority", priority_to_json(row.priority)), 150 + #("arrival_timestamp", arrival_timestamp_json), 151 + #("resolved_timestamp", resolved_timestamp_json), 152 + #("occurrence_category", category.to_json(category)), 153 + #("occurrence_subcategory", json.nullable(subcategory, subcategory.to_json)), 154 + #("priority", priority.to_json(priority)), 147 155 #("applicant_name", json.nullable(row.applicant_name, json.string)), 148 - #("applicant_role", maybe_role_to_json(row.applicant_role)), 156 + #("applicant_role", json.nullable(role, role.to_json)), 149 157 #("latitude", json.float(row.latitude)), 150 158 #("longitude", json.float(row.longitude)), 151 159 ])
+7 -7
src/app/domain/data_analysis/sql.gleam
··· 10 10 import pog 11 11 import youid/uuid.{type Uuid} 12 12 13 - /// A row you get from running the `occurrence_volume` query 14 - /// defined in `./src/app/domain/data_analysis/sql/occurrence_volume.sql`. 13 + /// A row you get from running the `occurrence_dataset` query 14 + /// defined in `./src/app/domain/data_analysis/sql/occurrence_dataset.sql`. 15 15 /// 16 16 /// > 🐿️ This type definition was generated automatically using v4.6.0 of the 17 17 /// > [squirrel package](https://github.com/giacomocavalieri/squirrel). 18 18 /// 19 - pub type OccurrenceVolumeRow { 20 - OccurrenceVolumeRow( 19 + pub type OccurrenceDatasetRow { 20 + OccurrenceDatasetRow( 21 21 occurrence_id: Uuid, 22 22 reported_timestamp: Timestamp, 23 23 arrival_timestamp: Option(Timestamp), ··· 37 37 /// > 🐿️ This function was generated automatically using v4.6.0 of 38 38 /// > the [squirrel package](https://github.com/giacomocavalieri/squirrel). 39 39 /// 40 - pub fn occurrence_volume( 40 + pub fn occurrence_dataset( 41 41 db: pog.Connection, 42 - ) -> Result(pog.Returned(OccurrenceVolumeRow), pog.QueryError) { 42 + ) -> Result(pog.Returned(OccurrenceDatasetRow), pog.QueryError) { 43 43 let decoder = { 44 44 use occurrence_id <- decode.field(0, uuid_decoder()) 45 45 use reported_timestamp <- decode.field(1, pog.timestamp_decoder()) ··· 67 67 ) 68 68 use latitude <- decode.field(9, decode.float) 69 69 use longitude <- decode.field(10, decode.float) 70 - decode.success(OccurrenceVolumeRow( 70 + decode.success(OccurrenceDatasetRow( 71 71 occurrence_id:, 72 72 reported_timestamp:, 73 73 arrival_timestamp:,
src/app/domain/data_analysis/sql/occurrence_volume.sql src/app/domain/data_analysis/sql/occurrence_dataset.sql
+6
src/app/domain/occurrence/category.gleam
··· 1 1 import gleam/dynamic/decode 2 + import gleam/json 2 3 import gleam/string 3 4 4 5 pub type Category { ··· 15 16 Fire -> "fire" 16 17 MedicEmergency -> "medic_emergency" 17 18 } 19 + } 20 + 21 + pub fn to_json(category: Category) { 22 + to_string(category) 23 + |> json.string 18 24 } 19 25 20 26 pub fn to_string_pt_br(category: Category) {
+6
src/app/domain/occurrence/priority.gleam
··· 1 1 import gleam/dynamic/decode 2 + import gleam/json 2 3 3 4 pub type Priority { 4 5 High ··· 12 13 Low -> "low" 13 14 Medium -> "medium" 14 15 } 16 + } 17 + 18 + pub fn to_json(priority: Priority) -> json.Json { 19 + to_string(priority) 20 + |> json.string 15 21 } 16 22 17 23 pub fn to_string_pt_br(value: Priority) {
+6
src/app/domain/occurrence/subcategory.gleam
··· 1 1 import gleam/dynamic/decode 2 + import gleam/json 2 3 import gleam/string 3 4 4 5 pub type Subcategory { ··· 39 40 HeartStop -> "heart_stop" 40 41 PreHospitalCare -> "pre_hospital_care" 41 42 } 43 + } 44 + 45 + pub fn to_json(subcategory: Subcategory) -> json.Json { 46 + to_string(subcategory) 47 + |> json.string 42 48 } 43 49 44 50 pub fn to_string_pt_br(subcategory: Subcategory) -> String {