diff options
author | Mateus Cruz <mateuscolvr@gmail.com> | 2024-02-06 02:56:02 -0300 |
---|---|---|
committer | Mateus Cruz <mateuscolvr@gmail.com> | 2024-02-06 02:56:02 -0300 |
commit | db882cae080d3820f1723a711398c21db27f826a (patch) | |
tree | 521898630757be1b8056539d919ded3aa69a66ba | |
parent | 7c92898c8f0adb4a6014ce5f434a7d862a0cdc57 (diff) |
small refactor
-rw-r--r-- | lib/client.ml | 5 | ||||
-rw-r--r-- | lib/handler.ml | 69 | ||||
-rw-r--r-- | lib/operation.ml | 8 | ||||
-rw-r--r-- | lib/query.ml | 7 | ||||
-rw-r--r-- | lib/serializer.ml | 30 |
5 files changed, 55 insertions, 64 deletions
diff --git a/lib/client.ml b/lib/client.ml deleted file mode 100644 index 8be4644..0000000 --- a/lib/client.ml +++ /dev/null @@ -1,5 +0,0 @@ -type t = - { id : int - ; mov_limit : int - ; balance : int - } diff --git a/lib/handler.ml b/lib/handler.ml index c02ed71..fb43239 100644 --- a/lib/handler.ml +++ b/lib/handler.ml @@ -1,39 +1,40 @@ open Piaf -let valid_debit value limit balance = - let balance_after_op = balance - value in - not (balance_after_op < limit * -1) -;; +type pool = ((module Rapper_helper.CONNECTION), Caqti_error.t) Caqti_eio.Pool.t -let create_transaction client_id (db_pool : Query.pool) (request : Request.t) = +let create_transaction client_id (db_pool : pool) (request : Request.t) = Caqti_eio.Pool.use (fun conn -> let module C = (val conn : Rapper_helper.CONNECTION) in C.with_transaction @@ fun () -> - let _ = Query.lock client_id conn in + ignore @@ Query.lock client_id conn; let client_opt = Option.join @@ Result.to_option @@ Query.find_client client_id conn in match client_opt with | Some client -> + let body = Result.to_option @@ Body.to_string request.body in + let json = + Option.map + (fun str -> + try Yojson.Safe.from_string str with + | _ -> `Null) + body + in + let decoded_op = Option.bind json (Utils.Decoder.decode Operation.decoder) in let insert_result = - let body = Result.to_option @@ Body.to_string request.body in - let json = - Option.map - (fun str -> - try Yojson.Safe.from_string str with - | _ -> `Null) - body - in - let decoded_op = Option.bind json (Utils.Decoder.decode Operation.decoder) in match decoded_op with | Some (`Credit { value = _value; description = _desc } as op) -> (match Query.execute_transaction ~client_id ~op conn with | Ok _ as ok -> ok | Error e -> Error (`DB e)) | Some (`Debit { value; description = _desc } as op) -> - if valid_debit value client.mov_limit client.balance + let valid_debit = + let balance_after_op = client.balance - value in + not (balance_after_op < client.mov_limit * -1) + in + if valid_debit then ( match Query.execute_transaction ~client_id ~op conn with | Ok _ as ok -> ok @@ -54,7 +55,7 @@ let create_transaction client_id (db_pool : Query.pool) (request : Request.t) = db_pool ;; -let get_balance client_id (db_pool : Query.pool) (_request : Request.t) = +let get_balance client_id (db_pool : pool) (_request : Request.t) = Caqti_eio.Pool.use (fun conn -> let client_opt = @@ -62,33 +63,15 @@ let get_balance client_id (db_pool : Query.pool) (_request : Request.t) = in match client_opt with | Some client -> - let client_balance_opt = - Option.join @@ Result.to_option @@ Query.balance client_id conn + let transaction_list = + (* NOTE: Talvez isso aqui não seja uma boa ideia *) + Result.fold ~ok:Fun.id ~error:(fun _ -> []) @@ Query.transactions client_id conn in - (match client_balance_opt with - | Some (balance_value, time) -> - let json : Yojson.Safe.t = - let balance = - let total = `Int balance_value in - let date = - `String - (Format.asprintf "%a" (Ptime.pp_rfc3339 ~tz_offset_s:(-10800) ()) time) - in - let limit = `Int client.mov_limit in - `Assoc [ "total", total; "data_extrato", date; "limite", limit ] - in - let t = - (* NOTE: Talvez isso aqui não seja uma boa ideia *) - Result.fold ~ok:Fun.id ~error:(fun _ -> []) - @@ Query.transactions client_id conn - in - let last_transactions = `List (List.map Serializer.transaction t) in - `Assoc [ "saldo", balance; "ultimas_transacoes", last_transactions ] - in - Ok (Response.of_string ~body:(Yojson.Safe.to_string json) `OK) - | None -> - Logs.info (fun m -> m "Não encontrei o extrato do cliente %d" client_id); - Ok (Response.create `Not_found)) + let json = + let time = Option.get @@ Ptime.of_float_s (Unix.time ()) in + Serializer.bank_statement time client transaction_list + in + Ok (Response.of_string ~body:(Yojson.Safe.to_string json) `OK) | None -> Logs.info (fun m -> m "Não encontrei o cliente %d" client_id); Ok (Response.create `Not_found)) diff --git a/lib/operation.ml b/lib/operation.ml index 54962fd..2e681f8 100644 --- a/lib/operation.ml +++ b/lib/operation.ml @@ -18,6 +18,12 @@ module TransactionType = struct ;; end +type client = + { id : int + ; mov_limit : int + ; balance : int + } + type transaction_payload = { value : int ; description : string @@ -28,8 +34,6 @@ type transaction_op = | `Debit of transaction_payload ] -type t = Balance of { client_id : int } - type transaction = { id : int ; client_id : int diff --git a/lib/query.ml b/lib/query.ml index 2dab927..40a2c22 100644 --- a/lib/query.ml +++ b/lib/query.ml @@ -1,5 +1,3 @@ -type pool = ((module Rapper_helper.CONNECTION), Caqti_error.t) Caqti_eio.Pool.t - module Q = struct let transaction = [%rapper @@ -27,7 +25,7 @@ module Q = struct ;; let client = - let open Client in + let open Operation in [%rapper get_opt {sql| @@ -61,8 +59,7 @@ module Q = struct let lock = [%rapper - execute - {sql| + execute {sql| SELECT pg_advisory_xact_lock(%int{client_id}) |sql}] ;; diff --git a/lib/serializer.ml b/lib/serializer.ml index 35464ac..1024767 100644 --- a/lib/serializer.ml +++ b/lib/serializer.ml @@ -4,13 +4,25 @@ let transaction (t : Operation.transaction) = | `Credit -> "c" | `Debit -> "d" in - `Assoc - [ "valor", `Int t.value - ; "tipo", `String transaction_type - ; "descricao", `String t.description - ; ( "realizada_em" - , `String - (Format.asprintf "%a" (Ptime.pp_rfc3339 ~tz_offset_s:(-10800) ()) t.created_at) - ) - ] + let value = "valor", `Int t.value in + let transaction_type = "tipo", `String transaction_type in + let description = "descricao", `String t.description in + let created_at = + let formatted_date = + Format.asprintf "%a" (Ptime.pp_rfc3339 ~tz_offset_s:(-10800) ()) t.created_at + in + "realizada_em", `String formatted_date + in + `Assoc [ value; transaction_type; description; created_at ] +;; + +let bank_statement time client transactions = + let date = + `String (Format.asprintf "%a" (Ptime.pp_rfc3339 ~tz_offset_s:(-10800) ()) time) + in + let limit = `Int client.Operation.mov_limit in + let total = `Int client.balance in + let balance = `Assoc [ "total", total; "data_extrato", date; "limite", limit ] in + let last_transactions = `List (List.map transaction transactions) in + `Assoc [ "saldo", balance; "ultimas_transacoes", last_transactions ] ;; |