Merge remote-tracking branch 'origin/trashlogger' into staging

This commit is contained in:
skeris 2024-06-06 21:01:08 +03:00
commit a470a23f4c
31 changed files with 767 additions and 53 deletions

40
.env.test Normal file

@ -0,0 +1,40 @@
# JWT settings
JWT_ISSUER="pena-auth-service"
JWT_AUDIENCE="pena"
JWT_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\nMIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgHgnvr7O2tiApjJfid1orFnIGm69\n80fZp+Lpbjo+NC/0whMFga2Biw5b1G2Q/B2u0tpO1Fs/E8z7Lv1nYfr5jx2S8x6B\ndA4TS2kB9Kf0wn0+7wSlyikHoKhbtzwXHZl17GsyEi6wHnsqNBSauyIWhpha8i+Y\n+3GyaOY536H47qyXAgMBAAE=\n-----END PUBLIC KEY-----"
HTTP_HOST=0.0.0.0
HTTP_PORT=8082
GRPC_HOST=0.0.0.0
GRPC_PORT=9001
GRPC_DOMEN=customer-service:9000
MONGO_HOST=localhost
MONGO_PORT=27020
MONGO_USER=test
MONGO_PASSWORD=test
MONGO_DB_NAME=admin
MONGO_AUTH=admin
KAFKA_BROKERS=localhost:9092
KAFKA_TOPIC_TARIFF=test-topic
AUTH_MICROSERVICE_USER_URL=http://localhost:8000/user
HUBADMIN_MICROSERVICE_TARIFF_URL=http://localhost:8001/tariff
CURRENCY_MICROSERVICE_TRANSLATE_URL=http://cbrfworker-service:8000/change
DISCOUNT_MICROSERVICE_GRPC_HOST=localhost:9040
PAYMENT_MICROSERVICE_GRPC_HOST=treasurer-service:9085
VERIFICATION_MICROSERVICE_USER_URL=http://10.8.0.8:7035/verification
TEMPLATEGEN_MICROSERVICE_URL=10.6.0.17
CODEWORD_MICROSERVICE_GRPC_HOST = http://localhost:8000/user
TRASH_LOG_HOST=localhost:7113
API_URL=https://api.smtp.bz/v1/smtp/send
MAIL_SENDER=noreply@mailing.pena.digital
MAIL_API_KEY=P0YsjUB137upXrr1NiJefHmXVKW1hmBWlpev
MAIL_AUTH_USERNAME=kotilion.95@gmail.com
MAIL_AUTH_PASSWORD=vWwbCSg4bf0p
MAIL_ADDRESS = mail@mail.com
MODULE_LOGGER = local-customer

2
.gitignore vendored

@ -5,3 +5,5 @@ vendor/
.env
main
/versionrecover.bolt
/recover.bolt

@ -821,7 +821,21 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/Error"
/account/pipe:
get:
tags:
- account
summary: Получение изменений аккаунта через SSE
operationId: accountPipe
security:
- Bearer: [ ]
responses:
'200':
description: Успешный ответ
content:
text/event-stream:
schema:
$ref: '#/components/schemas/Account'
components:

@ -4,18 +4,34 @@ import (
"encoding/json"
"fmt"
"log"
"os"
"time"
"go.uber.org/zap"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/app"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/initialize"
)
var (
commit string = os.Getenv("COMMIT")
buildTime string = os.Getenv("BUILD_TIME")
version string = os.Getenv("VERSION")
)
// $env:COMMIT=$(git rev-parse --short HEAD); $env:BUILD_TIME=$(Get-Date -UFormat "%Y-%m-%dT%H:%M:%SZ"); $env:VERSION=$(git describe --tags); go run cmd/app/main.go
func main() {
logger, err := zap.NewProduction(zap.AddStacktrace(zap.DPanicLevel))
if err != nil {
log.Fatalf("failed to init zap logger: %v", err)
}
ptime, err := time.Parse(time.RFC3339, buildTime)
if err != nil {
logger.Error("Error parsing build time:", zap.Error(err))
ptime = time.Now()
}
config, err := initialize.Configuration(".env.test")
if err != nil {
logger.Fatal("failed to init config: %v", zap.Error(err))
@ -28,7 +44,11 @@ func main() {
fmt.Println("env configuration: \n", string(configJSON))
if err := app.Run(config, logger); err != nil {
if err := app.Run(config, logger, app.Build{
Commit: commit,
Version: version,
BuildTime: ptime.Unix(),
}); err != nil {
logger.Fatal("failed to run app: %v", zap.Error(err))
}
}

@ -28,6 +28,7 @@ PAYMENT_MICROSERVICE_GRPC_HOST=treasurer-service:9085
VERIFICATION_MICROSERVICE_USER_URL=http://10.8.0.8:7035/verification
TEMPLATEGEN_MICROSERVICE_URL=10.6.0.17
CODEWORD_MICROSERVICE_GRPC_HOST = http://localhost:8000/user
TRASH_LOG_HOST=localhost:7113
API_URL=https://api.smtp.bz/v1/smtp/send
MAIL_SENDER=noreply@mailing.pena.digital

11
go.mod

@ -12,6 +12,7 @@ require (
github.com/pioz/faker v1.7.3
github.com/sethvargo/go-envconfig v1.0.0
github.com/stretchr/testify v1.8.4
github.com/themakers/hlog v0.0.0-20191205140925-235e0e4baddf
github.com/twmb/franz-go v1.16.1
github.com/twmb/franz-go/pkg/kadm v1.11.0
go.mongodb.org/mongo-driver v1.14.0
@ -19,12 +20,15 @@ require (
google.golang.org/genproto/googleapis/api v0.0.0-20240221002015-b0ce06bbee7c
google.golang.org/grpc v1.62.0
google.golang.org/protobuf v1.33.0
penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240223054633-6cb3d5ce45b6
penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240202120244-c4ef330cfe5d
penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240520145524-451212248881
penahub.gitlab.yandexcloud.net/external/trashlog.git v0.1.2-0.20240523172059-9bbe8a9faa31
)
require (
github.com/ClickHouse/clickhouse-go v1.5.4 // indirect
github.com/andybalholm/brotli v1.1.0 // indirect
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect
@ -37,9 +41,12 @@ require (
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/montanaflynn/stats v0.7.1 // indirect
github.com/pierrec/lz4/v4 v4.1.21 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/rs/xid v1.5.0 // indirect
github.com/skeris/appInit v1.0.2 // indirect
github.com/tealeg/xlsx v1.0.5 // indirect
github.com/twmb/franz-go/pkg/kmsg v1.7.0 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
@ -50,6 +57,7 @@ require (
github.com/xdg-go/scram v1.1.2 // indirect
github.com/xdg-go/stringprep v1.0.4 // indirect
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect
go.etcd.io/bbolt v1.3.6 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/crypto v0.20.0 // indirect
golang.org/x/net v0.21.0 // indirect
@ -59,5 +67,6 @@ require (
google.golang.org/genproto v0.0.0-20240221002015-b0ce06bbee7c // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240221002015-b0ce06bbee7c // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/tucnak/telebot.v2 v2.5.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

61
go.sum

@ -1,10 +1,16 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/ClickHouse/clickhouse-go v1.5.4 h1:cKjXeYLNWVJIx2J1K6H2CqyRmfwVJVY1OV1coaaFcI0=
github.com/ClickHouse/clickhouse-go v1.5.4/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI=
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/bkaradzic/go-lz4 v1.0.0 h1:RXc4wYsyz985CkXXeX04y4VnZFGG8Rd43pRaHsOXAKk=
github.com/bkaradzic/go-lz4 v1.0.0/go.mod h1:0YdlkowM3VswSROI7qDxhRvJ3sLhlFrRRwjwegp5jy4=
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/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58 h1:F1EaeKL/ta07PY/k9Os/UFtwERei2/XzGemhpGnBKNg=
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -14,10 +20,15 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg=
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-resty/resty/v2 v2.11.0 h1:i7jMfNOJYMp69lq7qozJP+bjgzfAzeOhuGlyDrqxT/8=
github.com/go-resty/resty/v2 v2.11.0/go.mod h1:iiP/OpA0CkcL3IGt1O0+/SIItFUbkkyw5BGXiVdTu+A=
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gofiber/fiber/v2 v2.52.1 h1:1RoU2NS+b98o1L77sdl5mboGPiW+0Ypsi5oLmcYlgHI=
github.com/gofiber/fiber/v2 v2.52.1/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ=
@ -39,10 +50,12 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
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/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
@ -62,6 +75,7 @@ github.com/labstack/echo/v4 v4.11.4 h1:vDZmA+qNeh1pd/cCkEicDMrjtrnMGQ1QFI9gWN1zG
github.com/labstack/echo/v4 v4.11.4/go.mod h1:noh7EvLwqDsmh/X/HWKPUl1AjzJrhyptRyEbQJfxen8=
github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
@ -69,38 +83,59 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE=
github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/onsi/ginkgo v1.16.0 h1:NBrNLB37exjJLxXtFOktx6CISBdS1aF8+7MwKlTV8U4=
github.com/onsi/ginkgo v1.16.0/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E=
github.com/onsi/gomega v1.11.0 h1:+CqWgvj0OZycCaqclBD1pxKHAU+tOkHmQIWvDHq2aug=
github.com/onsi/gomega v1.11.0/go.mod h1:azGKhqFUon9Vuj0YmTfLSmx0FUwqXYSTl5re8lQLTUg=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ=
github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pioz/faker v1.7.3 h1:Tez8Emuq0UN+/d6mo3a9m/9ZZ/zdfJk0c5RtRatrceM=
github.com/pioz/faker v1.7.3/go.mod h1:xSpay5w/oz1a6+ww0M3vfpe40pSIykeUPeWEc3TvVlc=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc=
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/sethvargo/go-envconfig v1.0.0 h1:1C66wzy4QrROf5ew4KdVw942CQDa55qmlYmw9FZxZdU=
github.com/sethvargo/go-envconfig v1.0.0/go.mod h1:Lzc75ghUn5ucmcRGIdGQ33DKJrcjk4kihFYgSTBmjIc=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/skeris/appInit v1.0.2 h1:Hr4KbXYd6kolTVq4cXGqDpgnpmaauiOiKizA1+Ep4KQ=
github.com/skeris/appInit v1.0.2/go.mod h1:4ElEeXWVGzU3dlYq/eMWJ/U5hd+LKisc1z3+ySh1XmY=
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=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/tealeg/xlsx v1.0.5 h1:+f8oFmvY8Gw1iUXzPk+kz+4GpbDZPK1FhPiQRd+ypgE=
github.com/tealeg/xlsx v1.0.5/go.mod h1:btRS8dz54TDnvKNosuAqxrM1QgN1udgk9O34bDCnORM=
github.com/themakers/bdd v0.0.0-20210316111417-6b1dfe326f33 h1:N9f/Q+2Ssa+yDcbfaoLTYvXmdeyUUxsJKdPUVsjSmiA=
github.com/themakers/bdd v0.0.0-20210316111417-6b1dfe326f33/go.mod h1:rpcH99JknBh8seZmlOlUg51gasZH6QH34oXNsIwYT6E=
github.com/themakers/hlog v0.0.0-20191205140925-235e0e4baddf h1:TJJm6KcBssmbWzplF5lzixXl1RBAi/ViPs1GaSOkhwo=
github.com/themakers/hlog v0.0.0-20191205140925-235e0e4baddf/go.mod h1:1FsorU3vnXO9xS9SrhUp8fRb/6H/Zfll0rPt1i4GWaA=
github.com/twmb/franz-go v1.16.1 h1:rpWc7fB9jd7TgmCyfxzenBI+QbgS8ZfJOUQE+tzPtbE=
github.com/twmb/franz-go v1.16.1/go.mod h1:/pER254UPPGp/4WfGqRi+SIRGE50RSQzVubQp6+N4FA=
github.com/twmb/franz-go/pkg/kadm v1.11.0 h1:FfeWJ0qadntFpAcQt8JzNXW4dijjytZNLrzJuzzzuxA=
@ -126,19 +161,26 @@ github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a/go.mod h1:ul22v+Nro/
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd80=
go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c=
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
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/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ=
go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@ -151,6 +193,7 @@ golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTk
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
@ -184,6 +227,7 @@ golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5h
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=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@ -219,6 +263,9 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
@ -256,15 +303,25 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/tucnak/telebot.v2 v2.5.0 h1:i+NynLo443Vp+Zn3Gv9JBjh3Z/PaiKAQwcnhNI7y6Po=
gopkg.in/tucnak/telebot.v2 v2.5.0/go.mod h1:BgaIIx50PSRS9pG59JH+geT82cfvoJU/IaI5TJdN3v8=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240223054633-6cb3d5ce45b6 h1:oV+/HNX+JPoQ3/GUx08hio7d45WpY0AMGrFs7j70QlA=
penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240223054633-6cb3d5ce45b6/go.mod h1:lTmpjry+8evVkXWbEC+WMOELcFkRD1lFMc7J09mOndM=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240202120244-c4ef330cfe5d h1:gbaDt35HMDqOK84WYmDIlXMI7rstUcRqNttaT6Kx1do=
penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240202120244-c4ef330cfe5d/go.mod h1:lTmpjry+8evVkXWbEC+WMOELcFkRD1lFMc7J09mOndM=
penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240520145524-451212248881 h1:U1/WGQdwZsmrV/ta7Uqm13Dg07IPN/5omS8gzBJYZv4=
penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240520145524-451212248881/go.mod h1:oRyhT55ctjqp/7ZxIzkR7OsQ7T/NLibsfrbb7Ytns64=
penahub.gitlab.yandexcloud.net/external/trashlog.git v0.1.2-0.20240523172059-9bbe8a9faa31 h1:WlRVJnzU0sti+qBq/JTCgFPU0RoxIqGHu7hzDirxE2k=
penahub.gitlab.yandexcloud.net/external/trashlog.git v0.1.2-0.20240523172059-9bbe8a9faa31/go.mod h1:3ml0dAGT8U8RhpevKBfRgG6yKZum8EI2uJxAb2WCIy4=

@ -4,8 +4,12 @@ import (
"context"
"errors"
"fmt"
"github.com/themakers/hlog"
"go.uber.org/zap/zapcore"
"os/signal"
"penahub.gitlab.yandexcloud.net/backend/penahub_common/mongo"
"penahub.gitlab.yandexcloud.net/external/trashlog.git/app"
"penahub.gitlab.yandexcloud.net/external/trashlog.git/wrappers/zaptrashlog"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/controller/http"
"syscall"
"time"
@ -24,7 +28,13 @@ const (
shutdownTimeout = 5 * time.Second
)
func Run(config *models.Config, logger *zap.Logger) (appErr error) {
type Build struct {
Commit string
Version string
BuildTime int64
}
func Run(config *models.Config, logger *zap.Logger, build Build) (appErr error) {
defer func() {
if recovered := recover(); recovered != nil {
appErr = errors.New("recovered panic on application run")
@ -37,6 +47,31 @@ func Run(config *models.Config, logger *zap.Logger) (appErr error) {
ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
defer cancel()
clickHouseLogger, err := zaptrashlog.NewCore(ctx, zap.InfoLevel, config.Service.TrashLogHost, build.Version, build.Commit, build.BuildTime)
if err != nil {
panic(err)
}
//telegrammLogger, err := zaptg.NewCore(ctx,
// zap.InfoLevel,
// "1408111289:AAHfWZRiBQRncb2gl2LtU8OeASjfJi4e8YE",
// build.Version,
// build.Commit,
// build.BuildTime,
// -1001256687920,
//)
//if err != nil {
// panic(err)
//}
loggerForHlog := logger.WithOptions(zap.WrapCore(func(core zapcore.Core) zapcore.Core {
return zapcore.NewTee(core, clickHouseLogger)
}))
loggerHlog := hlog.New(loggerForHlog).Module(config.Service.ModuleLogger)
loggerHlog.With(models.AllFields{})
loggerHlog.Emit(app.InfoSvcStarted{})
if err := kafka.Initialize(ctx, config.Service.Kafka.Brokers, []string{
config.Service.Kafka.Tariff.Topic,
}); err != nil {
@ -101,6 +136,7 @@ func Run(config *models.Config, logger *zap.Logger) (appErr error) {
Logger: logger,
Services: services,
Repositories: repositories,
HLogger: loggerHlog,
})
encrypt := qutils.NewEncrypt(config.Service.PubKey, config.Service.PrivKey)
@ -118,6 +154,7 @@ func Run(config *models.Config, logger *zap.Logger) (appErr error) {
serverHTTP := server.NewServer(server.ServerConfig{
Logger: logger,
Hlog: loggerHlog,
Controllers: []server.Controller{httpControllers.CurrencyController, httpControllers.HistoryController, httpControllers.CartController, httpControllers.WalletController, httpControllers.AccountController},
JWTConfig: &config.Service.JWT,
})

@ -1,6 +1,7 @@
package initialize
import (
"github.com/themakers/hlog"
"go.uber.org/zap"
qutils "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/utils"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/broker/tariff"
@ -19,6 +20,7 @@ type RpcControllersDeps struct {
Logger *zap.Logger
Services *Services
Repositories *Repositories
HLogger hlog.Logger
}
type RpcControllers struct {
@ -31,6 +33,7 @@ func NewRpcControllers(deps RpcControllersDeps) *RpcControllers {
PaymentController: payment.New(payment.Deps{
Logger: deps.Logger,
PaymentCallbackService: deps.Services.PaymentCallbackService,
HLogger: deps.HLogger,
}),
CustomerController: customer.New(customer.Deps{
Logger: deps.Logger,

@ -2,6 +2,7 @@ package payment
import (
"context"
"github.com/themakers/hlog"
"log"
"go.uber.org/zap"
@ -15,11 +16,13 @@ import (
type Deps struct {
Logger *zap.Logger
PaymentCallbackService *callback.PaymentCallbackService
HLogger hlog.Logger
}
type Controller struct {
logger *zap.Logger
paymentCallbackService *callback.PaymentCallbackService
hLogger hlog.Logger
}
func New(deps Deps) *Controller {
@ -34,6 +37,7 @@ func New(deps Deps) *Controller {
return &Controller{
logger: deps.Logger,
paymentCallbackService: deps.PaymentCallbackService,
hLogger: deps.HLogger,
}
}
@ -45,12 +49,20 @@ func (receiver *Controller) OnSuccess(ctx context.Context, in *payment_callback.
Currency: in.Payment.Currency,
Amount: in.Payment.Amount,
UserID: in.Payment.UserID,
Type: in.Payment.Type,
Type: in.Payment.Type,
}); err != nil {
receiver.logger.Error("failed to send success event on <OnSuccess> of <PaymentController>", zap.Error(err))
return nil, errors.GRPC("failed to send success event", err)
}
receiver.hLogger.Emit(models.InfoMoneyIncome{
CtxUserID: in.Payment.UserID,
CtxPrice: uint64(in.Payment.Amount),
KeyCurrency: in.Payment.Currency,
CtxID: in.Payment.PaymentID,
KeyPaymentType: in.Payment.Type,
})
return &emptypb.Empty{}, nil
}

@ -1,6 +1,10 @@
package account
import (
"bufio"
"context"
"encoding/json"
"fmt"
"github.com/gofiber/fiber/v2"
"go.uber.org/zap"
"math"
@ -11,6 +15,7 @@ import (
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/repository"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
"strconv"
"strings"
)
type Deps struct {
@ -39,7 +44,7 @@ func NewAccountController(deps Deps) *AccountController {
}
}
func (receiver *AccountController) DeleteAccount(ctx *fiber.Ctx) error {
func (receiver *AccountController) Delete(ctx *fiber.Ctx) error {
userID, ok := receiver.middleWare.ExtractUserID(ctx)
if !ok || userID == "" {
return receiver.middleWare.NoAuth(ctx)
@ -53,7 +58,7 @@ func (receiver *AccountController) DeleteAccount(ctx *fiber.Ctx) error {
return ctx.Status(fiber.StatusOK).JSON(account)
}
func (receiver *AccountController) ChangeAccount(ctx *fiber.Ctx) error {
func (receiver *AccountController) Update(ctx *fiber.Ctx) error {
userID, ok := receiver.middleWare.ExtractUserID(ctx)
if !ok || userID == "" {
return receiver.middleWare.NoAuth(ctx)
@ -72,7 +77,7 @@ func (receiver *AccountController) ChangeAccount(ctx *fiber.Ctx) error {
return ctx.Status(fiber.StatusOK).JSON(account)
}
func (receiver *AccountController) SetAccountVerificationStatus(ctx *fiber.Ctx) error {
func (receiver *AccountController) SetVerificationStatus(ctx *fiber.Ctx) error {
userID := ctx.Params("userId")
if userID == "" {
return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "invalid format for parameter userId")
@ -92,26 +97,39 @@ func (receiver *AccountController) SetAccountVerificationStatus(ctx *fiber.Ctx)
return ctx.Status(fiber.StatusOK).JSON(account)
}
func (receiver *AccountController) GetAccount(ctx *fiber.Ctx) error {
func (receiver *AccountController) Get(ctx *fiber.Ctx) error {
userID, ok := receiver.middleWare.ExtractUserID(ctx)
if !ok || userID == "" {
return receiver.middleWare.NoAuth(ctx)
}
hlogger := receiver.middleWare.ExtractLogger(ctx)
account, err := receiver.accountRepo.FindByUserID(ctx.Context(), userID)
if err != nil {
return receiver.middleWare.ErrorOld(ctx, err)
}
hlogger.Emit(models.InfoGetAccount{
CtxUserIP: ctx.IP(),
CtxUserPort: ctx.Port(),
KeyDomain: strings.Join(ctx.Subdomains(), "/"),
KeyPath: ctx.Path(),
CtxUserID: userID,
CtxAccountID: account.ID,
})
return ctx.Status(fiber.StatusOK).JSON(account)
}
func (receiver *AccountController) AddAccount(ctx *fiber.Ctx) error {
func (receiver *AccountController) Create(ctx *fiber.Ctx) error {
userID, ok := receiver.middleWare.ExtractUserID(ctx)
if !ok || userID == "" {
return receiver.middleWare.NoAuth(ctx)
}
hlogger := receiver.middleWare.ExtractLogger(ctx)
var er error
quizFrom := ctx.Cookies("quizFrom")
@ -143,10 +161,31 @@ func (receiver *AccountController) AddAccount(ctx *fiber.Ctx) error {
return receiver.middleWare.ErrorOld(ctx, err)
}
quiz := ""
if quizFrom != "" {
quiz = "quiz"
}
hlogger.Emit(models.InfoCreateAccount{
CtxUserIP: ctx.IP(),
CtxUserPort: ctx.Port(),
KeyDomain: strings.Join(ctx.Subdomains(), "/"),
KeyPath: ctx.Path(),
CtxUserID: userID,
CtxAccountID: account.ID,
KeyFromSource: quiz,
KeyFromID: quizFrom,
KeyFromPartner: quizUser,
CtxLogin: user.Login,
CtxEmail: user.Email,
CtxPhone: user.PhoneNumber,
KeyCurrency: account.Wallet.Currency,
})
return ctx.Status(fiber.StatusOK).JSON(account)
}
func (receiver *AccountController) DeleteDirectAccount(ctx *fiber.Ctx) error {
func (receiver *AccountController) DeleteCurrent(ctx *fiber.Ctx) error {
userID := ctx.Params("userId")
if userID == "" {
return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "invalid format for parameter userId")
@ -160,7 +199,7 @@ func (receiver *AccountController) DeleteDirectAccount(ctx *fiber.Ctx) error {
return ctx.Status(fiber.StatusOK).JSON(account)
}
func (receiver *AccountController) GetDirectAccount(ctx *fiber.Ctx) error {
func (receiver *AccountController) GetCurrent(ctx *fiber.Ctx) error {
userID := ctx.Params("userId")
if userID == "" {
return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "invalid format for parameter userId")
@ -174,7 +213,7 @@ func (receiver *AccountController) GetDirectAccount(ctx *fiber.Ctx) error {
return ctx.Status(fiber.StatusOK).JSON(account)
}
func (receiver *AccountController) PaginationAccounts(ctx *fiber.Ctx) error {
func (receiver *AccountController) Pagination(ctx *fiber.Ctx) error {
pageStr := ctx.Query("page", "1")
limitStr := ctx.Query("limit", "100")
@ -213,3 +252,49 @@ func (receiver *AccountController) PaginationAccounts(ctx *fiber.Ctx) error {
return ctx.Status(fiber.StatusOK).JSON(response)
}
func (receiver *AccountController) AccountPipe(ctx *fiber.Ctx) error {
userID, ok := receiver.middleWare.ExtractUserID(ctx)
if !ok || userID == "" {
return receiver.middleWare.NoAuth(ctx)
}
ctx.Set(fiber.HeaderContentType, "text/event-stream")
ctx.Set("Cache-Control", "no-cache")
ctx.Set("Connection", "keep-alive")
ctx.Set("Transfer-Encoding", "chunked")
accountCh := make(chan models.Account)
cancelCtx, cancel := context.WithCancel(ctx.Context())
go func(ctx context.Context) {
defer close(accountCh)
if err := receiver.accountRepo.AccountPipe(ctx, userID, accountCh); err != nil {
receiver.logger.Error("error in account pipe repo method", zap.Error(err))
}
}(cancelCtx)
ctx.Status(fiber.StatusOK).Context().SetBodyStreamWriter(func(w *bufio.Writer) {
for {
select {
case account, ok := <-accountCh:
if !ok {
return
}
accountJSON, err := json.Marshal(account)
if err != nil {
receiver.logger.Error("error marshal account JSON", zap.Error(err))
continue
}
fmt.Fprintf(w, "data: %s\n\n", accountJSON)
if err := w.Flush(); err != nil {
receiver.logger.Error("error flushing", zap.Error(err))
cancel()
return
}
}
}
})
return nil
}

@ -3,14 +3,15 @@ package account
import "github.com/gofiber/fiber/v2"
func (receiver *AccountController) Register(router fiber.Router) {
router.Delete("/account", receiver.DeleteAccount)
router.Get("/account", receiver.GetAccount)
router.Patch("/account", receiver.ChangeAccount)
router.Post("/account", receiver.AddAccount)
router.Delete("/account/:userId", receiver.DeleteDirectAccount)
router.Get("/account/:userId", receiver.GetDirectAccount)
router.Patch("/account/:userId", receiver.SetAccountVerificationStatus)
router.Get("/accounts", receiver.PaginationAccounts)
router.Delete("/account", receiver.Delete)
router.Get("/account", receiver.Get)
router.Patch("/account", receiver.Update)
router.Post("/account", receiver.Create)
router.Delete("/account/:userId", receiver.DeleteCurrent)
router.Get("/account/:userId", receiver.GetCurrent)
router.Patch("/account/:userId", receiver.SetVerificationStatus)
router.Get("/accounts", receiver.Pagination)
router.Get("/account/pipe", receiver.AccountPipe)
}
func (receiver *AccountController) Name() string {

@ -14,6 +14,7 @@ import (
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/utils"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/utils/transfer"
"penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/validate"
"strings"
"sync"
"time"
)
@ -53,12 +54,12 @@ func NewCartController(deps Deps) *CartController {
}
}
func (receiver *CartController) RemoveFromCart(ctx *fiber.Ctx) error {
func (receiver *CartController) Remove(ctx *fiber.Ctx) error {
userID, ok := receiver.middleWare.ExtractUserID(ctx)
if !ok || userID == "" {
return receiver.middleWare.NoAuth(ctx)
}
// todo проверить менять или нет
id := ctx.Query("id")
if id == "" {
return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "empty item id")
@ -83,6 +84,8 @@ func (receiver *CartController) Add2cart(ctx *fiber.Ctx) error {
return receiver.middleWare.NoAuth(ctx)
}
hlogger := receiver.middleWare.ExtractLogger(ctx)
tariffID := ctx.Query("id")
if tariffID == "" {
return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "empty item id")
@ -102,10 +105,20 @@ func (receiver *CartController) Add2cart(ctx *fiber.Ctx) error {
return receiver.middleWare.ErrorOld(ctx, err)
}
hlogger.Emit(models.InfoAddToCart{
CtxUserIP: ctx.IP(),
CtxUserPort: ctx.Port(),
KeyDomain: strings.Join(ctx.Subdomains(), "/"),
KeyPath: ctx.Path(),
CtxUserID: userID,
CtxAccountID: cartItems.ID,
CtxTariffID: tariffID,
})
return ctx.Status(fiber.StatusOK).JSON(cartItems)
}
func (receiver *CartController) PayCart(ctx *fiber.Ctx) error {
func (receiver *CartController) Pay(ctx *fiber.Ctx) error {
userID, ok := receiver.middleWare.ExtractUserID(ctx)
if !ok || userID == "" {
return receiver.middleWare.NoAuth(ctx)
@ -116,6 +129,8 @@ func (receiver *CartController) PayCart(ctx *fiber.Ctx) error {
return receiver.middleWare.NoAuth(ctx)
}
hlogger := receiver.middleWare.ExtractLogger(ctx)
account, err := receiver.accountRepo.FindByUserID(ctx.Context(), userID)
if err != nil {
return receiver.middleWare.ErrorOld(ctx, err)
@ -158,6 +173,20 @@ func (receiver *CartController) PayCart(ctx *fiber.Ctx) error {
}))
if account.Wallet.Money < int64(discountResponse.Price) {
hlogger.Emit(models.InfoPayCart{
CtxUserIP: ctx.IP(),
CtxUserPort: ctx.Port(),
KeyDomain: strings.Join(ctx.Subdomains(), "/"),
KeyPath: ctx.Path(),
CtxUserID: userID,
CtxAccountID: account.ID,
KeySuccess: false,
CtxPrice: discountResponse.Price - uint64(account.Wallet.Money),
CtxTariff: strings.Join(account.Cart, ","),
CtxDiscount: strings.Join(utils.GetAppliedDiscountsIDs(discountResponse.AppliedDiscounts), ","),
CtxRowPrice: tariffsAmount,
CtxRowData: utils.MarshalRawDetails(models.RawDetails{Tariffs: tariffs, Price: int64(discountResponse.Price)}),
})
return receiver.middleWare.Error(ctx, fiber.StatusPaymentRequired, "insufficient funds: %d", int64(discountResponse.Price)-account.Wallet.Money)
}
@ -269,5 +298,20 @@ func (receiver *CartController) PayCart(ctx *fiber.Ctx) error {
updatedAccount.Cart = []string{}
hlogger.Emit(models.InfoPayCart{
CtxUserIP: ctx.IP(),
CtxUserPort: ctx.Port(),
KeyDomain: strings.Join(ctx.Subdomains(), "/"),
KeyPath: ctx.Path(),
CtxUserID: userID,
CtxAccountID: updatedAccount.ID,
KeySuccess: true,
CtxPrice: discountResponse.Price,
CtxTariff: strings.Join(account.Cart, ","),
CtxDiscount: strings.Join(utils.GetAppliedDiscountsIDs(discountResponse.AppliedDiscounts), ","),
CtxRowPrice: tariffsAmount,
CtxRowData: utils.MarshalRawDetails(models.RawDetails{Tariffs: tariffs, Price: int64(discountResponse.Price)}),
})
return ctx.Status(fiber.StatusOK).JSON(updatedAccount)
}

@ -3,9 +3,9 @@ package cart
import "github.com/gofiber/fiber/v2"
func (receiver *CartController) Register(router fiber.Router) {
router.Delete("/cart", receiver.RemoveFromCart)
router.Delete("/cart", receiver.Remove)
router.Patch("/cart", receiver.Add2cart)
router.Post("/cart/pay", receiver.PayCart)
router.Post("/cart/pay", receiver.Pay)
}
func (receiver *CartController) Name() string {

@ -29,7 +29,7 @@ func NewCurrencyController(deps Deps) *CurrencyController {
}
}
func (receiver *CurrencyController) GetCurrencies(ctx *fiber.Ctx) error {
func (receiver *CurrencyController) Get(ctx *fiber.Ctx) error {
currencyList, err := receiver.currencyRepo.FindCurrenciesList(ctx.Context(), models.DefaultCurrencyListName)
if err != nil && err.Type() != errors.ErrNotFound {
return receiver.middleWare.ErrorOld(ctx, err)
@ -42,7 +42,7 @@ func (receiver *CurrencyController) GetCurrencies(ctx *fiber.Ctx) error {
return ctx.Status(fiber.StatusOK).JSON(currencyList)
}
func (receiver *CurrencyController) UpdateCurrencies(ctx *fiber.Ctx) error {
func (receiver *CurrencyController) Update(ctx *fiber.Ctx) error {
var req struct {
items []string
}

@ -3,8 +3,8 @@ package currency
import "github.com/gofiber/fiber/v2"
func (receiver *CurrencyController) Register(router fiber.Router) {
router.Get("/currencies", receiver.GetCurrencies)
router.Put("/currencies", receiver.UpdateCurrencies)
router.Get("/currencies", receiver.Get)
router.Put("/currencies", receiver.Update)
}
func (receiver *CurrencyController) Name() string {

@ -12,7 +12,9 @@ import (
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
codeword_rpc "penahub.gitlab.yandexcloud.net/pena-services/customer/internal/proto/codeword"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/service/history"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/utils"
"strconv"
"strings"
"time"
)
@ -51,7 +53,7 @@ func NewHistoryController(deps Deps) *HistoryController {
}
}
func (receiver *HistoryController) GetHistory(ctx *fiber.Ctx) error {
func (receiver *HistoryController) Get(ctx *fiber.Ctx) error {
var userID string
pageStr := ctx.Query("page")
@ -164,6 +166,8 @@ func (receiver *HistoryController) GetRecentTariffs(ctx *fiber.Ctx) error {
}
func (receiver *HistoryController) SendReport(ctx *fiber.Ctx) error {
hlogger := receiver.middleWare.ExtractLogger(ctx)
var req struct {
Id string `json:"id"`
}
@ -279,20 +283,21 @@ func (receiver *HistoryController) SendReport(ctx *fiber.Ctx) error {
}
}
hlogger.Emit(models.InfoReportRequest{
CtxUserIP: ctx.IP(),
CtxUserPort: ctx.Port(),
KeyDomain: strings.Join(ctx.Subdomains(), "/"),
KeyPath: ctx.Path(),
CtxUserID: tariffs.UserID,
CtxAccountID: account.ID,
CtxID: req.Id,
CtxTariff: strings.Join(utils.GetTariffsIDs(tariffs.RawDetails.Tariffs), ","),
CtxOrgName: account.Name.Orgname,
})
return ctx.SendStatus(fiber.StatusOK)
}
type QuizLogoStat2 struct {
Count int64 `json:"count,omitempty"`
Items map[string]Item `json:"items,omitempty"`
}
type Item struct {
Money int64 `json:"money,omitempty"`
Quizes map[string][2]int `json:"quizes,omitempty"`
Regs int `json:"regs,omitempty"`
}
func (receiver *HistoryController) QuizLogoStat(ctx *fiber.Ctx) error {
var req struct {
From *int `json:"from,omitempty"`

@ -3,7 +3,7 @@ package history
import "github.com/gofiber/fiber/v2"
func (receiver *HistoryController) Register(router fiber.Router) {
router.Get("/history", receiver.GetHistory)
router.Get("/history", receiver.Get)
router.Post("/history/ltv", receiver.CalculateLTV)
router.Post("/promocode/ltv", receiver.PromocodeLTV)
router.Post("/quizlogo/stat", receiver.QuizLogoStat)

@ -3,6 +3,7 @@ package http
import (
"fmt"
"github.com/gofiber/fiber/v2"
"github.com/themakers/hlog"
"go.uber.org/zap"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
)
@ -53,3 +54,8 @@ func (mw *MiddleWare) ExtractToken(ctx *fiber.Ctx) (string, bool) {
func (mw *MiddleWare) GetHealth(ctx *fiber.Ctx) error {
return ctx.Status(fiber.StatusOK).SendString("OK")
}
func (mw *MiddleWare) ExtractLogger(ctx *fiber.Ctx) hlog.Logger {
logger := ctx.Context().UserValue(models.LoggerKey).(hlog.Logger)
return logger
}

@ -13,6 +13,7 @@ import (
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/proto/treasurer"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/utils"
"penahub.gitlab.yandexcloud.net/pena-services/customer/pkg/validate"
"strings"
)
type Deps struct {
@ -59,6 +60,8 @@ func (receiver *WalletController) RequestMoney(ctx *fiber.Ctx) error {
return receiver.middleWare.NoAuth(ctx)
}
hlogger := receiver.middleWare.ExtractLogger(ctx)
var request models.GetPaymentLinkBody
if err := ctx.BodyParser(&request); err != nil {
return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "failed to bind payment link")
@ -77,6 +80,20 @@ func (receiver *WalletController) RequestMoney(ctx *fiber.Ctx) error {
return receiver.middleWare.ErrorOld(ctx, err)
}
hlogger.Emit(models.InfoRequestMoney{
CtxUserIP: ctx.IP(),
CtxUserPort: ctx.Port(),
KeyDomain: strings.Join(ctx.Subdomains(), "/"),
KeyPath: ctx.Path(),
CtxUserID: userID,
// todo
CtxAccountID: "",
KeyPaymentType: string(request.Type),
KeyCurrency: request.Currency,
CtxPrice: uint64(request.Amount),
CtxReturnURL: link,
})
return ctx.Status(fiber.StatusOK).JSON(&models.GetPaymentLinkResponse{Link: link})
}
@ -270,6 +287,8 @@ func (receiver *WalletController) PostWalletRspay(ctx *fiber.Ctx) error {
return receiver.middleWare.NoAuth(ctx)
}
hlogger := receiver.middleWare.ExtractLogger(ctx)
var req struct {
Money *float32 `json:"money,omitempty"`
}
@ -310,5 +329,16 @@ func (receiver *WalletController) PostWalletRspay(ctx *fiber.Ctx) error {
return receiver.middleWare.ErrorOld(ctx, err)
}
hlogger.Emit(models.InfoRSPay{
CtxUserIP: ctx.IP(),
CtxUserPort: ctx.Port(),
KeyDomain: strings.Join(ctx.Subdomains(), "/"),
KeyPath: ctx.Path(),
CtxUserID: userID,
CtxAccountID: user.ID,
CtxPrice: uint64(*req.Money),
CtxLogin: authData.Login,
})
return ctx.SendStatus(fiber.StatusOK)
}

@ -498,3 +498,40 @@ func (receiver *AccountRepository) QuizLogoStat(ctx context.Context, req QuizLog
return results, nil
}
func (receiver *AccountRepository) AccountPipe(ctx context.Context, userID string, accountCh chan<- models.Account) error {
pipeline := mongo.Pipeline{
{{"$match", bson.M{"operationType": "update", "fullDocument.userId": userID}}},
}
opts := options.ChangeStream()
opts.SetFullDocument(options.UpdateLookup)
changeStream, err := receiver.mongoDB.Watch(ctx, pipeline, opts)
if err != nil {
return err
}
defer changeStream.Close(ctx)
for {
select {
case <-ctx.Done():
return nil
default:
if changeStream.Next(ctx) {
var changeEvent struct {
FullDocument models.Account `bson:"fullDocument"`
}
if err := changeStream.Decode(&changeEvent); err != nil {
receiver.logger.Error("error decoding change event", zap.Error(err))
continue
}
select {
case accountCh <- changeEvent.FullDocument:
case <-ctx.Done():
return nil
}
}
}
}
}

@ -15,3 +15,4 @@ type User struct {
const AuthJWTDecodedUserIDKey = "userID"
const AuthJWTDecodedAccessTokenKey = "access-token"
const LoggerKey = "logger"

@ -37,8 +37,10 @@ type ServiceConfiguration struct {
JWT JWTConfiguration
Kafka KafkaConfiguration
Mail MailConfiguration
TrashLogHost string `env:"TRASH_LOG_HOST"`
PubKey string `env:"PUBLIC_KEY"`
PrivKey string `env:"PRIVATE_KEY"`
ModuleLogger string `env:"MODULE_LOGGER"`
}
type KafkaConfiguration struct {

121
internal/models/trashLog.go Normal file

@ -0,0 +1,121 @@
package models
type AllFields struct {
CtxUserIP string
CtxUserPort string
KeyDomain string
KeyPath string
CtxUserID string
KeyFromSource string
KeyFromID string
KeyFromPartner string
CtxLogin string
CtxAccountID string
CtxEmail string
CtxPhone string
KeyCurrency string
CtxTariffID string
KeySuccess bool
CtxPrice uint64
CtxTariff string
CtxDiscount string
CtxRowPrice uint64
CtxRowData string
KeyPaymentType string
CtxReturnURL string
CtxID string
CtxOrgName string
}
type InfoCreateAccount struct {
CtxUserIP string
CtxUserPort string
KeyDomain string
KeyPath string
CtxUserID string //айдишник юзера из токена
KeyFromSource string //метка, откуда пришел пользователь. если куки quizFrom не пустые, ставить quiz
KeyFromID string //значение той куки, quizFrom
KeyFromPartner string //то, что пишешь в поле partner
CtxLogin string // значение логина. мы там получаем его из сервиса авторизации
CtxAccountID string // айдишник свежесозданного аккаунта
CtxEmail, CtxPhone string //значения из запроса
KeyCurrency string //значение валюты кошелька. сейчас там фиксированное, но потом пригодится
}
type InfoGetAccount struct {
CtxUserIP string
CtxUserPort string
KeyDomain string
KeyPath string
CtxUserID string //айдишник юзера из токена
CtxAccountID string // айдишник аккаунта
}
type InfoAddToCart struct {
CtxUserIP string
CtxUserPort string
KeyDomain string
KeyPath string
CtxUserID string //айдишник юзера из токена
CtxAccountID string // айдишник аккаунта
CtxTariffID string //айдишник тарифа, добавленного в корзину
}
type InfoPayCart struct {
CtxUserIP string
CtxUserPort string
KeyDomain string
KeyPath string
CtxUserID string //айдишник юзера из токена
CtxAccountID string // айдишник аккаунта
KeySuccess bool // получилось оплатить или не хватило денег
CtxPrice uint64 // сумма в копейках. если не удалось оплатить - записать сколько денег не хватило
CtxTariff string // через запятую список покупаемых тарифов
CtxDiscount string // через запятую список применённых скидок
CtxRowPrice uint64 // стоимость без скидок
CtxRowData string // замаршаленные данные, которые обычно складываются в RawDetails
}
type InfoRequestMoney struct {
CtxUserIP string
CtxUserPort string
KeyDomain string
KeyPath string
CtxUserID string //айдишник юзера из токена
CtxAccountID string // айдишник аккаунта
KeyPaymentType string //направление оплаты, через которое оплачиваем
KeyCurrency string //значение валюты кошелька. сейчас там фиксированное, но потом пригодится
CtxPrice uint64 // сумма в копейках
CtxReturnURL string // возвращенный от аггрегатора линк на оплату
}
type InfoMoneyIncome struct {
CtxUserID string //айдишник юзера из токена
CtxPrice uint64 // сумма в копейках
KeyCurrency string //значение валюты кошелька. сейчас там фиксированное, но потом пригодится
CtxID string //айдишник запроса оплаты
KeyPaymentType string //направление оплаты, через которое оплачиваем
}
type InfoReportRequest struct {
CtxUserIP string
CtxUserPort string
KeyDomain string
KeyPath string
CtxUserID string //айдишник юзера из токена
CtxAccountID string // айдишник аккаунта
CtxID string //айдишник истории, по которой создаётся акт
CtxTariff string // через запятую список покупаемых тарифов
CtxOrgName string // orgname
}
type InfoRSPay struct {
CtxUserIP string
CtxUserPort string
KeyDomain string
KeyPath string
CtxUserID string //айдишник юзера из токена
CtxAccountID string // айдишник аккаунта
CtxPrice uint64 // сумма в копейках
CtxLogin string // значение логина. мы там получаем его из сервиса авторизации
}

@ -4,6 +4,7 @@ import (
"context"
"fmt"
"github.com/gofiber/fiber/v2"
"github.com/themakers/hlog"
"go.uber.org/zap"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/utils"
@ -11,12 +12,14 @@ import (
type ServerConfig struct {
Logger *zap.Logger
Hlog hlog.Logger
Controllers []Controller
JWTConfig *models.JWTConfiguration
}
type Server struct {
Logger *zap.Logger
Hlog hlog.Logger
Controllers []Controller
app *fiber.App
}
@ -26,10 +29,12 @@ func NewServer(config ServerConfig) *Server {
jwtUtil := utils.NewJWT(config.JWTConfig)
app.Use(utils.NewAuthenticator(jwtUtil))
app.Use(utils.ContextLogger(config.Hlog))
s := &Server{
Logger: config.Logger,
Controllers: config.Controllers,
Hlog: config.Hlog,
app: app,
}

@ -0,0 +1,31 @@
package utils
import (
"encoding/json"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/proto/discount"
)
func GetAppliedDiscountsIDs(appliedDiscounts []*discount.Discount) []string {
discounts := make([]string, len(appliedDiscounts))
for i, discount := range appliedDiscounts {
discounts[i] = discount.ID
}
return discounts
}
func MarshalRawDetails(details models.RawDetails) string {
data, err := json.Marshal(details)
if err != nil {
return ""
}
return string(data)
}
func GetTariffsIDs(tariffs []models.Tariff) []string {
result := make([]string, len(tariffs))
for i, tariff := range tariffs {
result[i] = tariff.ID
}
return result
}

@ -0,0 +1,14 @@
package utils
import (
"github.com/gofiber/fiber/v2"
"github.com/themakers/hlog"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
)
func ContextLogger(logger hlog.Logger) fiber.Handler {
return func(c *fiber.Ctx) error {
c.Locals(models.LoggerKey, logger)
return c.Next()
}
}

@ -0,0 +1,53 @@
package e2e
import (
"bufio"
"fmt"
"github.com/stretchr/testify/assert"
"net/http"
"penahub.gitlab.yandexcloud.net/pena-services/customer/tests/helpers"
"testing"
"time"
)
func TestAccountPipe(t *testing.T) {
url := "http://localhost:8082/account/pipe"
jwtUtil := helpers.InitializeJWT()
token, tokenErr := jwtUtil.Create("64e53ed187392e122e5d3d50")
if !assert.NoError(t, tokenErr) {
return
}
client := &http.Client{
Timeout: 100 * time.Second,
}
req, err := http.NewRequest("GET", url, nil)
if !assert.NoError(t, err) {
return
}
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Accept", "text/event-stream")
fmt.Println(token)
resp, err := client.Do(req)
if !assert.NoError(t, err) {
return
}
defer resp.Body.Close()
assert.Equal(t, http.StatusOK, resp.StatusCode, "Expected status code 200")
scanner := bufio.NewScanner(resp.Body)
for scanner.Scan() {
line := scanner.Text()
fmt.Println("Received:", line)
}
if err := scanner.Err(); err != nil {
t.Fatalf("Error reading response: %v", err)
}
}

@ -19,7 +19,7 @@ func TestBuyTariff(t *testing.T) {
defer cancel()
assert.NotPanics(t, func() {
token, tokenErr := jwtUtil.Create("64e5d9830fcca0596d82c0c7")
token, tokenErr := jwtUtil.Create("64ebda4387392e122e5d411f")
if isNoError := assert.NoError(t, tokenErr); !isNoError {
return
}
@ -36,7 +36,7 @@ func TestBuyTariff(t *testing.T) {
return
}
isUserIDValid := assert.Equal(t, "64e5d9830fcca0596d82c0c7", responseAddCart.Body.UserID)
isUserIDValid := assert.Equal(t, "64ebda4387392e122e5d411f", responseAddCart.Body.UserID)
isCartLengthValid := assert.Equal(t, 1, len(responseAddCart.Body.Cart))
isCartItemValid := assert.Equal(t, "64e6105384368b75221a5c3e", responseAddCart.Body.Cart[0])
@ -52,7 +52,7 @@ func TestBuyTariff(t *testing.T) {
return
}
assert.Equal(t, "64e5d9830fcca0596d82c0c7", responsePay.Body.UserID)
assert.Equal(t, "64ebda4387392e122e5d411f", responsePay.Body.UserID)
assert.Equal(t, 0, len(responsePay.Body.Cart))
//assert.Equal(t, responseAddCart.Body.Wallet.Cash-5000, responsePay.Body.Wallet.Cash)
//assert.Equal(t, responseAddCart.Body.Wallet.Money-5000, responsePay.Body.Wallet.Money)

@ -18,7 +18,7 @@ func TestGetAccount(t *testing.T) {
defer cancel()
assert.NotPanics(t, func() {
token, tokenErr := jwtUtil.Create("64e5d9830fcca0596d82c0c7")
token, tokenErr := jwtUtil.Create("64ebda4387392e122e5d411f")
if isNoError := assert.NoError(t, tokenErr); !isNoError {
return
}
@ -34,20 +34,20 @@ func TestGetAccount(t *testing.T) {
return
}
assert.Equal(t, "64e5d9830fcca0596d82c0c7", responseGetAccount.Body.UserID)
assert.Equal(t, "64ebda4387392e122e5d411f", responseGetAccount.Body.UserID)
})
})
t.Run("Получение аккаунта юзера по id", func(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
assert.NotPanics(t, func() {
token, tokenErr := jwtUtil.Create("64e5d9830fcca0596d82c0c7")
token, tokenErr := jwtUtil.Create("64e5e1ca87392e122e5d3de7")
if isNoError := assert.NoError(t, tokenErr); !isNoError {
return
}
responseGetAccount, errGetAccount := client.Get[models.Account, models.ResponseErrorHTTP](ctx, &client.RequestSettings{
URL: "http://localhost:8082/account/64e5d9830fcca0596d82c0c7",
URL: "http://localhost:8082/account/64e5e1ca87392e122e5d3de7",
Headers: map[string]string{"Authorization": fmt.Sprintf("Bearer %s", token)},
})
if isNoError := assert.NoError(t, errGetAccount); !isNoError {
@ -57,7 +57,7 @@ func TestGetAccount(t *testing.T) {
return
}
assert.Equal(t, "64e5d9830fcca0596d82c0c7", responseGetAccount.Body.UserID)
assert.Equal(t, "64e5e1ca87392e122e5d3de7", responseGetAccount.Body.UserID)
})
})
t.Run("Получение аккаунтов с пагинацией", func(t *testing.T) {

@ -0,0 +1,84 @@
package integration
import (
"context"
"database/sql"
"github.com/stretchr/testify/assert"
"github.com/themakers/hlog"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"log"
"os"
"penahub.gitlab.yandexcloud.net/external/trashlog.git/app"
"penahub.gitlab.yandexcloud.net/external/trashlog.git/wrappers/zaptrashlog"
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
"testing"
"time"
)
var (
commit string = os.Getenv("COMMIT")
buildTime string = os.Getenv("BUILD_TIME")
version string = os.Getenv("VERSION")
)
func TestTrashLogger(t *testing.T) {
logger, err := zap.NewProduction(zap.AddStacktrace(zap.DPanicLevel))
if err != nil {
log.Fatalf("failed to init zap logger: %v", err)
}
ptime := time.Now()
config := models.Config{
Service: models.ServiceConfiguration{
TrashLogHost: "localhost:7113",
},
}
ctx := context.Background()
clickHouseLogger, err := zaptrashlog.NewCore(ctx, zap.InfoLevel, config.Service.TrashLogHost, version, commit, ptime.Unix())
if err != nil {
panic(err)
}
loggerForHlog := logger.WithOptions(zap.WrapCore(func(core zapcore.Core) zapcore.Core {
return zapcore.NewTee(core, clickHouseLogger)
}))
loggerHlog := hlog.New(loggerForHlog).Module("customer_test")
loggerHlog.Emit(app.InfoSvcStarted{})
clientClickHouse, err := sql.Open(
"clickhouse",
"tcp://127.0.0.1:9000?debug=true",
)
assert.NoError(t, err)
time.Sleep(10 * time.Second)
rows, err := clientClickHouse.Query("SELECT svc_commit, svc_build_time, svc_version FROM statistics")
assert.NoError(t, err)
defer rows.Close()
foundCommit := false
foundVersion := false
for rows.Next() {
var commitValue, buildTimeValue, versionValue string
err := rows.Scan(&commitValue, &buildTimeValue, &versionValue)
assert.NoError(t, err)
if commitValue == commit {
foundCommit = true
}
if versionValue == version {
foundVersion = true
}
}
assert.Equal(t, foundCommit, true, "commit value do not match")
//assert.Equal(t, foundBuildTime, true, "buildTime value do not match")
assert.Equal(t, foundVersion, true, "version value do not match")
}