# Table of contents
- [Table of contents](#table-of-contents)
- [1. Description of custom types](#1-description-of-custom-types)
  - [AccessToken](#accesstoken)
  - [Building](#building)
  - [Planet](#planet)
  - [Research](#research)
  - [Resource](#resource)
  - [User](#user)
- [2. API endpoints](#2-api-endpoints)
  - [/generateAccessToken](#generateaccesstoken)
  - [/testAccessToken](#testaccesstoken)
  - [/planets/getPlanet](#planetsgetplanet)
  - [/planets/getAllPlanets](#planetsgetallplanets)
  - [/research/getResearch](#researchgetresearch)
  - [/research/performResearch](#researchperformresearch)
  - [/build/createBuilding](#buildcreatebuilding)
  - [/auth/changeUserData](#authchangeuserdata)

# 1. Description of custom types

## AccessToken
```ts
_id: ObjectId           // (MongoDB)
type: "A" | "S" | "X"   // Auth, Spy, Master
user: ObjectId | null   // master token has this field empty
entropy: string         // random bytes
createdAt: Date 
expiresAt: Date | null  // null for "never expires"
createdFrom: string
```

## Building
```ts
id: string
level: number
```

## Planet
```ts
_id: ObjectId,
owner: User,
name: string,
fields: number,
resources: Array<Resource>,
buildings: Array<Building>,
ships: Array<Ship>,
```

## Research
```ts
id: string
level: number
```

## Resource
```ts
name: string
amount: number
lastUpdated: Date
perHourMiningRate: number
```

## User
```ts
_id: ObjectId
username: string
email: string
password: string           // hashed with argon2
lastLogin: Date
research: Array<Research>
planets: {                 // getting user planets requires second call to DB
    partial: boolean;      // so by default "partial" is true, and "data" is empty
    data: Array<Planet>    // unless specified otherwise in code
}
createdAt: Date
updatedAt: Date
```

# 2. API endpoints

## /generateAccessToken

**URL: POST** /generateAccessToken

**DESCRIPTION:** Used for generating new access tokens. Type X access token required via Authorization header

**BODY:**
```json
{
    "username": "string"
}
```

**OUTPUT:**
```json
{
    "code": 200,
    "message": "OK",
    "accessToken": "A.MTcxODcxNDg2MTg5Mw.NjUzZTk2NzdlNWMzZDM2YjE1YmE3NGVi.QilYuiOT_svRX2iN7f7-jw"
}

```

## /testAccessToken

**URL: GET** /testAccessToken

**DESCRIPTION:** Used for testing access token validity. Type A access token required via Authorization header

**BODY:** N/A

**OUTPUT:**
```json
{
    "code": 200,
    "message": "OK",
    "data": "Access token valid for user gargamel"
}
```

## /planets/getPlanet

**URL: GET** /planets/getPlanet/*:planetId*

**DESCRIPTION:** Used to get data about specific planet with ID provided in URL. Type A access token required via Authorization header

**BODY:** N/A

**OUTPUT:**
```json
{
    "code": 200,
    "message": "OK",
    "data": {
        "id": "661d1163567111a5b4be8829",
        "owner": "653e9677e5c3d36b15ba74eb",
        "name": "Lyoko",
        "fields": 20,
        "resources": [],
        "buildings": [],
        "fleet": [],
    }
}
```

## /planets/getAllPlanets

**URL: GET** /planets/getAllPlanets/

**DESCRIPTION:** Limited view of all planets of all players

**BODY:** N/A

**OUTPUT:**
```json
{
    "code": 200,
    "message": "OK",
    "data": [
        {
            "planetId": "661d1163567111a5b4be8829",
            "ownerId": "653e9677e5c3d36b15ba74eb",
            "name": "Lyoko"
        },
        {
            "planetId": "666af607f0ae1e11d2d03544",
            "ownerId": "653e9677e5c3d36b15ba74eb",
            "name": "Cortex"
        }
    ]
}
```

## /research/getResearch

**URL: GET** /research/getResearch

**DESCRIPTION:** Used to get data about user research (which technologies are unlocked and on which level). Type A access token required via Authorization header

**BODY:** N/A

**OUTPUT:**
```json
{
    "code": 200,
    "message": "OK",
    "data": [
        {
            "id": "basic-engine",
            "level": 7
        },
        {
            "id": "advanced-engine",
            "level": 1
        }
    ]
}
```

## /research/performResearch

**URL: POST** /research/performResearch

**DESCRIPTION:** Used to send request to start researching. Required buildings and resources are checked on planet provided in body. Type A access token required via Authorization header

**BODY:**
```json
{
    "research": "string",
    "planetId": "string"
}
```

**OUTPUT:**
```json
{
    "code": 200,
    "message": "OK"
}
```

## /build/createBuilding

**URL: POST** /build/createBuilding

**DESCRIPTION:** Used to send request to build or upgrade building on planet. Required buildings and resources are checked on planet provided in body. Type A access token required via Authorization header

**BODY:**
```json
{
    "building": "string",
    "planetId": "string"
}
```

**OUTPUT:**
```json
{
    "code": 200,
    "message": "OK"
}
```

## /auth/changeUserData

**URL: PATCH** /auth/changeUserData/*:type*

**DESCRIPTION:** Used to change user username, email or password. Type A access token required via Authorization header in addition to current password in body

Type can be one of (anything other will throw ***400 Bad Request***):
- username
- email
- password

**BODY:**
```json
{
    "password": "string",
    "newUsername": "string",
    "newEmail": "string",
    "newPassword": "string"
}
```

**OUTPUT:**
```json
{
    "code": 200,
    "message": "OK"
}
```