IMP-299L impl proto (#2)

* IMP-299L impl proto

* IMP-299: impl proto

* IMP-299: impl proto

* IMP-299: impl proto

* IMP-299: impl proto

* IMP-299: feedback edits
This commit is contained in:
Anatolii Karlov 2024-08-12 21:35:55 +07:00 committed by GitHub
parent 4ad5339d77
commit d5286d5700
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 9021 additions and 1 deletions

10
.github/workflows/build-java.yaml vendored Normal file
View File

@ -0,0 +1,10 @@
name: Build java libraries
on:
pull_request:
branches:
- '*'
jobs:
build:
uses: valitydev/java-workflow/.github/workflows/maven-swag-build.yml@v3

19
.github/workflows/deploy-java.yaml vendored Normal file
View File

@ -0,0 +1,19 @@
name: Maven Deploy Artifact
on:
push:
branches:
- 'master'
- 'main'
- 'epic/**'
jobs:
deploy:
uses: valitydev/java-workflow/.github/workflows/maven-swag-deploy.yml@v3
secrets:
server-username: ${{ secrets.OSSRH_USERNAME }}
server-password: ${{ secrets.OSSRH_TOKEN }}
deploy-secret-key: ${{ secrets.OSSRH_GPG_SECRET_KEY }}
deploy-secret-key-password: ${{ secrets.OSSRH_GPG_SECRET_KEY_PASSWORD }}
github-token: ${{ secrets.GITHUB_TOKEN }}
mm-webhook-url: ${{ secrets.MATTERMOST_WEBHOOK_URL }}

31
.github/workflows/gh-pages.yaml vendored Normal file
View File

@ -0,0 +1,31 @@
name: gh-pages
on:
push:
branches: [ master ]
env:
NODEJS_VERSION: '16'
jobs:
publish:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
with:
submodules: recursive
- name: Setup Node.js
uses: actions/setup-node@v2
with:
node-version: ${{ env.NODEJS_VERSION }}
cache: npm
- run: npm install
- name: Patch specification
run: npm run build
- name: Bundle ReDoc site
run: npm run redoc
- name: Publish ReDoc on Github Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./dist

69
.gitignore vendored Normal file
View File

@ -0,0 +1,69 @@
# 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/
target
# User-specific stuff:
.idea/
.idea/workspace.xml
.idea/tasks.xml
.idea/dictionaries
.idea/vcs.xml
.idea/jsLibraryMappings.xml
*.iml
# 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
# Frontend
/lib
redoc-static.html
#Mac OS
.DS_Store

16
.redocly.yaml Normal file
View File

@ -0,0 +1,16 @@
# See https://docs.redoc.ly/cli/configuration/ for more information.
apis:
main:
root: 'openapi/openapi.yaml'
lint:
extends:
- recommended
plugins:
- './plugins/local.js'
preprocessors:
local/merge-schemas: on
features.openapi:
showConsole: true
pagination: section
layout: three-panel
routingStrategy: browser

View File

@ -1 +1,10 @@
# swag-disputes
## Local usage
Use commands in order:
```shell
npm install
npm start
```

265
openapi/openapi.yaml Normal file
View File

@ -0,0 +1,265 @@
openapi: 3.0.3
info:
title: Vality Disputes
version: 0.1.0
description: |
## Описание
Vality Disputes предоставляет операции для заявок в системе для открытия спора и предназначен для мерчантов.
## Детали взаимодействия
При любом обращении к API в заголовке `X-Request-ID` соответствующего запроса необходимо передать его уникальный идентификатор:
```
X-Request-ID: 37d735d4-0f42-4f05-89fa-eaa478fb5aa9
```
### Тип содержимого и кодировка
Система принимает данные либо в формате JSON либо multipart/form-data и возвращает данные в формате JSON и кодировке UTF-8:
```
Content-Type: application/json; charset=utf-8
Content-Type: multipart/form-data
```
termsOfService: https://vality.dev
contact:
name: Команда техподдержки
email: support@vality.dev
servers:
- url: https://api.vality.dev/disputes
security:
- bearerAuth: [ ]
tags:
- name: disputes
x-displayName: Disputes
description: |
Диспуты - это открытые споры по платежам.
paths:
/create:
post:
operationId: create
summary: Создать диспут
tags:
- disputes
parameters:
- $ref: '#/components/parameters/requestID'
requestBody:
description: Параметры диспута
required: true
content:
multipart/form-data:
schema:
type: object
required:
- invoiceId
- paymentId
- attachments
properties:
invoiceId:
$ref: '#/components/schemas/InvoiceID'
paymentId:
$ref: '#/components/schemas/PaymentID'
attachments:
type: array
items:
type: object
required:
- attachment
properties:
attachment:
type: string
format: binary
description: Загружаемый файл
name:
type: string
description: Имя файла
mimeType:
type: string
description: Тип файла
amount:
$ref: '#/components/schemas/Amount'
reason:
type: string
description: Причина открытия диспута
responses:
'200':
description: Диспут создан
content:
application/json:
schema:
type: object
required:
- disputeId
properties:
disputeId:
$ref: '#/components/schemas/DisputeId'
'400':
description: Ошибка в формате запроса
$ref: '#/components/responses/DefaultLogicError'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
'422':
description: Метод не поддерживается в рамках текущей интеграции
$ref: '#/components/responses/NotSupportedByProvider'
/status:
get:
operationId: status
summary: Получить статус диспута
tags:
- disputes
parameters:
- $ref: '#/components/parameters/requestID'
- name: invoiceId
description: Уникальный идентификатор инвоиса
in: query
required: true
schema:
$ref: '#/components/schemas/InvoiceID'
- name: paymentId
description: Уникальный идентификатор платежа
in: query
required: true
schema:
$ref: '#/components/schemas/PaymentID'
- name: disputeId
description: Идентификатор диспута
in: query
required: true
schema:
$ref: '#/components/schemas/DisputeId'
responses:
'200':
description: Получен статус диспута
content:
application/json:
schema:
type: object
required:
- status
properties:
status:
description: Статус диспута
type: string
enum:
- pending
- succeeded
- failed
reason:
description: Причина фейла
$ref: '#/components/schemas/DefaultLogicError'
changedAmount:
description: Измененная сумма платежа
$ref: '#/components/schemas/Amount'
'400':
description: Ошибка в формате запроса
$ref: '#/components/responses/DefaultLogicError'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
description: |
Взаимодействие между мерчантом и [системой](https://vality.dev/) осуществляется по защищенному протоколу (HTTPS). HTTP-запросы по нешифрованному каналу не поддерживаются.
Ознакомиться с деталями авторизации запросов к API можно в [данной](https://developer.vality.dev/docs/payments/overview/#api) статье.
Управлять API-ключами можно в [личном кабинете](https://dashboard.vality.dev/). Значение ключа следует передать в заголовке `Authorization`:
```
Authorization: Bearer MjMyNDQxMjM6NDUzRmRnZDQ0M...
```
Ключи не разделяются на тестовые и боевые. Для проведения тестовых транзакций используйте идентификатор тестового магазина.
**Важно! Не передавайте API-ключ третьим лицам!**
responses:
NotFound:
description: Target resource not found
content:
application/json:
schema:
$ref: '#/components/schemas/GeneralError'
Unauthorized:
description: Authorization error
DefaultLogicError:
description: Invalid data
content:
application/json:
schema:
$ref: '#/components/schemas/DefaultLogicError'
NotSupportedByProvider:
description: Not supported by provider
parameters:
requestID:
name: X-Request-ID
in: header
description: Идентификатор запроса к системе
required: true
schema:
type: string
maxLength: 40
minLength: 1
schemas:
InvoiceID:
description: Идентификатор инвоиса, на основе которого был создан платёж
type: string
maxLength: 40
minLength: 1
PaymentID:
description: Идентификатор платежа
type: string
maxLength: 40
minLength: 1
DisputeId:
description: Идентификатор диспута
type: string
maxLength: 40
minLength: 1
Amount:
type: object
required:
- amount
- exponent
properties:
amount:
description: Сумма платежа, которая будет оспариваться в диспуте
type: integer
format: int64
minimum: 1
currency:
description: >-
Валюта, символьный код согласно [ISO
4217](http://www.iso.org/iso/home/standards/currency_codes.htm).
type: string
pattern: '^[A-Z]{3}$'
DefaultLogicError:
type: object
required:
- code
- message
properties:
code:
description: Error code
type: string
enum:
- invalidRequest
- invalidDeadline
message:
description: Человекочитаемое описание ошибки
type: string
GeneralError:
type: object
required:
- message
properties:
message:
type: string

8352
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

15
package.json Normal file
View File

@ -0,0 +1,15 @@
{
"name": "@vality/swag-disputes",
"version": "0.1.0",
"dependencies": {
"@redocly/cli": "1.4.0",
"json-merge-patch": "1.0.2",
"redoc-cli": "0.13.21"
},
"scripts": {
"start": "openapi preview-docs",
"build": "openapi bundle -o openapi/openapi.yaml",
"redoc": "redoc-cli bundle openapi/openapi.yaml -o dist/index.html",
"validate": "openapi lint"
}
}

49
plugins/local.js Normal file
View File

@ -0,0 +1,49 @@
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);
};
Object.assign(node, merged);
delete node[trigger];
}
}
}
}

185
pom.xml Normal file
View File

@ -0,0 +1,185 @@
<?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>dev.vality</groupId>
<artifactId>library-parent-pom</artifactId>
<version>2.0.2</version>
</parent>
<artifactId>swag-disputes</artifactId>
<version>${revision}</version>
<packaging>jar</packaging>
<name>disputes</name>
<description>Generates jar artifact containing compiled openapi classes based on generated openapi yaml files
</description>
<properties>
<default.package>dev.vality.swag.disputes</default.package>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<revision>SNAPSHOT</revision>
<java.version>11</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<slf4j-version>2.0.13</slf4j-version>
<junit-version>4.13.2</junit-version>
<jackson-version>2.13.1</jackson-version>
<spring-version>3.3.1</spring-version>
<openapi-generator-version>7.6.0</openapi-generator-version>
</properties>
<dependencies>
<!--Spring dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>${spring-version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>${spring-version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring-version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
<version>${spring-version}</version>
<scope>provided</scope>
</dependency>
<!--third part -->
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-annotations</artifactId>
<version>2.2.22</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j-version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>6.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson-version}</version>
</dependency>
<dependency>
<groupId>org.openapitools</groupId>
<artifactId>jackson-databind-nullable</artifactId>
<version>0.2.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<version>3.0.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.10.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<profiles>
<profile>
<id>server</id>
<build>
<plugins>
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>${openapi-generator-version}</version>
<executions>
<execution>
<id>spring-server</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>openapi/openapi.yaml</inputSpec>
<generatorName>spring</generatorName>
<generateModels>true</generateModels>
<generateApis>true</generateApis>
<generateApiDocumentation>true</generateApiDocumentation>
<generateSupportingFiles>true</generateSupportingFiles>
<apiPackage>${default.package}.api</apiPackage>
<modelPackage>${default.package}.model</modelPackage>
<supportingFilesToGenerate>ApiUtil.java</supportingFilesToGenerate>
<configOptions>
<dateLibrary>java8</dateLibrary>
<delegatePattern>true</delegatePattern>
<useBeanValidation>true</useBeanValidation>
<useSpringBoot3>true</useSpringBoot3>
</configOptions>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>client</id>
<build>
<plugins>
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>${openapi-generator-version}</version>
<executions>
<execution>
<id>remote</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>openapi/openapi.yaml</inputSpec>
<generatorName>java</generatorName>
<configOptions>
<dateLibrary>java8</dateLibrary>
<useJakartaEe>true</useJakartaEe>
</configOptions>
<library>resttemplate</library>
<apiPackage>${default.package}.api</apiPackage>
<modelPackage>${default.package}.model</modelPackage>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>