# GACHA API

The api provides functionalities that allow user to purchase and ship gachapons online via a website. 

## Endpoints

Below are a list of endpoints that are made available for developers. All required data are to be sent over as json objects unless otherwise stated. Relevant results from query are returned as a json object with a key of "data" (see example below).

```json
{
  "success": true,
  "data": "some result",
}
```

### $\color{Orange}{\textsf{Authentication}}$

**GET**&emsp;`/api/auth/check-auth` <br/>
Checks if the user is logged in

**POST**&emsp;`/api/auth/refresh` <br/>
Request for access token refresh

**POST**&emsp;`/api/auth/signup` <br/>
Create a new user and send out a verification email
```json
"email": "example@email.com",
"name": "John Smith",
"password": "123456",
"country": 1 // id can be retrieved from /api/country
```

**POST**&emsp;`/api/auth/verify-email` <br/>
 Verify and initialise the user
```json
"token" : "5bd136b5-5f29-4a91-ac58-79c2c0700b60"
```

**POST**&emsp;`/api/auth/resend-verify` <br/>
 Send out an email with a new link for verification
```json
"id": 15 // user id
```

**POST**&emsp;`/api/auth/login` <br/>
 Log in user
```json
"email": "example@email.com",
"password": "123456"
```

**POST**&emsp;`/api/auth/logout` <br/>
 Log off user

**POST**&emsp;`/api/auth/logout-all` <br/>
 Log out all devices for a user

**POST**&emsp;`/api/auth/forgot-password` <br/>
 Send out an email with link to reset password
```json
"email": "example@email.com"
```

**POST**&emsp;`/api/auth/reset-password/:token` <br/>
 Update password from reset link
```json
"password": "abc123"
```

**POST**&emsp;`/api/auth/create-admin` <br/>
 Create an admin user
```json
"email": "example@email.com",
"name": "Jane Doe",
"password": "123456",
"pin": "secretpin",
"country": 1 // id can be retrieved from /api/country
```

**GET**&emsp;`/api/auth/all`&emsp;`Admin Only`<br/>
 Retrieve all verified users 

**PATCH**&emsp;`/api/auth/activate/:id`&emsp;`Admin Only`<br/>
 Activate a user

**PATCH**&emsp;`/api/auth/deactivate/:id`&emsp;`Admin Only`<br/>
 Deactivate a user 

**POST**&emsp;`/api/auth/send-email`&emsp;`Admin Only`<br/>
 Send an email to the user 
```json
"email": "example@email.com",
"subject": "Subject",
"message": "The content of the email",
```

### $\color{Orange}{\textsf{User Management}}$

**PATCH**&emsp;`/api/user/update-profile` <br/>
 Update user profile details
```json
"name" : "John Smith"
```

**PATCH**&emsp;`/api/user/update-password` <br/>
 Verify old password and update to new password
```json
"oldPassword": "123456",
"newPassword": "abc123"
```

**GET**&emsp;`/api/user/addresses/:type` <br/>
 Retrieve all addresses belonging to user

**GET**&emsp;`/api/user/address/:id` <br/>
 Retrieve the address belonging to user

**POST**&emsp;`/api/user/address` <br/>
 Create a new address
```json
"type": 0, // 0 - billing, 1 - shipping
"name": "John Smith",
"line1": "123 Toa Payoh Ave 6",
"line2": "#02-1234",
"city": "",
"state": "",
"postal": 123456,
"country": 0
```

**POST**&emsp;`/api/user/address/default/:id` <br/>
 Set address as the default address

**PATCH**&emsp;`/api/user/address` <br/>
 Update the address details
```json
"id": 1,
"type": 0, // 0 - billing, 1 - shipping
"name": "John Smith",
"line1": "456 Toa Payoh Ave 1",
"line2": "#11-1234",
"city": "",
"state": "",
"postal": 123456,
"country": 1
```

**DELETE**&emsp;`/api/user/address/:id` <br/>
 Delete the address

**GET**&emsp;`/api/user/info/:id`&emsp;`Admin Only`<br/>
 Retrieve basic information of user

**GET**&emsp;`/api/user/play-history/:id`&emsp;`Admin Only`<br/>
 Retrieve play history of user

**GET**&emsp;`/api/user/basic-stats`&emsp;`Admin Only`<br/>
 Retrieve basic monthly play stats

**GET**&emsp;`/api/user/top-players`&emsp;`Admin Only`<br/>
 Retrieve users with highest play count

### $\color{Orange}{\textsf{Transactions}}$
<!-- keeps track of transaction ref and sku (purchase history) -->
TBD

### $\color{Orange}{\textsf{Token Wallet}}$

**GET**&emsp;`/api/wallet` <br/>
 Retrieve tokens amount in wallet

