defmodule DaProductApp.RiskManagement.PosTransaction do use Ecto.Schema import Ecto.Changeset @derive {Jason.Encoder, only: [ :id, :transaction_id, :merchant_id, :terminal_id, :amount, :currency, :card_type, :card_number_masked, :mcc_code, :status, :transaction_time, :location, :country_code, :settlement_date, :batch_number, :authorization_code, :reference_number, :additional_data, :inserted_at, :updated_at ]} @primary_key {:id, :binary_id, autogenerate: true} schema "pos_transactions" do field :transaction_id, :string field :merchant_id, :string field :terminal_id, :string field :amount, :decimal field :currency, :string, default: "AED" field :card_type, :string # 'international', 'domestic' field :card_number_masked, :string field :mcc_code, :string field :status, :string field :transaction_time, :utc_datetime field :location, :string field :country_code, :string field :settlement_date, :date field :batch_number, :string field :authorization_code, :string field :reference_number, :string field :additional_data, :map timestamps(type: :utc_datetime) end @required_fields [:transaction_id, :merchant_id, :amount, :status, :transaction_time] @optional_fields [:terminal_id, :currency, :card_type, :card_number_masked, :mcc_code, :location, :country_code, :settlement_date, :batch_number, :authorization_code, :reference_number, :additional_data] @all_fields @required_fields ++ @optional_fields @valid_statuses ["completed", "pending", "failed", "hold"] @valid_card_types ["international", "domestic"] def changeset(pos_transaction, attrs) do pos_transaction |> cast(attrs, @all_fields) |> validate_required(@required_fields) |> validate_length(:transaction_id, min: 1, max: 100) |> validate_length(:merchant_id, min: 1, max: 50) |> validate_number(:amount, greater_than: 0) |> validate_inclusion(:status, @valid_statuses) |> validate_inclusion(:card_type, @valid_card_types) |> unique_constraint(:transaction_id) end def valid_statuses, do: @valid_statuses def valid_card_types, do: @valid_card_types @doc """ Creates a POS transaction and triggers risk evaluation. """ def create_pos_transaction(attrs \\ %{}) do result = %__MODULE__{} |> changeset(attrs) |> DaProductApp.Repo.insert() # Trigger risk evaluation for new POS transactions case result do {:ok, transaction} -> DaProductApp.Workers.TransactionRiskEvaluator.enqueue_evaluation(transaction.id, "POS") {:ok, transaction} error -> error end end end