CAPI-421: Draft initial spec (#1)

This commit is contained in:
Andrew Mayorov 2020-09-28 12:12:29 +03:00 committed by GitHub
parent 072c14f769
commit d8199c8f85
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
55 changed files with 4216 additions and 1 deletions

1
.gitignore vendored
View File

@ -38,7 +38,6 @@ node_modules
# Generated
web_deploy/
package-lock.json
# User-specific stuff:
.idea/

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "build-utils"]
path = build-utils
url = git@github.com:rbkmoney/build_utils

23
.redocly.yaml Normal file
View File

@ -0,0 +1,23 @@
# See https://docs.redoc.ly/cli/configuration/ for more information.
apiDefinitions:
binbase: "openapi/openapi.yaml"
lint:
rules:
api-servers: on
camel-case-names: on
model-description: on
no-extra-fields: on
operation-operationId: on
operation-description: on
operation-tags: on
parameter-description: on
path-declarations-must-exist: on
path-keys-no-trailing-slash: on
server-not-example: on
servers-no-trailing-slash: on
referenceDocs:
showConsole: true
layout:
scope: section
routingStrategy: browser
htmlTemplate: ./web/index.html

1
CODEOWNERS Normal file
View File

@ -0,0 +1 @@
* @rbkmoney/frontend

29
Jenkinsfile vendored Normal file
View File

@ -0,0 +1,29 @@
#!groovy
// -*- mode: groovy -*-
build('swag-organizations', 'docker-host') {
checkoutRepo()
loadBuildUtils('build-utils')
def pipeDefault
def withWsCache
runStage('load pipeline') {
env.JENKINS_LIB = "build-utils/jenkins_lib"
pipeDefault = load("${env.JENKINS_LIB}/pipeDefault.groovy")
withWsCache = load("${env.JENKINS_LIB}/withWsCache.groovy")
}
pipeDefault() {
runStage('install-deps') {
withWsCache("node_modules") {
sh 'make wc_install'
}
}
runStage('validate-spec') {
sh 'make wc_validate'
}
}
}

20
Makefile Normal file
View File

@ -0,0 +1,20 @@
UTILS_PATH := build-utils
TEMPLATES_PATH := .
SERVICE_NAME := swag-organizations
BUILD_IMAGE_TAG := 442c2c274c1d8e484e5213089906a4271641d95e
CALL_ANYWHERE := all install validate
CALL_W_CONTAINER := $(CALL_ANYWHERE)
all: validate
-include $(UTILS_PATH)/make_lib/utils_container.mk
.PHONY: $(CALL_W_CONTAINER)
install:
npm install
validate:
npm run validate

17
TODO.md Normal file
View File

@ -0,0 +1,17 @@
## Нужно сделать
* Описания разделов API.
* Конструирование пользовательских ролей из разрешений.
* Возможность редактировать администраторами user email сотрудников.
## Открытые вопросы
1. Если у меня как у сотрудника нет прав на просмотр сотрудников, могу ли я видеть идентификатор владельца?
1. Идентификатор сотрудника **равен** идентификатору пользователя, это ок?
В такой схеме есть небольшие утечки данных, вроде той, когда я как администратор могу понять, что пользователь состоит в тех же организациях, что и я. Непонятно, насколько это критично.
1. Если мы научимся 🌚 удалять магазины, как следить за консистентностью скоупов?
1. Ради простоты мы можем приравнять отзыв, принятие и протухание приглашения к его удалению, а по факту отзыва и принятия просто рассылать письма администраторам. Это избавит нас от необходимости держать все существовавшие когда-либо пришлашения в базе, и следить только за списком активных приглашений. Однако это может быть не очень дружественно к пользователям. Можем ли мы себе позволить это упрощение?

1
build-utils Submodule

@ -0,0 +1 @@
Subproject commit 39115931c6559011bf2f2ed353087976e6a7a5e7