**GET**&emsp;`/api/wallet/topup-history` <br/>
 Retrieve user top up history

**PATCH**&emsp;`/api/wallet/add` <br/>
 Add tokens to wallet
```json
"amount": 3
```

**PATCH**&emsp;`/api/wallet/use` <br/>
 Use tokens in wallet
```json
"amount": 3
```

**POST**&emsp;`/api/wallet/topup-option`&emsp;`Admin Only`<br/>
 Add a top-up sku for user to purchase
```json
"name": "3 tokens",
"description": "Add 3 tokens to your wallet",
"cost":300,
"coins":3,
"country": 1 // id can be retrieved from /api/country
```

**PATCH**&emsp;`/api/wallet/topup-option`&emsp;`Admin Only`<br/>
 Update a top-up sku
```json
"id":: 1
"name": "3 tokens",
"description": "Add 3 tokens to your wallet",
"cost":299,
"coins":3,
"country": 1 // id can be retrieved from /api/country
```

**DELETE**&emsp;`/api/wallet/topup-option/:id`&emsp;`Admin Only`<br/>
 Delete a top-up sku

**PATCH**&emsp;`/api/wallet/topup-option/activate/:id`&emsp;`Admin Only`<br/>
 Activate a top-up sku

**PATCH**&emsp;`/api/wallet/topup-option/deactivate/:id`&emsp;`Admin Only`<br/>
 Deactivate a top-up sku

**GET**&emsp;`/api/wallet/topup-option-admin`&emsp;`Admin Only`<br/>
 Retrieve all top up SKUs

**GET**&emsp;`/api/wallet/topup-option-admin/:id`&emsp;`Admin Only`<br/>
 Retrieve one top up SKU with id

**GET**&emsp;`/api/wallet/topup-history-admin/:id`&emsp;`Admin Only`<br/>
 Retrieve top up history of user

**GET**&emsp;`/api/wallet/monthly-sales`&emsp;`Admin Only`<br/>
 Retrieve top up monthly sales


### $\color{Orange}{\textsf{Series}}$

**GET**&emsp;`/api/series/all` <br/>
 Retrieve all available active series

**GET**&emsp;`/api/series/one/:id` <br/>
 Retrieve a particular series

**GET**&emsp;`/api/series/categories` <br/>
 Retrieve categories for all collection

**GET**&emsp;`/api/series/featured-categories` <br/>
 Retrieve categories for featured collection

**GET**&emsp;`/api/series/all/admin`&emsp;`Admin Only` <br/>
Retrieve all available series

**POST**&emsp;`/api/series/eligible:id` <br/>
 Check if player has enough tokens to play

**POST**&emsp;`/api/series/play:id` <br/>
 Roll a capsule

**POST**&emsp;`/api/series`&emsp;`Admin Only` <br/>
 Create a new series
```json
// multipart/form-data
"name": "Series Name",
"desc": "Short Description",
"cost": 3,
"category": 1,
"image": "IMG_1234.jpg", // FILE, NOT STRING
"type": 0, // 0 - gachapon, 1 - kuji
"tag": "anime,naruto"
```

**PATCH**&emsp;`/api/series`&emsp;`Admin Only` <br/>
 Update series details
```json
// multipart/form-data
"id": 1,
"name": "Series Name",
"desc": "Short Description",
"cost": 3,
"category": 1,
"image": "IMG_1234.jpg", // FILE, NOT STRING
"type": 0, // 0 - gachapon, 1 - kuji
"tag": "anime,bleach"
```

**PATCH**&emsp;`/api/series/activate/:id`&emsp;`Admin Only` <br/>
 Activate a series

**PATCH**&emsp;`/api/series/deactivate/:id`&emsp;`Admin Only` <br/>
 Deactivate a series

**DELETE**&emsp;`/api/series`&emsp;`Admin Only` <br/>
 Delete a series

**GET**&emsp;`/api/series/category/all` <br/>
 Retrieve all available categories

**GET**&emsp;`/api/series/category/one/:id` <br/>
 Retrieve a particular category

**POST**&emsp;`/api/series/category`&emsp;`Admin Only` <br/>
 Create a category for series
```json
"name" : "Anime"
```

**PATCH**&emsp;`/api/series/category`&emsp;`Admin Only` <br/>
 Update a category for series
```json
"id" : 4,
"name" : "TV"
```

**DELETE**&emsp;`/api/series/category/:id`&emsp;`Admin Only` <br/>
 Delete a category for series

**GET**&emsp;`/api/series/brand/all` <br/>
 Retrieve all available brands

**GET**&emsp;`/api/series/brand/one/:id` <br/>
 Retrieve a particular brand

 **POST**&emsp;`/api/series/brand`&emsp;`Admin Only` <br/>
 Create a brand for series
