FE-881: Claim management selection (#1)

This commit is contained in:
Rinat Arsaev 2019-07-16 15:41:45 +03:00 committed by GitHub
parent b5c77e22c5
commit 8b5952eff4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
92 changed files with 1662 additions and 0 deletions

61
.gitignore vendored Normal file
View File

@ -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

4
.gitmodules vendored Normal file
View File

@ -0,0 +1,4 @@
[submodule "build_utils"]
path = build_utils
url = git@github.com:rbkmoney/build_utils.git
branch = master

5
.prettierignore Normal file
View File

@ -0,0 +1,5 @@
package.json
package-lock.json
node_modules
build_utils
web_deploy

3
.prettierrc Normal file
View File

@ -0,0 +1,3 @@
{
"singleQuote": true
}

36
Jenkinsfile vendored Normal file
View File

@ -0,0 +1,36 @@
#!groovy
build('swag-claim-management', 'docker-host') {
checkoutRepo()
loadBuildUtils()
def pipeDefault
def gitUtils
runStage('load pipeline') {
env.JENKINS_LIB = "build_utils/jenkins_lib"
pipeDefault = load("${env.JENKINS_LIB}/pipeDefault.groovy")
gitUtils = load("${env.JENKINS_LIB}/gitUtils.groovy")
}
pipeDefault() {
runStage('init') {
withGithubSshCredentials {
sh 'make wc_init'
}
}
runStage('build') {
sh 'make wc_build'
}
// Java
runStage('Execute build container') {
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} wc_java.deploy'
} else {
sh 'make SETTINGS_XML=${SETTINGS_XML} wc_java.compile'
}
}
}
}
}

79
Makefile Normal file
View File

@ -0,0 +1,79 @@
SUBMODULES = build_utils
SUBTARGETS = $(patsubst %,%/.git,$(SUBMODULES))
UTILS_PATH := build_utils
TEMPLATES_PATH := .
# Name of the service
SERVICE_NAME := swag-claim-management
# Service image default tag
SERVICE_IMAGE_TAG ?= $(shell git rev-parse HEAD)
# The tag for service image to be pushed with
SERVICE_IMAGE_PUSH_TAG ?= $(SERVICE_IMAGE_TAG)
BUILD_IMAGE_TAG := f3732d29a5e622aabf80542b5138b3631a726adb
CALL_ANYWHERE := \
all submodules init build java.compile java.deploy
CALL_W_CONTAINER := $(CALL_ANYWHERE)
all: compile
-include $(UTILS_PATH)/make_lib/utils_image.mk
-include $(UTILS_PATH)/make_lib/utils_container.mk
.PHONY: $(CALL_W_CONTAINER)
$(SUBTARGETS): %/.git: %
git submodule update --init $<
touch $@
submodules: $(SUBTARGETS)
# NPM
init:
npm install
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.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)

View File