31
build.js Normal file
View File

@ -0,0 +1,31 @@
#!/usr/bin/env node
'use strict';
var Path = require('path');
var TARGET_DIR = 'dist'
if (process.argv[2]) {
TARGET_DIR = process.argv[2]
}
require('shelljs/global');
set('-e');
mkdir('-p', TARGET_DIR)
cp('-R', 'web/*', TARGET_DIR + '/');
exec('npm run openapi bundle -- -o ' + TARGET_DIR + ' --ext json');
exec('npm run openapi bundle -- -o ' + TARGET_DIR + ' --ext yaml');
exec([
'npm run redoc bundle --',
'--cdn',
'-o', Path.join(TARGET_DIR, 'index.html'),
Path.join(TARGET_DIR, 'openapi.yaml')
].join(' '));
var SWAGGER_UI_DIST = Path.dirname(require.resolve('swagger-ui-dist'));
var SWAGGER_UI_DIR = Path.join(TARGET_DIR, 'swagger-ui');
rm('-rf', SWAGGER_UI_DIR);
cp('-R', SWAGGER_UI_DIST, SWAGGER_UI_DIR);
sed('-i', 'https://petstore.swagger.io/v2/swagger.json', '../openapi.json', TARGET_DIR + '/swagger-ui/index.html');

View File

@ -0,0 +1,10 @@
name: X-Idempotency-Key
in: header
description: |
Уникальный ключ для обеспечения единоразовой (идемпотентной) обработки операции.
required: false
schema:
type: string
minLength: 4
maxLength: 64
example: 881D:08BA

View File

@ -0,0 +1,6 @@
name: invitationId
in: path
description: Идентификатор приглашения
required: true
schema:
$ref: '../schemas/InvitationId.yaml'

View File

@ -0,0 +1,6 @@
name: orgId
in: path
description: Идентификатор организации
required: true
schema:
$ref: '../schemas/OrganizationId.yaml'

View File

@ -0,0 +1,9 @@
name: X-Request-ID
in: header
description: Уникальный идентификатор запроса к системе
required: true
schema:
type: string
minLength: 4
maxLength: 64
example: RQID-Z08G3EFE5DZ429VVO755BM19D51

View File

@ -0,0 +1,6 @@
name: roleId
in: path
description: Идентификатор роли
required: true
schema:
$ref: '../schemas/RoleId.yaml'

View File

@ -0,0 +1,6 @@
name: userId
in: path
description: Идентификатор пользователя
required: true
schema:
$ref: '../schemas/UserId.yaml'

View File

@ -0,0 +1,15 @@
description: Переданы ошибочные данные
content:
application/json:
schema:
description: Ошибка в переданных данных
type: object
required:
- code
properties:
code:
type: string
enum:
- invalidRequest
message:
type: string

View File

@ -0,0 +1,33 @@
description: Приглашение для сотрудника
allOf:
- type: object
required:
- id
- createdAt
- expiresAt
properties:
id:
$ref: './InvitationId.yaml'
createdAt:
description: Дата и время создания
type: string
format: date-time
readOnly: true
expiresAt:
description: Дата и время истечения срока принятия
type: string
format: date-time
invitee:
$ref: './Invitee.yaml'
acceptToken:
allOf:
- $ref: './InvitationAcceptToken.yaml'
- readOnly: true
metadata:
description: |
Произвольный, специфичный для клиента API и непрозрачный для системы набор данных, ассоциированных с
данным приглашением
type: object
example:
mailTemplate: 'v2.beta'
- $ref: './InvitationStatus.yaml'

View File

@ -0,0 +1,7 @@
type: string
minLength: 1
maxLength: 4000
description:
Токен для принятия приглашения пользователем
example: |
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJsYXVyYS5wYWxtZXJAbmlpZGFyLnN1IiwiaWF0IjoxNTE2MjM5MDIyLCJvcmciOiJvcl9hZjllNzZ1YzViNDdoOGIxNTQuMTliOHhhNjFkYzk0Iiwicm9sZXMiOltdfQ.p0kQj5AuogXuBwBvAFWdk8beI5JThXksRH7kFUjvRMk

