generated from PenaSide/GolangTemplate
mergeconflicts
This commit is contained in:
commit
4f500f5ea5
10
Dockerfile
10
Dockerfile
@ -2,7 +2,7 @@
|
||||
FROM golang:1.20.3-alpine AS build
|
||||
|
||||
# Update packages and clear cache
|
||||
RUN apk update && apk add --no-cache curl && rm -rf /var/cache/apk/*
|
||||
RUN apk add --no-cache curl
|
||||
# Set work directory
|
||||
WORKDIR /app
|
||||
# Create binary directory
|
||||
@ -13,8 +13,6 @@ RUN mkdir /bin/golang-migrate -p
|
||||
ADD ./tools/migrate /bin/golang-migrate/
|
||||
# Add main files to app
|
||||
ADD . .
|
||||
# Download go depences
|
||||
RUN go mod download
|
||||
# Build app
|
||||
RUN GOOS=linux go build -o bin ./...
|
||||
|
||||
@ -24,9 +22,7 @@ RUN GOOS=linux go build -o bin ./...
|
||||
FROM alpine:3.18.3 AS test
|
||||
|
||||
# Install packages
|
||||
RUN apk --no-cache add ca-certificates && rm -rf /var/cache/apk/*
|
||||
# Set GO111MODULE env
|
||||
ENV GO111MODULE=off
|
||||
RUN apk --no-cache add ca-certificates
|
||||
# Create home directory
|
||||
WORKDIR /app
|
||||
# Copy build file
|
||||
@ -44,7 +40,7 @@ CMD [ "./app" ]
|
||||
FROM alpine:3.18.3 AS production
|
||||
|
||||
# Install packages
|
||||
RUN apk --no-cache add ca-certificates && rm -rf /var/cache/apk/*
|
||||
RUN apk --no-cache add ca-certificates
|
||||
# Create home directory
|
||||
WORKDIR /app
|
||||
# Copy build file
|
||||
|
11
Makefile
11
Makefile
@ -25,18 +25,21 @@ test.unit: ## run unit tests
|
||||
go test ./...
|
||||
|
||||
test.integration: ## run integration tests
|
||||
go mod vendor
|
||||
@make test.integration.up
|
||||
@make test.integration.start
|
||||
@make test.integration.down
|
||||
|
||||
test.integration.up: ## build integration test environment
|
||||
docker-compose -f deployments/test/docker-compose.yaml up -d
|
||||
docker-compose -f deployments/test/docker-compose.yaml up -d --remove-orphans
|
||||
|
||||
test.integration.down: ## shutting down integration environment
|
||||
docker-compose -f deployments/test/docker-compose.yaml down --volumes --rmi local
|
||||
docker-compose -f deployments/test/docker-compose.yaml down --volumes
|
||||
|
||||
test.integration.start: ## run integration test
|
||||
go test ./tests/integration/...
|
||||
docker-compose -p integration -f deployments/test/docker-compose.integration.yaml down
|
||||
docker-compose -p integration -f deployments/test/docker-compose.integration.yaml up --exit-code-from integration --remove-orphans
|
||||
docker-compose -p integration -f deployments/test/docker-compose.integration.yaml down
|
||||
|
||||
test.e2e.start: ## run integration test
|
||||
go test ./tests/e2e/...
|
||||
@ -48,4 +51,4 @@ dev.up: ## run dev environment
|
||||
docker-compose -f deployments/dev/docker-compose.yaml up -d
|
||||
|
||||
dev.down: ## shutting down dev environment
|
||||
docker-compose -f deployments/dev/docker-compose.yaml down --volumes --rmi local
|
||||
docker-compose -f deployments/dev/docker-compose.yaml down --volumes --rmi local
|
||||
|
@ -42,3 +42,4 @@ KAFKA_TOPIC_TARIFF - название топика для сообщений т
|
||||
## Полезные ссылки:
|
||||
|
||||
- [**Диаграммы**](./docs/diagram/README.md)
|
||||
- Для того чтобы создать новые endpoint, нужно прописать их в customer/api/openapi/v1/openapi.yaml, сделать его описание, с помощью инструкций в makefile сгенерировать файлы
|
||||
|
@ -4,7 +4,7 @@ info:
|
||||
description: |-
|
||||
Область ответственности сервиса - предоставление пользователю функционала корзины и кошелька.
|
||||
version: 1.0.0
|
||||
|
||||
|
||||
tags:
|
||||
- name: account
|
||||
description: аккаунт
|
||||
@ -16,7 +16,7 @@ tags:
|
||||
description: кошелёк
|
||||
- name: history
|
||||
description: история
|
||||
|
||||
|
||||
paths:
|
||||
/account:
|
||||
get:
|
||||
@ -28,24 +28,24 @@ paths:
|
||||
security:
|
||||
- Bearer: []
|
||||
responses:
|
||||
'200':
|
||||
"200":
|
||||
description: успешное получение
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Account'
|
||||
'401':
|
||||
$ref: "#/components/schemas/Account"
|
||||
"401":
|
||||
description: Неавторизован
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
'404':
|
||||
$ref: "#/components/schemas/Error"
|
||||
"404":
|
||||
description: Такого пользователя нет
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
$ref: "#/components/schemas/Error"
|
||||
post:
|
||||
tags:
|
||||
- account
|
||||
@ -55,18 +55,18 @@ paths:
|
||||
security:
|
||||
- Bearer: []
|
||||
responses:
|
||||
'200':
|
||||
"200":
|
||||
description: успешное создание аккаунта
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Account'
|
||||
'401':
|
||||
$ref: "#/components/schemas/Account"
|
||||
"401":
|
||||
description: Неавторизован
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
$ref: "#/components/schemas/Error"
|
||||
patch:
|
||||
tags:
|
||||
- account
|
||||
@ -76,24 +76,24 @@ paths:
|
||||
security:
|
||||
- Bearer: []
|
||||
requestBody:
|
||||
description: Модель имени
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Name'
|
||||
description: Модель имени
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Name"
|
||||
responses:
|
||||
'200':
|
||||
"200":
|
||||
description: успешное создание аккаунта
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Account'
|
||||
'401':
|
||||
$ref: "#/components/schemas/Account"
|
||||
"401":
|
||||
description: Неавторизован
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
$ref: "#/components/schemas/Error"
|
||||
delete:
|
||||
tags:
|
||||
- account
|
||||
@ -103,19 +103,19 @@ paths:
|
||||
security:
|
||||
- Bearer: []
|
||||
responses:
|
||||
'200':
|
||||
"200":
|
||||
description: успешное удаление аккаунта
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Account'
|
||||
'401':
|
||||
$ref: "#/components/schemas/Account"
|
||||
"401":
|
||||
description: Неавторизован
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
|
||||
$ref: "#/components/schemas/Error"
|
||||
|
||||
/accounts:
|
||||
get:
|
||||
tags:
|
||||
@ -141,7 +141,7 @@ paths:
|
||||
type: integer
|
||||
default: 100
|
||||
responses:
|
||||
'200':
|
||||
"200":
|
||||
description: успешное получение страницы аккаунтов
|
||||
content:
|
||||
application/json:
|
||||
@ -151,11 +151,11 @@ paths:
|
||||
totalPages:
|
||||
type: integer
|
||||
example: 11
|
||||
accounts:
|
||||
accounts:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/Account"
|
||||
|
||||
|
||||
/account/{userId}:
|
||||
get:
|
||||
tags:
|
||||
@ -173,24 +173,24 @@ paths:
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
"200":
|
||||
description: Успешное получение аккаунта
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Account'
|
||||
'401':
|
||||
$ref: "#/components/schemas/Account"
|
||||
"401":
|
||||
description: Неавторизован
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
'404':
|
||||
$ref: "#/components/schemas/Error"
|
||||
"404":
|
||||
description: Нет такого пользователя
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
$ref: "#/components/schemas/Error"
|
||||
patch:
|
||||
tags:
|
||||
- account
|
||||
@ -213,20 +213,20 @@ paths:
|
||||
type: object
|
||||
properties:
|
||||
status:
|
||||
$ref: '#/components/schemas/AccountStatus'
|
||||
$ref: "#/components/schemas/AccountStatus"
|
||||
responses:
|
||||
'200':
|
||||
"200":
|
||||
description: Успешное выставление статуса
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Account'
|
||||
'404':
|
||||
$ref: "#/components/schemas/Account"
|
||||
"404":
|
||||
description: Нет такого пользователя
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
$ref: "#/components/schemas/Error"
|
||||
delete:
|
||||
tags:
|
||||
- account
|
||||
@ -243,25 +243,25 @@ paths:
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: Успешное удаление аккаунта
|
||||
"200":
|
||||
description: Успешное удаление аккаунта
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Account'
|
||||
'401':
|
||||
$ref: "#/components/schemas/Account"
|
||||
"401":
|
||||
description: Неавторизован
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
'404':
|
||||
$ref: "#/components/schemas/Error"
|
||||
"404":
|
||||
description: Нет такого пользователя
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
|
||||
$ref: "#/components/schemas/Error"
|
||||
|
||||
/currencies:
|
||||
get:
|
||||
tags:
|
||||
@ -269,17 +269,17 @@ paths:
|
||||
summary: получить список одобренных валют
|
||||
operationId: getCurrencies
|
||||
responses:
|
||||
'200':
|
||||
"200":
|
||||
description: успешное получение списка валют
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
example:
|
||||
example:
|
||||
- "RUB"
|
||||
- "USD"
|
||||
- "CAD"
|
||||
items:
|
||||
items:
|
||||
type: string
|
||||
put:
|
||||
tags:
|
||||
@ -293,32 +293,32 @@ paths:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
example:
|
||||
example:
|
||||
- "RUB"
|
||||
- "USD"
|
||||
- "CAD"
|
||||
items:
|
||||
items:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
"200":
|
||||
description: успешное обновление списка валют
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
example:
|
||||
example:
|
||||
- "RUB"
|
||||
- "USD"
|
||||
- "CAD"
|
||||
items:
|
||||
items:
|
||||
type: string
|
||||
'401':
|
||||
"401":
|
||||
description: Uanuthorized
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
|
||||
$ref: "#/components/schemas/Error"
|
||||
|
||||
/cart:
|
||||
patch:
|
||||
tags:
|
||||
@ -336,24 +336,24 @@ paths:
|
||||
type: string
|
||||
example: "807f1f77bcf81cd799439011"
|
||||
responses:
|
||||
'200':
|
||||
"200":
|
||||
description: Добавлено в корзину
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Account'
|
||||
'401':
|
||||
$ref: "#/components/schemas/Account"
|
||||
"401":
|
||||
description: Неавторизован
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
'404':
|
||||
$ref: "#/components/schemas/Error"
|
||||
"404":
|
||||
description: Не найден такой тариф
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
$ref: "#/components/schemas/Error"
|
||||
delete:
|
||||
tags:
|
||||
- cart
|
||||
@ -369,25 +369,25 @@ paths:
|
||||
type: string
|
||||
example: "807f1f77bcf81cd799439011"
|
||||
responses:
|
||||
'200':
|
||||
"200":
|
||||
description: Удалено из корзины
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Account'
|
||||
'401':
|
||||
$ref: "#/components/schemas/Account"
|
||||
"401":
|
||||
description: Неавторизован
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
'404':
|
||||
$ref: "#/components/schemas/Error"
|
||||
"404":
|
||||
description: Не найден такой тариф
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
|
||||
$ref: "#/components/schemas/Error"
|
||||
|
||||
/cart/pay:
|
||||
post:
|
||||
tags:
|
||||
@ -398,34 +398,34 @@ paths:
|
||||
- Bearer: []
|
||||
description: Запрос на проведение оплаты корзины
|
||||
responses:
|
||||
'200':
|
||||
"200":
|
||||
description: успешная оплата корзины
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Account'
|
||||
'401':
|
||||
$ref: "#/components/schemas/Account"
|
||||
"401":
|
||||
description: Неавторизован
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
|
||||
$ref: "#/components/schemas/Error"
|
||||
|
||||
/wallet:
|
||||
patch:
|
||||
tags:
|
||||
- wallet
|
||||
summary: Изменить валюту кошелька
|
||||
operationId: changeCurrency
|
||||
description: >-
|
||||
description: >-
|
||||
При запросе необходимо:
|
||||
|
||||
|
||||
- Отвалидировать, что такая валюта одобрена
|
||||
|
||||
|
||||
- Получить данные из сервиса cbrf (выдам задачу на него чуть позднее)
|
||||
|
||||
|
||||
- Перевести валюту кошелька в новую валюту. Кошелёк нарочно целочисленный, чтобы не было претензий к точности с плавающей точкой, поэтому, например долларовый счёт считается в центах
|
||||
|
||||
|
||||
security:
|
||||
- Bearer: []
|
||||
requestBody:
|
||||
@ -435,29 +435,29 @@ paths:
|
||||
type: object
|
||||
required: [currency]
|
||||
properties:
|
||||
currency:
|
||||
currency:
|
||||
type: string
|
||||
example: "USD"
|
||||
responses:
|
||||
'200':
|
||||
"200":
|
||||
description: Успешная смена валюты кошелька
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Account"
|
||||
'401':
|
||||
"401":
|
||||
description: Неавторизован
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
'400':
|
||||
"400":
|
||||
description: Такая валюта не одобрена
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
'404':
|
||||
"404":
|
||||
description: Пользователь не найден
|
||||
content:
|
||||
application/json:
|
||||
@ -472,7 +472,7 @@ paths:
|
||||
- Bearer: []
|
||||
description: >-
|
||||
- Формируем запрос к сервису оплаты, с необходимыми постбэками
|
||||
|
||||
|
||||
- Получаем ответ от сервиса оплаты с ссылкой на оплату, которую надо передать пользователю
|
||||
requestBody:
|
||||
content:
|
||||
@ -482,7 +482,7 @@ paths:
|
||||
required: [type, currency, amount]
|
||||
properties:
|
||||
type:
|
||||
$ref: '#/components/schemas/PaymentType'
|
||||
$ref: "#/components/schemas/PaymentType"
|
||||
currency:
|
||||
type: string
|
||||
description: "ISO-4217 формат"
|
||||
@ -491,7 +491,7 @@ paths:
|
||||
type: integer
|
||||
example: 15020
|
||||
bankCard:
|
||||
$ref: '#/components/schemas/BankCard'
|
||||
$ref: "#/components/schemas/BankCard"
|
||||
phoneNumber:
|
||||
type: string
|
||||
example: "79000000000"
|
||||
@ -502,23 +502,23 @@ paths:
|
||||
type: string
|
||||
example: "https://site.ru/cart"
|
||||
responses:
|
||||
'200':
|
||||
"200":
|
||||
description: Успешный запрос денег
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
link:
|
||||
link:
|
||||
type: string
|
||||
example: "https://google.ru"
|
||||
'500':
|
||||
"500":
|
||||
description: Сервис оплаты вернул ошибку
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
|
||||
$ref: "#/components/schemas/Error"
|
||||
|
||||
/history:
|
||||
get:
|
||||
tags:
|
||||
@ -552,46 +552,107 @@ paths:
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
"200":
|
||||
description: Успешное получение событий
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
totalPages:
|
||||
totalPages:
|
||||
type: integer
|
||||
example: 11
|
||||
records:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/History'
|
||||
'401':
|
||||
$ref: "#/components/schemas/History"
|
||||
"401":
|
||||
description: Неавторизован
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
$ref: "#/components/schemas/Error"
|
||||
|
||||
/recent:
|
||||
get:
|
||||
tags:
|
||||
- history
|
||||
summary: Получение недавних тарифов
|
||||
description: Возвращает список уникальных тарифов из истории. Айди аккаунта получается из заголовка.
|
||||
operationId: getRecentTariffs
|
||||
security:
|
||||
- Bearer: []
|
||||
responses:
|
||||
'200':
|
||||
description: Успешный запрос
|
||||
get:
|
||||
tags:
|
||||
- history
|
||||
summary: Получение недавних тарифов
|
||||
description: Возвращает список уникальных тарифов из истории. Айди аккаунта получается из заголовка.
|
||||
security:
|
||||
- Bearer: []
|
||||
responses:
|
||||
'200':
|
||||
description: Успешный запрос
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/TariffID"
|
||||
'400':
|
||||
description: Неверный запрос
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
'404':
|
||||
description: Тарифы не найдены
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
'500':
|
||||
description: Внутренняя ошибка сервера
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required: [id]
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
example: "807f1f77bcf81cd799439011"
|
||||
/sendReport:
|
||||
post:
|
||||
tags:
|
||||
- history
|
||||
summary: отправить акт проделанных работ на почту
|
||||
operationId: sendReport
|
||||
security:
|
||||
- Bearer: []
|
||||
description: Запрос на отправку акта проделанных работ
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required: [id]
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
example: "807f1f77bcf81cd799439011"
|
||||
responses:
|
||||
"200":
|
||||
description: успешная отправка
|
||||
"401":
|
||||
description: Неавторизован
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
|
||||
components:
|
||||
schemas:
|
||||
|
||||
Account:
|
||||
type: object
|
||||
required: [_id, userId, cart, wallet, name, status, deleted, createdAt, updatedAt]
|
||||
required:
|
||||
[_id, userId, cart, wallet, name, status, deleted, createdAt, updatedAt]
|
||||
properties:
|
||||
_id:
|
||||
type: string
|
||||
@ -600,18 +661,18 @@ components:
|
||||
type: string
|
||||
example: "807f1f77bcf81cd799439011"
|
||||
name:
|
||||
$ref: '#/components/schemas/Name'
|
||||
$ref: "#/components/schemas/Name"
|
||||
cart:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
example:
|
||||
example:
|
||||
- "807f1f77bcf81cd799439011"
|
||||
- "807f1f77bcf81cd799439012"
|
||||
wallet:
|
||||
$ref: "#/components/schemas/Wallet"
|
||||
status:
|
||||
$ref: '#/components/schemas/AccountStatus'
|
||||
$ref: "#/components/schemas/AccountStatus"
|
||||
isDeleted:
|
||||
type: boolean
|
||||
example: false
|
||||
@ -624,11 +685,11 @@ components:
|
||||
deletedAt:
|
||||
type: string
|
||||
format: "date-time"
|
||||
|
||||
|
||||
Name:
|
||||
type: object
|
||||
properties:
|
||||
firstname:
|
||||
firstname:
|
||||
type: string
|
||||
example: Иван
|
||||
secondname:
|
||||
@ -665,7 +726,7 @@ components:
|
||||
type: string
|
||||
description: Имя владельца карты
|
||||
example: "IVAN IVANOV"
|
||||
|
||||
|
||||
Wallet:
|
||||
type: object
|
||||
required: [currency, cash, money, purchasesAmount, spent]
|
||||
@ -695,10 +756,11 @@ components:
|
||||
возникало денег изниоткуда. фиксируемся к одной валюте,
|
||||
она будет внутренней, никому её не покажем
|
||||
example: 10701
|
||||
|
||||
|
||||
History:
|
||||
type: object
|
||||
required: [id, userId, type, deleted, createdAt, updatedAt, comment, subject]
|
||||
required:
|
||||
[id, userId, type, deleted, createdAt, updatedAt, comment, subject]
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
@ -709,7 +771,7 @@ components:
|
||||
type:
|
||||
type: string
|
||||
example: "customer.tariffEnded"
|
||||
isDeleted:
|
||||
isDeleted:
|
||||
type: boolean
|
||||
example: false
|
||||
createdAt:
|
||||
@ -726,16 +788,37 @@ components:
|
||||
example: "я это сделал потому что 42"
|
||||
rawDetails:
|
||||
type: string
|
||||
description: >-
|
||||
description: >-
|
||||
Я пока не могу предположить, какие будут фильтры по
|
||||
истории, поэтому предлагаю в это
|
||||
поле просто класть строку с json.
|
||||
Ибо для каждого типа записи она своя.
|
||||
example: '{"tariffs":["807f1f77bcf81cd799439011","807f1f77bcf81cd799439011"]}'
|
||||
|
||||
|
||||
PaymentType:
|
||||
type: string
|
||||
enum: ["bankCard", "tinkoffBank", "qiwi", "sberbank", "yoomoney", "mobile", "installments", "cash", "sbp", "b2bSberbank", "alfabank"]
|
||||
enum:
|
||||
[
|
||||
"bankCard",
|
||||
"tinkoffBank",
|
||||
"qiwi",
|
||||
"sberbank",
|
||||
"yoomoney",
|
||||
"mobile",
|
||||
"installments",
|
||||
"cash",
|
||||
"sbp",
|
||||
"b2bSberbank",
|
||||
"alfabank",
|
||||
]
|
||||
|
||||
TariffID:
|
||||
type: object
|
||||
properties:
|
||||
ID:
|
||||
type: string
|
||||
example: "807f1f77bcf81cd799439011"
|
||||
|
||||
|
||||
AccountStatus:
|
||||
type: string
|
||||
@ -752,9 +835,9 @@ components:
|
||||
message:
|
||||
type: string
|
||||
example: user not found
|
||||
|
||||
|
||||
securitySchemes:
|
||||
Bearer: # arbitrary name for the security scheme
|
||||
Bearer: # arbitrary name for the security scheme
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
|
18
deployments/test/docker-compose.integration.yaml
Normal file
18
deployments/test/docker-compose.integration.yaml
Normal file
@ -0,0 +1,18 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
integration:
|
||||
container_name: customer-integration
|
||||
image: golang:1
|
||||
volumes:
|
||||
- ../..:/app:ro,z
|
||||
working_dir: /app
|
||||
command: go test ./tests/integration/...
|
||||
environment:
|
||||
- CUSTOMER_SERVICE=customer-service:8000
|
||||
networks:
|
||||
- test_test
|
||||
|
||||
networks:
|
||||
test_test:
|
||||
external: true
|
@ -7,7 +7,7 @@ services:
|
||||
customer-service:
|
||||
container_name: customer-service
|
||||
build:
|
||||
context: ../../.
|
||||
context: ../..
|
||||
dockerfile: Dockerfile
|
||||
target: test
|
||||
env_file:
|
||||
@ -39,24 +39,23 @@ services:
|
||||
- 8082:8000
|
||||
- 9092:9000
|
||||
depends_on:
|
||||
- customer-db
|
||||
- customer-migration
|
||||
- redpanda
|
||||
customer-db:
|
||||
condition: service_started
|
||||
customer-migration:
|
||||
condition: service_completed_successfully
|
||||
redpanda:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- test
|
||||
|
||||
customer-migration:
|
||||
container_name: customer-migration
|
||||
build:
|
||||
context: ../../.
|
||||
dockerfile: Dockerfile
|
||||
target: test
|
||||
command:
|
||||
[
|
||||
"sh",
|
||||
"-c",
|
||||
'migrate -source file://migrations -database "mongodb://test:test@customer-db:27017/admin?authSource=admin" up',
|
||||
]
|
||||
image: alpine
|
||||
command: migrate -source file://migrations -database "mongodb://test:test@customer-db:27017/admin" up
|
||||
volumes:
|
||||
- ../../migrations/test:/app/migrations:ro
|
||||
- ../../tools/migrate:/usr/local/bin/migrate:ro
|
||||
working_dir: /app
|
||||
depends_on:
|
||||
- customer-db
|
||||
networks:
|
||||
@ -105,17 +104,18 @@ services:
|
||||
networks:
|
||||
- test
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "rpk cluster health | grep -E 'Healthy:.+true' || exit 1"]
|
||||
interval: 15s
|
||||
timeout: 3s
|
||||
test: rpk cluster health | grep -q 'Healthy:.*true'
|
||||
interval: 2s
|
||||
timeout: 2s
|
||||
retries: 5
|
||||
start_period: 5s
|
||||
|
||||
console:
|
||||
tty: true
|
||||
container_name: customer-console
|
||||
image: docker.redpanda.com/redpandadata/console:v2.2.4
|
||||
entrypoint: /bin/sh
|
||||
command: -c "echo \"$$CONSOLE_CONFIG_FILE\" > /tmp/config.yml; /app/console"
|
||||
entrypoint: ''
|
||||
command: sh -c 'echo "$$CONSOLE_CONFIG_FILE" > /tmp/config.yml && exec /app/console'
|
||||
environment:
|
||||
CONFIG_FILEPATH: /tmp/config.yml
|
||||
CONSOLE_CONFIG_FILE: |
|
||||
@ -138,18 +138,20 @@ services:
|
||||
networks:
|
||||
- test
|
||||
depends_on:
|
||||
- redpanda
|
||||
connect:
|
||||
condition: service_started
|
||||
redpanda:
|
||||
condition: service_healthy
|
||||
|
||||
connect:
|
||||
tty: true
|
||||
image: docker.redpanda.com/redpandadata/connectors:latest
|
||||
hostname: connect
|
||||
container_name: connect
|
||||
networks:
|
||||
- test
|
||||
# hostname: connect
|
||||
container_name: customer-connect
|
||||
# platform: 'linux/amd64'
|
||||
depends_on:
|
||||
- redpanda
|
||||
redpanda:
|
||||
condition: service_healthy
|
||||
ports:
|
||||
- "8083:8083"
|
||||
environment:
|
||||
@ -170,6 +172,8 @@ services:
|
||||
CONNECT_GC_LOG_ENABLED: "false"
|
||||
CONNECT_HEAP_OPTS: -Xms512M -Xmx512M
|
||||
CONNECT_LOG_LEVEL: info
|
||||
networks:
|
||||
- test
|
||||
|
||||
networks:
|
||||
test:
|
||||
test:
|
||||
|
9
go.mod
9
go.mod
@ -16,7 +16,7 @@ require (
|
||||
github.com/twmb/franz-go v1.13.6
|
||||
github.com/twmb/franz-go/pkg/kadm v1.8.1
|
||||
go.mongodb.org/mongo-driver v1.11.4
|
||||
go.uber.org/zap v1.24.0
|
||||
go.uber.org/zap v1.26.0
|
||||
google.golang.org/genproto v0.0.0-20230223222841-637eb2293923
|
||||
google.golang.org/grpc v1.53.0
|
||||
google.golang.org/protobuf v1.31.0
|
||||
@ -25,6 +25,7 @@ require (
|
||||
require (
|
||||
github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect
|
||||
github.com/benbjohnson/clock v1.3.3 // indirect
|
||||
github.com/daixiang0/gci v0.11.2 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.6 // indirect
|
||||
github.com/go-openapi/swag v0.22.3 // indirect
|
||||
@ -34,6 +35,8 @@ require (
|
||||
github.com/google/go-cmp v0.5.9 // indirect
|
||||
github.com/google/uuid v1.3.1 // indirect
|
||||
github.com/gorilla/mux v1.8.0 // indirect
|
||||
github.com/hexops/gotextdiff v1.0.3 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/invopop/yaml v0.1.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/klauspost/compress v1.16.7 // indirect
|
||||
@ -48,6 +51,8 @@ require (
|
||||
github.com/pierrec/lz4/v4 v4.1.17 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/spf13/cobra v1.8.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/twmb/franz-go/pkg/kmsg v1.4.0 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasttemplate v1.2.2 // indirect
|
||||
@ -59,7 +64,7 @@ require (
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/crypto v0.12.0 // indirect
|
||||
golang.org/x/net v0.14.0 // indirect
|
||||
golang.org/x/sync v0.2.0 // indirect
|
||||
golang.org/x/sync v0.5.0 // indirect
|
||||
golang.org/x/sys v0.11.0 // indirect
|
||||
golang.org/x/text v0.12.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
|
17
go.sum
17
go.sum
@ -10,7 +10,10 @@ github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvF
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/daixiang0/gci v0.11.2 h1:Oji+oPsp3bQ6bNNgX30NBAVT18P4uBH4sRZnlOlTj7Y=
|
||||
github.com/daixiang0/gci v0.11.2/go.mod h1:xtHP9N7AHdNvtRNfcx9gwTDfw7FRJx4bZUsiEfiNNAI=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@ -63,6 +66,10 @@ github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8=
|
||||
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
|
||||
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/invopop/yaml v0.1.0 h1:YW3WGUoJEXYfzWBjn00zIlrw7brGVD0fUKRYDPAPhrc=
|
||||
github.com/invopop/yaml v0.1.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
@ -119,9 +126,14 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sethvargo/go-envconfig v0.9.0 h1:Q6FQ6hVEeTECULvkJZakq3dZMeBQ3JUpcKMfPQbKMDE=
|
||||
github.com/sethvargo/go-envconfig v0.9.0/go.mod h1:Iz1Gy1Sf3T64TQlJSvee81qDhf7YIlt8GMUX6yyNFs0=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
|
||||
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
@ -171,12 +183,15 @@ go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
|
||||
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
|
||||
go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
|
||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
|
||||
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
|
||||
go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
|
||||
go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
|
||||
go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
@ -211,6 +226,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
|
||||
golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
|
||||
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
@ -72,7 +72,9 @@ func Run(config *models.Config, logger *zap.Logger) (appErr error) {
|
||||
HubadminURL: &config.Service.HubadminMicroservice.URL,
|
||||
CurrencyURL: &config.Service.CurrencyMicroservice.URL,
|
||||
DiscountServiceConfiguration: &config.Service.DiscountMicroservice,
|
||||
VerificationURL: &config.Service.VerificationMicroservice.URL,
|
||||
PaymentServiceConfiguration: &config.Service.PaymentMicroservice,
|
||||
TemplategenURL: &config.Service.TemplategenMicroserviceURL.URL,
|
||||
})
|
||||
|
||||
repositories := initialize.NewRepositories(initialize.RepositoriesDeps{
|
||||
|
@ -13,14 +13,18 @@ type ClientsDeps struct {
|
||||
CurrencyURL *models.CurrencyMicroserviceURL
|
||||
DiscountServiceConfiguration *models.DiscountMicroserviceConfiguration
|
||||
PaymentServiceConfiguration *models.PaymentMicroserviceConfiguration
|
||||
VerificationURL *models.VerificationMicroserviceURL
|
||||
TemplategenURL *models.TemplategenMicroserviceURL
|
||||
}
|
||||
|
||||
type Clients struct {
|
||||
AuthClient *client.AuthClient
|
||||
HubadminClient *client.HubadminClient
|
||||
CurrencyClient *client.CurrencyClient
|
||||
DiscountClient *client.DiscountClient
|
||||
PaymentClient *client.PaymentClient
|
||||
AuthClient *client.AuthClient
|
||||
HubadminClient *client.HubadminClient
|
||||
CurrencyClient *client.CurrencyClient
|
||||
DiscountClient *client.DiscountClient
|
||||
PaymentClient *client.PaymentClient
|
||||
VerificationClient *client.VerificationClient
|
||||
TemplateClient *client.TemplateClient
|
||||
}
|
||||
|
||||
func NewClients(deps ClientsDeps) *Clients {
|
||||
@ -45,5 +49,13 @@ func NewClients(deps ClientsDeps) *Clients {
|
||||
Logger: deps.Logger,
|
||||
PaymentServiceHost: deps.PaymentServiceConfiguration.HostGRPC,
|
||||
}),
|
||||
VerificationClient: client.NewVerificationClient(client.VerificationClientDeps{
|
||||
Logger: deps.Logger,
|
||||
URLs: deps.VerificationURL,
|
||||
}),
|
||||
TemplateClient: client.NewTemplateClient(client.TemplateClientDeps{
|
||||
Logger: deps.Logger,
|
||||
URLs: deps.TemplategenURL,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
88
internal/interface/client/templategen.go
Normal file
88
internal/interface/client/templategen.go
Normal file
@ -0,0 +1,88 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"log"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/errors"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
|
||||
)
|
||||
|
||||
type TemplateClientDeps struct {
|
||||
Logger *zap.Logger
|
||||
URLs *models.TemplategenMicroserviceURL
|
||||
}
|
||||
|
||||
type TemplateClient struct {
|
||||
logger *zap.Logger
|
||||
urls *models.TemplategenMicroserviceURL
|
||||
}
|
||||
|
||||
func NewTemplateClient(deps TemplateClientDeps) *TemplateClient {
|
||||
if deps.Logger == nil {
|
||||
log.Panicln("logger is nil on <NewTemplateClient>")
|
||||
}
|
||||
|
||||
if deps.URLs == nil {
|
||||
log.Panicln("urls is nil on <NewTemplateClient>")
|
||||
}
|
||||
|
||||
return &TemplateClient{
|
||||
logger: deps.Logger,
|
||||
urls: deps.URLs,
|
||||
}
|
||||
}
|
||||
|
||||
func (receiver *TemplateClient) SendData(ctx context.Context, data models.RespGeneratorService, fileContents []byte, email string) errors.Error {
|
||||
tmplURL := receiver.urls.Templategen
|
||||
|
||||
body := &bytes.Buffer{}
|
||||
writer := multipart.NewWriter(body)
|
||||
|
||||
err := writer.WriteField("email", email)
|
||||
if err != nil {
|
||||
return errors.New(err, errors.ErrInternalError)
|
||||
}
|
||||
|
||||
jsonData, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
return errors.New(err, errors.ErrInternalError)
|
||||
}
|
||||
err = writer.WriteField("data", string(jsonData))
|
||||
if err != nil {
|
||||
return errors.New(err, errors.ErrInternalError)
|
||||
}
|
||||
|
||||
fileWriter, err := writer.CreateFormFile("file", "report.docx")
|
||||
if err != nil {
|
||||
return errors.New(err, errors.ErrInternalError)
|
||||
}
|
||||
_, err = fileWriter.Write(fileContents)
|
||||
if err != nil {
|
||||
return errors.New(err, errors.ErrInternalError)
|
||||
}
|
||||
|
||||
err = writer.Close()
|
||||
if err != nil {
|
||||
return errors.New(err, errors.ErrInternalError)
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPost, tmplURL, body)
|
||||
if err != nil {
|
||||
return errors.New(err, errors.ErrInternalError)
|
||||
}
|
||||
req.Header.Set("Content-Type", writer.FormDataContentType())
|
||||
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return errors.New(err, errors.ErrInternalError)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
return nil
|
||||
}
|
58
internal/interface/client/verification.go
Normal file
58
internal/interface/client/verification.go
Normal file
@ -0,0 +1,58 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/url"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/errors"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/client"
|
||||
)
|
||||
|
||||
type VerificationClientDeps struct {
|
||||
Logger *zap.Logger
|
||||
URLs *models.VerificationMicroserviceURL
|
||||
}
|
||||
|
||||
type VerificationClient struct {
|
||||
logger *zap.Logger
|
||||
urls *models.VerificationMicroserviceURL
|
||||
}
|
||||
|
||||
func NewVerificationClient(deps VerificationClientDeps) *VerificationClient {
|
||||
if deps.Logger == nil {
|
||||
log.Panicln("logger is nil on <NewVerificationClient>")
|
||||
}
|
||||
|
||||
if deps.URLs == nil {
|
||||
log.Panicln("urls is nil on <NewVerificationClient>")
|
||||
}
|
||||
|
||||
return &VerificationClient{
|
||||
logger: deps.Logger,
|
||||
urls: deps.URLs,
|
||||
}
|
||||
}
|
||||
|
||||
func (receiver *VerificationClient) GetVerification(ctx context.Context, userID string) (*models.Verification, errors.Error) {
|
||||
verifURL, err := url.JoinPath(receiver.urls.Verification, userID)
|
||||
if err != nil {
|
||||
return nil, errors.New(
|
||||
fmt.Errorf("failed to join path on <GetVerification> of <VerificationClient>: %w", err),
|
||||
errors.ErrInternalError,
|
||||
)
|
||||
}
|
||||
|
||||
response, err := client.Get[models.Verification, models.FastifyError](ctx, &client.RequestSettings{
|
||||
URL: verifURL,
|
||||
Headers: map[string]string{"Content-Type": "application/json"},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.New(err, errors.ErrInternalError)
|
||||
}
|
||||
|
||||
return response.Body, nil
|
||||
}
|
@ -87,3 +87,16 @@ func (receiver *Controller) GetRecentTariffs(ctx echo.Context) error {
|
||||
|
||||
return ctx.JSON(http.StatusOK, tariffs)
|
||||
}
|
||||
|
||||
// TODO:tests.
|
||||
func (receiver *Controller) SendReport(ctx echo.Context) error {
|
||||
historyID := ctx.Param("id")
|
||||
|
||||
err := receiver.historyService.GetHistoryByID(ctx.Request().Context(), historyID)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to send report on <SendReport> of <HistoryController>", zap.Error(err))
|
||||
return errors.HTTP(ctx, err)
|
||||
}
|
||||
|
||||
return ctx.NoContent(http.StatusOK)
|
||||
}
|
||||
|
@ -168,3 +168,93 @@ func (receiver *HistoryRepository) GetRecentTariffs(ctx context.Context, userID
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// TODO:tests.
|
||||
func (receiver *HistoryRepository) GetHistoryByID(ctx context.Context, historyID string) (*models.ReportHistory, errors.Error) {
|
||||
history := &models.ReportHistory{}
|
||||
err := receiver.mongoDB.FindOne(ctx, bson.M{"_id": historyID}).Decode(history)
|
||||
if err != nil {
|
||||
receiver.logger.Error(
|
||||
"failed to find by id in <GetHistoryById> of <HistoryRepository>",
|
||||
zap.String("historyID", historyID),
|
||||
zap.Error(err),
|
||||
)
|
||||
|
||||
if err == mongo.ErrNoDocuments {
|
||||
return nil, errors.New(
|
||||
fmt.Errorf("history not found with ID: %s", historyID),
|
||||
errors.ErrNotFound,
|
||||
)
|
||||
}
|
||||
|
||||
return nil, errors.New(
|
||||
fmt.Errorf("failed to find by id: %w", err),
|
||||
errors.ErrInternalError,
|
||||
)
|
||||
}
|
||||
|
||||
return history, nil
|
||||
}
|
||||
|
||||
// TODO:tests.
|
||||
func (receiver *HistoryRepository) GetDocNumber(ctx context.Context, userID string) (map[string]int, errors.Error) {
|
||||
findOptions := options.Find()
|
||||
findOptions.SetSort(bson.D{{Key: "createdAt", Value: 1}})
|
||||
|
||||
filter := bson.M{
|
||||
fields.History.UserID: userID,
|
||||
}
|
||||
|
||||
cursor, err := receiver.mongoDB.Find(ctx, filter, findOptions)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to get DocNumber list on <GetDocNumber> of <HistoryRepository>",
|
||||
zap.String("userId", userID),
|
||||
zap.Error(err),
|
||||
)
|
||||
return nil, errors.New(
|
||||
fmt.Errorf("failed to get DocNumber list on <GetDocNumber> of <HistoryRepository>: %w", err),
|
||||
errors.ErrInternalError,
|
||||
)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if err := cursor.Close(ctx); err != nil {
|
||||
receiver.logger.Error("failed to close cursor on <GetDocNumber> of <HistoryRepository>",
|
||||
zap.String("userId", userID),
|
||||
zap.Error(err),
|
||||
)
|
||||
}
|
||||
}()
|
||||
|
||||
result := make(map[string]int)
|
||||
var count int
|
||||
for cursor.Next(ctx) {
|
||||
var history models.History
|
||||
if err := cursor.Decode(&history); err != nil {
|
||||
receiver.logger.Error("failed to decode history on <GetDocNumber> of <HistoryRepository>",
|
||||
zap.String("userId", userID),
|
||||
zap.Error(err),
|
||||
)
|
||||
return nil, errors.New(
|
||||
fmt.Errorf("failed to decode history on <GetDocNumber> of <HistoryRepository>: %w", err),
|
||||
errors.ErrInternalError,
|
||||
)
|
||||
}
|
||||
|
||||
result[history.ID] = count
|
||||
count++
|
||||
}
|
||||
|
||||
if err := cursor.Err(); err != nil {
|
||||
receiver.logger.Error("cursor error on <GetDocNumber> of <HistoryRepository>",
|
||||
zap.String("userId", userID),
|
||||
zap.Error(err),
|
||||
)
|
||||
return nil, errors.New(
|
||||
fmt.Errorf("cursor error on <GetDocNumber> of <HistoryRepository>: %w", err),
|
||||
errors.ErrInternalError,
|
||||
)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
@ -65,6 +65,9 @@ type ServerInterface interface {
|
||||
// Получение недавних тарифов
|
||||
// (GET /recent)
|
||||
GetRecentTariffs(ctx echo.Context) error
|
||||
// отправить акт проделанных работ на почту
|
||||
// (POST /sendReport)
|
||||
SendReport(ctx echo.Context) error
|
||||
// Изменить валюту кошелька
|
||||
// (PATCH /wallet)
|
||||
ChangeCurrency(ctx echo.Context) error
|
||||
@ -317,6 +320,17 @@ func (w *ServerInterfaceWrapper) GetRecentTariffs(ctx echo.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// SendReport converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) SendReport(ctx echo.Context) error {
|
||||
var err error
|
||||
|
||||
ctx.Set(BearerScopes, []string{})
|
||||
|
||||
// Invoke the callback with all the unmarshaled arguments
|
||||
err = w.Handler.SendReport(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// ChangeCurrency converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) ChangeCurrency(ctx echo.Context) error {
|
||||
var err error
|
||||
@ -382,6 +396,7 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL
|
||||
router.PUT(baseURL+"/currencies", wrapper.UpdateCurrencies)
|
||||
router.GET(baseURL+"/history", wrapper.GetHistory)
|
||||
router.GET(baseURL+"/recent", wrapper.GetRecentTariffs)
|
||||
router.POST(baseURL+"/sendReport", wrapper.SendReport)
|
||||
router.PATCH(baseURL+"/wallet", wrapper.ChangeCurrency)
|
||||
router.POST(baseURL+"/wallet", wrapper.RequestMoney)
|
||||
|
||||
@ -390,73 +405,74 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL
|
||||
// Base64 encoded, gzipped, json marshaled Swagger object
|
||||
var swaggerSpec = []string{
|
||||
|
||||
"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",
|
||||
"SAAA",
|
||||
"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",
|
||||
}
|
||||
|
||||
// GetSwagger returns the content of the embedded swagger specification file
|
||||
|
@ -36,6 +36,7 @@ type walletController interface {
|
||||
type historyController interface {
|
||||
GetHistoryList(ctx echo.Context, params GetHistoryParams) error
|
||||
GetRecentTariffs(ctx echo.Context) error
|
||||
SendReport(ctx echo.Context) error
|
||||
}
|
||||
|
||||
type Deps struct {
|
||||
@ -152,6 +153,10 @@ func (receiver *API) GetRecentTariffs(ctx echo.Context) error {
|
||||
return receiver.historyController.GetRecentTariffs(ctx)
|
||||
}
|
||||
|
||||
func (receiver *API) SendReport(ctx echo.Context) error {
|
||||
return receiver.historyController.SendReport(ctx)
|
||||
}
|
||||
|
||||
// Wallet
|
||||
|
||||
func (receiver *API) RequestMoney(ctx echo.Context) error {
|
||||
|
@ -157,6 +157,11 @@ type GetHistoryParams struct {
|
||||
Type *string `form:"type,omitempty" json:"type,omitempty"`
|
||||
}
|
||||
|
||||
// SendReportJSONBody defines parameters for SendReport.
|
||||
type SendReportJSONBody struct {
|
||||
Id string `json:"id"`
|
||||
}
|
||||
|
||||
// ChangeCurrencyJSONBody defines parameters for ChangeCurrency.
|
||||
type ChangeCurrencyJSONBody struct {
|
||||
Currency string `json:"currency"`
|
||||
@ -184,6 +189,9 @@ type SetAccountVerificationStatusJSONRequestBody SetAccountVerificationStatusJSO
|
||||
// UpdateCurrenciesJSONRequestBody defines body for UpdateCurrencies for application/json ContentType.
|
||||
type UpdateCurrenciesJSONRequestBody = UpdateCurrenciesJSONBody
|
||||
|
||||
// SendReportJSONRequestBody defines body for SendReport for application/json ContentType.
|
||||
type SendReportJSONRequestBody SendReportJSONBody
|
||||
|
||||
// ChangeCurrencyJSONRequestBody defines body for ChangeCurrency for application/json ContentType.
|
||||
type ChangeCurrencyJSONRequestBody ChangeCurrencyJSONBody
|
||||
|
||||
|
@ -26,13 +26,15 @@ type ConfigurationGRPC struct {
|
||||
}
|
||||
|
||||
type ServiceConfiguration struct {
|
||||
AuthMicroservice AuthMicroserviceConfiguration
|
||||
HubadminMicroservice HubadminMicroserviceConfiguration
|
||||
CurrencyMicroservice CurrencyMicroserviceConfiguration
|
||||
DiscountMicroservice DiscountMicroserviceConfiguration
|
||||
PaymentMicroservice PaymentMicroserviceConfiguration
|
||||
JWT JWTConfiguration
|
||||
Kafka KafkaConfiguration
|
||||
AuthMicroservice AuthMicroserviceConfiguration
|
||||
HubadminMicroservice HubadminMicroserviceConfiguration
|
||||
CurrencyMicroservice CurrencyMicroserviceConfiguration
|
||||
DiscountMicroservice DiscountMicroserviceConfiguration
|
||||
PaymentMicroservice PaymentMicroserviceConfiguration
|
||||
VerificationMicroservice VerificationMicroserviceConfiguration
|
||||
TemplategenMicroserviceURL TemplategenMicroserviceConfiguration
|
||||
JWT JWTConfiguration
|
||||
Kafka KafkaConfiguration
|
||||
}
|
||||
|
||||
type KafkaConfiguration struct {
|
||||
@ -65,6 +67,14 @@ type CurrencyMicroserviceConfiguration struct {
|
||||
URL CurrencyMicroserviceURL
|
||||
}
|
||||
|
||||
type VerificationMicroserviceConfiguration struct {
|
||||
URL VerificationMicroserviceURL
|
||||
}
|
||||
|
||||
type TemplategenMicroserviceConfiguration struct {
|
||||
URL TemplategenMicroserviceURL
|
||||
}
|
||||
|
||||
type PaymentMicroserviceConfiguration struct {
|
||||
HostGRPC string `env:"PAYMENT_MICROSERVICE_GRPC_HOST,required"`
|
||||
}
|
||||
@ -84,3 +94,11 @@ type HubadminMicroserviceURL struct {
|
||||
type CurrencyMicroserviceURL struct {
|
||||
Translate string `env:"CURRENCY_MICROSERVICE_TRANSLATE_URL,required"`
|
||||
}
|
||||
|
||||
type VerificationMicroserviceURL struct {
|
||||
Verification string `env:"VERIFICATION_MICROSERVICE_USER_URL,required"`
|
||||
}
|
||||
|
||||
type TemplategenMicroserviceURL struct {
|
||||
Templategen string `env:"TEMPLATEGEN_MICROSERVICE_URL,required"`
|
||||
}
|
||||
|
@ -18,6 +18,23 @@ type TariffID struct {
|
||||
ID string `json:"id" bson:"_id"`
|
||||
}
|
||||
|
||||
type ReportHistory struct {
|
||||
ID string `json:"id" bson:"_id,omitempty"`
|
||||
UserID string `json:"userId" bson:"userId"`
|
||||
Comment string `json:"comment" bson:"comment"`
|
||||
Key string `json:"key" bson:"key"`
|
||||
RawDetails RawDetails `json:"rawDetails" bson:"rawDetails"`
|
||||
Deleted bool `json:"isDeleted" bson:"isDeleted"`
|
||||
CreatedAt time.Time `json:"createdAt" bson:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt"`
|
||||
DeletedAt *time.Time `json:"deletedAt,omitempty" bson:"deletedAt,omitempty"`
|
||||
}
|
||||
|
||||
type RawDetails struct {
|
||||
Tariffs []Tariff `json:"tariffs" bson:"tariffs"`
|
||||
Price int64 `json:"price" bson:"price"`
|
||||
}
|
||||
|
||||
func (receiver *History) Sanitize() *History {
|
||||
now := time.Now()
|
||||
|
||||
|
12
internal/models/templategen.go
Normal file
12
internal/models/templategen.go
Normal file
@ -0,0 +1,12 @@
|
||||
package models
|
||||
|
||||
type RespGeneratorService struct {
|
||||
DocNumber int `json:"docnumber"`
|
||||
Date string `json:"date"`
|
||||
OrgTaxNum string `json:"orgtaxnum"`
|
||||
OrgName Name `json:"orgname"`
|
||||
Name string `json:"name"`
|
||||
Amount uint64 `json:"amount"`
|
||||
Price int64 `json:"price"`
|
||||
Sum int64 `json:"sum"`
|
||||
}
|
19
internal/models/verification.go
Normal file
19
internal/models/verification.go
Normal file
@ -0,0 +1,19 @@
|
||||
package models
|
||||
|
||||
import "time"
|
||||
|
||||
type Verification struct {
|
||||
ID string `json:"_id" bson:"_id,omitempty"`
|
||||
UserID string `json:"userID" bson:"user_id,omitempty"`
|
||||
Accepted bool `json:"accepted" bson:"accepted"`
|
||||
Status string `json:"status" bson:"status,omitempty"`
|
||||
UpdatedAt time.Time `json:"updated_at" bson:"updated_at"`
|
||||
Comment string `json:"comment" bson:"comment,omitempty"`
|
||||
Files []VerificationFile `json:"files" bson:"files,omitempty"`
|
||||
TaxNumber string `json:"taxnumber" bson:"taxnumber,omitempty"`
|
||||
}
|
||||
|
||||
type VerificationFile struct {
|
||||
Name string `json:"name" bson:"name"`
|
||||
URL string `json:"url" bson:"url"`
|
||||
}
|
@ -5,6 +5,8 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"math"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.uber.org/zap"
|
||||
@ -33,16 +35,36 @@ type historyRepository interface {
|
||||
FindMany(context.Context, *GetHistories) ([]models.History, errors.Error)
|
||||
Insert(context.Context, *models.History) (*models.History, errors.Error)
|
||||
GetRecentTariffs(context.Context, string) ([]models.TariffID, errors.Error) // new
|
||||
GetHistoryByID(context.Context, string) (*models.ReportHistory, errors.Error)
|
||||
GetDocNumber(context.Context, string) (map[string]int, errors.Error)
|
||||
}
|
||||
|
||||
type authClient interface {
|
||||
GetUser(ctx context.Context, userID string) (*models.User, errors.Error)
|
||||
}
|
||||
|
||||
type verificationClient interface {
|
||||
GetUser(ctx context.Context, userID string) (*models.Verification, errors.Error)
|
||||
}
|
||||
|
||||
type temlategenClient interface {
|
||||
SendData(ctx context.Context, data models.RespGeneratorService, fileContents []byte, email string) errors.Error
|
||||
}
|
||||
|
||||
type Deps struct {
|
||||
Logger *zap.Logger
|
||||
Repository historyRepository
|
||||
Logger *zap.Logger
|
||||
Repository historyRepository
|
||||
AuthClient authClient
|
||||
VerificationClient verificationClient
|
||||
TemlategenClient temlategenClient
|
||||
}
|
||||
|
||||
type Service struct {
|
||||
logger *zap.Logger
|
||||
repository historyRepository
|
||||
logger *zap.Logger
|
||||
repository historyRepository
|
||||
AuthClient authClient
|
||||
VerificationClient verificationClient
|
||||
TemlategenClient temlategenClient
|
||||
}
|
||||
|
||||
func New(deps Deps) *Service {
|
||||
@ -54,9 +76,14 @@ func New(deps Deps) *Service {
|
||||
log.Panicln("repository is nil on <New (history service)>")
|
||||
}
|
||||
|
||||
if deps.AuthClient == nil {
|
||||
log.Panicln("auth client is nil on <New (account service)>")
|
||||
}
|
||||
|
||||
return &Service{
|
||||
logger: deps.Logger,
|
||||
repository: deps.Repository,
|
||||
AuthClient: deps.AuthClient,
|
||||
}
|
||||
}
|
||||
|
||||
@ -130,3 +157,105 @@ func (receiver *Service) GetRecentTariffs(ctx context.Context, userID string) ([
|
||||
|
||||
return tariffs, nil
|
||||
}
|
||||
|
||||
func (receiver *Service) GetHistoryByID(ctx context.Context, historyID string) errors.Error {
|
||||
if historyID == "" {
|
||||
receiver.logger.Error("history id is missing in <GetHistoryById> of <HistoryService>")
|
||||
return errors.New(
|
||||
fmt.Errorf("history id is missing: %w", errors.ErrInvalidArgs),
|
||||
errors.ErrInvalidArgs,
|
||||
)
|
||||
}
|
||||
|
||||
tariffs, err := receiver.repository.GetHistoryByID(ctx, historyID)
|
||||
if err != nil {
|
||||
receiver.logger.Error(
|
||||
"failed to get history by id in <GetHistoryById> of <HistoryService>",
|
||||
zap.String("historyID", historyID),
|
||||
zap.Error(err),
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
if tariffs.Key != models.CustomerHistoryKeyPayCart {
|
||||
receiver.logger.Error(
|
||||
"invalid history record key",
|
||||
zap.String("historyID", historyID),
|
||||
zap.Error(err),
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
historyMap, err := receiver.repository.GetDocNumber(ctx, tariffs.UserID)
|
||||
if err != nil {
|
||||
receiver.logger.Error(
|
||||
"failed to get history of sorting by date created in <GetDocNumber> of <HistoryService>",
|
||||
zap.String("historyID", historyID),
|
||||
zap.Error(err),
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
verifuser, err := receiver.VerificationClient.GetUser(ctx, tariffs.UserID)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to get user verification on <GetHistoryById> of <HistoryService>",
|
||||
zap.Error(err),
|
||||
zap.String("userID", tariffs.UserID),
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
if !verifuser.Accepted {
|
||||
receiver.logger.Error(
|
||||
"verification not accepted",
|
||||
zap.String("userID", tariffs.UserID),
|
||||
zap.Error(err),
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
authuser, err := receiver.AuthClient.GetUser(ctx, tariffs.UserID)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to get user on <GetHistoryById> of <HistoryService>",
|
||||
zap.Error(err),
|
||||
zap.String("userID", tariffs.UserID),
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
fileContents, readerr := os.ReadFile("./report.docx")
|
||||
if readerr != nil {
|
||||
return errors.New(
|
||||
fmt.Errorf("failed to read file: %w", errors.ErrInternalError),
|
||||
errors.ErrInternalError,
|
||||
)
|
||||
}
|
||||
|
||||
for _, tariff := range tariffs.RawDetails.Tariffs {
|
||||
totalAmount := uint64(0)
|
||||
for _, privilege := range tariff.Privileges {
|
||||
totalAmount += privilege.Amount
|
||||
}
|
||||
data := models.RespGeneratorService{
|
||||
DocNumber: historyMap[historyID] + 1,
|
||||
Date: time.Now().Format("2006-01-02"),
|
||||
OrgTaxNum: verifuser.TaxNumber,
|
||||
OrgName: models.Name{Orgname: "Orgname"},
|
||||
Name: tariff.Name,
|
||||
Amount: totalAmount,
|
||||
Price: tariffs.RawDetails.Price,
|
||||
Sum: tariffs.RawDetails.Price,
|
||||
}
|
||||
err = receiver.TemlategenClient.SendData(ctx, data, fileContents, authuser.Email)
|
||||
if err != nil {
|
||||
receiver.logger.Error("failed to send report to user on <GetHistoryById> of <HistoryService>",
|
||||
zap.Error(err),
|
||||
zap.String("userID", tariffs.UserID),
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
BIN
report.docx
Normal file
BIN
report.docx
Normal file
Binary file not shown.
37
tests/integration/history_report_test.go
Normal file
37
tests/integration/history_report_test.go
Normal file
@ -0,0 +1,37 @@
|
||||
package integration_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/swagger"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/client"
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/tests/helpers"
|
||||
)
|
||||
|
||||
func TestHistoryReport(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
jwtUtil := helpers.InitializeJWT()
|
||||
token, err := jwtUtil.Create("807f1f77bcf81cd799439077")
|
||||
// t.Log("TOKEN:", token)
|
||||
if ok := assert.NoError(t, err); !ok {
|
||||
return
|
||||
}
|
||||
|
||||
response, err := client.Post[struct{}, models.ResponseErrorHTTP](ctx, &client.RequestSettings{
|
||||
URL: "http://" + customerServiceBase + "/sendReport",
|
||||
Body: swagger.SendReportJSONBody{Id: "10002"},
|
||||
Headers: map[string]string{"Authorization": fmt.Sprintf("Bearer %s", token)},
|
||||
})
|
||||
if ok := assert.NoError(t, err); !ok {
|
||||
return
|
||||
}
|
||||
if ok := assert.Nil(t, response.Error); !ok {
|
||||
return
|
||||
}
|
||||
|
||||
assert.Equal(t, 200, response.StatusCode)
|
||||
}
|
@ -3,6 +3,7 @@ package integration_test
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@ -11,6 +12,8 @@ import (
|
||||
"penahub.gitlab.yandexcloud.net/pena-services/customer/tests/helpers"
|
||||
)
|
||||
|
||||
var customerServiceBase string = os.Getenv("CUSTOMER_SERVICE")
|
||||
|
||||
func TestSetAccountVerificationStatusNO(t *testing.T) {
|
||||
jwtUtil := helpers.InitializeJWT()
|
||||
|
||||
@ -25,7 +28,7 @@ func TestSetAccountVerificationStatusNO(t *testing.T) {
|
||||
}
|
||||
|
||||
response, getAccountErr := client.Patch[models.Account, models.ResponseErrorHTTP](ctx, &client.RequestSettings{
|
||||
URL: "http://localhost:8082/account/807f1f77bcf81cd799439077",
|
||||
URL: "http://" + customerServiceBase + "/account/807f1f77bcf81cd799439077",
|
||||
Body: models.SetAccountStatus{Status: models.AccountStatusNo},
|
||||
Headers: map[string]string{"Authorization": fmt.Sprintf("Bearer %s", token)},
|
||||
})
|
||||
@ -56,7 +59,7 @@ func TestSetAccountVerificationStatusORG(t *testing.T) {
|
||||
}
|
||||
|
||||
response, getAccountErr := client.Patch[models.Account, models.ResponseErrorHTTP](ctx, &client.RequestSettings{
|
||||
URL: "http://localhost:8082/account/807f1f77bcf81cd799439077",
|
||||
URL: "http://" + customerServiceBase + "/account/807f1f77bcf81cd799439077",
|
||||
Body: models.SetAccountStatus{Status: models.AccountStatusOrg},
|
||||
Headers: map[string]string{"Authorization": fmt.Sprintf("Bearer %s", token)},
|
||||
})
|
||||
@ -87,7 +90,7 @@ func TestSetAccountVerificationStatusNKO(t *testing.T) {
|
||||
}
|
||||
|
||||
response, getAccountErr := client.Patch[models.Account, models.ResponseErrorHTTP](ctx, &client.RequestSettings{
|
||||
URL: "http://localhost:8082/account/807f1f77bcf81cd799439077",
|
||||
URL: "http://" + customerServiceBase + "/account/807f1f77bcf81cd799439077",
|
||||
Body: models.SetAccountStatus{Status: models.AccountStatusNko},
|
||||
Headers: map[string]string{"Authorization": fmt.Sprintf("Bearer %s", token)},
|
||||
})
|
||||
@ -118,7 +121,7 @@ func TestSetAccountVerificationStatusFailure(t *testing.T) {
|
||||
}
|
||||
|
||||
response, getAccountErr := client.Patch[models.Account, models.ResponseErrorHTTP](ctx, &client.RequestSettings{
|
||||
URL: "http://localhost:8082/account/807f1f77bcf81cd799439077",
|
||||
URL: "http://" + customerServiceBase + "/account/807f1f77bcf81cd799439077",
|
||||
Body: models.SetAccountStatus{Status: "radnom-status"},
|
||||
Headers: map[string]string{"Authorization": fmt.Sprintf("Bearer %s", token)},
|
||||
})
|
||||
|
@ -25,7 +25,7 @@ func TestUpdateAccountName(t *testing.T) {
|
||||
}
|
||||
|
||||
response, getAccountErr := client.Patch[models.Account, models.ResponseErrorHTTP](ctx, &client.RequestSettings{
|
||||
URL: "http://localhost:8082/account",
|
||||
URL: "http://" + customerServiceBase + "/account",
|
||||
Body: models.Name{
|
||||
FirstName: "Ivan",
|
||||
Secondname: "Ivanov",
|
||||
|
0
tools/migrate
Normal file → Executable file
0
tools/migrate
Normal file → Executable file
Loading…
Reference in New Issue
Block a user