@ -1 +1,25 @@
# swag-claim-management
## Working on specification
### Install
1. Install [Node JS](https://nodejs.org/)
2. Clone repo and `cd`
- Run `npm install`
### Usage
1. Run `npm start`
2. Checkout console output to see where local server is started. You can use all [links](#links) (except `preview`) by replacing https://git@github.com:antonlva.github.io/rbkmoney-api-docs.git/ with url from the message: `Server started <url>`
3. Make changes using your favorite editor or `swagger-editor` (look for URL in console output)
4. All changes are immediately propagated to your local server, moreover all documentation pages will be automagically refreshed in a browser after each change
**TIP:** you can open `swagger-editor`, documentation and `swagger-ui` in parallel
5. Once you finish with the changes you can run tests using: `npm test`
6. Share you changes with the rest of the world by pushing to GitHub :smile:
Для генерации клиентского java-кода используйте команду
`npm run-script build && swagger-codegen generate -i web_deploy/swagger.json -l java -o ./java --api-package "com.rbkmoney.swag.claim_management.client" --artifact-id "swag-claim-management" --artifact-version "1.1.0" --group-id "com.rbkmoney" --model-package "com.rbkmoney.swag.claim_management.model" --library resttemplate --additional-properties dateLibrary=java8`
Для генерации серверного java-кода используйте команду
`mvn package`

1
build_utils Submodule

@ -0,0 +1 @@
Subproject commit ea4aa042f482551d624fd49a570d28488f479e93

51
gulpfile.js Normal file
View File

@ -0,0 +1,51 @@
var gulp = require('gulp');
var util = require('gulp-util');
var gulpConnect = require('gulp-connect');
var connect = require('connect');
var cors = require('cors');
var path = require('path');
var exec = require('child_process').exec;
var portfinder = require('portfinder');
var swaggerRepo = require('swagger-repo');
var DIST_DIR = 'web_deploy';
var SPEC_DIR = 'spec';
gulp.task('serve', ['build', 'watch', 'edit'], function() {
portfinder.getPort({ port: 3000 }, function(err, port) {
gulpConnect.server({
root: [DIST_DIR],
livereload: true,
port: port,
middleware: function(gulpConnect, opt) {
return [cors()];
}
});
});
});
gulp.task('edit', function() {
portfinder.getPort({ port: 5000 }, function(err, port) {
var app = connect();
app.use(swaggerRepo.swaggerEditorMiddleware());
app.listen(port);
util.log(
util.colors.green('swagger-editor started http://localhost:' + port)
);
});
});
gulp.task('build', function(cb) {
exec('npm run build', function(err, stdout, stderr) {
console.log(stderr);
cb(err);
});
});
gulp.task('reload', ['build'], function() {
gulp.src(DIST_DIR).pipe(gulpConnect.reload());
});
gulp.task('watch', function() {
gulp.watch([`${SPEC_DIR}/**/*`, 'web/**/*'], ['reload']);
});

29
package.json Normal file
View File

@ -0,0 +1,29 @@
{
"name": "swag-claim-management",
"version": "0.1.0",
"private": true,
"license": "UNLICENSED",
"scripts": {
"start": "gulp serve",
"build": "node ./scripts/build.js",
"swagger": "swagger-repo",
"test": "swagger-repo validate",
"prettier": "prettier \"**/*.{js,ts,md,json,prettierrc,html}\"",
"check": "npm run prettier -- --list-different",
"fix": "npm run prettier -- --write"
},
"devDependencies": {
"connect": "^3.4.1",
"cors": "^2.7.1",
"deploy-to-gh-pages": "^1.1.0",
"gulp": "^3.9.1",
"gulp-connect": "^4.2.0",
"gulp-util": "^3.0.7",
"json-merge-patch": "^0.2.3",
"portfinder": "^1.0.3",
"prettier": "^1.18.2",
"shelljs": "^0.7.0",
"swagger-repo": "^1.0.0",
"swagger-ui": "^2.1.4"
}
}

165
pom.xml Normal file
View File

@ -0,0 +1,165 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.rbkmoney</groupId>
<artifactId>parent</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>claim-management</artifactId>
<version>SNAPSHOT</version>
<packaging>jar</packaging>
<name>claim-management</name>
<description>Generates jar artifact containing compiled swagger classes based on generated swagger yaml files
</description>
<properties>
<default.package>com.rbkmoney.swag.claim_management</default.package>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<swagger-annotations-version>1.5.21</swagger-annotations-version>
<jodatime-version>2.7</jodatime-version>
<maven-plugin-version>1.0.0</maven-plugin-version>
<java.version>1.8</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<jetty-version>9.2.15.v20160210</jetty-version>
<slf4j-version>1.7.21</slf4j-version>
<junit-version>4.12</junit-version>
<servlet-api-version>2.5</servlet-api-version>
<springfox-version>2.7.0</springfox-version>
<jackson-version>2.8.9</jackson-version>
<jackson-threetenbp-version>2.6.4</jackson-threetenbp-version>
<spring-version>5.1.3.RELEASE</spring-version>
</properties>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j-version}</version>
<scope>provided</scope>
</dependency>
<!--Spring dependencies -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring-version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring-version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring-version}</version>
<scope>provided</scope>
</dependency>
<!--SpringFox dependencies-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${springfox-version}</version>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</exclusion>
<exclusion>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${springfox-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson-version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>${servlet-api-version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<!-- Bean Validation API support -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>io.swagger</groupId>
<artifactId>swagger-codegen-maven-plugin</artifactId>
<version>2.3.1</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>web_deploy/swagger.yaml</inputSpec>
<configOptions>
<dateLibrary>java8</dateLibrary>
</configOptions>
<language>spring</language>
<library>spring-mvc</library>
<apiPackage>${default.package}.api</apiPackage>
<modelPackage>${default.package}.model</modelPackage>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

28
scripts/build.js Executable file
View File

@ -0,0 +1,28 @@
#!/usr/bin/env node
'use strict';
var Path = require('path');
var TARGET_DIR = 'web_deploy';
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 swagger bundle -- -o ' + TARGET_DIR + '/swagger.json');
exec('npm run swagger bundle -- --yaml -o ' + TARGET_DIR + '/swagger.yaml');
var SWAGGER_UI_DIST = Path.dirname(require.resolve('swagger-ui'));
rm('-rf', TARGET_DIR + '/swagger-ui/');
cp('-R', SWAGGER_UI_DIST, TARGET_DIR + '/swagger-ui/');
sed(
'-i',
'https://developer.rbk.money/api/swagger.json',
'../swagger.json',
TARGET_DIR + '/swagger-ui/index.html'
);

View File

@ -0,0 +1,32 @@
var jpointer = require('json-pointer');
var mergePatch = require('json-merge-patch');
module.exports = {
pathExpression: '$..["x-merge-properties"]',
init: function(swagger) {
console.log('* x-merge-properties plugin');
},
process: function(parent, name, jsonpath, swagger) {
var value = parent[name];
if (!Array.isArray(value)) {
throw Error('x-merge-properties argument should be array at ' + jsonpath);
}
let required = [];
let properties = {};
value.forEach(function(obj) {
if (obj.$ref && typeof obj.$ref === 'string') {
obj = jpointer.get(swagger, obj.$ref.substring(1));
}
if (typeof obj !== 'object')
throw Error("Can't merge non-object values at " + jsonpath);
required = required.concat(obj.required || []);
properties = mergePatch.apply(properties, obj.properties || {});
});
delete parent[name];
parent.required = required;
parent.properties = properties;
},
finish: function(swagger) {
// TODO: cleanup unused $refs
}
};

View File

@ -0,0 +1,29 @@
var jpointer = require('json-pointer');
var mergePatch = require('json-merge-patch');
module.exports = {
pathExpression: '$..["x-rebillyMerge"]',
init: function(swagger) {
console.log('* x-rebillyMerge plugin');
},
process: function(parent, name, jsonpath, swagger) {
var value = parent[name];
if (!Array.isArray(value)) {
throw Error('x-rebillyMerge argument should be array at ' + jsonpath);
}
let res = null;
value.forEach(function(obj) {
if (typeof obj !== 'object')
throw Error("Can't merge non-object values at " + jsonpath);
if (obj.$ref && typeof obj.$ref === 'string') {
obj = jpointer.get(swagger, obj.$ref.substring(1));
}
res = mergePatch.apply(res, obj);
});
delete parent[name];
Object.assign(parent, res);
},
finish: function(swagger) {
// TODO: cleanup unused $refs
}
};

View File

@ -0,0 +1 @@
type: object

View File

@ -0,0 +1,7 @@
type: object
required:
- id
properties:
id:
type: integer
format: int32

View File

@ -0,0 +1,26 @@
type: object
allOf:
- $ref: '#/definitions/PaymentTool'
- type: object
description: Банковская карта
required:
- cardNumber
- expDate
properties:
cardNumber:
description: Номер банковской карты
type: string
pattern: '^\d{12,19}$'
expDate:
description: Срок действия банковской карты
type: string
pattern: '^\d{2}\/(\d{2}|\d{4})$'
cvv:
description: Код верификации
type: string
pattern: '^\d{3,4}$'
cardHolder:
description: Имя держателя карты
type: string
minLength: 1
maxLength: 100

View File

@ -0,0 +1,7 @@
type: object
required:
- id
properties:
id:
type: integer
format: int32

View File

@ -0,0 +1,34 @@
description: Заявка
type: object
discriminator: status
required:
- id
- status
- changeset
- revision
- createdAt
properties:
id:
description: Идентификатор заявки
type: integer
format: int64
status:
description: Статус заявки
type: string
changeset:
$ref: '#/definitions/ClaimChangeset'
revision:
description: Версия заявки
type: integer
format: int32
createdAt:
description: Дата создания
type: string
format: date-time
updatedAt:
description: Дата изменения
type: string
format: date-time
metadata:
description: Связанные с заявкой метаданные
type: object

View File

@ -0,0 +1,3 @@
type: object
allOf:
- $ref: '#/definitions/Claim'

View File

@ -0,0 +1,4 @@
description: Набор изменений
type: array
items:
$ref: '#/definitions/ModificationUnit'

View File

@ -0,0 +1,11 @@
type: object
allOf:
- $ref: '#/definitions/Claim'
- type: object
required:
- reason
properties:
reason:
description: Причина отклонения заявки
type: string
maxLength: 1000

View File

@ -0,0 +1,15 @@
type: object
allOf:
- $ref: '#/definitions/Modification'
- type: object
discriminator: claimModificationType
required:
- claimModificationType
properties:
claimModificationType:
type: string
enum:
- DocumentModificationUnit
- FileModificationUnit
- CommentModificationUnit
- StatusModificationUnit

View File

@ -0,0 +1,3 @@
type: object
allOf:
- $ref: '#/definitions/Claim'

View File

@ -0,0 +1,3 @@
type: object
allOf:
- $ref: '#/definitions/Claim'

View File

@ -0,0 +1,3 @@
type: object
allOf:
- $ref: '#/definitions/Claim'

View File

@ -0,0 +1,11 @@
type: object
allOf:
- $ref: '#/definitions/Claim'
- type: object
required:
- reason
properties:
reason:
description: Причина отзыва заявки
type: string
maxLength: 1000

View File

@ -0,0 +1,3 @@
type: object
allOf:
- $ref: '#/definitions/CommentModification'

View File

@ -0,0 +1,10 @@
description: Единичное изменение комментария
type: object
discriminator: commentModificationType
required:
- commentModificationType
properties:
commentModificationType:
type: string
enum:
- CommentCreated

View File

@ -0,0 +1,15 @@
type: object
allOf:
- $ref: '#/definitions/ClaimModification'
- type: object
required:
- id
- modification
properties:
id:
description: Идентификатор комментария
type: string
maxLength: 40
minLength: 1
modification:
$ref: '#/definitions/CommentModification'

View File

@ -0,0 +1,5 @@
description: |
Токен, сигнализирующий о том, что в ответе передана только часть данных.
Для получения следующей части нужно повторно обратиться к сервису, указав тот-же набор условий и полученый токен.
Если токена нет, получена последняя часть данных.
type: string

View File

@ -0,0 +1,6 @@
type: object
required:
- creation
properties:
creation:
$ref: '#/definitions/ContractAdjustmentParams'

View File

@ -0,0 +1,9 @@
type: object
required:
- adjustmentID
- modification
properties:
adjustmentID:
type: string
modification:
$ref: '#/definitions/ContractAdjustmentModification'

View File

@ -0,0 +1,6 @@
type: object
required:
- template
properties:
template:
$ref: '#/definitions/ContractTemplateRef'

View File

@ -0,0 +1,15 @@
type: object
discriminator: contractModificationType
required:
- contractModificationType
properties:
contractModificationType:
type: string
enum:
- ContractParams
- ContractTermination
- ContractAdjustmentModificationUnit
- PayoutToolModificationUnit
- LegalAgreement
- ReportPreferences
- ContractorID

View File

@ -0,0 +1,15 @@
type: object
allOf:
- $ref: '#/definitions/PartyModification'
- type: object
required:
- id
- modification
properties:
id:
description: Идентификатор договора
type: string
maxLength: 40
minLength: 1
modification:
$ref: '#/definitions/ContractModification'

View File

@ -0,0 +1,11 @@
type: object
allOf:
- $ref: '#/definitions/ContractModification'
- type: object
properties:
contractorID:
type: string
template:
$ref: '#/definitions/ContractTemplateRef'
paymentInstitution:
$ref: '#/definitions/PaymentInstitutionRef'

View File

@ -0,0 +1,7 @@
type: object
required:
- id
properties:
id:
type: integer
format: int32

View File

@ -0,0 +1,7 @@
type: object
allOf:
- $ref: '#/definitions/ContractModification'
- type: object
properties:
reason:
type: string

View File

@ -0,0 +1,14 @@
type: object
allOf:
- $ref: '#/definitions/ContractorModification'
- type: object
discriminator: contractorType
required:
- contractorType
properties:
contractorType:
type: string
enum:
- LegalEntity
# - RegisteredUser
# - PrivateEntity

View File

@ -0,0 +1 @@
type: string

View File

@ -0,0 +1,8 @@
type: integer
enum:
- value: 100
name: none
- value: 200
name: partial
- value: 300
name: full

View File

@ -0,0 +1,9 @@
type: object
required:
- identityDocuments
properties:
identityDocuments:
type: array
items:
type: string
format: binary

View File

@ -0,0 +1,11 @@
type: object
discriminator: contractorModificationType
required:
- contractorModificationType
properties:
contractorModificationType:
type: string
enum:
- Contractor
# - ContractorIdentificationLevel
# - ContractorIdentityDocumentsModification

View File

@ -0,0 +1,13 @@
type: object
allOf:
- $ref: '#/definitions/PartyModification'
- type: object
required:
- id
- modification
properties:
id:
description: Идентификатор
type: string
modification:
$ref: '#/definitions/ContractorModification'

View File

@ -0,0 +1,6 @@
type: object
required:
- symbolicCode
properties:
symbolicCode:
type: string

View File

@ -0,0 +1,15 @@
type: object
required:
- code
- message
properties:
code:
description: |
[Код ошибки](#tag/Error-Codes)
type: string
enum:
- invalidRequest
- invalidDeadline
message:
description: Человекочитаемое описание ошибки
type: string

View File

@ -0,0 +1,3 @@
type: object
allOf:
- $ref: '#/definitions/DocumentModification'

View File

@ -0,0 +1,9 @@
type: object
discriminator: documentModificationType
required:
- documentModificationType
properties:
documentModificationType:
type: string
enum:
- DocumentCreated

View File

@ -0,0 +1,15 @@
type: object
allOf:
- $ref: '#/definitions/ClaimModification'
- type: object
required:
- id
- modification
properties:
id:
description: Идентификатор документа
type: string
maxLength: 40
minLength: 1
modification:
$ref: '#/definitions/DocumentModification'

View File

@ -0,0 +1,3 @@
type: object
allOf:
- $ref: '#/definitions/FileModification'

View File

@ -0,0 +1,9 @@
type: object
discriminator: fileModificationType
required:
- fileModificationType
properties:
fileModificationType:
type: string
enum:
- FileCreated

View File

@ -0,0 +1,15 @@
type: object
allOf:
- $ref: '#/definitions/ClaimModification'
- type: object
required:
- id
- modification
properties:
id:
description: Идентификатор файла
type: string
maxLength: 40
minLength: 1
modification:
$ref: '#/definitions/FileModification'

View File

@ -0,0 +1,6 @@
type: object
required:
- message
properties:
message:
type: string

View File

@ -0,0 +1,14 @@
description: Невалидный набор изменений
type: object
required:
- reason
- invalid_changesets
properties:
reason:
description: Причина
type: string
invalid_changesets:
description: Список невалидных наборов изменений
type: array
items:
$ref: '#/definitions/ClaimChangeset'

View File

@ -0,0 +1,12 @@
description: Юридическое соглашение
type: object
required:
- signedAt
- legalAgreementID
properties:
signedAt:
type: string
legalAgreementID:
type: string
validUntil:
type: string

View File

@ -0,0 +1,13 @@
type: object
allOf:
- $ref: '#/definitions/Contractor'
- type: object
discriminator: legalEntityType
required:
- legalEntityType
properties:
legalEntityType:
type: string
enum:
- RussianLegalEntity
# - InternationalLegalEntity

View File

@ -0,0 +1,11 @@
description: Единичное изменение данных участника
type: object
discriminator: modificationType
required:
- modificationType
properties:
modificationType:
type: string
enum:
- PartyModification
- ClaimModification

View File

@ -0,0 +1,17 @@
description: ModificationUnit
type: object
required:
- modificationID
- createdAt
- modification
properties:
modificationID:
description: Идентификатор изменения
type: integer
format: int64
createdAt:
description: Дата и время создания
type: string
format: date-time
modification:
$ref: '#/definitions/Modification'

View File

@ -0,0 +1,14 @@
type: object
allOf:
- $ref: '#/definitions/Modification'
- type: object
discriminator: partyModificationType
required:
- partyModificationType
properties:
partyModificationType:
type: string
enum:
- ContractorModificationUnit
- ContractModificationUnit
- ShopModificationUnit

View File

@ -0,0 +1,7 @@
type: object
required:
- id
properties:
id:
type: integer
format: int32

View File

@ -0,0 +1,10 @@
type: object
discriminator: paymentToolType
properties:
paymentToolType:
description: Тип платежного средства
type: string
enum:
- CardData
required:
- paymentToolType

View File

@ -0,0 +1,11 @@
type: object
discriminator: payoutToolType
required:
- payoutToolType
properties:
payoutToolType:
type: string
enum:
- RussianBankAccount
# - InternationalBankAccount
- WalletInfo

View File

@ -0,0 +1,4 @@
type: object
properties:
creation:
$ref: '#/definitions/PayoutToolParams'

View File

@ -0,0 +1,9 @@
type: object
required:
- payoutToolID
- modification
properties:
payoutToolID:
type: string
modification:
$ref: '#/definitions/PayoutToolModification'

View File

@ -0,0 +1,9 @@
type: object
required:
- currency
- toolInfo
properties:
currency:
$ref: '#/definitions/CurrencyRef'
toolInfo:
$ref: '#/definitions/PayoutToolInfo'

View File

@ -0,0 +1 @@
type: string

View File

@ -0,0 +1,4 @@
type: object
properties:
serviceAcceptanceActPreferences:
$ref: '#/definitions/ServiceAcceptanceActPreferences'

View File

@ -0,0 +1,15 @@
type: object
required:
- position
- fullName
- document
properties:
position:
description: Наименование должности представителя
type: string
fullName:
description: ФИО представителя
type: string
document:
description: Документ, на основании которого действует представитель
$ref: '#/definitions/RepresentativeDocument'

View File

@ -0,0 +1,10 @@
type: object
discriminator: documentType
required:
- documentType
properties:
documentType:
type: string
enum:
- ArticlesOfAssociation
- LegalAgreement

View File

@ -0,0 +1,16 @@
description: Банковский счёт
type: object
required:
- account
- bankName
- bankPostAccount
- bankBik
properties:
account:
type: string
bankName:
type: string
bankPostAccount:
type: string
bankBik:
type: string

View File

@ -0,0 +1,43 @@
description: Юридическое лицо-резидент РФ
type: object
allOf:
- $ref: '#/definitions/LegalEntity'
- type: object
required:
- registeredName
- registeredNumber
- inn
- actualAddress
- postAddress
- epresentativePosition
- representativeFullName
- representativeDocument
- russianBankAccount
properties:
registeredName:
description: Наименование
type: string
registeredNumber:
description: ОГРН
type: string
inn:
description: ИНН/КПП
type: string
actualAddress:
description: Адрес места нахождения
type: string
postAddress:
description: Адрес для отправки корреспонденции (почтовый)
type: string
epresentativePosition:
description: Наименование должности ЕИО/представителя
type: string
representativeFullName:
description: ФИО ЕИО/представителя
type: string
representativeDocument:
description: Наименование документа, на основании которого действует ЕИО/представитель
type: string
russianBankAccount:
description: Реквизиты юр.лица
$ref: '#/definitions/RussianBankAccount'

View File

@ -0,0 +1,4 @@
type: object
properties:
schedule:
$ref: '#/definitions/BusinessScheduleRef'

View File

@ -0,0 +1,9 @@
type: object
required:
- schedule
- signer
properties:
schedule:
$ref: '#/definitions/BusinessScheduleRef'
signer:
$ref: '#/definitions/Representative'

View File

@ -0,0 +1,6 @@
type: object
required:
- currency
properties:
currency:
$ref: '#/definitions/CurrencyRef'

View File

@ -0,0 +1,9 @@
type: object
required:
- contractID
- payoutToolID
properties:
contractID:
type: string
payoutToolID:
type: string

View File

@ -0,0 +1,12 @@
type: object
required:
- name
properties:
name:
description: Название магазина
type: string
maxLength: 100
description:
description: Краткое описание
type: string
maxLength: 1000

View File

@ -0,0 +1,9 @@
description: Местоположение магазина, по которому можно его найти
type: object
discriminator: locationType
required:
- locationType
properties:
locationType:
description: Тип местоположения
type: string

View File

@ -0,0 +1,18 @@
type: object
properties:
creation:
$ref: '#/definitions/ShopParams'
categoryModification:
$ref: '#/definitions/CategoryRef'
detailsModification:
$ref: '#/definitions/ShopDetails'
contractModification:
$ref: '#/definitions/ShopContractModification'
payoutToolModification:
type: string
locationModification:
$ref: '#/definitions/ShopLocation'
shopAccountCreation:
$ref: '#/definitions/ShopAccountParams'
payoutScheduleModification:
$ref: '#/definitions/ScheduleModification'

View File

@ -0,0 +1,14 @@
type: object
allOf:
- $ref: '#/definitions/PartyModification'
required:
- id
- modification
properties:
id:
description: Идентификатор магазина
type: string
maxLength: 40
minLength: 1
modification:
$ref: '#/definitions/ShopModification'

View File

@ -0,0 +1,19 @@
description: Параметры магазина
type: object
required:
- category
- location
- details
- contractID
- payoutToolID
properties:
category:
$ref: '#/definitions/CategoryRef'
location:
$ref: '#/definitions/ShopLocation'
details:
$ref: '#/definitions/ShopDetails'
contractID:
type: string
payoutToolID:
type: string

View File

@ -0,0 +1,3 @@
type: object
allOf:
- $ref: '#/definitions/StatusModification'

View File

@ -0,0 +1,10 @@
description: Единичное изменение статуса заявки
type: object
discriminator: statusModificationType
required:
- statusModificationType
properties:
statusModificationType:
type: string
enum:
- StatusChanged

View File

@ -0,0 +1,20 @@
type: object
allOf:
- $ref: '#/definitions/ClaimModification'
- type: object
required:
- status
- modification
properties:
status:
description: Статус заявки
type: string
enum:
- pending
- review
- pendingAcceptance
- accepted
- denied
- revoked
modification:
$ref: '#/definitions/StatusModification'

View File

@ -0,0 +1,6 @@
type: object
required:
- walletID
properties:
walletID:
type: string

View File

@ -0,0 +1,84 @@
get:
description: Поиск заявок участника
operationId: searchClaims
tags:
- Claims
parameters:
- $ref: '#/parameters/requestID'
- $ref: '#/parameters/deadline'
- $ref: '#/parameters/limit'
- $ref: '#/parameters/continuationToken'
- name: claimStatuses
in: query
description: Статус заявки для поиска
required: false
type: array
items:
type: string
enum:
- pending
- review
- pendingAcceptance
- accepted
- denied
- revoked
responses:
'200':
description: Найденные заявки
schema:
type: object
properties:
continuationToken:
$ref: '#/definitions/ContinuationToken'
result:
type: array
items:
$ref: '#/definitions/Claim'
'400':
$ref: '#/responses/DefaultLogicError'
'401':
$ref: '#/responses/Unauthorized'
post:
description: |
Создать новую заявку с заданным набором изменений и отправить её на
премодерацию.
operationId: createClaim
tags:
- Claims
parameters:
- $ref: '#/parameters/requestID'
- $ref: '#/parameters/deadline'
- name: claimChangeset
in: body
required: true
schema:
$ref: '#/definitions/ClaimChangeset'
responses:
'201':
description: Заявка создана
schema:
$ref: '#/definitions/Claim'
'400':
description: Ошибочные данные в заявке
schema:
type: object
required:
- code
- message
properties:
code:
description: |
[Код ошибки](#tag/Error-Codes)
type: string
enum:
- changesetConflict
- invalidPartyStatus
- invalidChangeset
- invalidRequest
- invalidDeadline
message:
description: Человекочитаемое описание ошибки
type: string
example: Changeset conflict
'401':
$ref: '#/responses/Unauthorized'

View File

@ -0,0 +1,21 @@
get:
description: |
Получить заявку по её идентификатору.
operationId: getClaimByID
tags:
- Claims
parameters:
- $ref: '#/parameters/requestID'
- $ref: '#/parameters/deadline'
- $ref: '#/parameters/claimID'
responses:
'200':
description: Данные заявки
schema:
$ref: '#/definitions/Claim'
'404':
$ref: '#/responses/NotFound'
'401':
$ref: '#/responses/Unauthorized'
'400':
$ref: '#/responses/DefaultLogicError'

View File

@ -0,0 +1,43 @@
put:
description: Отозвать заявку по её идентификатору.
operationId: revokeClaimByID
tags:
- Claims
parameters:
- $ref: '#/parameters/requestID'
- $ref: '#/parameters/deadline'
- $ref: '#/parameters/claimID'
- $ref: '#/parameters/claimRevision'
- name: reason
in: body
schema:
$ref: '#/definitions/Reason'
responses:
'204':
description: Заявка отозвана
'404':
$ref: '#/responses/NotFound'
'401':
$ref: '#/responses/Unauthorized'
'400':
description: Ошибка отзыва заявки
schema:
type: object
required:
- code
- message
properties:
code:
description: |
[Код ошибки](#tag/Error-Codes)
type: string
enum:
- invalidClaimStatus
- invalidClaimRevision
- invalidPartyStatus
- invalidRequest
- invalidDeadline
message:
description: Человекочитаемое описание ошибки
type: string
example: Invalid claim status

View File

@ -0,0 +1,43 @@
put:
description: Обновить заявку по её идентификатору.
operationId: updateClaimByID
tags:
- Claims
parameters:
- $ref: '#/parameters/requestID'
- $ref: '#/parameters/deadline'
- $ref: '#/parameters/claimID'
- $ref: '#/parameters/claimRevision'
- name: changeset
in: body
schema:
$ref: '#/definitions/Modification'
responses:
'201':
description: Заявка обновлена
'404':
$ref: '#/responses/NotFound'
'401':
$ref: '#/responses/Unauthorized'
'400':
description: Ошибка при изменении заявки
schema:
type: object
required:
- code
- message
properties:
code:
description: |
[Код ошибки](#tag/Error-Codes)
type: string
enum:
- invalidClaimStatus
- invalidClaimRevision
- invalidPartyStatus
- invalidRequest
- invalidDeadline
message:
description: Человекочитаемое описание ошибки
type: string
example: Invalid claim status

110
spec/swagger.yaml Normal file
View File

@ -0,0 +1,110 @@
swagger: '2.0'
info:
version: 0.1.0
title: RBKmoney Claim Management API
description: |
RBKmoney Claim Management API служит для управления секретных вызовов.
termsOfService: 'http://rbk.money/'
contact:
name: RBKmoney support team
email: support@rbk.money
url: 'https://rbk.money'
host: api.rbk.money
basePath: /claim-management/v0
schemes:
- https
consumes:
- application/json; charset=utf-8
produces:
- application/json; charset=utf-8
securityDefinitions:
bearer:
type: apiKey
name: Authorization
in: header
description: >
Для аутентификации вызовов мы используем [JWT](https://jwt.io).
Cоответствующий ключ передается в заголовке.
```shell
Authorization: Bearer {TOKENIZATION|PRIVATE_JWT}
```
security:
- bearer: []
responses:
NotFound:
description: Заданный ресурс не найден
schema:
$ref: '#/definitions/GeneralError'
Unauthorized:
description: Ошибка авторизации
DefaultLogicError:
description: Неверные данные
schema:
$ref: '#/definitions/DefaultLogicError'
parameters:
requestID:
name: X-Request-ID
in: header
description: Уникальный идентификатор запроса к системе
required: true
type: string
maxLength: 32
minLength: 1
claimID:
name: claimID
in: path
description: Идентификатор заявки
required: true
type: integer
format: int64
claimRevision:
name: claimRevision
in: query
description: Версия заявки
required: true
type: integer
format: int32
limit:
name: limit
in: query
description: Лимит выборки
required: true
type: integer
format: int32
minimum: 1
maximum: 1000
deadline:
name: X-Request-Deadline
in: header
description: Максимальное время обработки запроса
required: false
type: string
maxLength: 40
minLength: 1
continuationToken:
name: continuationToken
in: query
required: false
description: >
Токен, сигнализирующий о том, что в ответе передана только часть данных.
Для получения следующей части нужно повторно обратиться к сервису, указав
тот-же набор условий и полученый токен.
Если токена нет, получена последняя часть данных.
type: string
tags:
- name: Claims
x-displayName: Заявки
description: >
Некоторая область данных может быть изменена только после премодерации на
стороне платформы. Например, создание и активация новых магазинов,
изменение финансовых данных вашего участника и т.п. требуют ручной
проверки сотрудниками RBKmoney. Попытка изменить такие данные приводит к
автоматическому созданию заявки на изменение данных. До тех пор, пока
заявка не одобрена, вы можете добавлять изменения. После одобрения они
будут применены к набору данных. В случае отказа по заявке данные
останутся в неизменном состоянии. Ближайшим аналогом заявок можно
представить Pull Request в распределенных системах контроля версий.

47
web/index.html Normal file
View File

@ -0,0 +1,47 @@
<!DOCTYPE html>
<html>
<head>
<title>RBKmoney Claim Management API</title>
<!-- needed for adaptive design -->
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link
href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700"
rel="stylesheet"
/>
<script src="https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js"></script>
<!--
ReDoc doesn't change outer page styles
-->
<style>
body {
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div id="redoc"></div>
<script type="text/javascript">
// Since we serve three different specs from a single domain we hack up a
// simple way to redirect user to one or another
var spec = window.location.search.substring(1);
if (spec.length == 0) {
spec = './swagger.json';
}
Redoc.init(
spec,
{
theme: {
breakpoints: {
// 3-panel view fix
medium: '75rem'
}
}
},
document.getElementById('redoc')
);
</script>
</body>
</html>

34
wercker.yml Normal file
View File

@ -0,0 +1,34 @@
box: node:7
build:
steps:
- npm-install
- npm-test
- script:
name: build docsite
code: npm run build -- ${WERCKER_OUTPUT_DIR}
release-v:
steps:
- script:
name: prepare release artifacts for branch v1, v2, etc.
code: mkdir -p out && cp ./web_deploy/swagger.{yaml,json} out/
- lordlothar99/git-push:
gh_oauth: ${GITHUB_API_TOKEN}
branch: release/${WERCKER_GIT_BRANCH}
basedir: out
message: Release ${WERCKER_GIT_OWNER}/${WERCKER_GIT_REPOSITORY}@${WERCKER_GIT_COMMIT}
after-steps:
- slack-notifier:
url: ${SLACK_WEBHOOK_URL}
username: "wercker"
# deploy:
# steps:
# - lukevivier/gh-pages:
# repo: rbkmoney/claim-management-ghpages
# token: ${GITHUB_API_TOKEN}
# after-steps:
# - slack-notifier:
# url: ${SLACK_WEBHOOK_URL}
# username: "wercker"