---
# System prepended metadata

title: Simplane API's design

---

# Simplane API's design
## Swagger:
- http://localhost:8282/simplane-service/swagger-ui/index.html
- /simplane-service/api-docs
## Database:
- mongodb+srv://lhquan:25251325Quan@cluster0.0u1hb.mongodb.net/?retryWrites=true&w=majority

## Mutable tables
### 1. Airport
| code | name | address |
| ---- | ---- | ------- |
| SGN | Tân Sơn Nhất | TP.HCM |
| HAN | Nội Bài | Hà Nội |
| VDH | Đồng Hới | Quảng Bình |
| VII | Vinh | Nghệ An |
| CXR | Cam Ranh | Khánh Hòa |
| VCA | Cần Thơ | Cần Thơ |
| DAD | Đà Nẵng | Đà Nẵng |

## Fixed tables
### 1. Manager account
| id | username | password | fullname |
| -- | -------- | -------- | -------- |
| 0 | admin | admin | Admin |


### 2. Ticket class

| id | enName | viName | canChange | changeFee | canReturn | returnFee |
| --- | --- | --- | --- | --- | ---| --- |
| P | Economy super lite | Phổ thông siêu tiết kiệm | false | 0 | false | 0 |
| L | Economy | Phổ thông | true | 120000.0 | false | 0 |
| C | Business | Thương gia | true | 0 | true | 30000.0 |

## Authenticate

### 1. Login
- Type: **POST**
- Path: `/auth/sign-in`
- Request's params:
```json=
{
    "username": "lehongquan",
    "password": "123456"
}
```
- Response:
```json=
{
  "statusCode": 200,
  "message": "Đăng nhập thành công",
  "data": {
    "isVerified": true,
    "fullname": "Lê Hồng Quân",
    "isAdmin": true,
    "username": "lehongquan",
    "token": "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJsZWhvbmdxdWFuIiwiaWF0IjoxNjU1MDM3MDY1LCJleHAiOjE2NTU2NDE4NjV9.pOnfcarliOp2K20_Gzej57hNJO4ehSQ-IkASptApYfnXcN4bidAU0xPtLe9dE7octwdk5-GZEtqSUrs-Z9Q2Kg"
  }
}
```

```json=
{
  "statusCode": 0,
  "message": "Mật khẩu không đúng! Vui lòng kiểm tra lại!"
}
```

```json=
{
  "statusCode": 0,
  "message": "Tài khoản không tồn tại! Vui lòng kiểm tra lại!"
}
```
- Note: `isAdmin` có thể không cần, mặc định là false, khi nào là tài khoản admin thì mới true

### 2. Sign up
- Type: **POST**
- Path: `/auth/sign-up`
- Request's params:
```json=
{
  "username": "lehongquan1",
  "password": "123456",
  "fullname": "Lê Hồng Quân",
  "accessToken": "",
  "isVerified": true,
  "idAdmin": true
}
```
- Response:
```json=
{
  "statusCode": 200,
  "data": {
    "username": "lehongquan2",
    "password": "123456",
    "fullname": "Lê Hồng Quân",
    "accessToken": "string",
    "isVerified": true,
    "idAdmin": true
  }
}
```

```json=
{
  "statusCode": 0,
  "message": "Tài khoản đã tồn tại! Vui lòng kiểm tra lại!"
}
```

### 3. Logout
- Type: **POST**
- Path: `/auth/sign-out`
- Request's params:
```json=
{
}
```
- Request's headers:
```json=
{
    "accessToken": "asdskd2312h3kj12h3jk123gh3g12h3g12"
}
```
    
- Response:
```json=
{
    "data": {}
    "result": 0,
    "code": "Success"
}
```

```json=
{
    "data": {}
    "result": -1,
    "code": "Fail",
    "errorMessage": "Tài khoản chưa đăng nhập"
}
```

## Flight

