Skip to content

Rfontt/simplified-transfer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Simplified Transfer System

Event Storming

Sticky notes 0.system simplified transfer - event storming - Knowledge.jpg

User Identification Flow 1.system simplified transfer - event storming.jpg

Deposit Flow 2.system simplified transfer - event storming.jpg

Transfer Flow 3. system simplified transfer - event storming.jpg

Articles explaining all project decisions process

Requirements

functional:

  • To both users:

    • The full name, the users document (CPF/CNPJ), email and password are required fields
  • To commons user:

    • A common user could transfer money to shopkeepers and others commons users
    • To transfer money, the user needs to have a positive balance in wallet.
  • To shopkeepers user:

    • Just receive money transfers but they couldn't transfer it

Non - functional:

  • CPF/CNPJ and email must be unique fields
  • Call this endpoint: https://util.devi.tools/api/v2/authorize to call a mock gateway authorization
  • The transfer operation needs be transactional, it means that if an error occur the money needs be refund in wallet
  • User needs be notified when receive a transfer. The notification could be a sms or an email
    • The notify service could be unavailable, so when it happening use a fallback or put in a dlq queue to retry
  • endpoint to transfer:
POST /transfer
Content-Type: application/json

{
  "value": 100.0,
  "payer": 4,
  "payee": 15
}
  • The database will use CQRS
    • Commands: It will handle with a Postgres database
    • Queries: It will handle with a MongoDB database
  • Consistency is not required, but the system must be available and partition-tolerant.

UML diagram

classDiagram
    direction LR

    %% =========================
    %% USER CONTEXT
    %% =========================

    class User {
        <<class>>
        -uuid id
        -string fullName
        -string document
        -string email
        -string password
        -Type type
        +GetFullName(userId uuid) string
        +GetEmail(userId uuid) string
        +GetUser(userId uuid) User
    }

    class UserRepository {
        <<interface>>
        +GetOne(id uuid) User
        +Save(user User) User
    }

    class Type {
        <<enumeration>>
        COMMON
        SHOPKEEPER
    }

    %% =========================
    %% ACCOUNT CONTEXT
    %% =========================

    class Account {
        <<class>>
        -uuid id
        -uuid userId
        -MonetaryAmount balance
        -AccountStatus status
        -Date createdAt
        +GetUserId(accountId uuid) String
        +GetAccountStatus(accountId uuid) AccountStatus
        +GetAccount(accountId uuid) Account
    }

    class AccountRepository {
        <<interface>>
        +GetOne(id AccountID) Account
        +Create(account Account) Account
    }

    class AccountStatus {
        <<enumeration>>
        ACTIVE
        BLOCKED
        CLOSED
    }

    class AccountTransactionStatus {
        <<enumeration>>
        PENDING
        COMPLETED
        FAILED
    }

    %% =========================
    %% DEPOSIT
    %% =========================

    class Deposit {
        <<class>>
        -uuid id
        -AccountID accountId
        -MonetaryAmount amount
        -AccountTransactionStatus status
        +GetDeposit(id uuid) Deposit
        +GetDepositTransactionStatus(id uuid) AccountTransactionStatus
        +GetDepositAmount(id uuid) MonetaryAmount
    }

    class DepositRepository {
        <<interface>>
        +GetOne(id uuid) Deposit
        +Create(deposit Deposit) Deposit
    }

    %% =========================
    %% TRANSFER
    %% =========================

    class Transfer {
        <<entity>>
        -uuid id
        -AccountID from
        -AccountID to
        -MonetaryAmount amount
        -AccountTransactionStatus status
        +GetTransfer(accountId uuid) Transfer
        +GetAmount(accountId uuid) MonetaryAmount
        +GetTransferTransactionStatus(id uuid) AccountTransactionStatus
    }

    class TransferRepository {
        <<interface>>
        +GetOne(id uuid) Transfer
        +Save(transfer Transfer) Transfer
    }

    %% =========================
    %% RELATIONSHIPS
    %% =========================

    User --> Type
    UserRepository --> User

    User "1" --> "1..*" Account : owns
    Account --> AccountStatus
    AccountRepository --> Account

    Deposit --> Account
    DepositRepository --> Deposit
    Deposit --> AccountTransactionStatus

    Transfer --> Account : from
    Transfer --> Account : to
    TransferRepository --> Transfer
    Transfer --> AccountTransactionStatus
Loading

About

Simplified transfer system challenge

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages