summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMateus Cruz <mateuscolvr@gmail.com>2024-02-06 02:56:02 -0300
committerMateus Cruz <mateuscolvr@gmail.com>2024-02-06 02:56:02 -0300
commitdb882cae080d3820f1723a711398c21db27f826a (patch)
tree521898630757be1b8056539d919ded3aa69a66ba
parent7c92898c8f0adb4a6014ce5f434a7d862a0cdc57 (diff)
small refactor
-rw-r--r--lib/client.ml5
-rw-r--r--lib/handler.ml69
-rw-r--r--lib/operation.ml8
-rw-r--r--lib/query.ml7
-rw-r--r--lib/serializer.ml30
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 ]
;;