### 1. Get flight
- Type: **GET**
- Path: `$/flight/:id`
- Request's params:
```json=
{
    "id": 3423
}
```
- Request's headers:
```json=
{
    "accessToken": "asdskd2312h3kj12h3jk123gh3g12h3g12"
}
```
- Reponse:
```json=
{
    "data":
    {
        "id": 3423,
        "code": "VN 6010",
        "fromAirport":
        {
            "code": "SGN",
            "name": "Tân Sơn Nhất",
            "address": "TP.HCM"
        },
        "toAirport":
        {
            "code": "HAN",
            "name": "Nội Bài",
            "address": "Hà Nội"
        },
        "datetime": "2022-05-27 05:55:00",
        "duration": 115,
        "ticketClassPrice":
        {
            "P": 230000.0,
            "L": 450000.0,
            "C": 1200000.0,
        },
        "seatAmount":
        {
            "P": 50,
            "L": 70,
            "C": 10,
        },
        "bookedAmount":
        {
            "P": 32,
            "L": 43,
            "C": 3,
        },
        "middleAirports": [
            {
                "code": "VDH",
                "name": "Đồng Hới",
                "address": "Quảng Bình"
            },
            {
                "code": "VII",
                "name": "Vinh",
                "address": "Nghệ An"
            },
        ],
        "stopDuration": [
            12,
            16
        ]
    },
    "result": 0,
    "code": "Success"
}
```

```json=
{
    "data": {}
    "result": -1,
    "code": "Fail",
    "errorMessage": "Không tồn tại chuyến bay có ID này"
}
```
- Note: Định dạng của _datetime_ là tùy ý

### 2. POST flight
- Type: **POST**
- Path: `$/flight`
- Request's params:

```json=
{
  "id": "",
  "fromAirportCode": "SGN",
  "toAirportCode": "HAN",
  "dateTime": "2022-06-12T16:24:28.024007Z",
  "duration": 0,
  "seatAmount": {
    "P": 100,
    "L": 50,
    "C": 20
  },
  "bookedAmount": {
    "P": 0,
    "L": 0,
    "C": 0
  },
  "ticketClassPrice": {
    "P": 1000000.0,
    "L": 2000000.0,
    "C": 3000000.0
  },
  "middleAirportCodes": [
    
  ],
  "stopDuration": [
    
  ]
}
```
- Reponse:
```json=
{
  "statusCode": 200,
  "data": {
    "id": "1015",
    "code": "VN-1015",
    "fromAirport": {
      "code": "SGN",
      "name": "Tân Sơn Nhất",
      "address": "TP.HCM"
    },
    "toAirport": {
      "code": "HAN",
      "name": "Nội Bài",
      "address": "Hà Nội"
    },
    "dateTime": "2022-06-12T16:24:28.119+00:00",
    "duration": 0,
    "seatAmount": {
      "P": 0,
      "C": 0,
      "L": 0
    },
    "bookedAmount": null,
    "middleAirports": null,
    "stopDurations": null
  }
}
```

### 3. Get flights
- Type: **GET**
- Path: `$/flight/:id`
- Request's params:
```json=
{
    "fromDate": "2022-05-20 00:00:00",
    "toDate": "2022-05-29 00:00:00",
}
```
- Request's headers:
```json=
{
    "accessToken": "asdskd2312h3kj12h3jk123gh3g12h3g12"
}
```
- Reponse:
```json=
{
    "data": [
        {
            "id": 3423,
            "code": "VN 6010",
            "fromAirport":
            {
                "code": "SGN",
                "name": "Tân Sơn Nhất",
                "address": "TP.HCM"
            },
            "toAirport":
            {
                "code": "HAN",
                "name": "Nội Bài",
                "address": "Hà Nội"
            },
            "datetime": "2022-05-27 05:55:00",
            "duration": 115,
            "seatAmount":
            {
                "P": 50,
                "L": 70,
                "C": 10,
            },
            "bookedAmount":
            {
                "P": 32,
                "L": 43,
                "C": 3,
            },
            "middleAirports": [
                {
                    "code": "VDH",
                    "name": "Đồng Hới",
                    "address": "Quảng Bình"
                },
                {
                    "code": "VII",
                    "name": "Vinh",
                    "address": "Nghệ An"
                },
            ],
            "stopDuration": [
                12,
                16
            ]
        },
        {
            "id": 3425,
            "code": "VN 800",
            "fromAirport":
            {
                "code": "VDH",
                "name": "Đồng Hới",
                "address": "Quảng Bình"
            },
            "toAirport":
            {
                "code": "SGN",
                "name": "Tân Sơn Nhất",
                "address": "TP.HCM"
            },
            "datetime": "2022-05-28 17:05:00",
            "duration": 85,
            "seatAmount":
            {
                "P": 60,
                "L": 80,
                "C": 15,
            },
            "bookedAmount":
            {
                "P": 45,
                "L": 32,
                "C": 8,
            },
            "middleAirports": [],
            "stopDuration": []
        },
    ],
    "result": 0,
    "code": "Success"
}
```