```json
"name" : "Bandai"
```

**PATCH**&emsp;`/api/series/brand`&emsp;`Admin Only` <br/>
 Update a brand for series
```json
"id" : 4,
"name" : "Takara Tomy"
```

**DELETE**&emsp;`/api/series/brand/:id`&emsp;`Admin Only` <br/>
 Delete a brand for series

 **POST**&emsp;`/api/series/event`&emsp;`Admin Only` <br/>
 Create a event for series
```json
"name" : "Clearance"
```

**GET**&emsp;`/api/series/event/all` <br/>
 Retrieve all available events

**GET**&emsp;`/api/series/event/one/:id` <br/>
 Retrieve a particular event

**PATCH**&emsp;`/api/series/event`&emsp;`Admin Only` <br/>
 Update a event for series
```json
"id" : 1,
"name" : "Offer"
```

**DELETE**&emsp;`/api/series/event/:id`&emsp;`Admin Only` <br/>
 Delete a event for series

**GET**&emsp;`/api/series/one-simple/admin/:id`&emsp;`Admin Only` <br/>
 Retrieve basic information of series

**GET**&emsp;`/api/series/top-played`&emsp;`Admin Only` <br/>
 Retrieve the most played series for the month

**GET**&emsp;`/api/series/featured`&emsp;`Admin Only` <br/>
 Retrieve featured series

**GET**&emsp;`/api/series/running-low`&emsp;`Admin Only` <br/>
 Retrieve series with stock under set threshold

### $\color{Orange}{\textsf{Prizes}}$

**POST**&emsp;`/api/prizes`&emsp;`Admin Only` <br/>
 Create a new prize and add it to a series
```json
// multipart/form-data
"id": 1, // series id
"name": "Prize Name",
"stock": 10,
"image": "IMG_1234.jpg" // FILE, NOT STRING
```

**PATCH**&emsp;`/api/prizes`&emsp;`Admin Only` <br/>
 Update prize details
```json
// multipart/form-data
"id": 1, // prize id
"name": "Prize Name",
"stock": 10,
"image": "IMG_1234.jpg" // FILE, NOT STRING
```

**PATCH**&emsp;`/api/prizes/won` <br/>
 Reduce count of prize by 1.
```json
"id" : 7 // prize id
```

**PATCH**&emsp;`/api/prizes/restock`&emsp;`Admin Only` <br/>
 Add count of prize by a specified amount.
```json
"id": 4, // prize id
"amount": 5
```

**DELETE**&emsp;`/api/prizes/:id`&emsp;`Admin Only` <br/>
 Delete a prize

### $\color{Orange}{\textsf{Locker}}$

**GET**&emsp;`/api/locker/all/:status` <br/>
 Retrieve locker of user
 ````json
 // status 
 // 0 - await shipping 
 // 1 - ordered 
 // 2 - expired 
 // 3 - discarded
 ````

**GET**&emsp;`/api/locker/has-space` <br/>
 Check if locker is full

**PATCH**&emsp;`/api/locker` <br/>
 Add prize to a locker
```json
"id": 4 // prize id
```

**POST**&emsp;`/api/locker/order` <br/>
 Shift prizes in locker to shipping order.
```json
"lockersId": [2,3,8,9], // array of locker id
"addressId": 7
```

**POST**&emsp;`/api/locker/forfeit` <br/>
 Discard prize in locker.
```json
"id": 13, // locker id
"prizeId": 4 
```

**GET**&emsp;`/api/locker/forfeited`&emsp;`Admin Only` <br/>
 Retrieve forfeited prizes

**PATCH**&emsp;`/api/locker/forfeited`&emsp;`Admin Only` <br/>
 Update forfeited prize status and set memo
```json
"id": 1,
"status": 2
"memo": "This is a memo"
```

### $\color{Orange}{\textsf{Shipping}}$

**GET**&emsp;`/api/shipping` <br/>
 Get all basic shipping orders of user

**GET**&emsp;`/api/shipping/one/:orderId` <br/>
 Get shipping details for one order

**PATCH**&emsp;`/api/shipping` <br/>
 Update address for order
```json
"orderId": "26-1770194264233",
"addressId": 6
```

**GET**&emsp;`/api/shipping-history-admin/:id`&emsp;`Admin Only` <br/>
 Retrieve shipping history of user

**GET**&emsp;`/api/shipping/all`&emsp;`Admin Only` <br/>
 Retrieve all shipping details

**GET**&emsp;`/api/shipping/all/:status`&emsp;`Admin Only` <br/>
 Retrieve all shipping details of a particular status

**PATCH**&emsp;`/api/shipping/status`&emsp;`Admin Only` <br/>
 Update shipping status