View File

@ -0,0 +1,16 @@
allOf:
- $ref: './Invitation.yaml'
- type: object
properties:
acceptedAt:
description: Дата и время принятия приглашения
type: string
format: date-time
member:
description: Сотрудник организации, принявший приглашение
type: object
required:
- id
properties:
id:
$ref: './UserId.yaml'

View File

@ -0,0 +1,2 @@
allOf:
- $ref: './Invitation.yaml'

View File

@ -0,0 +1,6 @@
description: Идентификатор приглашения
type: string
minLength: 1
maxLength: 40
example: 1KgIYBGsCgq
readOnly: true

View File

@ -0,0 +1,2 @@
allOf:
- $ref: './Invitation.yaml'

View File

@ -0,0 +1,12 @@
allOf:
- $ref: './Invitation.yaml'
- type: object
properties:
revokedAt:
description: Дата и время отзыва приглашения
type: string
format: date-time
reason:
description: Причина отзыва приглашения
type: string
maxLength: 1000

View File

@ -0,0 +1,14 @@
type: object
required:
- status
discriminator:
propertyName: status
mapping:
'Pending': './InvitationPending.yaml'
'Accepted': './InvitationAccepted.yaml'
'Expired': './InvitationExpired.yaml'
'Revoked': './InvitationRevoked.yaml'
properties:
status:
description: Статус приглашения
readOnly: true

View File

@ -0,0 +1,7 @@
type: string
enum:
- 'Pending'
- 'Accepted'
- 'Expired'
- 'Revoked'
default: 'Pending'

View File

@ -0,0 +1,23 @@
description: Приглашаемый пользователь
type: object
required:
- contact
- roles
properties:
contact:
description: Контактные данные для отправки приглашения
type: object
required:
- type
- email
properties:
type:
enum:
- EMail
email:
$ref: './UserEmail.yaml'
roles:
allOf:
- description: |
Роли, которые будут назначены сотруднику после принятия им приглашения
- $ref: './MemberRoleSet.yaml'

View File

@ -0,0 +1,13 @@
description: Сотрудник организации
type: object
required:
- id
- userEmail
- roles
properties:
id:
$ref: './UserId.yaml'
userEmail:
$ref: './UserEmail.yaml'
roles:
$ref: './MemberRoleSet.yaml'

View File

@ -0,0 +1,22 @@
description: Роль сотрудника в организации
type: object
required:
- roleId
properties:
roleId:
$ref: './RoleId.yaml'
scope:
description: Область действия этой роли
type: object
required:
- id
- resourceId
properties:
id:
$ref: './ResourceScopeId.yaml'
resourceId:
description: Идентификатор доступного в рамках области ресурса
type: string
minLength: 1
maxLength: 40
example: sh_27839dt482v28ab7escze113y858dp

View File

@ -0,0 +1,6 @@
description: Набор ролей сотрудника
type: array
minItems: 1
uniqueItems: true
items:
$ref: './MemberRole.yaml'

View File

@ -0,0 +1,32 @@
description: Модель организации
type: object
required:
- id
- createdAt
- name
- owner
properties:
id:
$ref: './OrganizationId.yaml'
createdAt:
description: Дата и время создания организации
type: string
format: date-time
readOnly: true
name:
description: Название организации в человекочитаемом виде
type: string
minLength: 4
maxLength: 100
example: 'stolovka3'
owner:
allOf:
- description: Идентификатор пользователя-владельца организации
- $ref: './UserId.yaml'
metadata:
description: |
Произвольный, специфичный для клиента API и непрозрачный для системы набор данных, ассоциированных с
данной организацией
type: object
example:
displayName: 'НИИДАР Столовая №3'

