v0.0.25 Добавлен gRPC сервис подписок/пидписчиков
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
3c0cd21139
commit
db403171da
1
.env
1
.env
@ -12,3 +12,4 @@ SMTP_PASSWORD="86AN1z1WxbFX6Q9u"
|
||||
SMTP_FROM=info@tailly.ru
|
||||
AppURL="https://tailly.ru"
|
||||
MESSAGE_SERVICE_ADDRESS="tailly_messages:50052"
|
||||
SUBSCRIBE_SERVICE_ADDRESS="tailly_subscribers:50053"
|
||||
@ -1,4 +1,4 @@
|
||||
FROM golang:1.25rc2-alpine AS builder
|
||||
FROM golang:1.25rc3-alpine AS builder
|
||||
|
||||
RUN apk add --no-cache git ca-certificates build-base
|
||||
|
||||
|
||||
@ -33,25 +33,47 @@ func main() {
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
grpcConn, err := grpc.Dial(
|
||||
// Подключение к MessageService gRPC
|
||||
messageConn, err := grpc.Dial(
|
||||
cfg.GRPC.MessageServiceAddress,
|
||||
grpc.WithInsecure(),
|
||||
grpc.WithKeepaliveParams(keepalive.ClientParameters{
|
||||
Time: 30 * time.Second, // Отправлять keepalive ping каждые 30 секунд
|
||||
Timeout: 10 * time.Second, // Ждать ответ 10 секунд
|
||||
PermitWithoutStream: true, // Разрешить keepalive даже без активных стримов
|
||||
Time: 30 * time.Second,
|
||||
Timeout: 10 * time.Second,
|
||||
PermitWithoutStream: true,
|
||||
}),
|
||||
grpc.WithConnectParams(grpc.ConnectParams{
|
||||
Backoff: backoff.DefaultConfig, // Экспоненциальная backoff-стратегия
|
||||
MinConnectTimeout: 5 * time.Second, // Минимальное время ожидания подключения
|
||||
Backoff: backoff.DefaultConfig,
|
||||
MinConnectTimeout: 5 * time.Second,
|
||||
}),
|
||||
grpc.WithDefaultServiceConfig(`{"loadBalancingPolicy":"round_robin"}`), // Политика балансировки
|
||||
grpc.WithDefaultServiceConfig(`{"loadBalancingPolicy":"round_robin"}`),
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to connect to messages gRPC service: %v", err)
|
||||
}
|
||||
defer grpcConn.Close()
|
||||
messageClient := proto.NewMessageServiceClient(grpcConn)
|
||||
defer messageConn.Close()
|
||||
messageClient := proto.NewMessageServiceClient(messageConn)
|
||||
|
||||
// Подключение к SubscribeService gRPC
|
||||
subscribeConn, err := grpc.Dial(
|
||||
cfg.GRPC.SubscribeServiceAddress, // Добавьте этот параметр в конфиг
|
||||
grpc.WithInsecure(),
|
||||
grpc.WithKeepaliveParams(keepalive.ClientParameters{
|
||||
Time: 30 * time.Second,
|
||||
Timeout: 10 * time.Second,
|
||||
PermitWithoutStream: true,
|
||||
}),
|
||||
grpc.WithConnectParams(grpc.ConnectParams{
|
||||
Backoff: backoff.DefaultConfig,
|
||||
MinConnectTimeout: 5 * time.Second,
|
||||
}),
|
||||
grpc.WithDefaultServiceConfig(`{"loadBalancingPolicy":"round_robin"}`),
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to connect to subscribe gRPC service: %v", err)
|
||||
}
|
||||
defer subscribeConn.Close()
|
||||
subscribeClient := proto.NewSubscribeServiceClient(subscribeConn)
|
||||
|
||||
// Инициализация зависимостей
|
||||
tokenAuth := auth.NewTokenAuth(
|
||||
@ -105,10 +127,11 @@ func main() {
|
||||
Recovery: recoveryService,
|
||||
Session: sessionService,
|
||||
Mail: mailService,
|
||||
Messages: messageClient, // Добавляем gRPC клиент
|
||||
Messages: messageClient,
|
||||
Subscribe: subscribeClient, // Добавляем gRPC клиент подписок
|
||||
}
|
||||
|
||||
// HTTP сервер - передаем db как дополнительный параметр
|
||||
// HTTP сервер
|
||||
server := http.NewServer(cfg, services, tokenAuth, db)
|
||||
|
||||
// Запуск сервера в отдельной горутине
|
||||
|
||||
79
go.mod
79
go.mod
@ -1,45 +1,100 @@
|
||||
module tailly_back_v2
|
||||
|
||||
go 1.25rc2
|
||||
go 1.25rc3
|
||||
|
||||
require (
|
||||
github.com/99designs/gqlgen v0.17.77
|
||||
github.com/aws/aws-sdk-go v1.55.7
|
||||
github.com/aws/aws-sdk-go v1.55.8
|
||||
github.com/caarlos0/env/v8 v8.0.0
|
||||
github.com/go-chi/chi/v5 v5.2.2
|
||||
github.com/golang-jwt/jwt/v5 v5.2.3
|
||||
github.com/golang-jwt/jwt/v5 v5.3.0
|
||||
github.com/gorilla/websocket v1.5.3
|
||||
github.com/jackc/pgx/v4 v4.18.3
|
||||
github.com/joho/godotenv v1.5.1
|
||||
github.com/lib/pq v1.10.9
|
||||
github.com/prometheus/client_golang v1.22.0
|
||||
github.com/prometheus/client_golang v1.23.0
|
||||
github.com/stretchr/testify v1.10.0
|
||||
github.com/testcontainers/testcontainers-go v0.38.0
|
||||
github.com/vektah/gqlparser/v2 v2.5.30
|
||||
golang.org/x/crypto v0.40.0
|
||||
google.golang.org/grpc v1.74.2
|
||||
google.golang.org/protobuf v1.36.6
|
||||
golang.org/x/crypto v0.41.0
|
||||
google.golang.org/grpc v1.75.0
|
||||
google.golang.org/protobuf v1.36.8
|
||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
||||
)
|
||||
|
||||
require (
|
||||
dario.cat/mergo v1.0.1 // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||
github.com/agnivade/levenshtein v1.2.1 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/containerd/errdefs v1.0.0 // indirect
|
||||
github.com/containerd/errdefs/pkg v0.3.0 // indirect
|
||||
github.com/containerd/log v0.1.0 // indirect
|
||||
github.com/containerd/platforms v0.2.1 // indirect
|
||||
github.com/cpuguy83/dockercfg v0.3.2 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/distribution/reference v0.6.0 // indirect
|
||||
github.com/docker/docker v28.2.2+incompatible // indirect
|
||||
github.com/docker/go-connections v0.5.0 // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/ebitengine/purego v0.8.4 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/go-logr/logr v1.4.3 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
|
||||
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
|
||||
github.com/jackc/pgconn v1.14.3 // indirect
|
||||
github.com/jackc/pgio v1.0.0 // indirect
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgproto3/v2 v2.3.3 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
|
||||
github.com/jackc/pgtype v1.14.0 // indirect
|
||||
github.com/jackc/puddle v1.3.0 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/klauspost/compress v1.18.0 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
|
||||
github.com/magiconair/properties v1.8.10 // indirect
|
||||
github.com/moby/docker-image-spec v1.3.1 // indirect
|
||||
github.com/moby/go-archive v0.1.0 // indirect
|
||||
github.com/moby/patternmatcher v0.6.0 // indirect
|
||||
github.com/moby/sys/sequential v0.6.0 // indirect
|
||||
github.com/moby/sys/user v0.4.0 // indirect
|
||||
github.com/moby/sys/userns v0.1.0 // indirect
|
||||
github.com/moby/term v0.5.0 // indirect
|
||||
github.com/morikuni/aec v1.0.0 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.1 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||
github.com/prometheus/client_model v0.6.2 // indirect
|
||||
github.com/prometheus/common v0.65.0 // indirect
|
||||
github.com/prometheus/procfs v0.17.0 // indirect
|
||||
github.com/shirou/gopsutil/v4 v4.25.5 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/sosodev/duration v1.3.1 // indirect
|
||||
golang.org/x/net v0.42.0 // indirect
|
||||
golang.org/x/sys v0.34.0 // indirect
|
||||
golang.org/x/text v0.27.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250721164621-a45f3dfb1074 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.12 // indirect
|
||||
github.com/tklauser/numcpus v0.6.1 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect
|
||||
go.opentelemetry.io/otel v1.37.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.37.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.37.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.7.1 // indirect
|
||||
golang.org/x/net v0.43.0 // indirect
|
||||
golang.org/x/sys v0.35.0 // indirect
|
||||
golang.org/x/text v0.28.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250818200422-3122310a409c // indirect
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
355
go.sum
355
go.sum
@ -1,5 +1,15 @@
|
||||
dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
|
||||
dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
||||
github.com/99designs/gqlgen v0.17.77 h1:zVW7iyRc9Z+qhvXx2wFFDpHub/E0I0Sz4/Ul2mQ61Pc=
|
||||
github.com/99designs/gqlgen v0.17.77/go.mod h1:yI/o31IauG2kX0IsskM4R894OCCG1jXJORhtLQqB7Oc=
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 h1:He8afgbRMd7mFxO99hRNu+6tazq8nFF9lIwo9JFroBk=
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
|
||||
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||
github.com/PuerkitoBio/goquery v1.10.3 h1:pFYcNSqHxBD06Fpj/KsbStFRsgRATgnf3LeXiUkhzPo=
|
||||
github.com/PuerkitoBio/goquery v1.10.3/go.mod h1:tMUX0zDMHXYlAQk6p35XxQMqMweEKB7iK7iLNd4RH4Y=
|
||||
github.com/agnivade/levenshtein v1.2.1 h1:EHBY3UOn1gwdy/VbFwgo4cxecRznFk7fKWN1KOX7eoM=
|
||||
@ -10,114 +20,393 @@ github.com/andybalholm/cascadia v1.3.3 h1:AG2YHrzJIm4BZ19iwJ/DAua6Btl3IwJX+VI4kk
|
||||
github.com/andybalholm/cascadia v1.3.3/go.mod h1:xNd9bqTn98Ln4DwST8/nG+H0yuB8Hmgu1YHNnWw0GeA=
|
||||
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q=
|
||||
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE=
|
||||
github.com/aws/aws-sdk-go v1.55.7 h1:UJrkFq7es5CShfBwlWAC8DA077vp8PyVbQd3lqLiztE=
|
||||
github.com/aws/aws-sdk-go v1.55.7/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU=
|
||||
github.com/aws/aws-sdk-go v1.55.8 h1:JRmEUbU52aJQZ2AjX4q4Wu7t4uZjOu71uyNmaWlUkJQ=
|
||||
github.com/aws/aws-sdk-go v1.55.8/go.mod h1:ZkViS9AqA6otK+JBBNH2++sx1sgxrPKcSzPPvQkUtXk=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/caarlos0/env/v8 v8.0.0 h1:POhxHhSpuxrLMIdvTGARuZqR4Jjm8AYmoi/JKlcScs0=
|
||||
github.com/caarlos0/env/v8 v8.0.0/go.mod h1:7K4wMY9bH0esiXSSHlfHLX5xKGQMnkH5Fk4TDSSSzfo=
|
||||
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
|
||||
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
|
||||
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
||||
github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=
|
||||
github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
|
||||
github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE=
|
||||
github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk=
|
||||
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
|
||||
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
|
||||
github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A=
|
||||
github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw=
|
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/cpuguy83/dockercfg v0.3.2 h1:DlJTyZGBDlXqUZ2Dk2Q3xHs/FtnooJJVaad2S9GKorA=
|
||||
github.com/cpuguy83/dockercfg v0.3.2/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
|
||||
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||
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=
|
||||
github.com/dgryski/trifles v0.0.0-20230903005119-f50d829f2e54 h1:SG7nF6SRlWhcT7cNTs5R6Hk4V2lcmLz2NsG2VnInyNo=
|
||||
github.com/dgryski/trifles v0.0.0-20230903005119-f50d829f2e54/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=
|
||||
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
|
||||
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||
github.com/docker/docker v28.2.2+incompatible h1:CjwRSksz8Yo4+RmQ339Dp/D2tGO5JxwYeqtMOEe0LDw=
|
||||
github.com/docker/docker v28.2.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
|
||||
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
|
||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/ebitengine/purego v0.8.4 h1:CF7LEKg5FFOsASUj0+QwaXf8Ht6TlFxg09+S9wz0omw=
|
||||
github.com/ebitengine/purego v0.8.4/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
|
||||
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
||||
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/go-chi/chi/v5 v5.2.2 h1:CMwsvRVTbXVytCk1Wd72Zy1LAsAh9GxMmSNWLHCG618=
|
||||
github.com/go-chi/chi/v5 v5.2.2/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops=
|
||||
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-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
||||
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.3 h1:kkGXqQOBSDDWRhWNXTFpqGSCMyh/PLnqUvMGJPDJDs0=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.3/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw=
|
||||
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
|
||||
github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
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/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
||||
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 h1:X5VWvz21y3gzm9Nw/kaUeku/1+uBhcekkmy4IkffJww=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
|
||||
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
|
||||
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
|
||||
github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8=
|
||||
github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
|
||||
github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA=
|
||||
github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE=
|
||||
github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s=
|
||||
github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o=
|
||||
github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY=
|
||||
github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI=
|
||||
github.com/jackc/pgconn v1.14.3 h1:bVoTr12EGANZz66nZPkMInAV/KHD2TxH9npjXXgiB3w=
|
||||
github.com/jackc/pgconn v1.14.3/go.mod h1:RZbme4uasqzybK2RK5c65VsHxoyaml09lx3tXOcO/VM=
|
||||
github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
|
||||
github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
|
||||
github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE=
|
||||
github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c=
|
||||
github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65 h1:DadwsjnMwFjfWc9y5Wi/+Zz7xoE5ALHsRQlOctkOiHc=
|
||||
github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak=
|
||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||
github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78=
|
||||
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA=
|
||||
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg=
|
||||
github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
|
||||
github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
|
||||
github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
||||
github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
||||
github.com/jackc/pgproto3/v2 v2.3.3 h1:1HLSx5H+tXR9pW3in3zaztoEwQYRC9SQaYUHjTSUOag=
|
||||
github.com/jackc/pgproto3/v2 v2.3.3/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
||||
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||
github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg=
|
||||
github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc=
|
||||
github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw=
|
||||
github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM=
|
||||
github.com/jackc/pgtype v1.14.0 h1:y+xUdabmyMkJLyApYuPj38mW+aAIqCe5uuBB51rH3Vw=
|
||||
github.com/jackc/pgtype v1.14.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4=
|
||||
github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=
|
||||
github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
|
||||
github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc=
|
||||
github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs=
|
||||
github.com/jackc/pgx/v4 v4.18.3 h1:dE2/TrEsGX3RBprb3qryqSV9Y60iZN1C6i8IrmW9/BA=
|
||||
github.com/jackc/pgx/v4 v4.18.3/go.mod h1:Ey4Oru5tH5sB6tV7hDmfWFahwF15Eb7DNXlRKx2CkVw=
|
||||
github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jackc/puddle v1.3.0 h1:eHK/5clGOatcjX3oWGBO/MpxpbHzSwud5EWTSCI+MX0=
|
||||
github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
|
||||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
||||
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=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
||||
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
||||
github.com/magiconair/properties v1.8.10 h1:s31yESBquKXCV9a/ScB3ESkOjUYYv+X0rg8SYxI99mE=
|
||||
github.com/magiconair/properties v1.8.10/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
||||
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
|
||||
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
|
||||
github.com/moby/go-archive v0.1.0 h1:Kk/5rdW/g+H8NHdJW2gsXyZ7UnzvJNOy6VKJqueWdcQ=
|
||||
github.com/moby/go-archive v0.1.0/go.mod h1:G9B+YoujNohJmrIYFBpSd54GTUB4lt9S+xVQvsJyFuo=
|
||||
github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk=
|
||||
github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
|
||||
github.com/moby/sys/atomicwriter v0.1.0 h1:kw5D/EqkBwsBFi0ss9v1VG3wIkVhzGvLklJ+w3A14Sw=
|
||||
github.com/moby/sys/atomicwriter v0.1.0/go.mod h1:Ul8oqv2ZMNHOceF643P6FKPXeCmYtlQMvpizfsSoaWs=
|
||||
github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU=
|
||||
github.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko=
|
||||
github.com/moby/sys/user v0.4.0 h1:jhcMKit7SA80hivmFJcbB1vqmw//wU61Zdui2eQXuMs=
|
||||
github.com/moby/sys/user v0.4.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs=
|
||||
github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g=
|
||||
github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28=
|
||||
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
|
||||
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
|
||||
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
||||
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
|
||||
github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=
|
||||
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_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q=
|
||||
github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
github.com/prometheus/client_golang v1.23.0 h1:ust4zpdl9r4trLY/gSjlm07PuiBq2ynaXXlptpfy8Uc=
|
||||
github.com/prometheus/client_golang v1.23.0/go.mod h1:i/o0R9ByOnHX0McrTMTyhYvKE4haaf2mW08I+jGAjEE=
|
||||
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
|
||||
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
|
||||
github.com/prometheus/common v0.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2VzE=
|
||||
github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8=
|
||||
github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0=
|
||||
github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw=
|
||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
||||
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
||||
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
||||
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
|
||||
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
|
||||
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
|
||||
github.com/shirou/gopsutil/v4 v4.25.5 h1:rtd9piuSMGeU8g1RMXjZs9y9luK5BwtnG7dZaQUJAsc=
|
||||
github.com/shirou/gopsutil/v4 v4.25.5/go.mod h1:PfybzyydfZcN+JMMjkF6Zb8Mq1A/VcogFFg7hj50W9c=
|
||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
||||
github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
|
||||
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/sosodev/duration v1.3.1 h1:qtHBDMQ6lvMQsL15g4aopM4HEfOaYuhWBw3NPTtlqq4=
|
||||
github.com/sosodev/duration v1.3.1/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg=
|
||||
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/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
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.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/testcontainers/testcontainers-go v0.38.0 h1:d7uEapLcv2P8AvH8ahLqDMMxda2W9gQN1nRbHS28HBw=
|
||||
github.com/testcontainers/testcontainers-go v0.38.0/go.mod h1:C52c9MoHpWO+C4aqmgSU+hxlR5jlEayWtgYrb8Pzz1w=
|
||||
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
|
||||
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
|
||||
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
|
||||
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
|
||||
github.com/vektah/gqlparser/v2 v2.5.30 h1:EqLwGAFLIzt1wpx1IPpY67DwUujF1OfzgEyDsLrN6kE=
|
||||
github.com/vektah/gqlparser/v2 v2.5.30/go.mod h1:D1/VCZtV3LPnQrcPBeR/q5jkSQIPti0uYCP/RI0gIeo=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
|
||||
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg=
|
||||
go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E=
|
||||
go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE=
|
||||
go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs=
|
||||
go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs=
|
||||
go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4=
|
||||
go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w=
|
||||
go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA=
|
||||
golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM=
|
||||
golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY=
|
||||
golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=
|
||||
golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8=
|
||||
golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=
|
||||
golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4=
|
||||
golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250721164621-a45f3dfb1074 h1:qJW29YvkiJmXOYMu5Tf8lyrTp3dOS+K4z6IixtLaCf8=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250721164621-a45f3dfb1074/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
|
||||
google.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4=
|
||||
google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM=
|
||||
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
|
||||
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw=
|
||||
go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
|
||||
go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 h1:Ahq7pZmv87yiyn3jeFz/LekZmPLLdKejuO3NcK9MssM=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0/go.mod h1:MJTqhM0im3mRLw1i8uGHnCvUEeS7VwRyxlLC78PA18M=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 h1:IeMeyr1aBvBiPVYihXIaeIZba6b8E1bYp7lbdxK8CQg=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0/go.mod h1:oVdCUtjq9MK9BlS7TtucsQwUcXcymNiEDjgDD2jMtZU=
|
||||
go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE=
|
||||
go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
|
||||
go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI=
|
||||
go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps=
|
||||
go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
|
||||
go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
|
||||
go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4=
|
||||
go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
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.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
||||
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
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=
|
||||
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
|
||||
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
|
||||
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.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
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/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
|
||||
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/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-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
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-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/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-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
|
||||
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4=
|
||||
golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
|
||||
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
|
||||
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 h1:vVKdlvoWBphwdxWKrFZEuM0kGgGLxUOYcY4U/2Vjg44=
|
||||
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/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-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
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-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
||||
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250728155136-f173205681a0 h1:0UOBWO4dC+e51ui0NFKSPbkHHiQ4TmrEfEZMLDyRmY8=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250728155136-f173205681a0/go.mod h1:8ytArBbtOy2xfht+y2fqKd5DRDJRUQhqbyEnQ4bDChs=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250818200422-3122310a409c h1:qXWI/sQtv5UKboZ/zUk7h+mrf/lXORyI+n9DKDAusdg=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250818200422-3122310a409c/go.mod h1:gw1tLEfykwDz2ET4a12jcXt4couGAm7IwsVaTy0Sflo=
|
||||
google.golang.org/grpc v1.75.0 h1:+TW+dqTd2Biwe6KKfhE5JpiYIBWq865PhKGSXiivqt4=
|
||||
google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ=
|
||||
google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc=
|
||||
google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/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/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE=
|
||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
|
||||
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
|
||||
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.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q=
|
||||
gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/caarlos0/env/v8"
|
||||
"github.com/joho/godotenv"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
@ -30,6 +31,7 @@ type Config struct {
|
||||
}
|
||||
GRPC struct {
|
||||
MessageServiceAddress string `env:"MESSAGE_SERVICE_ADDRESS"`
|
||||
SubscribeServiceAddress string `env:"SUBSCRIBE_SERVICE_ADDRESS"`
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -5,7 +5,6 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"tailly_back_v2/internal/domain"
|
||||
"tailly_back_v2/internal/http/middleware"
|
||||
"tailly_back_v2/proto"
|
||||
"time"
|
||||
)
|
||||
@ -19,17 +18,6 @@ type subscriptionResolver struct{ *Resolver }
|
||||
|
||||
// CreateChat is the resolver for the createChat field.
|
||||
func (r *mutationResolver) CreateChat(ctx context.Context, user1Id int, user2Id int) (*domain.Chat, error) {
|
||||
start := time.Now()
|
||||
success := false
|
||||
|
||||
defer func() {
|
||||
duration := time.Since(start)
|
||||
middleware.IncGQLOperation("mutation", "createChat", success, duration)
|
||||
if !success {
|
||||
middleware.IncError("gql_operation", "createChat", "error")
|
||||
}
|
||||
}()
|
||||
|
||||
// Просто вызываем gRPC метод, вся логика уже там
|
||||
res, err := r.MessageClient.CreateChat(ctx, &proto.CreateChatRequest{
|
||||
User1Id: int32(user1Id),
|
||||
@ -39,24 +27,12 @@ func (r *mutationResolver) CreateChat(ctx context.Context, user1Id int, user2Id
|
||||
return nil, fmt.Errorf("failed to create chat: %w", err)
|
||||
}
|
||||
|
||||
success = true
|
||||
// Преобразуем proto-чат в domain-модель
|
||||
return protoChatToDomain(res.Chat), nil
|
||||
}
|
||||
|
||||
// SendMessage реализация мутации для отправки сообщения
|
||||
func (r *mutationResolver) SendMessage(ctx context.Context, chatID int, content string) (*domain.Message, error) {
|
||||
start := time.Now()
|
||||
success := false
|
||||
|
||||
defer func() {
|
||||
duration := time.Since(start)
|
||||
middleware.IncGQLOperation("mutation", "sendMessage", success, duration)
|
||||
if !success {
|
||||
middleware.IncError("gql_operation", "sendMessage", "error")
|
||||
}
|
||||
}()
|
||||
|
||||
// Получаем senderID из контекста
|
||||
senderID, err := getUserIDFromContext(ctx)
|
||||
if err != nil {
|
||||
@ -71,25 +47,11 @@ func (r *mutationResolver) SendMessage(ctx context.Context, chatID int, content
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to send message: %w", err)
|
||||
}
|
||||
|
||||
success = true
|
||||
middleware.IncWebSocketMessage("outgoing", "chat_message")
|
||||
return protoMessageToDomain(res.Message), nil
|
||||
}
|
||||
|
||||
// UpdateMessageStatus реализация мутации для обновления статуса сообщения
|
||||
func (r *mutationResolver) UpdateMessageStatus(ctx context.Context, messageID int, status MessageStatus) (*domain.Message, error) {
|
||||
start := time.Now()
|
||||
success := false
|
||||
|
||||
defer func() {
|
||||
duration := time.Since(start)
|
||||
middleware.IncGQLOperation("mutation", "updateMessageStatus", success, duration)
|
||||
if !success {
|
||||
middleware.IncError("gql_operation", "updateMessageStatus", "error")
|
||||
}
|
||||
}()
|
||||
|
||||
var statusStr string
|
||||
switch status {
|
||||
case MessageStatusSent:
|
||||
@ -110,23 +72,11 @@ func (r *mutationResolver) UpdateMessageStatus(ctx context.Context, messageID in
|
||||
return nil, fmt.Errorf("failed to update message status: %w", err)
|
||||
}
|
||||
|
||||
success = true
|
||||
return protoMessageToDomain(res.Message), nil
|
||||
}
|
||||
|
||||
// GetChat реализация запроса для получения чата
|
||||
func (r *queryResolver) GetChat(ctx context.Context, user1Id int, user2Id int) (*domain.Chat, error) {
|
||||
start := time.Now()
|
||||
success := false
|
||||
|
||||
defer func() {
|
||||
duration := time.Since(start)
|
||||
middleware.IncGQLOperation("query", "getChat", success, duration)
|
||||
if !success {
|
||||
middleware.IncError("gql_operation", "getChat", "error")
|
||||
}
|
||||
}()
|
||||
|
||||
res, err := r.MessageClient.GetChat(ctx, &proto.GetChatRequest{
|
||||
User1Id: int32(user1Id),
|
||||
User2Id: int32(user2Id),
|
||||
@ -134,24 +84,11 @@ func (r *queryResolver) GetChat(ctx context.Context, user1Id int, user2Id int) (
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get chat: %w", err)
|
||||
}
|
||||
|
||||
success = true
|
||||
return protoChatToDomain(res.Chat), nil
|
||||
}
|
||||
|
||||
// GetChatMessages реализация запроса для получения сообщений чата
|
||||
func (r *queryResolver) GetChatMessages(ctx context.Context, chatID int, limit int, offset int) ([]*domain.Message, error) {
|
||||
start := time.Now()
|
||||
success := false
|
||||
|
||||
defer func() {
|
||||
duration := time.Since(start)
|
||||
middleware.IncGQLOperation("query", "getChatMessages", success, duration)
|
||||
if !success {
|
||||
middleware.IncError("gql_operation", "getChatMessages", "error")
|
||||
}
|
||||
}()
|
||||
|
||||
res, err := r.MessageClient.GetChatMessages(ctx, &proto.GetChatMessagesRequest{
|
||||
ChatId: int32(chatID),
|
||||
Limit: int32(limit),
|
||||
@ -160,58 +97,30 @@ func (r *queryResolver) GetChatMessages(ctx context.Context, chatID int, limit i
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get chat messages: %w", err)
|
||||
}
|
||||
|
||||
var messages []*domain.Message
|
||||
for _, msg := range res.Messages {
|
||||
messages = append(messages, protoMessageToDomain(msg))
|
||||
}
|
||||
|
||||
success = true
|
||||
return messages, nil
|
||||
}
|
||||
|
||||
// GetUserChats реализация запроса для получения чатов пользователя
|
||||
func (r *queryResolver) GetUserChats(ctx context.Context, userID int) ([]*domain.Chat, error) {
|
||||
start := time.Now()
|
||||
success := false
|
||||
|
||||
defer func() {
|
||||
duration := time.Since(start)
|
||||
middleware.IncGQLOperation("query", "getUserChats", success, duration)
|
||||
if !success {
|
||||
middleware.IncError("gql_operation", "getUserChats", "error")
|
||||
}
|
||||
}()
|
||||
|
||||
res, err := r.MessageClient.GetUserChats(ctx, &proto.GetUserChatsRequest{
|
||||
UserId: int32(userID),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get user chats: %w", err)
|
||||
}
|
||||
|
||||
var chats []*domain.Chat
|
||||
for _, chat := range res.Chats {
|
||||
chats = append(chats, protoChatToDomain(chat))
|
||||
}
|
||||
|
||||
success = true
|
||||
return chats, nil
|
||||
}
|
||||
|
||||
// MessageStream реализация подписки на новые сообщения
|
||||
func (r *subscriptionResolver) MessageStream(ctx context.Context, userID int) (<-chan *domain.Message, error) {
|
||||
start := time.Now()
|
||||
success := false
|
||||
|
||||
defer func() {
|
||||
duration := time.Since(start)
|
||||
middleware.IncGQLOperation("subscription", "messageStream", success, duration)
|
||||
if !success {
|
||||
middleware.IncError("gql_operation", "messageStream", "error")
|
||||
}
|
||||
}()
|
||||
|
||||
messageChan := make(chan *domain.Message, 100)
|
||||
|
||||
go func() {
|
||||
@ -227,14 +136,12 @@ func (r *subscriptionResolver) MessageStream(ctx context.Context, userID int) (<
|
||||
err := r.runMessageStream(ctx, userID, messageChan)
|
||||
if err != nil {
|
||||
log.Printf("MessageStream error: %v, reconnecting...", err)
|
||||
middleware.IncError("websocket_stream", "messageStream", "warning")
|
||||
}
|
||||
time.Sleep(2 * time.Second) // Задержка перед переподключением
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
success = true
|
||||
return messageChan, nil
|
||||
}
|
||||
|
||||
@ -248,7 +155,6 @@ func (r *subscriptionResolver) runMessageStream(ctx context.Context, userID int,
|
||||
})
|
||||
if err != nil {
|
||||
log.Printf("Failed to mark messages as delivered: %v", err)
|
||||
middleware.IncError("message_status", "updateStatus", "warning")
|
||||
}
|
||||
|
||||
streamCtx, cancel := context.WithCancel(ctx)
|
||||
@ -269,7 +175,6 @@ func (r *subscriptionResolver) runMessageStream(ctx context.Context, userID int,
|
||||
case <-heartbeat.C:
|
||||
// Отправляем ping для поддержания соединения
|
||||
if err := stream.Context().Err(); err != nil {
|
||||
middleware.IncError("websocket_heartbeat", "messageStream", "error")
|
||||
return fmt.Errorf("connection lost: %w", err)
|
||||
}
|
||||
case <-ctx.Done():
|
||||
@ -277,7 +182,6 @@ func (r *subscriptionResolver) runMessageStream(ctx context.Context, userID int,
|
||||
default:
|
||||
msg, err := stream.Recv()
|
||||
if err != nil {
|
||||
middleware.IncError("websocket_receive", "messageStream", "error")
|
||||
return fmt.Errorf("receive error: %w", err)
|
||||
}
|
||||
|
||||
@ -285,7 +189,6 @@ func (r *subscriptionResolver) runMessageStream(ctx context.Context, userID int,
|
||||
select {
|
||||
case messageChan <- protoMessageToDomain(msg.Message):
|
||||
log.Printf("Delivered message %d to user %d", msg.Message.Id, userID)
|
||||
middleware.IncWebSocketMessage("incoming", "chat_message")
|
||||
case <-ctx.Done():
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -9,15 +9,70 @@ import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type FollowResult struct {
|
||||
Success bool `json:"success"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
type Follower struct {
|
||||
UserID int `json:"userId"`
|
||||
Username string `json:"username"`
|
||||
Avatar string `json:"avatar"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
}
|
||||
|
||||
type FollowersResponse struct {
|
||||
Followers []*Follower `json:"followers"`
|
||||
TotalCount int `json:"totalCount"`
|
||||
}
|
||||
|
||||
type Following struct {
|
||||
UserID int `json:"userId"`
|
||||
Username string `json:"username"`
|
||||
Avatar string `json:"avatar"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
}
|
||||
|
||||
type FollowingResponse struct {
|
||||
Following []*Following `json:"following"`
|
||||
TotalCount int `json:"totalCount"`
|
||||
}
|
||||
|
||||
type MarkNotificationReadResult struct {
|
||||
Success bool `json:"success"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
type Mutation struct {
|
||||
}
|
||||
|
||||
type NotificationsResponse struct {
|
||||
Notifications []*SubscriptionNotification `json:"notifications"`
|
||||
TotalCount int `json:"totalCount"`
|
||||
UnreadCount int `json:"unreadCount"`
|
||||
}
|
||||
|
||||
type Query struct {
|
||||
}
|
||||
|
||||
type Subscription struct {
|
||||
}
|
||||
|
||||
type SubscriptionNotification struct {
|
||||
ID int `json:"id"`
|
||||
FollowerID int `json:"followerId"`
|
||||
FollowerUsername string `json:"followerUsername"`
|
||||
FollowerAvatar string `json:"followerAvatar"`
|
||||
IsRead bool `json:"isRead"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
ExpiresAt string `json:"expiresAt"`
|
||||
}
|
||||
|
||||
type UnfollowResult struct {
|
||||
Success bool `json:"success"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
type MessageStatus string
|
||||
|
||||
const (
|
||||
|
||||
@ -18,17 +18,20 @@ type Resolver struct {
|
||||
Services *service.Services
|
||||
DeviceRepo repository.DeviceRepository // Добавляем репозиторий устройств напрямую
|
||||
MessageClient proto.MessageServiceClient
|
||||
SubscribeClient proto.SubscribeServiceClient
|
||||
}
|
||||
|
||||
func NewResolver(
|
||||
services *service.Services,
|
||||
db *sql.DB, // Принимаем подключение к БД
|
||||
messageClient proto.MessageServiceClient,
|
||||
subscribeClient proto.SubscribeServiceClient,
|
||||
) *Resolver {
|
||||
return &Resolver{
|
||||
Services: services,
|
||||
DeviceRepo: repository.NewDeviceRepository(db),
|
||||
MessageClient: messageClient,
|
||||
SubscribeClient: subscribeClient,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -7,6 +7,16 @@ type User {
|
||||
emailConfirmedAt: String # Дата подтверждения email (может быть null)
|
||||
createdAt: String! # Дата создания
|
||||
updatedAt: String! # Дата обновления
|
||||
followersCount: Int!
|
||||
followingCount: Int!
|
||||
isFollowing(userId: Int!): Boolean!
|
||||
followers(limit: Int = 20, offset: Int = 0): FollowersResponse!
|
||||
following(limit: Int = 20, offset: Int = 0): FollowingResponse!
|
||||
subscriptionNotifications(
|
||||
unreadOnly: Boolean = false
|
||||
limit: Int = 20
|
||||
offset: Int = 0
|
||||
): NotificationsResponse!
|
||||
}
|
||||
|
||||
# Пост в блоге
|
||||
@ -104,6 +114,62 @@ type Device {
|
||||
lastActiveAt: String!
|
||||
}
|
||||
|
||||
# типы для подписок
|
||||
type Follower {
|
||||
userId: Int!
|
||||
username: String!
|
||||
avatar: String!
|
||||
createdAt: String!
|
||||
}
|
||||
|
||||
type Following {
|
||||
userId: Int!
|
||||
username: String!
|
||||
avatar: String!
|
||||
createdAt: String!
|
||||
}
|
||||
|
||||
type SubscriptionNotification {
|
||||
id: Int!
|
||||
followerId: Int!
|
||||
followerUsername: String!
|
||||
followerAvatar: String!
|
||||
isRead: Boolean!
|
||||
createdAt: String!
|
||||
expiresAt: String!
|
||||
}
|
||||
|
||||
type FollowersResponse {
|
||||
followers: [Follower!]!
|
||||
totalCount: Int!
|
||||
}
|
||||
|
||||
type FollowingResponse {
|
||||
following: [Following!]!
|
||||
totalCount: Int!
|
||||
}
|
||||
|
||||
type NotificationsResponse {
|
||||
notifications: [SubscriptionNotification!]!
|
||||
totalCount: Int!
|
||||
unreadCount: Int!
|
||||
}
|
||||
|
||||
type FollowResult {
|
||||
success: Boolean!
|
||||
message: String!
|
||||
}
|
||||
|
||||
type UnfollowResult {
|
||||
success: Boolean!
|
||||
message: String!
|
||||
}
|
||||
|
||||
type MarkNotificationReadResult {
|
||||
success: Boolean!
|
||||
message: String!
|
||||
}
|
||||
|
||||
# Запросы (получение данных)
|
||||
type Query {
|
||||
me: User! # Получить текущего пользователя
|
||||
@ -117,6 +183,27 @@ type Query {
|
||||
getUserChats(userId: Int!): [Chat!]!
|
||||
mySessions: [Session!]!
|
||||
comments(postID: Int!): [Comment!]!
|
||||
# Получить количество подписчиков
|
||||
getFollowersCount(userId: Int!): Int!
|
||||
|
||||
# Получить количество подписок
|
||||
getFollowingCount(userId: Int!): Int!
|
||||
|
||||
# Проверить подписку
|
||||
isFollowing(followingId: Int!): Boolean!
|
||||
|
||||
# Получить список подписчиков
|
||||
getFollowers(userId: Int!, limit: Int = 20, offset: Int = 0): FollowersResponse!
|
||||
|
||||
# Получить список подписок
|
||||
getFollowing(userId: Int!, limit: Int = 20, offset: Int = 0): FollowingResponse!
|
||||
|
||||
# Получить уведомления о подписках
|
||||
getSubscriptionNotifications(
|
||||
unreadOnly: Boolean = false
|
||||
limit: Int = 20
|
||||
offset: Int = 0
|
||||
): NotificationsResponse!
|
||||
}
|
||||
|
||||
# Мутации (изменение данных)
|
||||
@ -155,6 +242,9 @@ type Mutation {
|
||||
# Повторная отправка подтверждения email
|
||||
resendEmailConfirmation: Boolean!
|
||||
deletePost(id: Int!): Boolean!
|
||||
followUser(followingId: Int!): FollowResult!
|
||||
unfollowUser(followingId: Int!): UnfollowResult!
|
||||
markNotificationAsRead(notificationId: Int!): MarkNotificationReadResult!
|
||||
}
|
||||
|
||||
type Subscription {
|
||||
|
||||
240
internal/http/graph/subscriber_resolvers.go
Normal file
240
internal/http/graph/subscriber_resolvers.go
Normal file
@ -0,0 +1,240 @@
|
||||
package graph
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"tailly_back_v2/proto"
|
||||
)
|
||||
|
||||
// FollowUser is the resolver for the followUser field.
|
||||
func (r *mutationResolver) FollowUser(ctx context.Context, followingID int) (*FollowResult, error) {
|
||||
followerID, err := getUserIDFromContext(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("authentication required: %w", err)
|
||||
}
|
||||
|
||||
res, err := r.SubscribeClient.FollowUser(ctx, &proto.FollowRequest{
|
||||
FollowerId: int32(followerID),
|
||||
FollowingId: int32(followingID),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to follow user: %w", err)
|
||||
}
|
||||
return &FollowResult{Success: res.Success, Message: res.Message}, nil
|
||||
}
|
||||
|
||||
// UnfollowUser is the resolver for the unfollowUser field.
|
||||
func (r *mutationResolver) UnfollowUser(ctx context.Context, followingID int) (*UnfollowResult, error) {
|
||||
followerID, err := getUserIDFromContext(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("authentication required: %w", err)
|
||||
}
|
||||
|
||||
res, err := r.SubscribeClient.UnfollowUser(ctx, &proto.UnfollowRequest{
|
||||
FollowerId: int32(followerID),
|
||||
FollowingId: int32(followingID),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to unfollow user: %w", err)
|
||||
}
|
||||
|
||||
return &UnfollowResult{Success: res.Success, Message: res.Message}, nil
|
||||
}
|
||||
|
||||
// MarkNotificationAsRead is the resolver for the markNotificationAsRead field.
|
||||
func (r *mutationResolver) MarkNotificationAsRead(ctx context.Context, notificationID int) (*MarkNotificationReadResult, error) {
|
||||
userID, err := getUserIDFromContext(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("authentication required: %w", err)
|
||||
}
|
||||
|
||||
res, err := r.SubscribeClient.MarkNotificationAsRead(ctx, &proto.MarkNotificationReadRequest{
|
||||
UserId: int32(userID),
|
||||
NotificationId: int32(notificationID),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to unfollow user: %w", err)
|
||||
}
|
||||
|
||||
return &MarkNotificationReadResult{Success: res.Success, Message: res.Message}, nil
|
||||
}
|
||||
|
||||
// GetFollowersCount is the resolver for the getFollowersCount field.
|
||||
func (r *queryResolver) GetFollowersCount(ctx context.Context, userID int) (int, error) {
|
||||
|
||||
res, err := r.SubscribeClient.GetFollowersCount(ctx, &proto.GetCountRequest{
|
||||
UserId: int32(userID),
|
||||
})
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("failed to get followers count: %w", err)
|
||||
}
|
||||
|
||||
return int(res.Count), nil
|
||||
}
|
||||
|
||||
// GetFollowingCount is the resolver for the getFollowingCount field.
|
||||
func (r *queryResolver) GetFollowingCount(ctx context.Context, userID int) (int, error) {
|
||||
res, err := r.SubscribeClient.GetFollowingCount(ctx, &proto.GetCountRequest{
|
||||
UserId: int32(userID),
|
||||
})
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("failed to get following count: %w", err)
|
||||
}
|
||||
|
||||
return int(res.Count), nil
|
||||
}
|
||||
|
||||
// IsFollowing is the resolver for the isFollowing field.
|
||||
func (r *queryResolver) IsFollowing(ctx context.Context, followingID int) (bool, error) {
|
||||
followerID, err := getUserIDFromContext(ctx)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("authentication required: %w", err)
|
||||
}
|
||||
|
||||
res, err := r.SubscribeClient.IsFollowing(ctx, &proto.IsFollowingRequest{
|
||||
FollowerId: int32(followerID),
|
||||
FollowingId: int32(followingID),
|
||||
})
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to check subscription status: %w", err)
|
||||
}
|
||||
|
||||
return res.IsFollowing, nil
|
||||
}
|
||||
|
||||
// GetFollowers is the resolver for the getFollowers field.
|
||||
func (r *queryResolver) GetFollowers(ctx context.Context, userID int, limit *int, offset *int) (*FollowersResponse, error) {
|
||||
|
||||
limitVal := 20
|
||||
if limit != nil {
|
||||
limitVal = *limit
|
||||
}
|
||||
|
||||
offsetVal := 0
|
||||
if offset != nil {
|
||||
offsetVal = *offset
|
||||
}
|
||||
|
||||
res, err := r.SubscribeClient.GetFollowers(ctx, &proto.GetFollowersRequest{
|
||||
UserId: int32(userID),
|
||||
Limit: int32(limitVal),
|
||||
Offset: int32(offsetVal),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get followers: %w", err)
|
||||
}
|
||||
|
||||
return &FollowersResponse{
|
||||
Followers: convertProtoFollowersToGraphQL(res.Followers),
|
||||
TotalCount: int(res.TotalCount),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Вспомогательная функция для преобразования
|
||||
func convertProtoFollowersToGraphQL(protoFollowers []*proto.GetFollowersResponse_Follower) []*Follower {
|
||||
var followers []*Follower
|
||||
for _, pf := range protoFollowers {
|
||||
followers = append(followers, &Follower{
|
||||
UserID: int(pf.UserId),
|
||||
Username: pf.Username,
|
||||
Avatar: pf.Avatar,
|
||||
})
|
||||
}
|
||||
return followers
|
||||
}
|
||||
|
||||
// GetFollowing is the resolver for the getFollowing field.
|
||||
func (r *queryResolver) GetFollowing(ctx context.Context, userID int, limit *int, offset *int) (*FollowingResponse, error) {
|
||||
|
||||
limitVal := 20
|
||||
if limit != nil {
|
||||
limitVal = *limit
|
||||
}
|
||||
|
||||
offsetVal := 0
|
||||
if offset != nil {
|
||||
offsetVal = *offset
|
||||
}
|
||||
|
||||
res, err := r.SubscribeClient.GetFollowing(ctx, &proto.GetFollowingRequest{
|
||||
UserId: int32(userID),
|
||||
Limit: int32(limitVal),
|
||||
Offset: int32(offsetVal),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get following: %w", err)
|
||||
}
|
||||
|
||||
return &FollowingResponse{
|
||||
Following: convertProtoFollowingToGraphQL(res.Following),
|
||||
TotalCount: int(res.TotalCount),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Вспомогательная функция для преобразования
|
||||
func convertProtoFollowingToGraphQL(protoFollowing []*proto.GetFollowingResponse_Following) []*Following {
|
||||
var following []*Following
|
||||
for _, pf := range protoFollowing {
|
||||
following = append(following, &Following{
|
||||
UserID: int(pf.UserId),
|
||||
Username: pf.Username,
|
||||
Avatar: pf.Avatar,
|
||||
})
|
||||
}
|
||||
return following
|
||||
}
|
||||
|
||||
// GetSubscriptionNotifications is the resolver for the getSubscriptionNotifications field.
|
||||
func (r *queryResolver) GetSubscriptionNotifications(ctx context.Context, unreadOnly *bool, limit *int, offset *int) (*NotificationsResponse, error) {
|
||||
|
||||
userID, err := getUserIDFromContext(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("authentication required: %w", err)
|
||||
}
|
||||
|
||||
unreadOnlyVal := false
|
||||
if unreadOnly != nil {
|
||||
unreadOnlyVal = *unreadOnly
|
||||
}
|
||||
|
||||
limitVal := 20
|
||||
if limit != nil {
|
||||
limitVal = *limit
|
||||
}
|
||||
|
||||
offsetVal := 0
|
||||
if offset != nil {
|
||||
offsetVal = *offset
|
||||
}
|
||||
|
||||
res, err := r.SubscribeClient.GetSubscriptionNotifications(ctx, &proto.GetNotificationsRequest{
|
||||
UserId: int32(userID),
|
||||
UnreadOnly: unreadOnlyVal,
|
||||
Limit: int32(limitVal),
|
||||
Offset: int32(offsetVal),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get notifications: %w", err)
|
||||
}
|
||||
|
||||
return &NotificationsResponse{
|
||||
Notifications: convertProtoNotificationsToGraphQL(res.Notifications),
|
||||
TotalCount: int(res.TotalCount),
|
||||
UnreadCount: int(res.UnreadCount),
|
||||
}, nil
|
||||
}
|
||||
func convertProtoNotificationsToGraphQL(protoNotifs []*proto.GetNotificationsResponse_Notification) []*SubscriptionNotification {
|
||||
var notifications []*SubscriptionNotification
|
||||
for _, pn := range protoNotifs {
|
||||
notifications = append(notifications, &SubscriptionNotification{
|
||||
ID: int(pn.Id),
|
||||
FollowerID: int(pn.FollowerId),
|
||||
FollowerUsername: pn.FollowerUsername,
|
||||
FollowerAvatar: pn.FollowerAvatar,
|
||||
IsRead: pn.IsRead,
|
||||
CreatedAt: pn.CreatedAt,
|
||||
ExpiresAt: pn.ExpiresAt,
|
||||
})
|
||||
}
|
||||
return notifications
|
||||
}
|
||||
@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"tailly_back_v2/internal/domain"
|
||||
"tailly_back_v2/internal/service"
|
||||
"tailly_back_v2/proto"
|
||||
"time"
|
||||
)
|
||||
|
||||
@ -118,3 +119,140 @@ func (r *queryResolver) Users(ctx context.Context) ([]*domain.User, error) {
|
||||
}
|
||||
return users, nil
|
||||
}
|
||||
|
||||
// FollowersCount is the resolver for the followersCount field.
|
||||
func (r *userResolver) FollowersCount(ctx context.Context, obj *domain.User) (int, error) {
|
||||
res, err := r.SubscribeClient.GetFollowersCount(ctx, &proto.GetCountRequest{
|
||||
UserId: int32(obj.ID),
|
||||
})
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("failed to get followers count: %w", err)
|
||||
}
|
||||
return int(res.Count), nil
|
||||
}
|
||||
|
||||
// FollowingCount is the resolver for the followingCount field.
|
||||
func (r *userResolver) FollowingCount(ctx context.Context, obj *domain.User) (int, error) {
|
||||
res, err := r.SubscribeClient.GetFollowingCount(ctx, &proto.GetCountRequest{
|
||||
UserId: int32(obj.ID),
|
||||
})
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("failed to get following count: %w", err)
|
||||
}
|
||||
return int(res.Count), nil
|
||||
}
|
||||
|
||||
// IsFollowing is the resolver for the isFollowing field.
|
||||
func (r *userResolver) IsFollowing(ctx context.Context, obj *domain.User, userID int) (bool, error) {
|
||||
currentUserID, err := getUserIDFromContext(ctx)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("authentication required: %w", err)
|
||||
}
|
||||
|
||||
res, err := r.SubscribeClient.IsFollowing(ctx, &proto.IsFollowingRequest{
|
||||
FollowerId: int32(currentUserID),
|
||||
FollowingId: int32(userID),
|
||||
})
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to check subscription status: %w", err)
|
||||
}
|
||||
return res.IsFollowing, nil
|
||||
}
|
||||
|
||||
// Followers is the resolver for the followers field.
|
||||
func (r *userResolver) Followers(ctx context.Context, obj *domain.User, limit *int, offset *int) (*FollowersResponse, error) {
|
||||
limitVal := 20
|
||||
if limit != nil {
|
||||
limitVal = *limit
|
||||
}
|
||||
|
||||
offsetVal := 0
|
||||
if offset != nil {
|
||||
offsetVal = *offset
|
||||
}
|
||||
|
||||
res, err := r.SubscribeClient.GetFollowers(ctx, &proto.GetFollowersRequest{
|
||||
UserId: int32(obj.ID),
|
||||
Limit: int32(limitVal),
|
||||
Offset: int32(offsetVal),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get followers: %w", err)
|
||||
}
|
||||
|
||||
return &FollowersResponse{
|
||||
Followers: convertProtoFollowersToGraphQL(res.Followers),
|
||||
TotalCount: int(res.TotalCount),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Following is the resolver for the following field.
|
||||
func (r *userResolver) Following(ctx context.Context, obj *domain.User, limit *int, offset *int) (*FollowingResponse, error) {
|
||||
limitVal := 20
|
||||
if limit != nil {
|
||||
limitVal = *limit
|
||||
}
|
||||
|
||||
offsetVal := 0
|
||||
if offset != nil {
|
||||
offsetVal = *offset
|
||||
}
|
||||
|
||||
res, err := r.SubscribeClient.GetFollowing(ctx, &proto.GetFollowingRequest{
|
||||
UserId: int32(obj.ID),
|
||||
Limit: int32(limitVal),
|
||||
Offset: int32(offsetVal),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get following: %w", err)
|
||||
}
|
||||
|
||||
return &FollowingResponse{
|
||||
Following: convertProtoFollowingToGraphQL(res.Following),
|
||||
TotalCount: int(res.TotalCount),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// SubscriptionNotifications is the resolver for the subscriptionNotifications field.
|
||||
func (r *userResolver) SubscriptionNotifications(ctx context.Context, obj *domain.User, unreadOnly *bool, limit *int, offset *int) (*NotificationsResponse, error) {
|
||||
currentUserID, err := getUserIDFromContext(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("authentication required: %w", err)
|
||||
}
|
||||
|
||||
// Можно смотреть только свои уведомления
|
||||
if obj.ID != currentUserID {
|
||||
return nil, fmt.Errorf("access denied: can only view your own notifications")
|
||||
}
|
||||
|
||||
unreadOnlyVal := false
|
||||
if unreadOnly != nil {
|
||||
unreadOnlyVal = *unreadOnly
|
||||
}
|
||||
|
||||
limitVal := 20
|
||||
if limit != nil {
|
||||
limitVal = *limit
|
||||
}
|
||||
|
||||
offsetVal := 0
|
||||
if offset != nil {
|
||||
offsetVal = *offset
|
||||
}
|
||||
|
||||
res, err := r.SubscribeClient.GetSubscriptionNotifications(ctx, &proto.GetNotificationsRequest{
|
||||
UserId: int32(obj.ID),
|
||||
UnreadOnly: unreadOnlyVal,
|
||||
Limit: int32(limitVal),
|
||||
Offset: int32(offsetVal),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get notifications: %w", err)
|
||||
}
|
||||
|
||||
return &NotificationsResponse{
|
||||
Notifications: convertProtoNotificationsToGraphQL(res.Notifications),
|
||||
TotalCount: int(res.TotalCount),
|
||||
UnreadCount: int(res.UnreadCount),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -10,128 +10,29 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
// HTTP метрики
|
||||
httpRequestsTotal = promauto.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Name: "http_requests_total",
|
||||
Help: "Total number of HTTP requests",
|
||||
},
|
||||
[]string{"method", "path", "status", "handler"},
|
||||
[]string{"method", "path", "status"},
|
||||
)
|
||||
|
||||
httpRequestDuration = promauto.NewHistogramVec(
|
||||
prometheus.HistogramOpts{
|
||||
Name: "http_request_duration_seconds",
|
||||
Help: "Duration of HTTP requests",
|
||||
Buckets: []float64{0.01, 0.05, 0.1, 0.5, 1, 2.5, 5, 10},
|
||||
Buckets: []float64{0.1, 0.5, 1, 2.5, 5, 10},
|
||||
},
|
||||
[]string{"method", "path", "handler"},
|
||||
[]string{"method", "path"},
|
||||
)
|
||||
|
||||
// GraphQL специфичные метрики
|
||||
gqlOperationsTotal = promauto.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Name: "graphql_operations_total",
|
||||
Help: "Total number of GraphQL operations",
|
||||
httpResponseSize = promauto.NewSummaryVec(
|
||||
prometheus.SummaryOpts{
|
||||
Name: "http_response_size_bytes",
|
||||
Help: "Size of HTTP responses",
|
||||
},
|
||||
[]string{"operation", "type", "name", "success"},
|
||||
)
|
||||
|
||||
gqlOperationDuration = promauto.NewHistogramVec(
|
||||
prometheus.HistogramOpts{
|
||||
Name: "graphql_operation_duration_seconds",
|
||||
Help: "Duration of GraphQL operations",
|
||||
Buckets: []float64{0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 2, 5},
|
||||
},
|
||||
[]string{"operation", "name"},
|
||||
)
|
||||
|
||||
// Бизнес метрики
|
||||
usersTotal = promauto.NewGauge(
|
||||
prometheus.GaugeOpts{
|
||||
Name: "users_total",
|
||||
Help: "Total number of registered users",
|
||||
},
|
||||
)
|
||||
|
||||
postsTotal = promauto.NewGauge(
|
||||
prometheus.GaugeOpts{
|
||||
Name: "posts_total",
|
||||
Help: "Total number of posts",
|
||||
},
|
||||
)
|
||||
|
||||
commentsTotal = promauto.NewGauge(
|
||||
prometheus.GaugeOpts{
|
||||
Name: "comments_total",
|
||||
Help: "Total number of comments",
|
||||
},
|
||||
)
|
||||
|
||||
messagesTotal = promauto.NewGauge(
|
||||
prometheus.GaugeOpts{
|
||||
Name: "messages_total",
|
||||
Help: "Total number of messages",
|
||||
},
|
||||
)
|
||||
|
||||
activeWebsockets = promauto.NewGauge(
|
||||
prometheus.GaugeOpts{
|
||||
Name: "websocket_connections_active",
|
||||
Help: "Number of active WebSocket connections",
|
||||
},
|
||||
)
|
||||
|
||||
websocketMessagesTotal = promauto.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Name: "websocket_messages_total",
|
||||
Help: "Total number of WebSocket messages",
|
||||
},
|
||||
[]string{"direction", "type"},
|
||||
)
|
||||
|
||||
// Метрики ошибок
|
||||
errorsTotal = promauto.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Name: "errors_total",
|
||||
Help: "Total number of errors by type",
|
||||
},
|
||||
[]string{"type", "source", "severity"},
|
||||
)
|
||||
|
||||
// Метрики базы данных
|
||||
dbQueriesTotal = promauto.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Name: "db_queries_total",
|
||||
Help: "Total number of database queries",
|
||||
},
|
||||
[]string{"operation", "table", "success"},
|
||||
)
|
||||
|
||||
dbQueryDuration = promauto.NewHistogramVec(
|
||||
prometheus.HistogramOpts{
|
||||
Name: "db_query_duration_seconds",
|
||||
Help: "Duration of database queries",
|
||||
Buckets: []float64{0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 2},
|
||||
},
|
||||
[]string{"operation", "table"},
|
||||
)
|
||||
|
||||
// Метрики кэша
|
||||
cacheHitsTotal = promauto.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Name: "cache_hits_total",
|
||||
Help: "Total number of cache hits",
|
||||
},
|
||||
[]string{"type", "name"},
|
||||
)
|
||||
|
||||
cacheMissesTotal = promauto.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Name: "cache_misses_total",
|
||||
Help: "Total number of cache misses",
|
||||
},
|
||||
[]string{"type", "name"},
|
||||
[]string{"method", "path"},
|
||||
)
|
||||
)
|
||||
|
||||
@ -146,108 +47,21 @@ func MetricsMiddleware(next http.Handler) http.Handler {
|
||||
duration := time.Since(start).Seconds()
|
||||
status := strconv.Itoa(rw.status)
|
||||
|
||||
// Определяем handler type
|
||||
handlerType := "http"
|
||||
if r.URL.Path == "/query" {
|
||||
handlerType = "graphql"
|
||||
} else if r.URL.Path == "/ws" {
|
||||
handlerType = "websocket"
|
||||
}
|
||||
|
||||
// Регистрируем метрики
|
||||
httpRequestsTotal.WithLabelValues(
|
||||
r.Method,
|
||||
r.URL.Path,
|
||||
status,
|
||||
handlerType,
|
||||
).Inc()
|
||||
|
||||
httpRequestDuration.WithLabelValues(
|
||||
r.Method,
|
||||
r.URL.Path,
|
||||
handlerType,
|
||||
).Observe(duration)
|
||||
|
||||
httpResponseSize.WithLabelValues(
|
||||
r.Method,
|
||||
r.URL.Path,
|
||||
).Observe(float64(rw.size))
|
||||
})
|
||||
}
|
||||
|
||||
// GraphQLMetricsMiddleware для отслеживания GraphQL операций
|
||||
func GraphQLMetricsMiddleware() func(http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.URL.Path != "/query" {
|
||||
next.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
// Здесь можно парсить GraphQL запрос и извлекать информацию об операции
|
||||
// Для простоты пока пропускаем
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Вспомогательные функции для обновления метрик
|
||||
|
||||
func IncGQLOperation(operationType, operationName string, success bool, duration time.Duration) {
|
||||
status := "false"
|
||||
if success {
|
||||
status = "true"
|
||||
}
|
||||
|
||||
gqlOperationsTotal.WithLabelValues(
|
||||
operationType, // operation
|
||||
operationName, // type (возможно нужно переименовать)
|
||||
operationName, // name (дублирование)
|
||||
status, // success
|
||||
).Inc()
|
||||
|
||||
gqlOperationDuration.WithLabelValues(
|
||||
operationType,
|
||||
operationName,
|
||||
).Observe(duration.Seconds())
|
||||
}
|
||||
|
||||
func IncWebSocketMessage(direction, messageType string) {
|
||||
websocketMessagesTotal.WithLabelValues(direction, messageType).Inc()
|
||||
}
|
||||
|
||||
func SetActiveWebsockets(count int) {
|
||||
activeWebsockets.Set(float64(count))
|
||||
}
|
||||
|
||||
func IncError(errorType, source, severity string) {
|
||||
errorsTotal.WithLabelValues(errorType, source, severity).Inc()
|
||||
}
|
||||
|
||||
func IncDBQuery(operation, table string, success bool, duration time.Duration) {
|
||||
status := "false"
|
||||
if success {
|
||||
status = "true"
|
||||
}
|
||||
|
||||
dbQueriesTotal.WithLabelValues(operation, table, status).Inc()
|
||||
dbQueryDuration.WithLabelValues(operation, table).Observe(duration.Seconds())
|
||||
}
|
||||
|
||||
func IncCacheHit(cacheType, cacheName string) {
|
||||
cacheHitsTotal.WithLabelValues(cacheType, cacheName).Inc()
|
||||
}
|
||||
|
||||
func IncCacheMiss(cacheType, cacheName string) {
|
||||
cacheMissesTotal.WithLabelValues(cacheType, cacheName).Inc()
|
||||
}
|
||||
|
||||
func SetUsersCount(count int) {
|
||||
usersTotal.Set(float64(count))
|
||||
}
|
||||
|
||||
func SetPostsCount(count int) {
|
||||
postsTotal.Set(float64(count))
|
||||
}
|
||||
|
||||
func SetCommentsCount(count int) {
|
||||
commentsTotal.Set(float64(count))
|
||||
}
|
||||
|
||||
func SetMessagesCount(count int) {
|
||||
messagesTotal.Set(float64(count))
|
||||
}
|
||||
|
||||
@ -66,7 +66,7 @@ func (s *Server) configureRouter() {
|
||||
s.router.Use(middleware.CORS(allowedOrigins))
|
||||
|
||||
// Основной GraphQL обработчик
|
||||
resolver := graph.NewResolver(s.services, s.db, s.services.Messages)
|
||||
resolver := graph.NewResolver(s.services, s.db, s.services.Messages, s.services.Subscribe)
|
||||
srv := handler.NewDefaultServer(graph.NewExecutableSchema(graph.Config{
|
||||
Resolvers: resolver,
|
||||
}))
|
||||
|
||||
@ -16,9 +16,10 @@ type Services struct {
|
||||
Recovery RecoveryService
|
||||
Audit AuditService
|
||||
Messages proto.MessageServiceClient
|
||||
Subscribe proto.SubscribeServiceClient
|
||||
}
|
||||
|
||||
func NewServices(authService AuthService, userService UserService, postService PostService, commentService CommentService, likeService LikeService, mailService MailService, auditService AuditService, recoveryService RecoveryService, sessionService SessionService, messages proto.MessageServiceClient) *Services {
|
||||
func NewServices(authService AuthService, userService UserService, postService PostService, commentService CommentService, likeService LikeService, mailService MailService, auditService AuditService, recoveryService RecoveryService, sessionService SessionService, messages proto.MessageServiceClient, subscribe proto.SubscribeServiceClient) *Services {
|
||||
return &Services{
|
||||
Auth: authService,
|
||||
User: userService,
|
||||
@ -30,5 +31,6 @@ func NewServices(authService AuthService, userService UserService, postService P
|
||||
Recovery: recoveryService,
|
||||
Audit: auditService,
|
||||
Messages: messages,
|
||||
Subscribe: subscribe,
|
||||
}
|
||||
}
|
||||
|
||||
1304
proto/subscribe.pb.go
Normal file
1304
proto/subscribe.pb.go
Normal file
File diff suppressed because it is too large
Load Diff
154
proto/subscribe.proto
Normal file
154
proto/subscribe.proto
Normal file
@ -0,0 +1,154 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
|
||||
option go_package = ".;proto";
|
||||
|
||||
// Сервис для работы с подписками
|
||||
service SubscribeService {
|
||||
// Подписаться на пользователя
|
||||
rpc FollowUser (FollowRequest) returns (FollowResponse);
|
||||
|
||||
// Отписаться от пользователя
|
||||
rpc UnfollowUser (UnfollowRequest) returns (UnfollowResponse);
|
||||
|
||||
// Получить список подписчиков пользователя
|
||||
rpc GetFollowers (GetFollowersRequest) returns (GetFollowersResponse);
|
||||
|
||||
// Получить список подписок пользователя
|
||||
rpc GetFollowing (GetFollowingRequest) returns (GetFollowingResponse);
|
||||
|
||||
// Проверить, подписан ли пользователь на другого
|
||||
rpc IsFollowing (IsFollowingRequest) returns (IsFollowingResponse);
|
||||
|
||||
// Получить уведомления о подписках для пользователя
|
||||
rpc GetSubscriptionNotifications (GetNotificationsRequest) returns (GetNotificationsResponse);
|
||||
|
||||
// Пометить уведомление как прочитанное
|
||||
rpc MarkNotificationAsRead (MarkNotificationReadRequest) returns (MarkNotificationReadResponse);
|
||||
|
||||
// Получить только КОЛИЧЕСТВО подписчиков
|
||||
rpc GetFollowersCount (GetCountRequest) returns (GetCountResponse);
|
||||
|
||||
// Получить только КОЛИЧЕСТВО подписок
|
||||
rpc GetFollowingCount (GetCountRequest) returns (GetCountResponse);
|
||||
}
|
||||
|
||||
message GetCountRequest {
|
||||
int32 user_id = 1;
|
||||
}
|
||||
|
||||
// Ответ с количеством
|
||||
message GetCountResponse {
|
||||
int32 count = 1;
|
||||
}
|
||||
|
||||
// Запрос на подписку
|
||||
message FollowRequest {
|
||||
int32 follower_id = 1; // ID пользователя, который подписывается
|
||||
int32 following_id = 2; // ID пользователя, на которого подписываются
|
||||
}
|
||||
|
||||
// Ответ на подписку
|
||||
message FollowResponse {
|
||||
bool success = 1; // Успешность операции
|
||||
string message = 2; // Сообщение (например, об ошибке)
|
||||
int32 subscription_id = 3; // ID созданной подписки
|
||||
int32 notification_id = 4; // ID созданного уведомления
|
||||
}
|
||||
|
||||
// Запрос на отписку
|
||||
message UnfollowRequest {
|
||||
int32 follower_id = 1;
|
||||
int32 following_id = 2;
|
||||
}
|
||||
|
||||
// Ответ на отписку
|
||||
message UnfollowResponse {
|
||||
bool success = 1;
|
||||
string message = 2;
|
||||
}
|
||||
|
||||
// Запрос на получение подписчиков
|
||||
message GetFollowersRequest {
|
||||
int32 user_id = 1; // ID пользователя, чьих подписчиков запрашиваем
|
||||
int32 limit = 2; // Лимит (для пагинации)
|
||||
int32 offset = 3; // Смещение (для пагинации)
|
||||
}
|
||||
|
||||
// Ответ с подписчиками
|
||||
message GetFollowersResponse {
|
||||
repeated Follower followers = 1; // Список подписчиков
|
||||
int32 total_count = 2; // Общее количество подписчиков
|
||||
message Follower {
|
||||
int32 user_id = 1;
|
||||
string username = 2;
|
||||
string avatar = 3;
|
||||
}
|
||||
}
|
||||
|
||||
// Запрос на получение подписок
|
||||
message GetFollowingRequest {
|
||||
int32 user_id = 1; // ID пользователя, чьи подписки запрашиваем
|
||||
int32 limit = 2;
|
||||
int32 offset = 3;
|
||||
}
|
||||
|
||||
// Ответ с подписками
|
||||
message GetFollowingResponse {
|
||||
repeated Following following = 1; // Список подписок
|
||||
int32 total_count = 2; // Общее количество подписок
|
||||
message Following {
|
||||
int32 user_id = 1;
|
||||
string username = 2;
|
||||
string avatar = 3;
|
||||
}
|
||||
}
|
||||
|
||||
// Запрос на проверку подписки
|
||||
message IsFollowingRequest {
|
||||
int32 follower_id = 1;
|
||||
int32 following_id = 2;
|
||||
}
|
||||
|
||||
// Ответ на проверку подписки
|
||||
message IsFollowingResponse {
|
||||
bool is_following = 1; // true - подписан, false - не подписан
|
||||
}
|
||||
|
||||
// Запрос на получение уведомлений
|
||||
message GetNotificationsRequest {
|
||||
int32 user_id = 1; // ID пользователя, чьи уведомления запрашиваем
|
||||
bool unread_only = 2; // Только непрочитанные
|
||||
int32 limit = 3;
|
||||
int32 offset = 4;
|
||||
}
|
||||
|
||||
// Ответ с уведомлениями
|
||||
message GetNotificationsResponse {
|
||||
repeated Notification notifications = 1;
|
||||
int32 total_count = 2;
|
||||
int32 unread_count = 3; // Количество непрочитанных уведомлений
|
||||
message Notification {
|
||||
int32 id = 1;
|
||||
int32 subscription_id = 2;
|
||||
int32 follower_id = 3;
|
||||
string follower_username = 4;
|
||||
string follower_avatar = 5;
|
||||
bool is_read = 6;
|
||||
string created_at = 7;
|
||||
string expires_at = 8;
|
||||
}
|
||||
}
|
||||
|
||||
// Запрос на пометку уведомления как прочитанного
|
||||
message MarkNotificationReadRequest {
|
||||
int32 notification_id = 1;
|
||||
int32 user_id = 2; // Для проверки прав
|
||||
}
|
||||
|
||||
// Ответ на пометку уведомления
|
||||
message MarkNotificationReadResponse {
|
||||
bool success = 1;
|
||||
string message = 2;
|
||||
}
|
||||
447
proto/subscribe_grpc.pb.go
Normal file
447
proto/subscribe_grpc.pb.go
Normal file
@ -0,0 +1,447 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.5.1
|
||||
// - protoc v3.21.12
|
||||
// source: subscribe.proto
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
context "context"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.64.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion9
|
||||
|
||||
const (
|
||||
SubscribeService_FollowUser_FullMethodName = "/proto.SubscribeService/FollowUser"
|
||||
SubscribeService_UnfollowUser_FullMethodName = "/proto.SubscribeService/UnfollowUser"
|
||||
SubscribeService_GetFollowers_FullMethodName = "/proto.SubscribeService/GetFollowers"
|
||||
SubscribeService_GetFollowing_FullMethodName = "/proto.SubscribeService/GetFollowing"
|
||||
SubscribeService_IsFollowing_FullMethodName = "/proto.SubscribeService/IsFollowing"
|
||||
SubscribeService_GetSubscriptionNotifications_FullMethodName = "/proto.SubscribeService/GetSubscriptionNotifications"
|
||||
SubscribeService_MarkNotificationAsRead_FullMethodName = "/proto.SubscribeService/MarkNotificationAsRead"
|
||||
SubscribeService_GetFollowersCount_FullMethodName = "/proto.SubscribeService/GetFollowersCount"
|
||||
SubscribeService_GetFollowingCount_FullMethodName = "/proto.SubscribeService/GetFollowingCount"
|
||||
)
|
||||
|
||||
// SubscribeServiceClient is the client API for SubscribeService service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
//
|
||||
// Сервис для работы с подписками
|
||||
type SubscribeServiceClient interface {
|
||||
// Подписаться на пользователя
|
||||
FollowUser(ctx context.Context, in *FollowRequest, opts ...grpc.CallOption) (*FollowResponse, error)
|
||||
// Отписаться от пользователя
|
||||
UnfollowUser(ctx context.Context, in *UnfollowRequest, opts ...grpc.CallOption) (*UnfollowResponse, error)
|
||||
// Получить список подписчиков пользователя
|
||||
GetFollowers(ctx context.Context, in *GetFollowersRequest, opts ...grpc.CallOption) (*GetFollowersResponse, error)
|
||||
// Получить список подписок пользователя
|
||||
GetFollowing(ctx context.Context, in *GetFollowingRequest, opts ...grpc.CallOption) (*GetFollowingResponse, error)
|
||||
// Проверить, подписан ли пользователь на другого
|
||||
IsFollowing(ctx context.Context, in *IsFollowingRequest, opts ...grpc.CallOption) (*IsFollowingResponse, error)
|
||||
// Получить уведомления о подписках для пользователя
|
||||
GetSubscriptionNotifications(ctx context.Context, in *GetNotificationsRequest, opts ...grpc.CallOption) (*GetNotificationsResponse, error)
|
||||
// Пометить уведомление как прочитанное
|
||||
MarkNotificationAsRead(ctx context.Context, in *MarkNotificationReadRequest, opts ...grpc.CallOption) (*MarkNotificationReadResponse, error)
|
||||
// Получить только КОЛИЧЕСТВО подписчиков
|
||||
GetFollowersCount(ctx context.Context, in *GetCountRequest, opts ...grpc.CallOption) (*GetCountResponse, error)
|
||||
// Получить только КОЛИЧЕСТВО подписок
|
||||
GetFollowingCount(ctx context.Context, in *GetCountRequest, opts ...grpc.CallOption) (*GetCountResponse, error)
|
||||
}
|
||||
|
||||
type subscribeServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewSubscribeServiceClient(cc grpc.ClientConnInterface) SubscribeServiceClient {
|
||||
return &subscribeServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *subscribeServiceClient) FollowUser(ctx context.Context, in *FollowRequest, opts ...grpc.CallOption) (*FollowResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(FollowResponse)
|
||||
err := c.cc.Invoke(ctx, SubscribeService_FollowUser_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *subscribeServiceClient) UnfollowUser(ctx context.Context, in *UnfollowRequest, opts ...grpc.CallOption) (*UnfollowResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(UnfollowResponse)
|
||||
err := c.cc.Invoke(ctx, SubscribeService_UnfollowUser_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *subscribeServiceClient) GetFollowers(ctx context.Context, in *GetFollowersRequest, opts ...grpc.CallOption) (*GetFollowersResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(GetFollowersResponse)
|
||||
err := c.cc.Invoke(ctx, SubscribeService_GetFollowers_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *subscribeServiceClient) GetFollowing(ctx context.Context, in *GetFollowingRequest, opts ...grpc.CallOption) (*GetFollowingResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(GetFollowingResponse)
|
||||
err := c.cc.Invoke(ctx, SubscribeService_GetFollowing_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *subscribeServiceClient) IsFollowing(ctx context.Context, in *IsFollowingRequest, opts ...grpc.CallOption) (*IsFollowingResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(IsFollowingResponse)
|
||||
err := c.cc.Invoke(ctx, SubscribeService_IsFollowing_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *subscribeServiceClient) GetSubscriptionNotifications(ctx context.Context, in *GetNotificationsRequest, opts ...grpc.CallOption) (*GetNotificationsResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(GetNotificationsResponse)
|
||||
err := c.cc.Invoke(ctx, SubscribeService_GetSubscriptionNotifications_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *subscribeServiceClient) MarkNotificationAsRead(ctx context.Context, in *MarkNotificationReadRequest, opts ...grpc.CallOption) (*MarkNotificationReadResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(MarkNotificationReadResponse)
|
||||
err := c.cc.Invoke(ctx, SubscribeService_MarkNotificationAsRead_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *subscribeServiceClient) GetFollowersCount(ctx context.Context, in *GetCountRequest, opts ...grpc.CallOption) (*GetCountResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(GetCountResponse)
|
||||
err := c.cc.Invoke(ctx, SubscribeService_GetFollowersCount_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *subscribeServiceClient) GetFollowingCount(ctx context.Context, in *GetCountRequest, opts ...grpc.CallOption) (*GetCountResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(GetCountResponse)
|
||||
err := c.cc.Invoke(ctx, SubscribeService_GetFollowingCount_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// SubscribeServiceServer is the server API for SubscribeService service.
|
||||
// All implementations must embed UnimplementedSubscribeServiceServer
|
||||
// for forward compatibility.
|
||||
//
|
||||
// Сервис для работы с подписками
|
||||
type SubscribeServiceServer interface {
|
||||
// Подписаться на пользователя
|
||||
FollowUser(context.Context, *FollowRequest) (*FollowResponse, error)
|
||||
// Отписаться от пользователя
|
||||
UnfollowUser(context.Context, *UnfollowRequest) (*UnfollowResponse, error)
|
||||
// Получить список подписчиков пользователя
|
||||
GetFollowers(context.Context, *GetFollowersRequest) (*GetFollowersResponse, error)
|
||||
// Получить список подписок пользователя
|
||||
GetFollowing(context.Context, *GetFollowingRequest) (*GetFollowingResponse, error)
|
||||
// Проверить, подписан ли пользователь на другого
|
||||
IsFollowing(context.Context, *IsFollowingRequest) (*IsFollowingResponse, error)
|
||||
// Получить уведомления о подписках для пользователя
|
||||
GetSubscriptionNotifications(context.Context, *GetNotificationsRequest) (*GetNotificationsResponse, error)
|
||||
// Пометить уведомление как прочитанное
|
||||
MarkNotificationAsRead(context.Context, *MarkNotificationReadRequest) (*MarkNotificationReadResponse, error)
|
||||
// Получить только КОЛИЧЕСТВО подписчиков
|
||||
GetFollowersCount(context.Context, *GetCountRequest) (*GetCountResponse, error)
|
||||
// Получить только КОЛИЧЕСТВО подписок
|
||||
GetFollowingCount(context.Context, *GetCountRequest) (*GetCountResponse, error)
|
||||
mustEmbedUnimplementedSubscribeServiceServer()
|
||||
}
|
||||
|
||||
// UnimplementedSubscribeServiceServer must be embedded to have
|
||||
// forward compatible implementations.
|
||||
//
|
||||
// NOTE: this should be embedded by value instead of pointer to avoid a nil
|
||||
// pointer dereference when methods are called.
|
||||
type UnimplementedSubscribeServiceServer struct{}
|
||||
|
||||
func (UnimplementedSubscribeServiceServer) FollowUser(context.Context, *FollowRequest) (*FollowResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method FollowUser not implemented")
|
||||
}
|
||||
func (UnimplementedSubscribeServiceServer) UnfollowUser(context.Context, *UnfollowRequest) (*UnfollowResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method UnfollowUser not implemented")
|
||||
}
|
||||
func (UnimplementedSubscribeServiceServer) GetFollowers(context.Context, *GetFollowersRequest) (*GetFollowersResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetFollowers not implemented")
|
||||
}
|
||||
func (UnimplementedSubscribeServiceServer) GetFollowing(context.Context, *GetFollowingRequest) (*GetFollowingResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetFollowing not implemented")
|
||||
}
|
||||
func (UnimplementedSubscribeServiceServer) IsFollowing(context.Context, *IsFollowingRequest) (*IsFollowingResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method IsFollowing not implemented")
|
||||
}
|
||||
func (UnimplementedSubscribeServiceServer) GetSubscriptionNotifications(context.Context, *GetNotificationsRequest) (*GetNotificationsResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetSubscriptionNotifications not implemented")
|
||||
}
|
||||
func (UnimplementedSubscribeServiceServer) MarkNotificationAsRead(context.Context, *MarkNotificationReadRequest) (*MarkNotificationReadResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method MarkNotificationAsRead not implemented")
|
||||
}
|
||||
func (UnimplementedSubscribeServiceServer) GetFollowersCount(context.Context, *GetCountRequest) (*GetCountResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetFollowersCount not implemented")
|
||||
}
|
||||
func (UnimplementedSubscribeServiceServer) GetFollowingCount(context.Context, *GetCountRequest) (*GetCountResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetFollowingCount not implemented")
|
||||
}
|
||||
func (UnimplementedSubscribeServiceServer) mustEmbedUnimplementedSubscribeServiceServer() {}
|
||||
func (UnimplementedSubscribeServiceServer) testEmbeddedByValue() {}
|
||||
|
||||
// UnsafeSubscribeServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to SubscribeServiceServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeSubscribeServiceServer interface {
|
||||
mustEmbedUnimplementedSubscribeServiceServer()
|
||||
}
|
||||
|
||||
func RegisterSubscribeServiceServer(s grpc.ServiceRegistrar, srv SubscribeServiceServer) {
|
||||
// If the following call pancis, it indicates UnimplementedSubscribeServiceServer was
|
||||
// embedded by pointer and is nil. This will cause panics if an
|
||||
// unimplemented method is ever invoked, so we test this at initialization
|
||||
// time to prevent it from happening at runtime later due to I/O.
|
||||
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
|
||||
t.testEmbeddedByValue()
|
||||
}
|
||||
s.RegisterService(&SubscribeService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _SubscribeService_FollowUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(FollowRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SubscribeServiceServer).FollowUser(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: SubscribeService_FollowUser_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SubscribeServiceServer).FollowUser(ctx, req.(*FollowRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SubscribeService_UnfollowUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(UnfollowRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SubscribeServiceServer).UnfollowUser(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: SubscribeService_UnfollowUser_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SubscribeServiceServer).UnfollowUser(ctx, req.(*UnfollowRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SubscribeService_GetFollowers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetFollowersRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SubscribeServiceServer).GetFollowers(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: SubscribeService_GetFollowers_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SubscribeServiceServer).GetFollowers(ctx, req.(*GetFollowersRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SubscribeService_GetFollowing_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetFollowingRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SubscribeServiceServer).GetFollowing(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: SubscribeService_GetFollowing_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SubscribeServiceServer).GetFollowing(ctx, req.(*GetFollowingRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SubscribeService_IsFollowing_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(IsFollowingRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SubscribeServiceServer).IsFollowing(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: SubscribeService_IsFollowing_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SubscribeServiceServer).IsFollowing(ctx, req.(*IsFollowingRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SubscribeService_GetSubscriptionNotifications_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetNotificationsRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SubscribeServiceServer).GetSubscriptionNotifications(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: SubscribeService_GetSubscriptionNotifications_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SubscribeServiceServer).GetSubscriptionNotifications(ctx, req.(*GetNotificationsRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SubscribeService_MarkNotificationAsRead_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(MarkNotificationReadRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SubscribeServiceServer).MarkNotificationAsRead(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: SubscribeService_MarkNotificationAsRead_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SubscribeServiceServer).MarkNotificationAsRead(ctx, req.(*MarkNotificationReadRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SubscribeService_GetFollowersCount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetCountRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SubscribeServiceServer).GetFollowersCount(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: SubscribeService_GetFollowersCount_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SubscribeServiceServer).GetFollowersCount(ctx, req.(*GetCountRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SubscribeService_GetFollowingCount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetCountRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SubscribeServiceServer).GetFollowingCount(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: SubscribeService_GetFollowingCount_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SubscribeServiceServer).GetFollowingCount(ctx, req.(*GetCountRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// SubscribeService_ServiceDesc is the grpc.ServiceDesc for SubscribeService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var SubscribeService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "proto.SubscribeService",
|
||||
HandlerType: (*SubscribeServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "FollowUser",
|
||||
Handler: _SubscribeService_FollowUser_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "UnfollowUser",
|
||||
Handler: _SubscribeService_UnfollowUser_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetFollowers",
|
||||
Handler: _SubscribeService_GetFollowers_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetFollowing",
|
||||
Handler: _SubscribeService_GetFollowing_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "IsFollowing",
|
||||
Handler: _SubscribeService_IsFollowing_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetSubscriptionNotifications",
|
||||
Handler: _SubscribeService_GetSubscriptionNotifications_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "MarkNotificationAsRead",
|
||||
Handler: _SubscribeService_MarkNotificationAsRead_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetFollowersCount",
|
||||
Handler: _SubscribeService_GetFollowersCount_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetFollowingCount",
|
||||
Handler: _SubscribeService_GetFollowingCount_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "subscribe.proto",
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user