diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..af166b0
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,61 @@
+# Dir for API portal deploy
+dist
+out
+
+# Logs
+logs
+*.log
+npm-debug.log*
+
+# Runtime data
+pids
+*.pid
+*.seed
+
+# Directory for instrumented libs generated by jscoverage/JSCover
+lib-cov
+
+# Coverage directory used by tools like istanbul
+coverage
+
+# node-waf configuration
+.lock-wscript
+
+# Compiled binary addons (http://nodejs.org/api/addons.html)
+build/Release
+
+# Dependency directory
+node_modules
+
+# Optional npm cache directory
+.npm
+
+# Optional REPL history
+.node_repl_history
+
+# CI
+.wercker
+
+# Generated
+web_deploy/
+package-lock.json
+
+# User-specific stuff:
+.idea/
+.idea/workspace.xml
+.idea/tasks.xml
+.idea/dictionaries
+.idea/vcs.xml
+.idea/jsLibraryMappings.xml
+
+# Sensitive or high-churn files:
+.idea/dataSources.ids
+.idea/dataSources.xml
+.idea/dataSources.local.xml
+.idea/sqlDataSources.xml
+.idea/dynamic.xml
+.idea/uiDesigner.xml
+
+# Gradle:
+.idea/gradle.xml
+.idea/libraries
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..ca5a761
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,4 @@
+[submodule "build_utils"]
+ path = build_utils
+ url = git@github.com:rbkmoney/build_utils.git
+ branch = master
diff --git a/.redocly.yaml b/.redocly.yaml
new file mode 100644
index 0000000..692bbae
--- /dev/null
+++ b/.redocly.yaml
@@ -0,0 +1,18 @@
+# See https://docs.redoc.ly/cli/configuration/ for more information.
+apiDefinitions:
+ core: "openapi/openapi.yaml"
+lint:
+ plugins:
+ - './plugins/local.js'
+ extends:
+ - recommended
+ rules:
+ tag-description: off
+ preprocessors:
+ local/merge-schemas: on
+referenceDocs:
+ showConsole: true
+ layout:
+ scope: section
+ routingStrategy: browser
+ htmlTemplate: ./web/index.html
diff --git a/Jenkinsfile b/Jenkinsfile
new file mode 100644
index 0000000..ef60d43
--- /dev/null
+++ b/Jenkinsfile
@@ -0,0 +1,58 @@
+#!groovy
+// -*- mode: groovy -*-
+
+build('openapi-notification', 'docker-host') {
+ checkoutRepo()
+ loadBuildUtils('build_utils')
+
+ def pipeDefault
+ def withWsCache
+ def gitUtils
+ runStage('load pipeline') {
+ env.JENKINS_LIB = "build_utils/jenkins_lib"
+ pipeDefault = load("${env.JENKINS_LIB}/pipeDefault.groovy")
+ withWsCache = load("${env.JENKINS_LIB}/withWsCache.groovy")
+ gitUtils = load("${env.JENKINS_LIB}/gitUtils.groovy")
+ }
+
+ pipeDefault() {
+
+ runStage('install-deps') {
+ withWsCache("node_modules") {
+ sh 'make wc_install'
+ }
+ }
+
+ runStage('validate-spec') {
+ sh 'make wc_validate'
+ }
+
+ runStage('bundle') {
+ sh 'make wc_build'
+ }
+
+ // Java
+ runStage('build java client & server') {
+ withCredentials([[$class: 'FileBinding', credentialsId: 'java-maven-settings.xml', variable: 'SETTINGS_XML']]) {
+ if (env.BRANCH_NAME == 'master' || env.BRANCH_NAME.startsWith('epic/')) {
+ sh 'make SETTINGS_XML=${SETTINGS_XML} BRANCH_NAME=${BRANCH_NAME} java.openapi.deploy_client'
+ sh 'make SETTINGS_XML=${SETTINGS_XML} BRANCH_NAME=${BRANCH_NAME} java.openapi.deploy_server'
+ } else {
+ sh 'make SETTINGS_XML=${SETTINGS_XML} BRANCH_NAME=${BRANCH_NAME} java.openapi.compile_client'
+ sh 'make SETTINGS_XML=${SETTINGS_XML} BRANCH_NAME=${BRANCH_NAME} java.openapi.compile_server'
+ }
+ }
+ }
+
+ // Release
+ if (env.BRANCH_NAME == 'master' || env.BRANCH_NAME.startsWith('epic/')) {
+ runStage('publish release bundle') {
+ dir("web_deploy") {
+ gitUtils.push(commitMsg: "Generated from commit: $COMMIT_ID \n\non $BRANCH_NAME in $RBK_REPO_URL\n\nChanges:\n$COMMIT_MSG",
+ files: "*", branch: "release/$BRANCH_NAME", orphan: true)
+ }
+ }
+ }
+
+ }
+}
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..c460192
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,90 @@
+UTILS_PATH := build_utils
+TEMPLATES_PATH := .
+
+SERVICE_NAME := openapi-notification
+BUILD_IMAGE_TAG := 442c2c274c1d8e484e5213089906a4271641d95e
+
+CALL_ANYWHERE := all install validate build java.compile java.deploy
+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
+
+build:
+ npm run build
+
+# Java
+
+ifdef SETTINGS_XML
+DOCKER_RUN_OPTS = -v $(SETTINGS_XML):$(SETTINGS_XML)
+DOCKER_RUN_OPTS += -e SETTINGS_XML=$(SETTINGS_XML)
+endif
+
+ifdef LOCAL_BUILD
+DOCKER_RUN_OPTS += -v $$HOME/.m2:/home/$(UNAME)/.m2:rw
+endif
+
+COMMIT_HASH := $(shell git --no-pager log -1 --pretty=format:"%h")
+NUMBER_COMMITS := $(shell git rev-list --count HEAD)
+
+JAVA_PKG_VERSION := 1.$(NUMBER_COMMITS)-$(COMMIT_HASH)
+
+ifdef BRANCH_NAME
+ifeq "$(findstring epic,$(BRANCH_NAME))" "epic"
+JAVA_PKG_VERSION := $(JAVA_PKG_VERSION)-epic
+endif
+endif
+
+MVN = mvn -s $(SETTINGS_XML) -Dcommit.number="$(NUMBER_COMMITS)"
+
+java.openapi.compile_client: java.settings
+ $(MVN) clean && \
+ $(MVN) compile -P="client"
+
+java.openapi.deploy_client: java.settings
+ $(MVN) clean && \
+ $(MVN) versions:set versions:commit -DnewVersion="$(JAVA_PKG_VERSION)-client" && \
+ $(MVN) deploy -P="client"
+
+java.openapi.install_client: java.settings
+ $(MVN) clean && \
+ $(MVN) versions:set versions:commit -DnewVersion="$(JAVA_PKG_VERSION)-client" && \
+ $(MVN) install -P="client"
+
+java.openapi.compile_server: java.settings
+ $(MVN) clean && \
+ $(MVN) compile -P="server"
+
+java.openapi.deploy_server: java.settings
+ $(MVN) clean && \
+ $(MVN) versions:set versions:commit -DnewVersion="$(JAVA_PKG_VERSION)-server" && \
+ $(MVN) deploy -P="server"
+
+java.openapi.install_server: java.settings
+ $(MVN) clean && \
+ $(MVN) versions:set versions:commit -DnewVersion="$(JAVA_PKG_VERSION)-server" && \
+ $(MVN) install -P="server"
+
+java.compile: java.settings
+ $(MVN) compile
+
+java.deploy: java.settings
+ $(MVN) versions:set versions:commit -DnewVersion="$(JAVA_PKG_VERSION)" && \
+ $(MVN) deploy
+
+java.install: java.settings
+ $(MVN) clean && \
+ $(MVN) versions:set versions:commit -DnewVersion="$(JAVA_PKG_VERSION)" && \
+ $(MVN) install
+
+java.settings:
+ $(if $(SETTINGS_XML),, echo "SETTINGS_XML not defined"; exit 1)
diff --git a/build_utils b/build_utils
new file mode 160000
index 0000000..a7655bc
--- /dev/null
+++ b/build_utils
@@ -0,0 +1 @@
+Subproject commit a7655bc60c877a65cdfe3d9b668021d970d88a76
diff --git a/openapi/components/parameters/continuationToken.yaml b/openapi/components/parameters/continuationToken.yaml
new file mode 100644
index 0000000..506f606
--- /dev/null
+++ b/openapi/components/parameters/continuationToken.yaml
@@ -0,0 +1,5 @@
+name: continuationToken
+in: query
+required: false
+schema:
+ $ref: '../schemas/ContinuationToken.yaml'
diff --git a/openapi/components/parameters/fromTime.yaml b/openapi/components/parameters/fromTime.yaml
new file mode 100644
index 0000000..d42e88f
--- /dev/null
+++ b/openapi/components/parameters/fromTime.yaml
@@ -0,0 +1,6 @@
+name: fromTime
+in: query
+required: false
+schema:
+ type: string
+ format: date-time
diff --git a/openapi/components/parameters/limit.yaml b/openapi/components/parameters/limit.yaml
new file mode 100644
index 0000000..e3861bc
--- /dev/null
+++ b/openapi/components/parameters/limit.yaml
@@ -0,0 +1,6 @@
+name: limit
+in: query
+required: false
+schema:
+ type: integer
+ format: int32
diff --git a/openapi/components/parameters/notificationId.yaml b/openapi/components/parameters/notificationId.yaml
new file mode 100644
index 0000000..47f5811
--- /dev/null
+++ b/openapi/components/parameters/notificationId.yaml
@@ -0,0 +1,5 @@
+name: notificationId
+in: query
+required: true
+schema:
+ $ref: '../schemas/NotificationId.yaml'
diff --git a/openapi/components/parameters/notificationResourceId.yaml b/openapi/components/parameters/notificationResourceId.yaml
new file mode 100644
index 0000000..4a3f623
--- /dev/null
+++ b/openapi/components/parameters/notificationResourceId.yaml
@@ -0,0 +1,5 @@
+name: id
+in: path
+required: true
+schema:
+ $ref: '../schemas/NotificationId.yaml'
diff --git a/openapi/components/parameters/requestId.yaml b/openapi/components/parameters/requestId.yaml
new file mode 100644
index 0000000..b4cbda3
--- /dev/null
+++ b/openapi/components/parameters/requestId.yaml
@@ -0,0 +1,9 @@
+name: X-Request-ID
+in: header
+description: Уникальный идентификатор запроса к системе
+required: true
+schema:
+ type: string
+ minLength: 4
+ maxLength: 32
+ example: RQID-Z08G3EFE5DZ429VVO755BM19D51
diff --git a/openapi/components/parameters/status.yaml b/openapi/components/parameters/status.yaml
new file mode 100644
index 0000000..02e8900
--- /dev/null
+++ b/openapi/components/parameters/status.yaml
@@ -0,0 +1,5 @@
+name: status
+in: query
+required: false
+schema:
+ $ref: '../schemas/NotificationStatus.yaml'
diff --git a/openapi/components/parameters/title.yaml b/openapi/components/parameters/title.yaml
new file mode 100644
index 0000000..2ad9eea
--- /dev/null
+++ b/openapi/components/parameters/title.yaml
@@ -0,0 +1,6 @@
+name: title
+in: query
+required: false
+schema:
+ description: Заголовок уведомления
+ type: string
diff --git a/openapi/components/parameters/toTime.yaml b/openapi/components/parameters/toTime.yaml
new file mode 100644
index 0000000..0d3695b
--- /dev/null
+++ b/openapi/components/parameters/toTime.yaml
@@ -0,0 +1,6 @@
+name: toTime
+in: query
+required: false
+schema:
+ type: string
+ format: date-time
diff --git a/openapi/components/responses/BadRequest.yaml b/openapi/components/responses/BadRequest.yaml
new file mode 100644
index 0000000..9507180
--- /dev/null
+++ b/openapi/components/responses/BadRequest.yaml
@@ -0,0 +1,15 @@
+description: Переданы ошибочные данные
+content:
+ application/json:
+ schema:
+ description: Ошибка в переданных данных
+ type: object
+ required:
+ - code
+ properties:
+ code:
+ type: string
+ enum:
+ - invalidRequest
+ message:
+ type: string
diff --git a/openapi/components/responses/Forbidden.yaml b/openapi/components/responses/Forbidden.yaml
new file mode 100644
index 0000000..873dc62
--- /dev/null
+++ b/openapi/components/responses/Forbidden.yaml
@@ -0,0 +1,5 @@
+description: Access forbidden.
+content:
+ application/json:
+ schema:
+ $ref: ../schemas/Error.yaml
diff --git a/openapi/components/responses/NotFound.yaml b/openapi/components/responses/NotFound.yaml
new file mode 100644
index 0000000..6a5a79c
--- /dev/null
+++ b/openapi/components/responses/NotFound.yaml
@@ -0,0 +1,5 @@
+description: Resource was not found
+content:
+ application/json:
+ schema:
+ $ref: ../schemas/Error.yaml
diff --git a/openapi/components/responses/NotificationSearchResult.yaml b/openapi/components/responses/NotificationSearchResult.yaml
new file mode 100644
index 0000000..e7fd579
--- /dev/null
+++ b/openapi/components/responses/NotificationSearchResult.yaml
@@ -0,0 +1,10 @@
+type: object
+required:
+ - result
+properties:
+ continuationToken:
+ $ref: '../schemas/ContinuationToken.yaml'
+ result:
+ type: array
+ items:
+ $ref: '../schemas/Notification.yaml'
diff --git a/openapi/components/responses/Unauthorized.yaml b/openapi/components/responses/Unauthorized.yaml
new file mode 100644
index 0000000..a879ff2
--- /dev/null
+++ b/openapi/components/responses/Unauthorized.yaml
@@ -0,0 +1,5 @@
+description: Несанкционированный доступ, использовались неверные учетные данные.
+content:
+ application/json:
+ schema:
+ $ref: ../schemas/Error.yaml
diff --git a/openapi/components/schemas/ContinuationToken.yaml b/openapi/components/schemas/ContinuationToken.yaml
new file mode 100644
index 0000000..e7561f9
--- /dev/null
+++ b/openapi/components/schemas/ContinuationToken.yaml
@@ -0,0 +1,5 @@
+description: |
+ Токен, сигнализирующий о том, что в ответе передана только часть данных.
+ Для получения следующей части нужно повторно обратиться к сервису, указав тот же набор условий и полученый токен.
+ Если токена нет, получена последняя часть данных.
+type: string
diff --git a/openapi/components/schemas/Error.yaml b/openapi/components/schemas/Error.yaml
new file mode 100644
index 0000000..98673db
--- /dev/null
+++ b/openapi/components/schemas/Error.yaml
@@ -0,0 +1,22 @@
+type: object
+properties:
+ status:
+ type: integer
+ minimum: 100
+ maximum: 600
+ description: The HTTP status code.
+ error:
+ type: string
+ type:
+ type: string
+ description: >-
+ A URI reference [[RFC3986](https://tools.ietf.org/html/rfc3986)] that
+ identifies the problem type. It should provide human-readable
+ documentation for the problem type. When this member is not present, its
+ value is assumed to be "about:blank".
+ title:
+ type: string
+ description: >-
+ A short, human-readable summary of the problem type. It SHOULD NOT change
+ from occurrence to occurrence of the problem, except for purposes of
+ localization.
diff --git a/openapi/components/schemas/MarkAllNotifications.yaml b/openapi/components/schemas/MarkAllNotifications.yaml
new file mode 100644
index 0000000..428a584
--- /dev/null
+++ b/openapi/components/schemas/MarkAllNotifications.yaml
@@ -0,0 +1,9 @@
+type: object
+required:
+ - status
+properties:
+ status:
+ type: string
+ enum:
+ - read
+ - unread
diff --git a/openapi/components/schemas/MarkNotifications.yaml b/openapi/components/schemas/MarkNotifications.yaml
new file mode 100644
index 0000000..8effedb
--- /dev/null
+++ b/openapi/components/schemas/MarkNotifications.yaml
@@ -0,0 +1,14 @@
+type: object
+required:
+ - status
+ - notificationIds
+properties:
+ status:
+ type: string
+ enum:
+ - read
+ - unread
+ notificationIds:
+ type: array
+ items:
+ $ref: ../schemas/NotificationId.yaml
diff --git a/openapi/components/schemas/Notification.yaml b/openapi/components/schemas/Notification.yaml
new file mode 100644
index 0000000..7d838b4
--- /dev/null
+++ b/openapi/components/schemas/Notification.yaml
@@ -0,0 +1,25 @@
+description: Сущность уведомления
+type: object
+required:
+ - id
+ - createdAt
+ - status
+ - title
+ - content
+properties:
+ id:
+ $ref: './NotificationId.yaml'
+ createdAt:
+ description: Дата и время создания уведомления
+ type: string
+ format: date-time
+ readOnly: true
+ status:
+ $ref: './NotificationStatus.yaml'
+ title:
+ description: Заголовок уведомления
+ type: string
+ content:
+ description: Текст уведомления
+ type: string
+
diff --git a/openapi/components/schemas/NotificationId.yaml b/openapi/components/schemas/NotificationId.yaml
new file mode 100644
index 0000000..4225fc8
--- /dev/null
+++ b/openapi/components/schemas/NotificationId.yaml
@@ -0,0 +1,4 @@
+description: Идентификатор уведомления
+type: string
+format: uuid
+readOnly: true
diff --git a/openapi/components/schemas/NotificationStatus.yaml b/openapi/components/schemas/NotificationStatus.yaml
new file mode 100644
index 0000000..da7c2e8
--- /dev/null
+++ b/openapi/components/schemas/NotificationStatus.yaml
@@ -0,0 +1,5 @@
+description: Статус уведомления
+type: string
+enum:
+ - read
+ - unread
diff --git a/openapi/components/security-schemes/Bearer.yaml b/openapi/components/security-schemes/Bearer.yaml
new file mode 100644
index 0000000..8bc3fbc
--- /dev/null
+++ b/openapi/components/security-schemes/Bearer.yaml
@@ -0,0 +1,10 @@
+type: http
+scheme: bearer
+bearerFormat: JWT
+description: >
+ Для аутентификации вызовов мы используем [JWT](https://jwt.io).
+ Cоответствующий ключ передается в заголовке.
+
+ ```shell
+ Authorization: Bearer {TOKENIZATION|PRIVATE_JWT}
+ ```
diff --git a/openapi/docs/api.md b/openapi/docs/api.md
new file mode 100644
index 0000000..cf67857
--- /dev/null
+++ b/openapi/docs/api.md
@@ -0,0 +1 @@
+RBKmoney Notification API
diff --git a/openapi/openapi.yaml b/openapi/openapi.yaml
new file mode 100644
index 0000000..4ab2751
--- /dev/null
+++ b/openapi/openapi.yaml
@@ -0,0 +1,40 @@
+openapi: 3.0.0
+info:
+ version: 1.0.0
+ title: RBKmoney Notification API
+ description:
+ $ref: './docs/api.md'
+ termsOfService: http://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
+servers:
+ - url: 'https://{subdomain}.rbk.money/notify/{version}'
+ variables:
+ subdomain:
+ default: api
+ version:
+ enum:
+ - v1
+ default: v1
+security:
+ - bearer: []
+paths:
+ /notification:
+ $ref: ./paths/notification.yaml
+ '/notification/{id}':
+ $ref: './paths/notification@{id}.yaml'
+ '/notification/remove':
+ $ref: './paths/notificationDelete.yaml'
+ '/notification/mark':
+ $ref: './paths/notificationMark.yaml'
+ '/notification/mark/all':
+ $ref: './paths/notificationMarkAll.yaml'
+components:
+ securitySchemes:
+ bearer:
+ $ref: './components/security-schemes/Bearer.yaml'
diff --git a/openapi/paths/notification.yaml b/openapi/paths/notification.yaml
new file mode 100644
index 0000000..4bbbd2a
--- /dev/null
+++ b/openapi/paths/notification.yaml
@@ -0,0 +1,28 @@
+get:
+ summary: Получить список уведомлений
+ operationId: notificationList
+ tags:
+ - notifications
+ parameters:
+ - $ref: '../components/parameters/requestId.yaml'
+ - $ref: '../components/parameters/title.yaml'
+ - $ref: '../components/parameters/status.yaml'
+ - $ref: '../components/parameters/fromTime.yaml'
+ - $ref: '../components/parameters/toTime.yaml'
+ - $ref: '../components/parameters/limit.yaml'
+ - $ref: '../components/parameters/continuationToken.yaml'
+ responses:
+ '200':
+ description: Найденное уведомление
+ content:
+ application/json:
+ schema:
+ $ref: '../components/responses/NotificationSearchResult.yaml'
+ '400':
+ $ref: '../components/responses/BadRequest.yaml'
+ '401':
+ $ref: ../components/responses/Unauthorized.yaml
+ '403':
+ $ref: ../components/responses/Forbidden.yaml
+ '404':
+ description: Уведомление не найдено
diff --git a/openapi/paths/notification@{id}.yaml b/openapi/paths/notification@{id}.yaml
new file mode 100644
index 0000000..df226c1
--- /dev/null
+++ b/openapi/paths/notification@{id}.yaml
@@ -0,0 +1,39 @@
+get:
+ summary: Получить данные уведомления
+ operationId: notification
+ tags:
+ - notifications
+ parameters:
+ - $ref: '../components/parameters/requestId.yaml'
+ - $ref: '../components/parameters/notificationResourceId.yaml'
+ responses:
+ '200':
+ description: Найденное уведомление
+ content:
+ application/json:
+ schema:
+ $ref: '../components/schemas/Notification.yaml'
+ '400':
+ $ref: '../components/responses/BadRequest.yaml'
+ '401':
+ $ref: ../components/responses/Unauthorized.yaml
+ '403':
+ $ref: ../components/responses/Forbidden.yaml
+ '404':
+ description: Уведомление не найдено
+delete:
+ summary: Удалить уведомление
+ operationId: deleteNotification
+ tags:
+ - notifications
+ parameters:
+ - $ref: '../components/parameters/requestId.yaml'
+ - $ref: '../components/parameters/notificationResourceId.yaml'
+ responses:
+ '200':
+ description: Уведомление удалено
+ '401':
+ $ref: ../components/responses/Unauthorized.yaml
+ '404':
+ $ref: ../components/responses/NotFound.yaml
+
diff --git a/openapi/paths/notificationDelete.yaml b/openapi/paths/notificationDelete.yaml
new file mode 100644
index 0000000..e9b7252
--- /dev/null
+++ b/openapi/paths/notificationDelete.yaml
@@ -0,0 +1,28 @@
+delete:
+ summary: Удалить уведомления
+ operationId: deleteNotifications
+ tags:
+ - notifications
+ parameters:
+ - $ref: '../components/parameters/requestId.yaml'
+ requestBody:
+ content:
+ application/json:
+ schema:
+ type: object
+ required:
+ - notificationIds
+ properties:
+ notificationIds:
+ type: array
+ items:
+ $ref: ../components/schemas/NotificationId.yaml
+ responses:
+ '200':
+ description: Уведомления удалены
+ '400':
+ $ref: '../components/responses/BadRequest.yaml'
+ '401':
+ $ref: ../components/responses/Unauthorized.yaml
+ '403':
+ $ref: ../components/responses/Forbidden.yaml
diff --git a/openapi/paths/notificationMark.yaml b/openapi/paths/notificationMark.yaml
new file mode 100644
index 0000000..5e9317e
--- /dev/null
+++ b/openapi/paths/notificationMark.yaml
@@ -0,0 +1,21 @@
+post:
+ summary: Отметить выбранные уведомления
+ operationId: notificationMark
+ tags:
+ - notifications
+ parameters:
+ - $ref: '../components/parameters/requestId.yaml'
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: ../components/schemas/MarkNotifications.yaml
+ responses:
+ '200':
+ description: Уведомления отмечены
+ '400':
+ $ref: '../components/responses/BadRequest.yaml'
+ '401':
+ $ref: ../components/responses/Unauthorized.yaml
+ '403':
+ $ref: ../components/responses/Forbidden.yaml
diff --git a/openapi/paths/notificationMarkAll.yaml b/openapi/paths/notificationMarkAll.yaml
new file mode 100644
index 0000000..44a0f30
--- /dev/null
+++ b/openapi/paths/notificationMarkAll.yaml
@@ -0,0 +1,21 @@
+post:
+ summary: Отметить все уведомления
+ operationId: notificationMarkAll
+ tags:
+ - notifications
+ parameters:
+ - $ref: '../components/parameters/requestId.yaml'
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: ../components/schemas/MarkAllNotifications.yaml
+ responses:
+ '200':
+ description: Уведомления отмечены
+ '400':
+ $ref: '../components/responses/BadRequest.yaml'
+ '401':
+ $ref: ../components/responses/Unauthorized.yaml
+ '403':
+ $ref: ../components/responses/Forbidden.yaml
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..81342e4
--- /dev/null
+++ b/package.json
@@ -0,0 +1,15 @@
+{
+ "name": "swag-notification",
+ "version": "0.1.0",
+ "private": true,
+ "dependencies": {
+ "@redocly/openapi-cli": "^1.0.0-beta.53",
+ "json-merge-patch": "^1.0.0",
+ "redoc-cli": "^0.12.1"
+ },
+ "scripts": {
+ "start": "openapi preview-docs",
+ "build": "openapi bundle -o web_deploy/openapi.yaml && openapi bundle -o web_deploy/openapi.json",
+ "validate": "openapi lint"
+ }
+}
diff --git a/plugins/local.js b/plugins/local.js
new file mode 100644
index 0000000..c042a9c
--- /dev/null
+++ b/plugins/local.js
@@ -0,0 +1,50 @@
+const jsonmergepatch = require('json-merge-patch');
+
+module.exports = {
+
+ id: 'local',
+
+ preprocessors: {
+ oas3: {
+ 'merge-schemas': MergeSchemas
+ }
+ }
+
+};
+
+function MergeSchemas() {
+ const trigger = 'x-mergeSchemas';
+ return {
+ Schema: {
+ leave(node, ctx) {
+ if (!node[trigger]) {
+ return;
+ }
+ var schemas = node[trigger];
+ if (!Array.isArray(schemas)) {
+ return ctx.report({
+ message: "Argument should be an array of schemas",
+ location: ctx.location.child(trigger)
+ });
+ }
+ let merged = null;
+ for (index = schemas.length - 1; index >= 0; --index) {
+ let schema = schemas[index];
+ if (typeof schema !== 'object') {
+ return ctx.report({
+ message: "Non-object value",
+ location: ctx.location.child(trigger).child(index)
+ });
+ }
+ if (schema.$ref && typeof schema.$ref === 'string') {
+ schema = ctx.resolve(schema).node;
+ }
+ merged = jsonmergepatch.apply(merged, schema);
+ console.log(merged);
+ };
+ Object.assign(node, merged);
+ delete node[trigger];
+ }
+ }
+ }
+}
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..3829a9b
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,204 @@
+
+