## Ticket

### 1. Get ticket
- Type: **GET**
- Path: `/ticket`
- Request's params:
```json=
{
    "id": 446
}
```
- Request's headers:
```json=
{
    "accessToken": "asdskd2312h3kj12h3jk123gh3g12h3g12"
}
```
- Reponse:
```json=
{
  "statusCode": 0,
  "message": null,
  "data": [
    {
      "id": "1004",
      "flightCode": "VN-1012",
      "flightDate": 1655049315776,
      "passenger": {
        "id": "1005",
        "firstName": "Đặng",
        "lastName": "Phương Nam",
        "identityNumber": "147893652",
        "email": "dpnam@gmail.com",
        "phoneNumber": "123456789"
      },
      "ticketClassId": "P",
      "price": 10000,
      "bookedTime": 1655747656317,
      "idUser": "1000"
    },
    {
      "id": "1005",
      "flightCode": "VN-1012",
      "flightDate": 1655049315776,
      "passenger": {
        "id": "1006",
        "firstName": "Đặng",
        "lastName": "Phương Nam",
        "identityNumber": "147893652",
        "email": "dpnam@gmail.com",
        "phoneNumber": "123456789"
      },
      "ticketClassId": "P",
      "price": 10000,
      "bookedTime": 1655747656317,
      "idUser": "1000"
    }
  ]
}
```

```json=
{
    "data": {}
    "result": -1,
    "code": "Fail",
    "errorMessage": "Không tồn tại vé có ID này"
}
```
- Note:
    - _passenger_, _bookedTime_, _verifiedTime_ có thể NULL
    - Quy tắc:
```java=
boolean isBooked = passenger != null && bookedTime != null;
boolean isPending = passenger != null && bookedTime != null && verifiedTime == null;
boolean isVerified = passenger != null && bookedTime != null && verifiedTime != null;
```

### 2. POST ticket
- Type: **POST**
- Path: `/ticket`


- Request's headers:
```json=
{
    "accessToken": "asdskd2312h3kj12h3jk123gh3g12h3g12"
}
```
- Body:
```json=

{
  "id": "",
  "flightCode": "VN-1012",
  "flightDate": 1655049315776,
  "passenger": {
    "id": "",
    "firstName": "Đặng",
    "lastName": "Phương Nam",
    "identityNumber": "147893652",
    "email": "dpnam@gmail.com",
    "phoneNumber": "123456789"
  },
  "ticketClassId": "P",
  "price": 10000,
  "bookedTime": 1655747656317,
  "idUser": "1000"
}

```

- Reponse:
```json=
{
  "statusCode": 200,
  "data": {
    "id": "1005",
    "flightCode": "VN-1012",
    "flightDate": 1655049315776,
    "passenger": null,
    "ticketClassId": "P",
    "price": 10000,
    "bookedTime": 1655747656317,
    "idUser": "1000"
  }
}
```

## Report

