summaryrefslogtreecommitdiff
path: root/lib/operation.ml
blob: 911c4096c735a368ea3d439a584d5c639ea618c1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
module TransactionType = struct
  type t =
    [ `Credit
    | `Debit
    ]

  let t =
    let encode = function
      | `Credit -> "credit"
      | `Debit -> "debit"
    in
    let decode = function
      | "credit" -> Ok `Credit
      | "debit" -> Ok `Debit
      | _ -> Error "Invalid transaction type"
    in
    Caqti_type.(enum ~encode ~decode "transaction_type")
  ;;
end

type client =
  { id : int
  ; mov_limit : int
  ; balance : int
  }

type transaction_payload =
  { value : int
  ; description : string
  }

type transaction_op =
  [ `Credit of transaction_payload
  | `Debit of transaction_payload
  ]

type transaction =
  { id : int
  ; client_id : int
  ; value : int
  ; transaction_type : TransactionType.t
  ; description : string
  ; created_at : Ptime.t
  }

let decoder : transaction_op Utils.Decoder.decoder =
  let open Utils.Decoder in
  let open Syntax in
  let transaction_type_decoder =
    literal "c" *> return (fun p -> `Credit p)
    <|> literal "d" *> return (fun p -> `Debit p)
  in
  (fun value transaction_type description -> transaction_type { value; description })
  <$> ("valor" <: (int >>= fun x -> if x >= 1 then return x else fail))
  <*> ("tipo" <: transaction_type_decoder)
  <*> ("descricao"
       <: (string
           >>= fun s ->
           let len = String.length s in
           if len <= 10 && len >= 1 then return s else fail))
;;