View File

@ -0,0 +1,6 @@
description: Идентификатор организации
type: string
minLength: 1
maxLength: 40
example: or_af9e76uc5b47h8b154.19b8xa61dc94
readOnly: true

View File

@ -0,0 +1,6 @@
type: object
required:
- invitation
properties:
invitation:
$ref: './InvitationAcceptToken.yaml'

View File

@ -0,0 +1,9 @@
type: object
required:
- org
- member
properties:
org:
$ref: './Organization.yaml'
member:
$ref: './Member.yaml'

View File

@ -0,0 +1,4 @@
description: Идентификатор ограничения для роли
type: string
enum:
- Shop

View File

@ -0,0 +1,20 @@
description: Роль в организации
type: object
required:
- id
- name
properties:
id:
$ref: './RoleId.yaml'
name:
description: Название роли в человекочитаемом виде
type: string
minLength: 4
maxLength: 100
example: 'Shop Manager'
scopes:
description: Возможные области действия для роли
type: array
uniqueItems: true
items:
$ref: './ResourceScopeId.yaml'

View File

@ -0,0 +1,7 @@
description: Идентификатор роли
type: string
enum:
- Administrator
- Accountant
- Integrator
- Manager

View File

@ -0,0 +1,6 @@
description: Адрес электронной почты пользователя в организации
type: string
minLength: 4
maxLength: 100
format: email
example: 'laura.palmer@niidar.su'

View File

@ -0,0 +1,6 @@
description: Идентификатор пользователя
type: string
minLength: 1
maxLength: 40
example: 'fjbvae05:44d0-4oz4-8745.6dql4xc6a75c'
readOnly: true

View File