### 1. Get report (by staff)
- Type: **GET**
- Path: `$URL/api/report/get`
- Request's params:
```json=
{
    "year": 2022,
    "staffId": 123,
}
```
- Request's headers:
```json=
{
    "accessToken": "asdskd2312h3kj12h3jk123gh3g12h3g12"
}
```
- Reponse:
```json=
{
    "data":
    {
        "year": 2022,
        "staffId": 123,
        "monthlyReports": [
            {
                "year": 2022,
                "staffId": 123,
                "month": 1,
                "ticketCount": 35,
                "revenue": 52300000.0,
            },
            {
                "year": 2022,
                "staffId": 123,
                "month": 2,
                "ticketCount": 24,
                "revenue": 31200000.0,
            },
            ...
            {
                "year": 2022,
                "staffId": 123,
                "month": 12,
                "ticketCount": 46,
                "revenue": 75200000.0,
            },
        ]
    }
    "result": 0,
    "code": "Success"
}
```

### 2. Get report (by manager)
- Type: **GET**
- Path: `$URL/api/report/get`
- Request's params:
```json=
{
    "year": 2022,
}
```
- Request's headers:
```json=
{
    "accessToken": "jjh24kjh34234jh32jk4kj324jkh234kjh4"
}
```
- Reponse:
```json=
{
    "data":
    {
        "year": 2022,
        "monthlyReports": [
            {
                "year": 2022,
                "month": 1,
                "flightCount": 60,
                "ticketCount": 312,
                "revenue": 523000000.0,
            },
            {
                "year": 2022,
                "month": 2,
                "flightCount": 58,
                "ticketCount": 246,
                "revenue": 312000000.0,
            },
            ...
            {
                "year": 2022,
                "month": 12,
                "flightCount": 75,
                "ticketCount": 412,
                "revenue": 752000000.0,
            },
        ]
    }
    "result": 0,
    "code": "Success"
}
```
- Note:
    - Phân biệt request của staff và manager bằng accessToken
    - Manager thì không có staffId, vì manager xem được của báo cáo của tất cả staff
    - Manager xem được báo cáo tổng của tất cả các nhân viên, và có thêm số lượng chuyến bay

## Staff (only Manager)

### 1. Get staffs

- Type: **GET**
- Path: `$URL/api/staff`
- Request's headers:
```json=
{
    "accessToken": "asdskd2312h3kj12h3jk123gh3g12h3g12"
}
```
- Reponse:
```json=
{
    "data": [
        {
            "id": 123,
            "username": "lehongquan2",  
            "fullname": "Lê Hồng Quân",  
            "totalTicket": 124.0,
            "totalRevenue": 45200000.0,
        },
        {
            "id": 123,
            "username": "lehongquan2",  
            "fullname": "Lê Hồng Quân",  
            "totalTicket": 124.0,
            "totalRevenue": 45200000.0,
        },
        {
            "id": 123,
            "username": "lehongquan2",  
            "fullname": "Lê Hồng Quân",  
            "totalTicket": 124.0,
            "totalRevenue": 45200000.0,
        },
    ],
    "result": 200,
    "code": "Success"
}
```

### 2. Remove staff
- Type: **DELETE**
- Path: `$URL/api/staff`
- Request's params:
```json=
{
    "id": 123,
}
```
- Request's headers:
```json=
{
    "accessToken": "jjh24kjh34234jh32jk4kj324jkh234kjh4"
}
```
- Reponse:
```json=
{
    "data": { }
    "result": 200,
    "code": "Success"
}
```

## Ticket Class

### 1. Get list
- Type: **GET**
- Path: `$URL/api/ticket-class/gets`
- Request's params:
```json=
{
}
```
- Request's headers:
```json=
{
}
```
- Reponse:
```json=
{
    "data": [
        {
            "id": "P",
            "enName": "Economy super lite",
            "viName": "Phổ thông siêu tiết kiệm",
            "canChange": false,
            "changeFee": 0.0,
            "canReturn": false,
            "returnFee": 0.0,
        },
        ...
    ],
    "result": 0,
    "code": "Success"
}
```
- Note: Xem bảng 2 ở Fixed tables