- https://medium.com/@rfontt/event-storming-questionar-organizar-e-decidir-assertivamente-ab00891b6b50
- https://medium.com/@rfontt/event-storming-na-pr%C3%A1tica-2aaaf99c33fa
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.
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