@ -0,0 +1,14 @@
type: http
scheme: bearer
bearerFormat: JWT
description: >
Для аутентификации вызовов мы используем [JWT](https://jwt.io).
Токен доступа передается в заголовке.
```shell
Authorization: Bearer {JWT}
```
Запросы к данному API авторизуются сессионным токеном доступа,
который вы получаете в результате аутентификации в личном кабинете
по адресу https://dashboard.rbk.money/.

50
openapi/docs/api.md Normal file
View File

@ -0,0 +1,50 @@
RBKmoney Organizations API является интерфейсом для управления различными
аспектами вашей организации. Все изменения состояния организации, будь то
приглашение новых сотрудников, добавление ролей уже существующим сотрудникам
или настройка области их ответственности осуществляются с помощью вызовов
соответствующих методов API. Любые сторонние приложения, включая ваш личный кабинет,
являются внешними приложениями-клиентами.
Мы предоставляем REST API поверх HTTP-протокола, схема которого описывается в
соответствии со стандартом [OpenAPI 3][OAS3].
Коды возврата описываются соответствующими HTTP-статусами. Платформа принимает и
возвращает значения JSON в теле запросов и ответов.
[OAS3]: https://swagger.io/specification/
## Формат содержимого
Любой запрос к API должен выполняться в кодировке UTF-8 и с указанием
содержимого в формате JSON.
```
Content-Type: application/json; charset=utf-8
```
## Запросы
Любой вызов методов API обязан предваряться предоставлением уникального для клиента
платформы идентификатора запроса. Данный ID передается в соответствующем заголовке каждого
HTTP-запроса:
```
X-Request-ID: RQID-Z08G3EFE5DZ429VVO755BM19D51
```
Мы требуем его, чтобы иметь возможность отследить жизненный цикл любого отдельного запроса
в системе, когда того требуют задачи аудита или обращения в техническую поддержку.
### Идемпотентность
При совершении некоторых запросов вы можете указать _ключ идемпотентности_ уникальный набор
символов для обеспечения идемпотентной обработки запросов.
```
X-Idempotency-Key: 881D:08BA
```
Даже если платформа получит множество запросов на совершение определённой операции с одним и тем
же значением ключа идемпотентности, эта операция будет выполнена е более чем один_ раз.
Таким образом, в случае кратковременных проблем с сетевой доступностью вы можете отправлять запросы
повторно и быть уверенными в том, что, например, приглашение новому сотруднику в итоге будет
отправлено только один раз.

View File

@ -0,0 +1,34 @@
## Общие ошибки
Ошибки возникающие при попытках совершения недопустимых операций, операций с невалидными объектами или несуществующими ресурсами. Имеют следующий вид:
```json
{
"code": "string",
"message": "string"
}
```
В поле `message` содержится информация по произошедшей ошибке. Например:
```json
{
"code": "invalidRequest",
"message": "Property 'name' is required."
}
```
## Ошибки обработки запросов
В процессе обработки запросов силами нашей платформы могут происходить различные непредвиденные ситуации. Об их появлении платформа сигнализирует по протоколу HTTP соответствующими [статусами][5xx], обозначающими ошибки сервера.
| Код | Описание |
| ------- | ---------- |
| **500** | В процессе обработки платформой запроса возникла непредвиденная ситуация. При получении подобного кода ответа мы рекомендуем обратиться в техническую поддержку. |
| **503** | Платформа временно недоступна и не готова обслуживать данный запрос. Запрос гарантированно не выполнен, при получении подобного кода ответа попробуйте выполнить его позднее, когда доступность платформы будет восстановлена. |
| **504** | Платформа превысила допустимое время обработки запроса, результат запроса не определён. Попробуйте отправить запрос повторно или выяснить результат выполнения исходного запроса, если повторное исполнение запроса нежелательно. |
[5xx]: https://tools.ietf.org/html/rfc7231#section-6.6
Если вы получили ошибку, которой нет в данном описании, обратитесь в техническую поддержку.

58
openapi/openapi.yaml Normal file
View File

@ -0,0 +1,58 @@
openapi: 3.0.3
info:
version: 1.0.0
title: RBKmoney Organizations API
description:
$ref: './docs/api.md'
termsOfService: 'https://rbk.money/'
contact:
name: RBKmoney Support Team
email: support@rbk.money
url: 'https://developer.rbk.money'
license:
name: Apache 2.0
url: https://www.apache.org/licenses/LICENSE-2.0.html
security:
- bearer: []
tags:
- name: orgs
x-displayName: Организации
- name: members
x-displayName: Сотрудники
- name: invitations
x-displayName: Приглашения
- name: roles
x-displayName: Роли
- name: error-codes
x-displayName: Коды ошибок
description:
$ref: './docs/error-codes.md'
paths:
/user/membership:
$ref: ./paths/membership.yaml
/user/membership/{orgId}:
$ref: ./paths/orgMembership.yaml
/orgs:
$ref: ./paths/orgs.yaml
/orgs/{orgId}:
$ref: ./paths/org.yaml
/orgs/{orgId}/roles:
$ref: ./paths/roles.yaml
/orgs/{orgId}/roles/{roleId}:
$ref: ./paths/role.yaml
/orgs/{orgId}/members:
$ref: ./paths/members.yaml
/orgs/{orgId}/members/{userId}:
$ref: ./paths/member.yaml
/orgs/{orgId}/members/{userId}/roles:
$ref: ./paths/memberRoles.yaml
/orgs/{orgId}/invitations:
$ref: ./paths/invitations.yaml
/orgs/{orgId}/invitations/{invitationId}:
$ref: ./paths/invitation.yaml
servers:
- url: 'https://api.rbk.money/org/v1'
components:
securitySchemes:
bearer:
$ref: './components/security-schemes/Bearer.yaml'

View File

@ -0,0 +1,71 @@
get:
summary: Получить данные приглашения
operationId: getInvitation
tags:
- invitations
parameters:
- $ref: '../components/parameters/requestId.yaml'
- $ref: '../components/parameters/orgId.yaml'
- $ref: '../components/parameters/invitationId.yaml'
responses:
'200':
description: Приглашение найдено
content:
application/json:
schema:
$ref: '../components/schemas/Invitation.yaml'
'404':
description: Приглашение не найдено
'403':
description: Данные недоступны
'400':
$ref: '../components/responses/BadRequest.yaml'
patch:
summary: Отозвать приглашение
operationId: revokeInvitation
tags:
- invitations
parameters:
- $ref: '../components/parameters/requestId.yaml'
- $ref: '../components/parameters/orgId.yaml'
- $ref: '../components/parameters/invitationId.yaml'
requestBody:
content:
application/json:
schema:
type: object
required:
- status
properties:
status:
type: string
enum:
- Revoked
reason:
description: Причина отзыва приглашения
type: string
maxLength: 1000
responses:
'204':
description: Приглашение отозвано
'422':
description: Отзыв невозможен
content:
application/json:
schema:
type: object
properties:
code:
type: string
enum:
- invalidStatus
message:
description: Человекочитаемое описание ошибки
type: string
'404':
description: Приглашение не найдено
'403':
description: Операция недоступна
'400':
$ref: '../components/responses/BadRequest.yaml'

View File

@ -0,0 +1,78 @@
get:
summary: Перечислить приглашения
operationId: listInvitations
tags:
- invitations
parameters:
- $ref: '../components/parameters/requestId.yaml'
- $ref: '../components/parameters/orgId.yaml'
- description: Фильтр по статусу приглашения
name: status
in: query
required: false
schema:
$ref: '../components/schemas/InvitationStatusName.yaml'
responses:
'200':
description: Найдены приглашения
content:
application/json:
schema:
type: object
required:
- results
properties:
results:
type: array
items:
$ref: '../components/schemas/Invitation.yaml'
'403':
description: Операция недоступна
'404':
description: Организация не найдена
'400':
$ref: '../components/responses/BadRequest.yaml'
post:
summary: Сформировать приглашение
operationId: createInvitation
tags:
- invitations
parameters:
- $ref: '../components/parameters/requestId.yaml'
- $ref: '../components/parameters/idempotencyKey.yaml'
- $ref: '../components/parameters/orgId.yaml'
requestBody:
description: Данные нового приглашения
required: true
content:
application/json:
schema:
$ref: '../components/schemas/Invitation.yaml'
responses:
'201':
description: Приглашение сформировано
content:
application/json:
schema:
$ref: '../components/schemas/Invitation.yaml'
'422':
description: Невозможно совершить операцию
content:
application/json:
schema:
type: object
properties:
code:
type: string
enum:
- invalidRole
message:
description: Человекочитаемое описание ошибки
type: string
'403':
description: Операция недоступна
'404':
description: Организация не найдена
'400':
$ref: '../components/responses/BadRequest.yaml'

41
openapi/paths/member.yaml Normal file
View File

@ -0,0 +1,41 @@
get:
summary: Получить данные сотрудника
operationId: getOrgMember
tags:
- members
parameters:
- $ref: '../components/parameters/requestId.yaml'
- $ref: '../components/parameters/orgId.yaml'
- $ref: '../components/parameters/userId.yaml'
responses:
'200':
description: Данные найдены
content:
application/json:
schema:
$ref: '../components/schemas/Member.yaml'
'403':
description: Данные недоступны
'404':
description: Сотрудник не найден
'400':
$ref: '../components/responses/BadRequest.yaml'
delete:
summary: Исключить сотрудника из организации
operationId: expelOrgMember
tags:
- members
parameters:
- $ref: '../components/parameters/requestId.yaml'
- $ref: '../components/parameters/orgId.yaml'
- $ref: '../components/parameters/userId.yaml'
responses:
'204':
description: Сотрудник более не состоит в организации
'403':
description: Операция недоступна
'404':
description: Организация не найдена
'400':
$ref: '../components/responses/BadRequest.yaml'

View File

@ -0,0 +1,79 @@
put:
summary: Назначить сотруднику роль
operationId: assignMemberRole
tags:
- members
parameters:
- $ref: '../components/parameters/requestId.yaml'
- $ref: '../components/parameters/orgId.yaml'
- $ref: '../components/parameters/userId.yaml'
requestBody:
content:
application/json:
schema:
$ref: '../components/schemas/MemberRole.yaml'
responses:
# TODO
# Нужно ли возвращать получившийся набор ролей?
'204':
description: Роль назначена
'422':
# TODO
# Может упростить пока и не энфорсить это требование на API?
description: Невозможно совершить операцию
content:
application/json:
schema:
type: object
properties:
code:
type: string
enum:
- onlyRoleLeft
message:
description: Человекочитаемое описание ошибки
type: string
'403':
description: Операция недоступна
'404':
description: Сотрудник не найден
'400':
$ref: '../components/responses/BadRequest.yaml'
delete:
summary: Снять роль с сотрудника
operationId: removeMemberRole
tags:
- members
parameters:
- $ref: '../components/parameters/requestId.yaml'
- $ref: '../components/parameters/orgId.yaml'
- $ref: '../components/parameters/userId.yaml'
requestBody:
content:
application/json:
schema:
$ref: '../components/schemas/MemberRole.yaml'
responses:
'204':
description: Сотрудник более не обладает указанной ролью
'422':
description: Невозможно совершить операцию
content:
application/json:
schema:
type: object
properties:
code:
type: string
enum:
- invalidRole
message:
description: Человекочитаемое описание ошибки
type: string
'403':
description: Операция недоступна
'404':
description: Сотрудник не найден
'400':
$ref: '../components/responses/BadRequest.yaml'

View File

@ -0,0 +1,28 @@
get:
summary: Перечислить сотрудников организации
operationId: listOrgMembers
tags:
- members
parameters:
- $ref: '../components/parameters/requestId.yaml'
- $ref: '../components/parameters/orgId.yaml'
responses:
'200':
description: Найдены сотрудники
content:
application/json:
schema:
type: object
required:
- results
properties:
results:
type: array
items:
$ref: '../components/schemas/Member.yaml'
'403':
description: Данные недоступны
'404':
description: Организация не найдена
'400':
$ref: '../components/responses/BadRequest.yaml'

View File

@ -0,0 +1,69 @@
get:
summary: Перечислить доступные организации
operationId: listOrgMembership
tags:
- orgs
parameters:
- $ref: '../components/parameters/requestId.yaml'
responses:
'200':
description: Найдены доступные организации
content:
application/json:
schema:
type: object
required:
- results
properties:
results:
type: array
items:
$ref: '../components/schemas/Organization.yaml'
'400':
$ref: '../components/responses/BadRequest.yaml'
post:
summary: Вступить в организацию по приглашению
operationId: joinOrg
tags:
- orgs
parameters:
- $ref: '../components/parameters/requestId.yaml'
requestBody:
content:
application/json:
schema:
$ref: '../components/schemas/OrganizationJoinRequest.yaml'
responses:
'201':
description: Пользователь вступил в организацию
content:
application/json:
schema:
$ref: '../components/schemas/OrganizationMembership.yaml'
headers:
location:
description: URL членства в организации
required: true
schema:
type: string
format: uri
example: 'https://api.rbk.money/org/v1/user/membership/or_af9e76uc5b47h8b154.19b8xa61dc94'
'422':
description: Невозможно совершить операцию
content:
application/json:
schema:
type: object
properties:
code:
type: string
enum:
- invitationExpired
message:
description: Человекочитаемое описание ошибки
type: string
'403':
description: Вступление невозможно
'400':
$ref: '../components/responses/BadRequest.yaml'

19
openapi/paths/org.yaml Normal file
View File

@ -0,0 +1,19 @@
get:
summary: Получить данные организации
operationId: getOrg
tags:
- orgs
parameters:
- $ref: '../components/parameters/requestId.yaml'
- $ref: '../components/parameters/orgId.yaml'
responses:
'200':
description: Организация найдена
content:
application/json:
schema:
$ref: '../components/schemas/Organization.yaml'
'404':
description: Организация не найдена
'400':
$ref: '../components/responses/BadRequest.yaml'

View File

@ -0,0 +1,37 @@
get:
summary: Посмотреть своё членство в организации
operationId: inquireOrgMembership
tags:
- orgs
parameters:
- $ref: '../components/parameters/requestId.yaml'
- $ref: '../components/parameters/orgId.yaml'
responses:
'200':
description: Получены данные членства
content:
application/json:
schema:
$ref: '../components/schemas/OrganizationMembership.yaml'
'404':
description: Организация не найдена
'400':
$ref: '../components/responses/BadRequest.yaml'
delete:
summary: Отменить своё членство в организации
operationId: cancelOrgMembership
tags:
- orgs
parameters:
- $ref: '../components/parameters/requestId.yaml'
- $ref: '../components/parameters/orgId.yaml'
responses:
'204':
description: Членство отменено
'404':
description: Организация не найдена
'403':
description: Операция недоступна
'400':
$ref: '../components/responses/BadRequest.yaml'

24
openapi/paths/orgs.yaml Normal file
View File

@ -0,0 +1,24 @@
post:
summary: Создать новую организацию
operationId: createOrg
tags:
- orgs
parameters:
- $ref: '../components/parameters/requestId.yaml'
- $ref: '../components/parameters/idempotencyKey.yaml'
requestBody:
description: Данные организации
required: true
content:
application/json:
schema:
$ref: '../components/schemas/Organization.yaml'
responses:
'201':
description: Организация создана
content:
application/json:
schema:
$ref: '../components/schemas/Organization.yaml'
'400':
$ref: '../components/responses/BadRequest.yaml'

22
openapi/paths/role.yaml Normal file
View File

@ -0,0 +1,22 @@
get:
summary: Получить данные о роли
operationId: getOrgRole
tags:
- roles
parameters:
- $ref: '../components/parameters/requestId.yaml'
- $ref: '../components/parameters/orgId.yaml'
- $ref: '../components/parameters/roleId.yaml'
responses:
'200':
description: Найдены роли
content:
application/json:
schema:
$ref: '../components/schemas/Role.yaml'
'403':
description: Данные недоступны
'404':
description: Организация не найдена
'400':
$ref: '../components/responses/BadRequest.yaml'

28
openapi/paths/roles.yaml Normal file
View File

@ -0,0 +1,28 @@
get:
summary: Перечислить доступные роли в организации
operationId: listOrgRoles
tags:
- roles
parameters:
- $ref: '../components/parameters/requestId.yaml'
- $ref: '../components/parameters/orgId.yaml'
responses:
'200':
description: Найдены роли
content:
application/json:
schema:
type: object
required:
- results
properties:
results:
type: array
items:
$ref: '../components/schemas/Role.yaml'
'403':
description: Данные недоступны
'404':
description: Организация не найдена
'400':
$ref: '../components/responses/BadRequest.yaml'

3102
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

20
package.json Normal file
View File

@ -0,0 +1,20 @@
{
"name": "rbkmoney-organizations-api",
"version": "1.0.0",
"dependencies": {
"@redocly/openapi-cli": "^0.12.7",
"redoc-cli": "^0.9.8",
"json-merge-patch": "^0.2.3",
"json-pointer": "^0.6.0",
"shelljs": "^0.7.0",
"swagger-ui-dist": "^3.18.3"
},
"private": true,
"scripts": {
"start": "openapi preview-docs",
"build": "node ./build.js",
"validate": "openapi validate",
"openapi": "openapi",
"redoc": "redoc-cli"
}
}