{
  "openapi": "3.0.0",
  "info": {
    "title": "API Цифрового Кооператива",
    "version": "1",
    "license": {
      "name": "MIT",
      "url": "https://github.com/hagopj13/node-express-boilerplate/blob/master/LICENSE"
    }
  },
  "servers": [
    {
      "url": "http://localhost:2998/v1"
    }
  ],
  "paths": {
    "/auth/login": {
      "post": {
        "summary": "Login",
        "tags": [
          "Auth"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "email",
                  "password"
                ],
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email"
                  },
                  "password": {
                    "type": "string",
                    "format": "password"
                  }
                },
                "example": {
                  "email": "fake@example.com",
                  "password": "password1"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "user": {
                      "$ref": "#/components/schemas/User"
                    },
                    "tokens": {
                      "$ref": "#/components/schemas/AuthTokens"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Invalid email or password",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "code": 401,
                  "message": "Invalid email or password"
                }
              }
            }
          }
        }
      }
    },
    "/auth/logout": {
      "post": {
        "summary": "Logout",
        "tags": [
          "Auth"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "refreshToken"
                ],
                "properties": {
                  "refreshToken": {
                    "type": "string"
                  }
                },
                "example": {
                  "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1ZWJhYzUzNDk1NGI1NDEzOTgwNmMxMTIiLCJpYXQiOjE1ODkyOTg0ODQsImV4cCI6MTU4OTMwMDI4NH0.m1U63blB0MLej_WfB7yC2FTMnCziif9X8yzwDEfJXAg"
                }
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "No content"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/auth/refresh-tokens": {
      "post": {
        "summary": "Refresh auth tokens",
        "tags": [
          "Auth"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "refreshToken"
                ],
                "properties": {
                  "refreshToken": {
                    "type": "string"
                  }
                },
                "example": {
                  "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1ZWJhYzUzNDk1NGI1NDEzOTgwNmMxMTIiLCJpYXQiOjE1ODkyOTg0ODQsImV4cCI6MTU4OTMwMDI4NH0.m1U63blB0MLej_WfB7yC2FTMnCziif9X8yzwDEfJXAg"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthTokens"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/auth/forgot-password": {
      "post": {
        "summary": "Forgot password",
        "description": "An email will be sent to reset password.",
        "tags": [
          "Auth"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "email"
                ],
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email"
                  }
                },
                "example": {
                  "email": "fake@example.com"
                }
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "No content"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/auth/reset-password": {
      "post": {
        "summary": "Reset password",
        "tags": [
          "Auth"
        ],
        "parameters": [
          {
            "in": "query",
            "name": "token",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The reset password token"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "password"
                ],
                "properties": {
                  "password": {
                    "type": "string",
                    "format": "password",
                    "minLength": 8,
                    "description": "At least one number and one letter"
                  }
                },
                "example": {
                  "password": "password1"
                }
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "No content"
          },
          "401": {
            "description": "Password reset failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "code": 401,
                  "message": "Password reset failed"
                }
              }
            }
          }
        }
      }
    },
    "/auth/send-verification-email": {
      "post": {
        "summary": "Send verification email",
        "description": "An email will be sent to verify email.",
        "tags": [
          "Auth"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "204": {
            "description": "No content"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/auth/verify-email": {
      "post": {
        "summary": "verify email",
        "tags": [
          "Auth"
        ],
        "parameters": [
          {
            "in": "query",
            "name": "token",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The verify email token"
          }
        ],
        "responses": {
          "204": {
            "description": "No content"
          },
          "401": {
            "description": "verify email failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "code": 401,
                  "message": "verify email failed"
                }
              }
            }
          }
        }
      }
    },
    "/orders/ipn": {
      "post": {
        "tags": [
          "Orders"
        ],
        "summary": "Обработка IPN уведомления",
        "description": "Маршрут для обработки IPN уведомления.",
        "responses": {
          "200": {
            "description": "Успешное выполнение запроса."
          }
        }
      }
    },
    "/orders/initial": {
      "post": {
        "tags": [
          "Orders"
        ],
        "summary": "Создание регистрационного платежа",
        "description": "Маршрут для создания регистрационного платежа.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ICreateInitialPayment"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Успешное выполнение запроса.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ICreatedPayment"
                }
              }
            }
          }
        }
      }
    },
    "/orders/deposit": {
      "post": {
        "tags": [
          "Orders"
        ],
        "summary": "Создание депозита в кошелёк",
        "description": "Маршрут для создания депозита.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ICreateDeposit"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Успешное выполнение запроса.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ICreatedPayment"
                }
              }
            }
          }
        }
      }
    },
    "/users": {
      "post": {
        "summary": "Создать пользователя",
        "description": "Только администраторы могут создавать новых пользователей.",
        "tags": [
          "Users"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ICreateUser"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/User"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/DuplicateEmail"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      },
      "get": {
        "summary": "Получить всех пользователей",
        "description": "Только администратор может получить всех пользователей",
        "tags": [
          "Users"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "in": "query",
            "name": "username",
            "schema": {
              "type": "string"
            },
            "description": "Системное имя пользователя"
          },
          {
            "in": "query",
            "name": "role",
            "schema": {
              "type": "string"
            },
            "description": "Роль пользователя"
          },
          {
            "in": "query",
            "name": "sortBy",
            "schema": {
              "type": "string"
            },
            "description": "Сортировка по полю в формате field:desc/asc (например, name:asc)"
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 10
            },
            "description": "Максимальное количество пользователей"
          },
          {
            "in": "query",
            "name": "page",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            },
            "description": "Номер страницы"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/User"
                      }
                    },
                    "page": {
                      "type": "integer",
                      "example": 1
                    },
                    "limit": {
                      "type": "integer",
                      "example": 10
                    },
                    "totalPages": {
                      "type": "integer",
                      "example": 1
                    },
                    "totalResults": {
                      "type": "integer",
                      "example": 1
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/users/{username}": {
      "get": {
        "summary": "Получить пользователя",
        "description": "Авторизованные пользователи могут получать только свою собственную информацию. Только администраторы могут получать информацию о других пользователях.",
        "tags": [
          "Users"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "username",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Идентификатор пользователя"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/User"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      },
      "patch": {
        "summary": "Обновить пользователя",
        "description": "Только администраторы могут обновлять информацию о других пользователях.",
        "tags": [
          "Users"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "username",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Системное имя пользователя"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email",
                    "description": "должен быть уникальным"
                  },
                  "password": {
                    "type": "string",
                    "format": "password",
                    "minLength": 8,
                    "description": "Минимум одна цифра и одна буква"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/User"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/DuplicateEmail"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Token": {
        "type": "object",
        "properties": {
          "token": {
            "type": "string"
          },
          "expires": {
            "type": "string",
            "format": "date-time"
          }
        },
        "example": {
          "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1ZWJhYzUzNDk1NGI1NDEzOTgwNmMxMTIiLCJpYXQiOjE1ODkyOTg0ODQsImV4cCI6MTU4OTMwMDI4NH0.m1U63blB0MLej_WfB7yC2FTMnCziif9X8yzwDEfJXAg",
          "expires": "2020-05-12T16:18:04.793Z"
        }
      },
      "AuthTokens": {
        "type": "object",
        "properties": {
          "access": {
            "$ref": "#/components/schemas/Token"
          },
          "refresh": {
            "$ref": "#/components/schemas/Token"
          }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "code": {
            "type": "number"
          },
          "message": {
            "type": "string"
          }
        }
      },
      "User": {
        "type": "object",
        "properties": {
          "username": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "created",
              "joined",
              "payed",
              "registered",
              "active",
              "blocked"
            ]
          },
          "is_registered": {
            "type": "boolean"
          },
          "type": {
            "type": "string",
            "enum": [
              "individual",
              "entrepreneur",
              "organization"
            ]
          },
          "public_key": {
            "type": "string"
          },
          "referer": {
            "type": "string"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "role": {
            "type": "string"
          },
          "is_email_verified": {
            "type": "boolean"
          },
          "private_data": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/IEntrepreneurData"
              },
              {
                "$ref": "#/components/schemas/IIndividualData"
              },
              {
                "$ref": "#/components/schemas/IOrganizationData"
              }
            ],
            "nullable": true
          }
        }
      },
      "ICreatedPayment": {
        "type": "object",
        "required": [
          "order_num",
          "confirmation_token"
        ],
        "properties": {
          "order_num": {
            "type": "number"
          },
          "confirmation_token": {
            "type": "string"
          }
        }
      },
      "ICreateDeposit": {
        "type": "object",
        "required": [
          "username",
          "quantity"
        ],
        "properties": {
          "username": {
            "type": "string"
          },
          "quantity": {
            "type": "string"
          }
        }
      },
      "ICreateInitialPayment": {
        "type": "object",
        "required": [
          "username"
        ],
        "properties": {
          "username": {
            "type": "string"
          }
        }
      },
      "IIndividualData": {
        "type": "object",
        "properties": {
          "first_name": {
            "type": "string"
          },
          "last_name": {
            "type": "string"
          },
          "middle_name": {
            "type": "string"
          },
          "birthdate": {
            "type": "string"
          },
          "full_address": {
            "type": "string"
          },
          "phone": {
            "type": "string"
          },
          "email": {
            "type": "string",
            "format": "email"
          }
        },
        "required": [
          "first_name",
          "last_name",
          "middle_name",
          "birthdate",
          "full_address",
          "phone",
          "email"
        ]
      },
      "RepresentedBySchema": {
        "type": "object",
        "properties": {
          "first_name": {
            "type": "string"
          },
          "last_name": {
            "type": "string"
          },
          "middle_name": {
            "type": "string"
          },
          "position": {
            "type": "string"
          },
          "based_on": {
            "type": "string"
          }
        },
        "required": [
          "first_name",
          "last_name",
          "middle_name",
          "position",
          "based_on"
        ]
      },
      "RussiaDetailsSchema": {
        "type": "object",
        "properties": {
          "inn": {
            "type": "string"
          },
          "ogrn": {
            "type": "string"
          }
        },
        "required": [
          "inn",
          "ogrn"
        ]
      },
      "RussianBankDetailsSchema": {
        "type": "object",
        "properties": {
          "bik": {
            "type": "string"
          },
          "inn": {
            "type": "string"
          },
          "corr": {
            "type": "string"
          },
          "kpp": {
            "type": "string"
          }
        },
        "required": [
          "bik",
          "inn",
          "corr",
          "kpp"
        ]
      },
      "IBankAccount": {
        "type": "object",
        "properties": {
          "currency": {
            "type": "string",
            "enum": [
              "RUB",
              "Other"
            ]
          },
          "card_number": {
            "type": "string"
          },
          "bank_name": {
            "type": "string"
          },
          "account_number": {
            "type": "string"
          },
          "details": {
            "$ref": "#/components/schemas/RussianBankDetailsSchema"
          }
        },
        "required": [
          "currency",
          "card_number",
          "bank_name",
          "account_number",
          "details"
        ]
      },
      "IOrganizationData": {
        "type": "object",
        "properties": {
          "is_cooperative": {
            "type": "boolean",
            "default": false
          },
          "short_name": {
            "type": "string"
          },
          "full_name": {
            "type": "string"
          },
          "represented_by": {
            "$ref": "#/components/schemas/RepresentedBySchema"
          },
          "country": {
            "type": "string",
            "enum": [
              "Russia",
              "Other"
            ]
          },
          "city": {
            "type": "string"
          },
          "full_address": {
            "type": "string"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "phone": {
            "type": "string"
          },
          "details": {
            "$ref": "#/components/schemas/RussiaDetailsSchema"
          },
          "bank_account": {
            "$ref": "#/components/schemas/IBankAccount"
          }
        },
        "required": [
          "is_cooperative",
          "short_name",
          "full_name",
          "represented_by",
          "country",
          "city",
          "full_address",
          "email",
          "phone",
          "details",
          "bank_account"
        ]
      },
      "IEntrepreneurData": {
        "type": "object",
        "properties": {
          "first_name": {
            "type": "string"
          },
          "last_name": {
            "type": "string"
          },
          "middle_name": {
            "type": "string"
          },
          "birthdate": {
            "type": "string"
          },
          "phone": {
            "type": "string"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "country": {
            "type": "string",
            "enum": [
              "Russia",
              "Other"
            ]
          },
          "city": {
            "type": "string"
          },
          "full_address": {
            "type": "string"
          },
          "details": {
            "$ref": "#/components/schemas/RussiaDetailsSchema"
          },
          "bank_account": {
            "$ref": "#/components/schemas/IBankAccount"
          }
        },
        "required": [
          "first_name",
          "last_name",
          "middle_name",
          "birthdate",
          "phone",
          "email",
          "country",
          "city",
          "full_address",
          "details",
          "bank_account"
        ]
      },
      "ICreateUser": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "format": "email"
          },
          "password": {
            "type": "string"
          },
          "role": {
            "type": "string",
            "enum": [
              "user",
              "admin"
            ]
          },
          "public_key": {
            "type": "string"
          },
          "username": {
            "type": "string"
          },
          "referer": {
            "type": "string",
            "minLength": 12,
            "maxLength": 12
          },
          "type": {
            "type": "string",
            "enum": [
              "individual",
              "entrepreneur",
              "organization"
            ]
          },
          "individual_data": {
            "$ref": "#/components/schemas/IIndividualData"
          },
          "organization_data": {
            "$ref": "#/components/schemas/IOrganizationData"
          },
          "entrepreneur_data": {
            "$ref": "#/components/schemas/IEntrepreneurData"
          }
        },
        "required": [
          "email",
          "password",
          "role",
          "public_key",
          "username",
          "type"
        ]
      },
      "IDocument": {
        "type": "object",
        "properties": {
          "hash": {
            "type": "string"
          },
          "signature": {
            "type": "string"
          },
          "public_key": {
            "type": "string"
          },
          "meta": {
            "type": "object"
          }
        },
        "required": [
          "hash",
          "signature",
          "public_key",
          "meta"
        ]
      },
      "IJoinCooperative": {
        "type": "object",
        "properties": {
          "username": {
            "type": "string"
          },
          "document": {
            "$ref": "#/components/schemas/IDocument"
          }
        },
        "required": [
          "username",
          "document"
        ]
      }
    },
    "responses": {
      "DuplicateEmail": {
        "description": "Email already taken",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "code": 400,
              "message": "Email already taken"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Unauthorized",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "code": 401,
              "message": "Please authenticate"
            }
          }
        }
      },
      "Forbidden": {
        "description": "Forbidden",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "code": 403,
              "message": "Forbidden"
            }
          }
        }
      },
      "NotFound": {
        "description": "Not found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "code": 404,
              "message": "Not found"
            }
          }
        }
      }
    },
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      }
    }
  },
  "tags": [
    {
      "name": "Auth",
      "description": "Управление аудентификацией"
    },
    {
      "name": "Orders",
      "description": "Управление платежами"
    },
    {
      "name": "Users",
      "description": "Управление пользователями"
    }
  ]
}