```json
"orderId": "26-1770194264233",
"status": 1 // 0 - pending, 1 - processing, 2 - shipped
```

**PATCH**&emsp;`/api/shipping/tracking`&emsp;`Admin Only` <br/>
 Update tracking number and memo
```json
"orderId": "26-1770194264233",
"tracking": "abcdefgh",
"memo": "Thank you"
```

**GET**&emsp;`/api/shipping/shipping-option` <br/>
 Retrieve available shipping options

 **GET**&emsp;`/api/shipping/shipping-option-admin`&emsp;`Admin Only` <br/>
 Retrieve available shipping options for admin

 **GET**&emsp;`/api/shipping/shipping-option-admin/:id`&emsp;`Admin Only` <br/>
 Retrieve one shipping options for admin

**POST**&emsp;`/api/shipping/shipping-option`&emsp;`Admin Only`<br/>
 Add a shipping sku for user to purchase
```json
"name": "Standard Shipping",
"description": "Standard International Shipping",
"cost":499,
"trackingLink": "https://www.speedpost.com.sg",
"country": 1 // id can be retrieved from /api/country
```

**PATCH**&emsp;`/api/shipping/shipping-option`&emsp;`Admin Only`<br/>
 Update a shipping sku
```json
"id": 1,
"name": "Standard Shipping",
"description": "Standard International Shipping",
"cost":399,
"trackingLink": "https://www.speedpost.com.sg",
"country": 1 // id can be retrieved from /api/country
```

**DELETE**&emsp;`/api/shipping/shipping-option/:id`&emsp;`Admin Only`<br/>
 Delete a shipping sku

**PATCH**&emsp;`/api/shipping/shipping-option/activate/:id`&emsp;`Admin Only`<br/>
 Activate a shipping sku

**PATCH**&emsp;`/api/shipping/shipping-option/deactivate/:id`&emsp;`Admin Only`<br/>
 Deactivate a shipping sku

**GET**&emsp;`/api/shipping/monthly-sales`&emsp;`Admin Only` <br/>
 Retrieve shipping order monthly sales

### $\color{Orange}{\textsf{Country}}$

**GET**&emsp;`/api/country` <br/>
 Retrieve all activated countries

 **GET**&emsp;`/api/country/all`&emsp;`Admin Only`<br/>
 Retrieve all available countries

 **GET**&emsp;`/api/country/one/:id`&emsp;`Admin Only`<br/>
 Retrieve one country

**POST**&emsp;`/api/country`&emsp;`Admin Only`<br/>
 Add a country
```json
"longName": "Singapore",
"shortName": "SG",
"currency": "SGD"
```

**PATCH**&emsp;`/api/country`&emsp;`Admin Only`<br/>
 Update a country
```json
"id": 1,
"longName": "Singapore",
"shortName": "SG",
"currency": "SGD"
```

**DELETE**&emsp;`/api/country/:id`&emsp;`Admin Only`<br/>
 Delete a country

**PATCH**&emsp;`/api/country/activate/:id`&emsp;`Admin Only`<br/>
 Activate a country

**PATCH**&emsp;`/api/country/deactivate/:id`&emsp;`Admin Only`<br/>
 Deactivate a country

### $\color{Orange}{\textsf{News}}$

**GET**&emsp;`/api/news` <br/>
 Retrieve news

**PATCH**&emsp;`/api/news`&emsp;`Admin Only`<br/>
 Update news for news ticker
```json
"content": "News content",
```

## Error Codes

The table below shows the different error codes that can be returned by the api. It can be retrieved by reading the **errcode** key from the return object, e.g.
```json
{
  "success": false,
  "errcode": 1001,
}
```
| Code | Description |
|:----:|:------------|
|1000| Server error
|1001| Database connection error
|1002| Uncaught error
|1003| Missing/invalid required data
|1004| Reject existing user (Sign Up)
|1005| Reject deactivated user
|1006| Non-existent/invalid user
|1007| Invalid credentials provided
|1008| Invalid token provided
|1009| Token expired
|1010| Email already verified (Verify Email)
|1011| Non-existent/invalid address
|1012| User account setup error, contact system admin
|1013| Non-existent/invalid wallet
|1014| Insufficient tokens
|1015| Invalid admin creation pin
|1016| Forbidden access
|1017| Reject deletion, in use
|1018| Reject deactivated series 
|1019| Locker is full
|1020| Machine has ran out of capsule
|1021| Invalid order
|1022| Email not verified
|1023| Invalid brand
|1024| Invalid category
|1025| Invalid prize
|1026| Invalid SKU
|1027| Invalid country
|1028| Reject deactivated country
|1029| Invalid Series
|1030| Invalid Event
|1031| Series contains prizes, reject deletion