Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

30 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 - DDD good practices

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages