# Mutual Fund System
## Sequence Diagram
```sequence
title: Mutual Fund System
User->Bank: 1. create user
Bank->User Management: 1.1 create user
User Management-->Bank: 1.2 return result
Bank->Account Management: 1.4 create account
Account Management-->Bank: 1.5 return result
Bank-->User: 1.6 return result
User->Bank: 2. sign agreement
Bank->Agreement Management: 2.1 check agreement status
Agreement Management-->Bank: 2.2 return agreement detail
Bank-->User: 2.3 display agreement detail
User->Bank: 2.4 confirm for signing
Bank->Agreement Management: 2.5 update agreement status
Agreement Management-->Bank: 2.6 return result
Bank-->User: 2.7 return result
User->Bank: 3. user login
Bank->User Management: 3.1 check login info
User Management-->Bank: 3.2 return result
Bank-->User: 3.3 return result
User->Bank: 4 request funds avaliable
Bank->Agreement Management: 4.1 check agreement
Agreement Management-->Bank: 4.2 return result
note right of Bank: has agreement ?
Bank->Fund Management: 4.3 look up for the funds avaliable
Fund Management-->Bank: 4.4 return data
Bank-->User: 4.5 display the fund list
User->Bank: 5. select the target fund and amount of money
Bank->Fund Management: 5.1 check fund detail
Fund Management-->Bank: 5.2 return fund detail
Bank-->User: 5.3 display the fund detail
User->Bank: 6. confirm for purchase
Bank->Account Management: 6.1 check account balance
Account Management-->Bank: 6.2 return account balance
note right of Bank: balance not enough ?
Bank->Notification: 6.3 send warning
Notification-->>User: 6.4 A warning message sent to user
Bank->Fund Management: 6.5 get the detail of the fund
Fund Management-->Bank: 6.6 return fund detail
Bank->Order Management: 6.7 create and record order
Order Management-->Bank: 6.8 return result
note right of Bank: closing hours passed ?
Bank->Notification: 6.9 send message to user
Notification-->User: 6.10 notify the result of transaction
Bank-->User: 6.11 return result with extra info
note right of Bank: is trading date ?
Bank->Account Management: 6.12 check account balance and debit
Account Management-->Bank: 6.13 return account detail
note right of Bank: balance not enough ?
Bank->Notification: 6.14 send warning
Notification-->>User: 6.15 A warning message sent to user
note right of Bank: last check before closing hours
Bank->Order Management: 6.16 get order detail
Order Management-->Bank: 6.17 return order detail
Bank->Fund Management: 6.18 update fund detail
Fund Management-->Bank: 6.19 return result
Bank->Account Management: 6.20 update user account
Account Management-->Bank: 6.21 return result
Bank->Notification: 6.22 send message
Notification --> User: 6.23 notify the result of the transaction
```
---
## APIs
* POST /users: Create user
* POST /users/login: Login
* POST /agreements: Sign agreement
* GET /funds: View list of available funds to purchase
* GET /funds/{id}: View details of a specific fund
* POST /funds/{id}/purchase: Confirm purchase of a fund
* GET /accounts/{id}: View account details
* POST /accounts/{id}/deposit: Deposit
* POST /accounts/{id}/withdraw: Withdraw
* GET /transactions/{id}: View details of a specific transaction
* GET /orders/{id}: View details of a specific order
---
### Create User
* URL: /users
* Method: POST
* Request Body:
```
{
"username": "JohnDoe",
"email": "johndoe@example.com",
"password": "abc123456",
"phone": "886912345678"
}
```
* Response:
* Success (201):
```
{
"success": true,
"id": 12345,
"accountId": "acc0000000001"
}
```
* Failure (400):
```
{
"error": "user already existed."
}
```
---
### Login
* URL: /users/login
* Method: POST
* Request Body:
```
{
"username": "JohnDoe",
"email": "johndoe@example.com",
"password": "abc123456"
}
```
* Response:
* Success (200):
```
{
"token": "jwt_token"
}
```
* Failure (401):
```
{
"error": "Invalid email or password."
}
```
---
### Sign Agreement
* URL: /agreements
* Method: POST
* Request Body:
```
{
"user_id": "12345",
"agreement_id": "67890",
}
```
* Response:
* Success (200):
```
{
"id": "67890",
"user_id": "12345",
"status": "signed"
}
```
* Failure (404):
```
{
"error": "User not found."
}
```
* Failure (400):
```
{
"error": "Agreement has already been signed."
}
```
---
### View list of available funds to purchase
* URL: /funds
* Method: GET
* Request Headers:
```
Authorization: Bearer <JWT token>
```
* Response:
* Success (200):
```
{
"funds": [
{
"id": "123456",
"name": "ABC Fund",
"type": "A",
"currency": "USD",
"nav": 34.62,
"fee": 1.5
},
{
"id": "234567",
"name": "DEF Fund",
"type": "B",
"currency": "EUR",
"nav": 56.78,
"fee": 2.0
}
]
}
```
* Failure (401):
```
{
"error": "Unauthorized"
}
```
___
### View details of a specific fund
* URL: /funds/{id}
* Method: GET
* Request Headers:
```
Authorization: Bearer <JWT token>
```
* Request Body: N/A
```
```
* Response
* Success (200):
```
{
"id": "12345",
"name": "ABC Mutual Fund",
"net_assets_value": 100.0,
"currency": "USD",
"fund_type": "Stocks",
"fee_schedule": "1.5%",
"prospectus": "https://example.com/prospectus"
}
```
* Failure (404):
```
{
"error": "Fund not found."
}
```
---
### Confirm purchase of a fund
* URL: /funds/{id}/purchase
* Method: POST
* Request Headers:
```
Authorization: Bearer <JWT token>
```
* Request Body:
```
{
"amount": 100,
"tradingFee": 1.5,
"tradingType": "prepay"
}
```
* Response:
* Success (201):
```
{
"id": "12345",
"fundId": "abc123",
"amount": 100,
"tradingFee": 1.5,
"tradingType": "prepay",
"status": "pending",
"createdAt": "2022-12-10T15:30:00Z"
}
```
* Failure (400):
```
{
"error": "Invalid trading type."
}
```
---
### View account details
* URL: /accounts/{id}
* Method: GET
* Request Headers:
```
Authorization: Bearer <JWT token>
```
* Request Body: N/A
```
```
* Response:
* Success (200):
```
{
"id": "12345",
"balance": 1000.00,
"orders": [
{
"id": "1",
"fund_id": "ABC",
"quantity": 100,
"price": 34.62,
"date": "2022-12-10"
},
{
"id": "2",
"fund_id": "XYZ",
"quantity": 50,
"price": 20.34,
"date": "2022-12-09"
}
],
"transactions": [
{
"id": "1",
"type": "DEPOSIT",
"amount": 500.00,
"date": "2022-12-09"
},
{
"id": "2",
"type": "WITHDRAW",
"amount": 100.00,
"date": "2022-12-08"
}
]
}
```
* Failure (404):
```
{
"error": "Account not found."
}
```
---
### Deposit
* URL: /accounts/{id}/deposit
* Method: POST
* Request Headers:
```
Authorization: Bearer <JWT token>
```
* Request Body:
```
{
"amount": 1000
}
```
* Response:
* Success (200):
```
{
"id": "12345",
"balance": 1000
}
```
* Failure (400):
```
{
"error": "Invalid amount"
}
// or
{
"error": "Account not found"
}
```
---
### Withdraw
* URL: /accounts/{id}/withdraw
* Method: POST
* Request Headers:
```
Authorization: Bearer <JWT token>
```
* Request Body:
```
{
"amount": 1000
}
```
* Response:
* Success (200):
```
{
"id": "12345",
"username": "JohnDoe",
"email": "johndoe@example.com",
"balance": 10000
}
```
* Failure (400):
```
{
"error": "Insufficient balance."
}
```
---
### View details of a specific transaction
* URL: /transactions/{id}
* Method: GET
* Request Headers:
```
Authorization: Bearer <JWT token>
```
* Request Body: N/A
```
```
* Response:
* Success (200):
```
{
"id": "12345",
"type": "deposit",
"amount": 100,
"date": "2022-10-10"
}
```
* Failure (404):
```
{
"error": "Transaction not found."
}
```
---
### View details of a specific order
* URL: /orders/{id}
* Method: GET
* Request Headers:
```
Authorization: Bearer <JWT token>
```
* Request Body: N/A
```
```
* Response:
* Success (200):
```
{
"id": "12345",
"fund_id": "67890",
"fund_name": "ABC Fund",
"amount": 10000,
"price": 100.50,
"status": "pending",
"created_at": "2022-12-10T12:00:00Z"
}
```
* Failure (404):
```
{
"error": "Order not found."
}
```
---
## Table Schema
### users
```sql!
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(255) NOT NULL UNIQUE,
email VARCHAR(255) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
phone VARCHAR(255) NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
deleted_at DATETIME
);
```
### agreements
```sql!
CREATE TABLE agreements (
id INTEGER PRIMARY KEY AUTO_INCREMENT,
user_id INTEGER NOT NULL,
signed_at DATETIME DEFAULT CURRENT_TIMESTAMP,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
deleted_at DATETIME
);
```
### funds
```sql!
CREATE TABLE funds (
id INTEGER PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
nav DECIMAL(10, 4) NOT NULL,
fee DECIMAL(10, 4) NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
deleted_at DATETIME
);
```
### orders
```sql!
CREATE TABLE orders (
id INTEGER PRIMARY KEY AUTO_INCREMENT,
user_id INTEGER NOT NULL,
fund_id INTEGER NOT NULL,
amount DECIMAL(10, 4) NOT NULL,
status ENUM('pending', 'completed', 'failed', 'cancelled') NOT NULL DEFAULT 'pending',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
deleted_at DATETIME
);
```
### accounts
```sql!
CREATE TABLE accounts (
id INTEGER PRIMARY KEY AUTO_INCREMENT,
user_id INTEGER NOT NULL,
balance DECIMAL(10,4) NOT NULL DEFAULT 0,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
deleted_at DATETIME
)
```
### user_funds
```sql!
CREATE TABLE user_funds (
user_id INTEGER NOT NULL,
fund_id INTEGER NOT NULL,
units DECIMAL(10,4) NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
deleted_at DATETIME
)
```
### transaction
```sql!
CREATE TABLE transactions (
id INTEGER PRIMARY KEY AUTO_INCREMENT,
user_id INTEGER NOT NULL,
type ENUM('deposit', 'withdraw') NOT NULL,
amount DECIMAL(10,4) NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
)
```