├── .gitmodules ├── README ├── polling ├── migrations │ ├── 000003_trigger_table.down.sql │ ├── 000002_insert_table.down.sql │ ├── 000001_create_table.down.sql │ ├── 000001_create_table.up.sql │ └── 000003_trigger_table.up.sql ├── .vscode │ └── settings.json ├── .env ├── protos │ ├── void.proto │ ├── question.proto │ ├── poll.proto │ ├── result.proto │ └── users.proto ├── config │ ├── checkErr.go │ └── getEnv.go ├── Dockerfile ├── go.mod ├── README ├── main.go ├── service │ ├── poll.go │ ├── quesiton.go │ ├── user.go │ └── result.go ├── Makefile ├── docker-compose.yaml ├── index.html ├── storage │ ├── postgres.go │ ├── storage.go │ └── managers │ │ ├── user.go │ │ ├── question.go │ │ ├── result.go │ │ └── poll.go ├── go.sum └── genprotos │ ├── void.pb.go │ ├── result_grpc.pb.go │ ├── poll_grpc.pb.go │ ├── question_grpc.pb.go │ └── users_grpc.pb.go ├── api-gateway ├── files │ └── results.xlsx ├── protos │ ├── void.proto │ ├── question.proto │ ├── poll.proto │ ├── result.proto │ └── users.proto ├── .env ├── config │ ├── checkErr.go │ ├── helperFuncs.go │ └── getEnv.go ├── Dockerfile ├── README.md ├── api │ ├── handlers │ │ ├── init.go │ │ ├── answers.go │ │ ├── question.go │ │ ├── results.go │ │ ├── poll.go │ │ └── auth.go │ ├── token │ │ └── token.go │ ├── middleware │ │ └── middleware.go │ └── router.go ├── main.go ├── docker-compose.yaml ├── Makefile ├── tokens.txt ├── drivers │ └── minio.go ├── models │ └── models.go ├── go.mod └── genprotos │ ├── void.pb.go │ ├── result_grpc.pb.go │ ├── poll_grpc.pb.go │ ├── question_grpc.pb.go │ └── users_grpc.pb.go ├── tokens └── .github └── workflows └── deploy.yml /.gitmodules: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | HELLO WORLD -------------------------------------------------------------------------------- /polling/migrations/000003_trigger_table.down.sql: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /polling/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "liveServer.settings.port": 5501 3 | } -------------------------------------------------------------------------------- /api-gateway/files/results.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azizbek-qodirov/web-poll/HEAD/api-gateway/files/results.xlsx -------------------------------------------------------------------------------- /polling/.env: -------------------------------------------------------------------------------- 1 | POLL_SERVICE_PORT=:50051 2 | DB_HOST=polling-cont 3 | DB_PORT=5432 4 | DB_USER=postgres 5 | DB_PASSWORD=root 6 | DB_NAME=polling_db -------------------------------------------------------------------------------- /polling/migrations/000002_insert_table.down.sql: -------------------------------------------------------------------------------- 1 | DELETE FROM poll_answers; 2 | DELETE FROM results; 3 | DELETE FROM questions; 4 | DELETE FROM polls; 5 | DELETE FROM users; -------------------------------------------------------------------------------- /polling/migrations/000001_create_table.down.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE poll_answers; 2 | DROP TABLE results; 3 | DROP TABLE questions; 4 | DROP TABLE polls; 5 | DROP TABLE users; 6 | DROP TYPE gender_type; 7 | -------------------------------------------------------------------------------- /polling/protos/void.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package polling; 4 | 5 | option go_package = "genprotos/"; 6 | 7 | 8 | message Void {}; 9 | 10 | message ByID{ 11 | string id = 1; 12 | } 13 | -------------------------------------------------------------------------------- /api-gateway/protos/void.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package polling; 4 | 5 | option go_package = "genprotos/"; 6 | 7 | 8 | message Void {}; 9 | 10 | message ByID{ 11 | string id = 1; 12 | } 13 | -------------------------------------------------------------------------------- /api-gateway/.env: -------------------------------------------------------------------------------- 1 | GATEWAY_SERVICE_PORT=:8080 2 | POLL_SERVICE_PORT=:50051 3 | DB_HOST=poll_service 4 | DB_PORT=5432 5 | DB_USER=postgres 6 | DB_PASSWORD=root 7 | DB_NAME=polling_db 8 | # SENDER_EMAIL=farruhbekturdiqulov@gmail.com 9 | # APP_PASSWORD="vitsksiycvwxyrdt" -------------------------------------------------------------------------------- /api-gateway/config/checkErr.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | type ErrorManager struct{} 4 | 5 | func NewErrorManager() *ErrorManager { 6 | return &ErrorManager{} 7 | } 8 | 9 | func (e *ErrorManager) CheckErr(err error) { 10 | if err != nil { 11 | panic(err) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /polling/config/checkErr.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "log" 5 | ) 6 | 7 | type ErrorManager struct{} 8 | 9 | func NewErrorManager() *ErrorManager { 10 | return &ErrorManager{} 11 | } 12 | 13 | func (e *ErrorManager) CheckErr(err error) { 14 | if err != nil { 15 | log.Fatal(err.Error()) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /api-gateway/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.22.4 AS builder 2 | WORKDIR /app 3 | COPY go.mod ./ 4 | COPY go.sum ./ 5 | RUN go mod download 6 | COPY . . 7 | RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o myapp . 8 | 9 | FROM alpine:latest 10 | WORKDIR /app 11 | COPY --from=builder /app/myapp . 12 | 13 | COPY .env . 14 | EXPOSE 8080 15 | CMD ["./myapp"] -------------------------------------------------------------------------------- /polling/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.22.4 AS builder 2 | WORKDIR /app 3 | COPY go.mod ./ 4 | COPY go.sum ./ 5 | RUN go mod download 6 | COPY . . 7 | RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o myapp . 8 | 9 | FROM alpine:latest 10 | WORKDIR /app 11 | COPY --from=builder /app/myapp . 12 | 13 | COPY .env . 14 | EXPOSE 50051 15 | CMD ["./myapp"] -------------------------------------------------------------------------------- /tokens: -------------------------------------------------------------------------------- 1 | eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImZvam90b2Y2MzNAZ2l2ZWhpdC5jb20iLCJleHAiOjE3MjQ0MDEzMjUsImlhdCI6MTcyNDE0MjEyNSwicm9sZSI6InVzZXIiLCJ1c2VyX2lkIjoiOWY0ZjFhNTAtZDEzYi00Zjk5LWE5NzgtN2FhYTEyNzM5NjBjIn0.JvBdTz1TF_ujxDck2Wc_LLzN5KDG6hQC8mMOSgcMTpY 2 | 3 | 4 | eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6InRlaG9jb2QyOThAaXRlcmFkZXYuY29tIiwiZXhwIjoxNzI0NDAyMjE0LCJpYXQiOjE3MjQxNDMwMTQsInJvbGUiOiJhZG1pbiIsInVzZXJfaWQiOiI5NGY1ZmNiMy1iNDQyLTRlODMtODI1Ny1hNTdiMTFmOTkwOWIifQ.IObQS_JSoJJxGqZLpOHuBTBmRY4_dfSHDn_QI5RcXME -------------------------------------------------------------------------------- /polling/go.mod: -------------------------------------------------------------------------------- 1 | module poll-service 2 | 3 | go 1.22.4 4 | 5 | require ( 6 | github.com/google/uuid v1.6.0 7 | github.com/joho/godotenv v1.5.1 8 | github.com/lib/pq v1.10.9 9 | github.com/spf13/cast v1.6.0 10 | // golang.org/x/crypto v0.23.0 11 | google.golang.org/grpc v1.65.0 12 | google.golang.org/protobuf v1.34.2 13 | ) 14 | 15 | require ( 16 | golang.org/x/net v0.25.0 // indirect 17 | golang.org/x/sys v0.20.0 // indirect 18 | golang.org/x/text v0.15.0 // indirect 19 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 // indirect 20 | ) 21 | -------------------------------------------------------------------------------- /api-gateway/README.md: -------------------------------------------------------------------------------- 1 | 2 | eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6InFvZGlyb3Zheml6YmVrMjQ5QGdtYWlsLmNvbSIsImV4cCI6MTcyMjYzMDQ4OSwiaWF0IjoxNzIyNTQ0MDg5LCJyb2xlIjoidXNlciIsInVzZXJfaWQiOiIzN2QwNWExMy01MTE2LTRkNDMtOWRmNS0wZjAzNmI0OTgyOTQifQ.cJ2r6DMOARgO66wkZqm6nIa3Le52xKSgzlnwpUdJ4rI 3 | 4 | 5 | : 6 | eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImZhcnJ1aGJla3R1cmRpcXVsb3ZAZ21haWwuY29tIiwiZXhwIjoxNzI1MjgzNzgwLCJpYXQiOjE3MjUwMjQ1ODAsInJvbGUiOiJhZG1pbiIsInVzZXJfaWQiOiIzZDQ0MWZiZC0wYTFjLTQzNGUtOWNjNS0wZjQ3MzcwZjZkODQifQ.iMPGSWGOr1zIPeIvDTF5LyTFgxxl0tXjXtsipDWG7iE 7 | 8 | -------------------------------------------------------------------------------- /polling/README: -------------------------------------------------------------------------------- 1 | protoc --go_out=./ --go-grpc_out=./ protos/*.proto 2 | 3 | user 4 | eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImZhcnJ1aGJla3R1cmRpcXVsb3ZAZ21haWwuY29tIiwiZXhwIjoxNzI1ODgxOTA0LCJpYXQiOjE3MjU2MjI3MDQsInJvbGUiOiJ1c2VyIiwidXNlcl9pZCI6Ijg5NDUzOWZmLWU5YWUtNGZkNy05MzUxLWVjMDYyYWRiNzY3OCJ9.TtcOSZATjIFh0EfkQCET8xtOC4zyYjhmFvCJ5i6szfQ 5 | 6 | 7 | admin 8 | eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImZhcnJ1aGJla3R1cmRpcXVsb3ZAZ21haWwuY29tIiwiZXhwIjoxNzI1ODgyMDM5LCJpYXQiOjE3MjU2MjI4MzksInJvbGUiOiJhZG1pbiIsInVzZXJfaWQiOiI4OTQ1MzlmZi1lOWFlLTRmZDctOTM1MS1lYzA2MmFkYjc2NzgifQ.aCQg8zDEW8XsBoo7fM9o1qETjLBoJJnmwqNcYyl8ATM -------------------------------------------------------------------------------- /api-gateway/api/handlers/init.go: -------------------------------------------------------------------------------- 1 | package handlers 2 | 3 | import ( 4 | pb "auth-service/genprotos" 5 | 6 | "google.golang.org/grpc" 7 | ) 8 | 9 | type HTTPHandler struct { 10 | User pb.UserServiceClient 11 | Poll pb.PollServiceClient 12 | Question pb.QuestionServiceClient 13 | Result pb.ResultServiceClient 14 | } 15 | 16 | func NewHandler(conn *grpc.ClientConn) *HTTPHandler { 17 | return &HTTPHandler{ 18 | User: pb.NewUserServiceClient(conn), 19 | Poll: pb.NewPollServiceClient(conn), 20 | Question: pb.NewQuestionServiceClient(conn), 21 | Result: pb.NewResultServiceClient(conn), 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /api-gateway/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "auth-service/api" 5 | "fmt" 6 | 7 | cf "auth-service/config" 8 | 9 | "google.golang.org/grpc" 10 | "google.golang.org/grpc/credentials/insecure" 11 | ) 12 | 13 | func main() { 14 | config := cf.Load() 15 | em := cf.NewErrorManager() 16 | 17 | PollConn, err := grpc.NewClient(fmt.Sprintf("poll_service%s", config.POLL_SERVICE_PORT), grpc.WithTransportCredentials(insecure.NewCredentials())) 18 | em.CheckErr(err) 19 | defer PollConn.Close() 20 | 21 | roter := api.NewRouter(PollConn) 22 | fmt.Println("Server is running on port ", config.GATEWAY_SERVICE_PORT) 23 | if err := roter.Run(config.GATEWAY_SERVICE_PORT); err != nil { 24 | panic(err) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /api-gateway/docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: '3.8' 2 | 3 | services: 4 | admin-service: 5 | container_name: admin_service 6 | build: ./ 7 | ports: 8 | - "8080:8080" 9 | networks: 10 | - mynetwork 11 | volumes: 12 | - ./files:/files 13 | 14 | # redis: 15 | # image: redis:latest 16 | # container_name: redis 17 | # ports: 18 | # - "6380:6379" 19 | # networks: 20 | # - mynetwork 21 | 22 | minio: 23 | container_name: minio 24 | image: quay.io/minio/minio:latest 25 | volumes: 26 | - minio:/data 27 | ports: 28 | - 9000:9000 29 | - 9001:9001 30 | environment: 31 | MINIO_ROOT_USER: 'user' 32 | MINIO_ROOT_PASSWORD: 'password' 33 | MINIO_ADDRESS: ':9000' 34 | MINIO_CONSOLE_ADDRESS: ':9001' 35 | command: minio server /data 36 | networks: 37 | - mynetwork 38 | 39 | networks: 40 | mynetwork: 41 | external: true 42 | name: global-net 43 | 44 | volumes: 45 | files_volume: 46 | minio: -------------------------------------------------------------------------------- /polling/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "net" 6 | 7 | cf "poll-service/config" 8 | "poll-service/storage" 9 | 10 | pb "poll-service/genprotos" 11 | service "poll-service/service" 12 | 13 | "google.golang.org/grpc" 14 | ) 15 | 16 | func main() { 17 | config := cf.Load() 18 | em := cf.NewErrorManager() 19 | db, err := storage.NewPostgresStorage(config) 20 | em.CheckErr(err) 21 | defer db.PgClient.Close() 22 | 23 | listener, err := net.Listen("tcp", config.POLL_SERVICE_PORT) 24 | if err != nil { 25 | log.Fatalf("failed to listen: %v", err) 26 | } 27 | 28 | s := grpc.NewServer() 29 | pb.RegisterPollServiceServer(s, service.NewPollService(db)) 30 | pb.RegisterQuestionServiceServer(s, service.NewQuestionService(db)) 31 | pb.RegisterUserServiceServer(s, service.NewUserService(db)) 32 | pb.RegisterResultServiceServer(s, service.NewResultService(db)) 33 | 34 | log.Printf("server listening at %v", listener.Addr()) 35 | if err := s.Serve(listener); err != nil { 36 | log.Fatalf("failed to serve: %v", err) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /api-gateway/Makefile: -------------------------------------------------------------------------------- 1 | run: 2 | clear; 3 | go mod tidy; 4 | go run main.go; 5 | migrate_up: 6 | migrate -path migrations -database postgres://mrbek:QodirovCoder@localhost:5432/delivery_auth -verbose up 7 | 8 | migrate_down: 9 | migrate -path migrations -database postgres://mrbek:QodirovCoder@localhost:5432/delivery_auth -verbose down 10 | 11 | migrate_force: 12 | migrate -path migrations -database postgres://mrbek:QodirovCoder@localhost:5432/delivery_auth -verbose force 1 13 | 14 | migrate_file: 15 | migrate create -ext sql -dir migrations -seq create_table 16 | 17 | swag-gen: 18 | ~/go/bin/swag init -g ./api/router.go -o api/docs force 1 19 | 20 | proto-gen: 21 | protoc --go_out=./ --go-grpc_out=./ protos/*.proto 22 | 23 | proto-gen0: 24 | protoc --go_out=./ --go-grpc_out=./ --experimental_allow_proto3_optional protos/*.proto 25 | 26 | 27 | ps: 28 | docker ps -a 29 | 30 | pg: 31 | docker exec -it $(c) psql -U postgres -d polling_db 32 | 33 | down: 34 | docker compose down 35 | 36 | up: 37 | docker compose up 38 | 39 | build: 40 | docker compose up --build -------------------------------------------------------------------------------- /polling/service/poll.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | pb "poll-service/genprotos" 6 | st "poll-service/storage" 7 | ) 8 | 9 | type PollService struct { 10 | storage st.StorageI 11 | pb.UnimplementedPollServiceServer 12 | } 13 | 14 | func NewPollService(storage st.StorageI) *PollService { 15 | return &PollService{storage: storage} 16 | } 17 | 18 | func (s *PollService) Create(ctx context.Context, req *pb.PollCreateReq) (*pb.Void, error) { 19 | return s.storage.Poll().Create(ctx, req) 20 | } 21 | 22 | func (s *PollService) GetByID(ctx context.Context, req *pb.ByID) (*pb.PollGetByIDRes, error) { 23 | return s.storage.Poll().GetByID(ctx, req) 24 | } 25 | 26 | func (s *PollService) Update(ctx context.Context, req *pb.PollUpdateReq) (*pb.Void, error) { 27 | return s.storage.Poll().Update(ctx, req) 28 | } 29 | 30 | func (s *PollService) Delete(ctx context.Context, req *pb.ByID) (*pb.Void, error) { 31 | return s.storage.Poll().Delete(ctx, req) 32 | } 33 | 34 | func (s *PollService) GetAll(ctx context.Context, req *pb.PollGetAllReq) (*pb.PollGetAllRes, error) { 35 | return s.storage.Poll().GetAll(ctx, req) 36 | } 37 | -------------------------------------------------------------------------------- /polling/Makefile: -------------------------------------------------------------------------------- 1 | run: 2 | clear; go run main.go 3 | 4 | proto-gen: 5 | protoc --go_out=./ --go-grpc_out=./ protos/*.proto 6 | 7 | proto-gen0: 8 | protoc --go_out=./ --go-grpc_out=./ --experimental_allow_proto3_optional protos/*.proto 9 | 10 | migrate_up: 11 | migrate -path migrations -database postgres://postgres:root@localhost:5432/polling_db?sslmode=disable -verbose up 12 | 13 | migrate_down: 14 | migrate -path migrations -database postgres://postgres:root@localhost:5432/polling_db?sslmode=disable -verbose down 15 | 16 | migrate_force: 17 | migrate -path migrations -database postgres://postgres:root@localhost:5432/polling_db?sslmode=disable -verbose force 1 18 | 19 | migrate_file: 20 | migrate create -ext sql -dir migrations -seq create_table 21 | 22 | swag-gen: 23 | ~/go/bin/swag init -g ./api/router.go -o api/docs force 1 24 | 25 | ps: 26 | docker ps -a 27 | 28 | pg: 29 | docker exec -it $(c) psql -U postgres -d polling_db 30 | 31 | down: 32 | docker compose down 33 | 34 | up: 35 | docker compose up 36 | 37 | build: 38 | docker compose up --build 39 | 40 | psql-con: 41 | docker exec -it polling-cont psql -U postgres -d polling_db; -------------------------------------------------------------------------------- /polling/config/getEnv.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | 7 | "github.com/joho/godotenv" 8 | "github.com/spf13/cast" 9 | ) 10 | 11 | type Config struct { 12 | POLL_SERVICE_PORT string 13 | 14 | DB_HOST string 15 | DB_PORT int 16 | DB_USER string 17 | DB_PASSWORD string 18 | DB_NAME string 19 | } 20 | 21 | func Load() Config { 22 | if err := godotenv.Load(); err != nil { 23 | fmt.Println("No .env file found") 24 | } 25 | 26 | config := Config{} 27 | 28 | config.POLL_SERVICE_PORT = cast.ToString(coalesce("POLL_SERVICE_PORT", ":50051")) 29 | 30 | config.DB_HOST = cast.ToString(coalesce("DB_HOST", "polling-cont")) 31 | config.DB_PORT = cast.ToInt(coalesce("DB_PORT", 5432)) 32 | config.DB_USER = cast.ToString(coalesce("DB_USER", "postgres")) 33 | config.DB_PASSWORD = cast.ToString(coalesce("DB_PASSWORD", "root")) 34 | config.DB_NAME = cast.ToString(coalesce("DB_NAME", "polling_db")) 35 | 36 | return config 37 | } 38 | 39 | func coalesce(key string, defaultValue interface{}) interface{} { 40 | val, exists := os.LookupEnv(key) 41 | 42 | if exists { 43 | return val 44 | } 45 | 46 | return defaultValue 47 | } 48 | -------------------------------------------------------------------------------- /api-gateway/tokens.txt: -------------------------------------------------------------------------------- 1 | admin: 2 | 3 | eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImZhcnJ1aGJla3R1cmRpcXVsb3ZAZ21haWwuY29tIiwiZXhwIjoxNzI1ODgyNzE5LCJpYXQiOjE3MjU2MjM1MTksInJvbGUiOiJhZG1pbiIsInVzZXJfaWQiOiI4OTQ1MzlmZi1lOWFlLTRmZDctOTM1MS1lYzA2MmFkYjc2NzgifQ.jElwrAv9HXT61dEif7dnbXR07EdyeKcLPSSWyEXVByw 4 | 5 | user: 6 | 7 | eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6Indqd3hqYnVmaHd0dHNlbXB0cUBuYm1iYi5jb20iLCJleHAiOjE3MjUwNDk3NzIsImlhdCI6MTcyNDc5MDU3Miwicm9sZSI6InVzZXIiLCJ1c2VyX2lkIjoiM2U1MTdhN2YtNjc0ZC00MDljLTk3NzctNTNlYjg1NzAyNTA5In0.unFlIg7bBiLz2sWwxuMgn66RDCRm7t9KWaS7foymB40 8 | 9 | { 10 | "answers": [ 11 | { 12 | "answer_point": 18, 13 | "num": 1, 14 | "question_id": "b8aeedae-be34-464d-a016-0ca6755cf904" 15 | } 16 | ], 17 | "poll_id": "e3a2920e-8f23-4603-8086-3dfd8cffaffb", 18 | "user_id": "280b6bab-b1ab-44ab-b9ad-6c0419d84713" 19 | } 20 | 21 | 22 | { 23 | "age": "31", 24 | "email": "farruhbekturdiqulov@gmail.com", 25 | "gender": "male", 26 | "level_type": "junior", 27 | "name": "Farruhbek", 28 | "nation": "o`zbek", 29 | "password": "77777", 30 | "phone_number": "+998973211221", 31 | "surname": "string", 32 | "working_experience": 2 33 | } -------------------------------------------------------------------------------- /polling/service/quesiton.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | pb "poll-service/genprotos" 6 | st "poll-service/storage" 7 | ) 8 | 9 | type QuestionService struct { 10 | storage st.StorageI 11 | pb.UnimplementedQuestionServiceServer 12 | } 13 | 14 | 15 | func NewQuestionService(storage st.StorageI) *QuestionService { 16 | return &QuestionService{storage: storage} 17 | } 18 | 19 | func (s *QuestionService) Create(ctx context.Context, req *pb.QuestionCreateReq) (*pb.Void, error) { 20 | return s.storage.Question().Create(ctx, req) 21 | } 22 | 23 | func (s *QuestionService) GetByID(ctx context.Context, req *pb.ByID) (*pb.QuestionGetByIDRes, error) { 24 | return s.storage.Question().GetByID(ctx, req) 25 | } 26 | 27 | func (s *QuestionService) Update(ctx context.Context, req *pb.QuestionUpdateReq) (*pb.Void, error) { 28 | return s.storage.Question().Update(ctx, req) 29 | } 30 | 31 | func (s *QuestionService) Delete(ctx context.Context, req *pb.ByID) (*pb.Void, error) { 32 | return s.storage.Question().Delete(ctx, req) 33 | } 34 | 35 | func (s *QuestionService) GetAll(ctx context.Context, req *pb.QuestionGetAllReq) (*pb.QuestionGetAllRes, error) { 36 | return s.storage.Question().GetAll(ctx, req) 37 | } 38 | -------------------------------------------------------------------------------- /polling/protos/question.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package polling; 4 | 5 | option go_package = "genprotos/"; 6 | 7 | import "protos/void.proto"; 8 | import "protos/poll.proto"; 9 | 10 | service QuestionService { 11 | rpc Create(QuestionCreateReq) returns (Void); 12 | rpc Update(QuestionUpdateReq) returns (Void); 13 | rpc Delete(ByID) returns (Void); 14 | rpc GetByID(ByID) returns (QuestionGetByIDRes); 15 | rpc GetAll(QuestionGetAllReq) returns (QuestionGetAllRes); 16 | } 17 | 18 | message QuestionCreateReq { 19 | optional string content = 3; 20 | optional string poll_id = 4; 21 | } 22 | 23 | message QuestionUpdateReq { 24 | optional string id = 1; 25 | optional string content = 2; 26 | } 27 | 28 | message QuestionGetByIDRes { 29 | optional string id = 1; 30 | optional string content = 2; 31 | optional string poll_id = 3; 32 | } 33 | 34 | message QuestionGetAllRes { 35 | repeated Question question = 1; 36 | PollGetByIDRes poll = 2; 37 | } 38 | 39 | message QuestionGetAllReq { 40 | optional string poll_id = 1; 41 | } 42 | 43 | message Question { 44 | optional string id = 1; 45 | optional int32 num = 2; 46 | optional string content = 3; 47 | optional string poll_id = 4; 48 | } 49 | -------------------------------------------------------------------------------- /api-gateway/protos/question.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package polling; 4 | 5 | option go_package = "genprotos/"; 6 | 7 | import "protos/void.proto"; 8 | import "protos/poll.proto"; 9 | 10 | service QuestionService { 11 | rpc Create(QuestionCreateReq) returns (Void); 12 | rpc Update(QuestionUpdateReq) returns (Void); 13 | rpc Delete(ByID) returns (Void); 14 | rpc GetByID(ByID) returns (QuestionGetByIDRes); 15 | rpc GetAll(QuestionGetAllReq) returns (QuestionGetAllRes); 16 | } 17 | 18 | message QuestionCreateReq { 19 | optional string content = 3; 20 | optional string poll_id = 4; 21 | } 22 | 23 | message QuestionUpdateReq { 24 | optional string id = 1; 25 | optional string content = 2; 26 | } 27 | 28 | message QuestionGetByIDRes { 29 | optional string id = 1; 30 | optional string content = 2; 31 | optional string poll_id = 3; 32 | } 33 | 34 | message QuestionGetAllRes { 35 | repeated Question question = 1; 36 | PollGetByIDRes poll = 2; 37 | } 38 | 39 | message QuestionGetAllReq { 40 | optional string poll_id = 1; 41 | } 42 | 43 | message Question { 44 | optional string id = 1; 45 | optional int32 num = 2; 46 | optional string content = 3; 47 | optional string poll_id = 4; 48 | } 49 | -------------------------------------------------------------------------------- /api-gateway/config/helperFuncs.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "database/sql" 5 | "errors" 6 | "regexp" 7 | 8 | "github.com/google/uuid" 9 | "golang.org/x/crypto/bcrypt" 10 | ) 11 | 12 | func IsValidEmail(email string) bool { 13 | return regexp.MustCompile(`^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`).MatchString(email) 14 | } 15 | 16 | func IsValidPassword(password string) error { 17 | if len(password) <= 4 { 18 | return errors.New("password must be at least 4 characters long") 19 | } 20 | return nil 21 | } 22 | 23 | func HashPassword(password string) (string, error) { 24 | hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) 25 | if err != nil { 26 | return "", err 27 | } 28 | return string(hashedPassword), nil 29 | } 30 | 31 | func CheckPasswordHash(password, hash string) bool { 32 | err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password)) 33 | return err == nil 34 | } 35 | 36 | func IsValidUUID(id string) error { 37 | if err := uuid.Validate(id); err != nil { 38 | return errors.New("invalid user uuid") 39 | } 40 | return nil 41 | } 42 | 43 | func CheckRowsAffected(res sql.Result, object string) error { 44 | rowsAffected, err := res.RowsAffected() 45 | if err != nil { 46 | return err 47 | } 48 | if rowsAffected == 0 { 49 | return errors.New(object + " not found") 50 | } 51 | return nil 52 | } 53 | -------------------------------------------------------------------------------- /polling/docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: '3.8' 2 | 3 | services: 4 | migrate: 5 | image: migrate/migrate 6 | networks: 7 | - mynetwork 8 | volumes: 9 | - ./migrations:/migrations 10 | command: ["-path", "/migrations", "-database", "postgres://postgres:root@postgres-db:5432/polling_db?sslmode=disable", "up"] 11 | depends_on: 12 | - postgres-db 13 | 14 | postgres-db: 15 | container_name: polling-cont 16 | image: postgres:latest 17 | environment: 18 | PGUSER: postgres 19 | POSTGRES_PASSWORD: root 20 | POSTGRES_DB: polling_db 21 | volumes: 22 | - db:/var/lib/postgresql/data 23 | ports: 24 | - "5434:5432" 25 | networks: 26 | - mynetwork 27 | restart: unless-stopped 28 | healthcheck: 29 | test: ["CMD-SHELL", "pg_isready -d postgres"] 30 | interval: 30s 31 | timeout: 10s 32 | retries: 5 33 | 34 | poll-service: 35 | container_name: poll_service 36 | build: . 37 | ports: 38 | - "50051:50051" 39 | networks: 40 | - mynetwork 41 | depends_on: 42 | - postgres-db 43 | environment: 44 | - DB_HOST=postgres-db 45 | - DB_PORT=5432 46 | - DB_USER=postgres 47 | - DB_PASSWORD=root 48 | - DB_NAME=polling_db 49 | 50 | networks: 51 | mynetwork: 52 | external: true 53 | name: global-net 54 | driver: bridge 55 | 56 | 57 | volumes: 58 | db: 59 | -------------------------------------------------------------------------------- /polling/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Download Results 5 | 6 | 7 | 8 | 9 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /polling/service/user.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | pb "poll-service/genprotos" 6 | st "poll-service/storage" 7 | ) 8 | 9 | type UserService struct { 10 | storage st.StorageI 11 | pb.UnimplementedUserServiceServer 12 | } 13 | 14 | func NewUserService(storage st.StorageI) *UserService { 15 | return &UserService{storage: storage} 16 | } 17 | 18 | func (s *UserService) Register(ctx context.Context, req *pb.RegisterReq) (*pb.Void, error) { 19 | return s.storage.User().Register(ctx, req) 20 | } 21 | 22 | // func (s *UserService) ConfirmUser(ctx context.Context, req *pb.ConfirmUserReq) (*pb.Void, error) { 23 | // return s.storage.User().ConfirmUser(ctx, req) 24 | // } 25 | 26 | func (s *UserService) Profile(ctx context.Context, req *pb.GetProfileReq) (*pb.GetProfileResp, error) { 27 | return s.storage.User().Profile(ctx, req) 28 | } 29 | 30 | // func (s *UserService) UpdatePassword(ctx context.Context, req *pb.UpdatePasswordReq) (*pb.Void, error) { 31 | // return s.storage.User().UpdatePassword(ctx, req) 32 | // } 33 | 34 | func (s *UserService) IsEmailExists(ctx context.Context, req *pb.IsEmailExistsReq) (*pb.IsEmailExistsResp, error) { 35 | return s.storage.User().IsEmailExists(ctx, req) 36 | } 37 | 38 | func (s *UserService) GetByID(ctx context.Context, req *pb.GetProfileByIdReq) (*pb.GetProfileByIdResp, error) { 39 | return s.storage.User().GetByID(ctx, req) 40 | } 41 | 42 | func (s *UserService) GetByEmail(ctx context.Context, req *pb.ByEmail) (*pb.GetProfileByIdResp, error) { 43 | return s.storage.User().GetByEmail(ctx, req) 44 | } 45 | -------------------------------------------------------------------------------- /api-gateway/config/getEnv.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | 7 | "github.com/joho/godotenv" 8 | "github.com/spf13/cast" 9 | ) 10 | 11 | type Config struct { 12 | GATEWAY_SERVICE_PORT string 13 | POLL_SERVICE_PORT string 14 | DB_HOST string 15 | DB_PORT int 16 | DB_USER string 17 | DB_PASSWORD string 18 | DB_NAME string 19 | SENDER_EMAIL string 20 | APP_PASSWORD string 21 | } 22 | 23 | func Load() Config { 24 | if err := godotenv.Load(); err != nil { 25 | fmt.Println("No .env file found") 26 | } 27 | 28 | config := Config{} 29 | 30 | config.GATEWAY_SERVICE_PORT = cast.ToString(coalesce("GATEWAY_SERVICE_PORT", ":8080")) 31 | config.POLL_SERVICE_PORT = cast.ToString(coalesce("POLL_SERVICE_PORT", ":50051")) 32 | config.DB_HOST = cast.ToString(coalesce("DB_HOST", "localhost")) 33 | config.DB_PORT = cast.ToInt(coalesce("DB_PORT", 5432)) 34 | config.DB_USER = cast.ToString(coalesce("DB_USER", "postgres")) 35 | config.DB_PASSWORD = cast.ToString(coalesce("DB_PASSWORD", "root")) 36 | config.DB_NAME = cast.ToString(coalesce("DB_NAME", "delivery_auth")) 37 | config.SENDER_EMAIL = cast.ToString(coalesce("SENDER_EMAIL", "email@example.com")) 38 | config.APP_PASSWORD = cast.ToString(coalesce("APP_PASSWORD", "your_app_password_here")) 39 | 40 | return config 41 | } 42 | 43 | func coalesce(key string, defaultValue interface{}) interface{} { 44 | val, exists := os.LookupEnv(key) 45 | 46 | if exists { 47 | return val 48 | } 49 | 50 | return defaultValue 51 | } 52 | -------------------------------------------------------------------------------- /api-gateway/drivers/minio.go: -------------------------------------------------------------------------------- 1 | package minio_connect 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "log" 7 | 8 | "github.com/minio/minio-go/v7" 9 | "github.com/minio/minio-go/v7/pkg/credentials" 10 | ) 11 | 12 | func MinIOConnect() (*minio.Client, error) { 13 | endpoint := "minio:9000" //minio 14 | accessKeyID := "user" 15 | secretAccessKey := "password" 16 | useSSL := false 17 | 18 | minioClient, err := minio.New(endpoint, &minio.Options{ 19 | Creds: credentials.NewStaticV4(accessKeyID, secretAccessKey, ""), 20 | Secure: useSSL, 21 | }) 22 | if err != nil { 23 | log.Println(err) 24 | return nil, err 25 | } 26 | 27 | bucketName := "another-bucket" 28 | 29 | err = minioClient.MakeBucket(context.Background(), bucketName, minio.MakeBucketOptions{}) 30 | if err != nil { 31 | // Check to see if we already own this bucket (which happens if you run this twice) 32 | exists, errBucketExists := minioClient.BucketExists(context.Background(), bucketName) 33 | if errBucketExists != nil && exists { 34 | log.Println(err) 35 | return nil, err 36 | } 37 | } 38 | 39 | policy := fmt.Sprintf(`{ 40 | "Version": "2012-10-17", 41 | "Statement": [ 42 | { 43 | "Effect": "Allow", 44 | "Principal": "*", 45 | "Action": ["s3:GetObject"], 46 | "Resource": ["arn:aws:s3:::%s/*"] 47 | } 48 | ] 49 | }`, bucketName) 50 | 51 | err = minioClient.SetBucketPolicy(context.Background(), bucketName, policy) 52 | if err != nil { 53 | log.Println("error while setting bucket policy : ", err) 54 | return nil, err 55 | } 56 | 57 | return minioClient, err 58 | } 59 | -------------------------------------------------------------------------------- /polling/protos/poll.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package polling; 4 | 5 | option go_package = "genprotos/"; 6 | 7 | import "protos/void.proto"; 8 | 9 | 10 | service PollService { 11 | rpc Create(PollCreateReq) returns (Void); 12 | rpc Update(PollUpdateReq) returns (Void); 13 | rpc Delete(ByID) returns (Void); 14 | rpc GetByID(ByID) returns (PollGetByIDRes); 15 | rpc GetAll(PollGetAllReq) returns (PollGetAllRes); 16 | } 17 | 18 | message PollCreateReq { 19 | optional string title = 1; 20 | optional string subtitle = 2; 21 | repeated Option options = 3; 22 | repeated Feedback feedbacks = 4; 23 | } 24 | 25 | message Feedback { 26 | optional int32 from = 1; 27 | optional int32 to = 2; 28 | optional string text = 3; 29 | } 30 | 31 | message Option { 32 | optional string variant = 1; 33 | optional int32 ball = 2; 34 | } 35 | 36 | message PollUpdateReq { 37 | optional string id = 1; 38 | optional string title = 2; 39 | optional string subtitle = 3; 40 | repeated Option options = 4; 41 | repeated Feedback feedbacks = 5; 42 | 43 | } 44 | 45 | message PollUpdateReqSwag { 46 | optional string title = 1; 47 | optional string subtitle = 2; 48 | repeated Option options = 3; 49 | repeated Feedback feedbacks = 4; 50 | 51 | } 52 | 53 | message PollGetByIDRes { 54 | optional string id = 1; 55 | optional int32 poll_num = 2; 56 | optional string title = 3; 57 | optional string subtitle = 4; 58 | repeated Option options = 5; 59 | repeated Feedback feedback = 6; 60 | } 61 | 62 | message PollGetAllReq { 63 | optional string user_id = 1; 64 | } 65 | 66 | message PollGetAllRes { 67 | repeated PollGetByIDRes poll = 1; 68 | } -------------------------------------------------------------------------------- /api-gateway/protos/poll.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package polling; 4 | 5 | option go_package = "genprotos/"; 6 | 7 | import "protos/void.proto"; 8 | 9 | 10 | service PollService { 11 | rpc Create(PollCreateReq) returns (Void); 12 | rpc Update(PollUpdateReq) returns (Void); 13 | rpc Delete(ByID) returns (Void); 14 | rpc GetByID(ByID) returns (PollGetByIDRes); 15 | rpc GetAll(PollGetAllReq) returns (PollGetAllRes); 16 | } 17 | 18 | message PollCreateReq { 19 | optional string title = 1; 20 | optional string subtitle = 2; 21 | repeated Option options = 3; 22 | repeated Feedback feedbacks = 4; 23 | } 24 | 25 | message Feedback { 26 | optional int32 from = 1; 27 | optional int32 to = 2; 28 | optional string text = 3; 29 | } 30 | 31 | message Option { 32 | optional string variant = 1; 33 | optional int32 ball = 2; 34 | } 35 | 36 | message PollUpdateReq { 37 | optional string id = 1; 38 | optional string title = 2; 39 | optional string subtitle = 3; 40 | repeated Option options = 4; 41 | repeated Feedback feedbacks = 5; 42 | 43 | } 44 | 45 | message PollUpdateReqSwag { 46 | optional string title = 1; 47 | optional string subtitle = 2; 48 | repeated Option options = 3; 49 | repeated Feedback feedbacks = 4; 50 | 51 | } 52 | 53 | message PollGetByIDRes { 54 | optional string id = 1; 55 | optional int32 poll_num = 2; 56 | optional string title = 3; 57 | optional string subtitle = 4; 58 | repeated Option options = 5; 59 | repeated Feedback feedback = 6; 60 | } 61 | 62 | message PollGetAllReq { 63 | optional string user_id = 1; 64 | } 65 | 66 | message PollGetAllRes { 67 | repeated PollGetByIDRes poll = 1; 68 | } -------------------------------------------------------------------------------- /polling/protos/result.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package polling; 4 | 5 | option go_package = "genprotos/"; 6 | 7 | import "protos/users.proto"; 8 | import "protos/void.proto"; 9 | import "protos/poll.proto"; 10 | 11 | 12 | service ResultService { 13 | rpc CreateResult(CreateResultReq) returns (CreateResultRes); 14 | rpc SavePollAnswer(SavePollAnswerReq) returns (Void); 15 | rpc GetResultsInExcel(Void) returns (ExcelResultsRes); 16 | rpc GetPollResults(ByIDs) returns (ByIDResponse); 17 | } 18 | 19 | message ByIDs { 20 | optional string result_id = 1; 21 | optional string poll_id = 2; 22 | } 23 | 24 | message CreateResultReq { 25 | optional string user_id = 1; 26 | optional string poll_id = 2; 27 | } 28 | 29 | message CreateResultRes { 30 | optional string result_id = 1; 31 | } 32 | 33 | message SavePollAnswerReq { 34 | optional string result_id = 1; 35 | optional string question_id = 2; 36 | optional int32 question_num = 3; 37 | optional int32 answer = 4; 38 | } 39 | 40 | message GetPoll { 41 | optional string poll_id = 1; 42 | } 43 | 44 | message IncomingResult { 45 | optional string poll_id = 1; 46 | optional string user_id = 2; 47 | repeated IncomingAnswer answers = 3; 48 | } 49 | 50 | message IncomingAnswer { 51 | optional int32 num = 1; 52 | optional string question_id = 2; 53 | optional int32 answer_point = 3; 54 | } 55 | 56 | message ExcelResultsRes { 57 | repeated ResultRes results = 1; 58 | } 59 | 60 | message ResultRes { 61 | UserExcelResp user = 1; 62 | optional int32 poll_num = 2; 63 | repeated IncomingAnswer answers = 3; 64 | } 65 | 66 | message ByIDResponse { 67 | repeated IncomingAnswer answers = 1; 68 | repeated Feedback feed = 2; 69 | } 70 | -------------------------------------------------------------------------------- /api-gateway/protos/result.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package polling; 4 | 5 | option go_package = "genprotos/"; 6 | 7 | import "protos/users.proto"; 8 | import "protos/void.proto"; 9 | import "protos/poll.proto"; 10 | 11 | 12 | service ResultService { 13 | rpc CreateResult(CreateResultReq) returns (CreateResultRes); 14 | rpc SavePollAnswer(SavePollAnswerReq) returns (Void); 15 | rpc GetResultsInExcel(Void) returns (ExcelResultsRes); 16 | rpc GetPollResults(ByIDs) returns (ByIDResponse); 17 | } 18 | 19 | message ByIDs { 20 | optional string result_id = 1; 21 | optional string poll_id = 2; 22 | } 23 | 24 | message CreateResultReq { 25 | optional string user_id = 1; 26 | optional string poll_id = 2; 27 | } 28 | 29 | message CreateResultRes { 30 | optional string result_id = 1; 31 | } 32 | 33 | message SavePollAnswerReq { 34 | optional string result_id = 1; 35 | optional string question_id = 2; 36 | optional int32 question_num = 3; 37 | optional int32 answer = 4; 38 | } 39 | 40 | message GetPoll { 41 | optional string poll_id = 1; 42 | } 43 | 44 | message IncomingResult { 45 | optional string poll_id = 1; 46 | optional string user_id = 2; 47 | repeated IncomingAnswer answers = 3; 48 | } 49 | 50 | message IncomingAnswer { 51 | optional int32 num = 1; 52 | optional string question_id = 2; 53 | optional int32 answer_point = 3; 54 | } 55 | 56 | message ExcelResultsRes { 57 | repeated ResultRes results = 1; 58 | } 59 | 60 | message ResultRes { 61 | UserExcelResp user = 1; 62 | optional int32 poll_num = 2; 63 | repeated IncomingAnswer answers = 3; 64 | } 65 | 66 | message ByIDResponse { 67 | repeated IncomingAnswer answers = 1; 68 | repeated Feedback feed = 2; 69 | } 70 | -------------------------------------------------------------------------------- /polling/migrations/000001_create_table.up.sql: -------------------------------------------------------------------------------- 1 | DO $$ 2 | BEGIN 3 | IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'gender_type') THEN 4 | CREATE TYPE gender_type AS ENUM ('male', 'female'); 5 | END IF; 6 | END 7 | $$; 8 | 9 | -- Create users table 10 | CREATE TABLE IF NOT EXISTS users ( 11 | id UUID PRIMARY KEY DEFAULT gen_random_uuid(), 12 | name VARCHAR(255) NOT NULL, 13 | surname VARCHAR(255) NOT NULL, 14 | gender gender_type NOT NULL, 15 | age VARCHAR(50) NOT NULL, 16 | nation VARCHAR(50) NOT NULL, 17 | email VARCHAR(100) NOT NULL UNIQUE, 18 | password VARCHAR NOT NULL, 19 | phone_number VARCHAR(15) NOT NULL, 20 | working_experience INT CHECK (working_experience >= 0), 21 | level_type VARCHAR NOT NULL, 22 | is_confirmed BOOLEAN DEFAULT TRUE, 23 | role VARCHAR(20) DEFAULT 'user', 24 | confirmed_at TIMESTAMP 25 | ); 26 | 27 | -- Create polls table 28 | CREATE TABLE IF NOT EXISTS polls ( 29 | id UUID PRIMARY KEY DEFAULT gen_random_uuid(), 30 | poll_num INT, 31 | title VARCHAR(255) NOT NULL, 32 | subtitle TEXT NOT NULL, 33 | options JSONB, 34 | feedbacks JSONB 35 | ); 36 | 37 | -- Create questions table 38 | CREATE TABLE IF NOT EXISTS questions ( 39 | id UUID PRIMARY KEY DEFAULT gen_random_uuid(), 40 | num INT, 41 | content TEXT NOT NULL, 42 | poll_id UUID REFERENCES polls(id) ON DELETE CASCADE, 43 | UNIQUE (poll_id, num) 44 | ); 45 | 46 | -- ############# Storing Results 47 | CREATE TABLE IF NOT EXISTS results ( 48 | id UUID PRIMARY KEY DEFAULT gen_random_uuid(), 49 | user_id UUID REFERENCES users(id), 50 | poll_id UUID REFERENCES polls(id) 51 | ); 52 | 53 | CREATE TABLE IF NOT EXISTS poll_answers ( 54 | id UUID PRIMARY KEY DEFAULT gen_random_uuid(), 55 | result_id UUID REFERENCES results(id), 56 | question_id UUID REFERENCES questions(id), 57 | answer INT 58 | ); 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /polling/storage/postgres.go: -------------------------------------------------------------------------------- 1 | package storage 2 | 3 | import ( 4 | "database/sql" 5 | "fmt" 6 | 7 | "poll-service/config" 8 | "poll-service/storage/managers" 9 | 10 | _ "github.com/lib/pq" 11 | ) 12 | 13 | type Storage struct { 14 | PgClient *sql.DB 15 | UserS *managers.UserManager 16 | QuestionS *managers.QuestionManager 17 | PollS *managers.PollManager 18 | ResultS *managers.ResultManager 19 | } 20 | 21 | func NewPostgresStorage(config config.Config) (*Storage, error) { 22 | // ################# POSTGRESQL CONNECTION ###################### // 23 | conn := fmt.Sprintf("host=%s user=%s dbname=%s password=%s port=%d sslmode=disable", 24 | config.DB_HOST, config.DB_USER, config.DB_NAME, config.DB_PASSWORD, config.DB_PORT) 25 | db, err := sql.Open("postgres", conn) 26 | fmt.Println(conn) 27 | if err != nil { 28 | return nil, err 29 | } 30 | if err = db.Ping(); err != nil { 31 | return nil, err 32 | } 33 | fmt.Println("Successfully connected to database pgsql!") 34 | 35 | um := managers.NewUserManager(db) 36 | pm := managers.NewPollManager(db) 37 | qm := managers.NewQuestionManager(db) 38 | rm := managers.NewResultManager(db) 39 | 40 | return &Storage{ 41 | PgClient: db, 42 | UserS: um, 43 | PollS: pm, 44 | QuestionS: qm, 45 | ResultS: rm, 46 | }, nil 47 | } 48 | 49 | func (s *Storage) Poll() PollI { 50 | if s.PollS == nil { 51 | s.PollS = managers.NewPollManager(s.PgClient) 52 | } 53 | return s.PollS 54 | } 55 | 56 | func (s *Storage) User() UserI { 57 | if s.UserS == nil { 58 | s.UserS = managers.NewUserManager(s.PgClient) 59 | } 60 | return s.UserS 61 | } 62 | 63 | func (s *Storage) Question() QuestionI { 64 | if s.QuestionS == nil { 65 | s.QuestionS = managers.NewQuestionManager(s.PgClient) 66 | } 67 | return s.QuestionS 68 | } 69 | 70 | func (s *Storage) Result() ResultI { 71 | if s.ResultS == nil { 72 | s.ResultS = managers.NewResultManager(s.PgClient) 73 | } 74 | return s.ResultS 75 | } 76 | -------------------------------------------------------------------------------- /polling/storage/storage.go: -------------------------------------------------------------------------------- 1 | package storage 2 | 3 | import ( 4 | "context" 5 | pb "poll-service/genprotos" 6 | ) 7 | 8 | type StorageI interface { 9 | User() UserI 10 | Poll() PollI 11 | Question() QuestionI 12 | Result() ResultI 13 | } 14 | 15 | type UserI interface { 16 | Register(ctx context.Context, req *pb.RegisterReq) (*pb.Void, error) 17 | // ConfirmUser(ctx context.Context, req *pb.ConfirmUserReq) (*pb.Void, error) 18 | Profile(ctx context.Context, req *pb.GetProfileReq) (*pb.GetProfileResp, error) 19 | // UpdatePassword(ctx context.Context, req *pb.UpdatePasswordReq) (*pb.Void, error) 20 | IsEmailExists(ctx context.Context, req *pb.IsEmailExistsReq) (*pb.IsEmailExistsResp, error) 21 | GetByID(ctx context.Context, req *pb.GetProfileByIdReq) (*pb.GetProfileByIdResp, error) 22 | GetByEmail(ctx context.Context, req *pb.ByEmail) (*pb.GetProfileByIdResp, error) 23 | } 24 | 25 | type PollI interface { 26 | Create(ctx context.Context, req *pb.PollCreateReq) (*pb.Void, error) 27 | GetByID(ctx context.Context, req *pb.ByID) (*pb.PollGetByIDRes, error) 28 | Update(ctx context.Context, req *pb.PollUpdateReq) (*pb.Void, error) 29 | Delete(ctx context.Context, req *pb.ByID) (*pb.Void, error) 30 | GetAll(ctx context.Context, req *pb.PollGetAllReq) (*pb.PollGetAllRes, error) 31 | } 32 | 33 | type QuestionI interface { 34 | Create(ctx context.Context, req *pb.QuestionCreateReq) (*pb.Void, error) 35 | GetByID(ctx context.Context, req *pb.ByID) (*pb.QuestionGetByIDRes, error) 36 | Update(ctx context.Context, req *pb.QuestionUpdateReq) (*pb.Void, error) 37 | Delete(ctx context.Context, req *pb.ByID) (*pb.Void, error) 38 | GetAll(ctx context.Context, req *pb.QuestionGetAllReq) (*pb.QuestionGetAllRes, error) 39 | } 40 | 41 | type ResultI interface { 42 | CreateResult(ctx context.Context, req *pb.CreateResultReq) (*pb.CreateResultRes, error) 43 | SavePollAnswer(ctx context.Context, req *pb.SavePollAnswerReq) (*pb.Void, error) 44 | GetResultsInExcel(ctx context.Context, req *pb.Void) (*pb.ExcelResultsRes, error) 45 | GetByIDRes(ctx context.Context, req *pb.ByIDs) (*pb.ByIDResponse, error) 46 | } 47 | -------------------------------------------------------------------------------- /api-gateway/api/handlers/answers.go: -------------------------------------------------------------------------------- 1 | package handlers 2 | 3 | import ( 4 | pb "auth-service/genprotos" 5 | "fmt" 6 | "net/http" 7 | 8 | "github.com/gin-gonic/gin" 9 | ) 10 | 11 | // Send answers godoc 12 | // @Summary Handles results 13 | // @Description incoming results of user 14 | // @Tags answer 15 | // @Accept json 16 | // @Produce json 17 | // @Param poll body pb.IncomingResult true "Poll creation request" 18 | // @Success 201 {object} string "Successfully posted" 19 | // @Failure 400 {object} string "Invalid request payload" 20 | // @Failure 500 {object} string "Server error" 21 | // @Router /send-answers [POST] 22 | // @Security BearerAuth 23 | func (h *HTTPHandler) SendAnswers(c *gin.Context) { 24 | var req pb.IncomingResult 25 | if err := c.ShouldBindJSON(&req); err != nil { 26 | c.JSON(400, gin.H{"error": err.Error()}) 27 | return 28 | } 29 | 30 | poll := pb.CreateResultReq{ 31 | UserId: req.UserId, 32 | PollId: req.PollId, 33 | } 34 | 35 | id, err := h.Result.CreateResult(c, &poll) 36 | if err != nil { 37 | c.JSON(http.StatusInternalServerError, gin.H{"error": "Couldn't create result", "details": err.Error()}) 38 | return 39 | } 40 | 41 | fmt.Println(len(req.Answers), req.Answers) 42 | fmt.Println(id.ResultId) 43 | for _, i := range req.Answers { 44 | _, err := h.Result.SavePollAnswer(c, &pb.SavePollAnswerReq{ 45 | ResultId: id.ResultId, 46 | QuestionId: i.QuestionId, 47 | Answer: i.AnswerPoint, 48 | }) 49 | if err != nil { 50 | c.JSON(400, gin.H{"error": "Couldn't save answer", "details": err.Error()}) 51 | return 52 | } 53 | } 54 | 55 | feedResult, err := h.Result.GetPollResults(c, &pb.ByIDs{ 56 | ResultId: id.ResultId, 57 | PollId: poll.PollId, 58 | }) 59 | if err != nil { 60 | c.JSON(http.StatusInternalServerError, gin.H{"error": "Couldn't get results", "details": err.Error()}) 61 | return 62 | } 63 | 64 | res := feedResult.Feed 65 | // Agar feedResult.Feed slice bo'lsa, uni to'g'ridan-to'g'ri ishlatasiz 66 | if len(feedResult.Feed) > 6 { 67 | res = feedResult.Feed[6:] // 6-indeksdan keyingi elementlarni oling 68 | } 69 | c.JSON(201, gin.H{"message": "Successfully posted", "id": id.ResultId, "feedback": res}) 70 | 71 | } 72 | -------------------------------------------------------------------------------- /api-gateway/api/token/token.go: -------------------------------------------------------------------------------- 1 | package token 2 | 3 | import ( 4 | "errors" 5 | "log" 6 | "time" 7 | 8 | "github.com/golang-jwt/jwt" 9 | ) 10 | 11 | const ( 12 | signingKey = "mrbek" 13 | ) 14 | 15 | type Tokens struct { 16 | AccessToken string `json:"access_token"` 17 | RefreshToken string `json:"refresh_token"` 18 | Role string `json:"role"` 19 | } 20 | 21 | func GenerateJWTToken(userID string, email string, role string) *Tokens { 22 | accessToken := jwt.New(jwt.SigningMethodHS256) 23 | refreshToken := jwt.New(jwt.SigningMethodHS256) 24 | 25 | claims := accessToken.Claims.(jwt.MapClaims) 26 | claims["user_id"] = userID 27 | claims["email"] = email 28 | claims["role"] = role 29 | claims["iat"] = time.Now().Unix() 30 | claims["exp"] = time.Now().Add(180 * time.Minute).Unix() // Token expires in 3 minutes 31 | access, err := accessToken.SignedString([]byte(signingKey)) 32 | if err != nil { 33 | log.Fatal("error while generating access token : ", err) 34 | } 35 | 36 | rftClaims := refreshToken.Claims.(jwt.MapClaims) 37 | rftClaims["user_id"] = userID 38 | rftClaims["email"] = email 39 | rftClaims["role"] = role 40 | rftClaims["iat"] = time.Now().Unix() 41 | rftClaims["exp"] = time.Now().Add(72 * time.Hour).Unix() // Refresh token expires in 24 hours 42 | refresh, err := refreshToken.SignedString([]byte(signingKey)) 43 | if err != nil { 44 | log.Fatal("error while generating refresh token : ", err) 45 | } 46 | 47 | return &Tokens{ 48 | AccessToken: access, 49 | RefreshToken: refresh, 50 | Role: role, 51 | } 52 | } 53 | 54 | func ValidateToken(tokenStr string) (bool, error) { 55 | _, err := ExtractClaim(tokenStr) 56 | if err != nil { 57 | return false, err 58 | } 59 | return true, nil 60 | } 61 | 62 | func ExtractClaim(tokenStr string) (jwt.MapClaims, error) { 63 | token, err := jwt.Parse(tokenStr, func(token *jwt.Token) (interface{}, error) { 64 | return []byte(signingKey), nil 65 | }) 66 | if err != nil { 67 | return nil, errors.New("parsing token:" + err.Error()) 68 | } 69 | if !token.Valid { 70 | return nil, errors.New("invalid token") 71 | } 72 | 73 | claims, ok := token.Claims.(jwt.MapClaims) 74 | if !ok { 75 | return nil, errors.New("invalid token claims") 76 | } 77 | 78 | return claims, nil 79 | } 80 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: Web Polling Service 2 | 3 | on: 4 | push: 5 | branches: [ "main" ] 6 | pull_request: 7 | branches: [ "main" ] 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - name: Checkout Repository 15 | uses: actions/checkout@v4 16 | 17 | - name: Deploy Application 18 | uses: appleboy/ssh-action@master 19 | with: 20 | host: ${{ secrets.SSH_HOST }} 21 | username: ${{ secrets.SSH_USER }} 22 | password: ${{ secrets.SSH_PASSWORD }} 23 | port: ${{ secrets.SSH_PORT }} 24 | script: | 25 | # Define ANSI color codes 26 | RED='\033[0;31m' 27 | GREEN='\033[0;32m' 28 | YELLOW='\033[1;33m' 29 | BLUE='\033[0;34m' 30 | NC='\033[0m' # No Color 31 | function log_info { 32 | echo -e "${YELLOW}$1${NC}" 33 | } 34 | function log_success { 35 | echo -e "${GREEN}$1${NC}" 36 | } 37 | function log_error { 38 | echo -e "${RED}$1${NC}" 39 | } 40 | # Pull latest code from GitHub 41 | log_info "---------------- PULLING CODE FROM GITHUB ----------------" 42 | cd web-poll 43 | git stash 44 | git pull origin main 45 | log_success "---------------- CODE PULLED FROM GITHUB -----------------" 46 | # Restart polling service 47 | log_info "---------------- NAVIGATING TO POLLING DIRECTORY ----------------" 48 | cd polling 49 | sudo docker compose down 50 | log_error "---------------- POLLING SERVICES STOPPED ----------------" 51 | sudo docker compose up --build -d 52 | log_success "---------------- POLLING SERVICES STARTED ----------------" 53 | # Restart API Gateway service 54 | log_info "---------------- NAVIGATING TO API-GATEWAY DIRECTORY ----------------" 55 | cd ../api-gateway 56 | sudo docker compose down 57 | log_error "---------------- API-GATEWAY SERVICES STOPPED ----------------" 58 | sudo docker compose up --build -d 59 | log_success "---------------- API-GATEWAY SERVICES STARTED ----------------" 60 | -------------------------------------------------------------------------------- /api-gateway/models/models.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | type RegisterReqSwag struct { 4 | Email string `json:"email"` // User's email address 5 | Password string `json:"password"` // User's password 6 | } 7 | 8 | type RegisterReq struct { 9 | ID string `json:"id"` // User's unique identifier 10 | Email string `json:"email"` // User's email address 11 | Password string `json:"password"` // User's password 12 | Role string 13 | } 14 | 15 | type LoginReq struct { 16 | Email string `json:"email"` // User's email 17 | Password string `json:"password"` // User's password 18 | } 19 | 20 | type GetProfileReq struct { 21 | Email string `json:"email"` // Username of the profile to retrieve 22 | } 23 | 24 | type GetProfileResp struct { 25 | ID string `json:"id"` // User's unique identifier 26 | Email string `json:"email"` // User's email address 27 | Password string `json:"password"` // User's password 28 | Role string `json:"role"` 29 | IsConfirmed bool `json:"is_confirmed"` // Add IsConfirmed to the model 30 | } 31 | 32 | type GetProfileByIdReq struct { 33 | ID string `json:"id"` // Username of the profile to retrieve 34 | } 35 | 36 | type GetProfileByIdResp struct { 37 | ID string `json:"id"` // User's unique identifier 38 | Email string `json:"email"` // User's email address 39 | Role string `json:"role"` 40 | } 41 | 42 | type ForgotPasswordReq struct { 43 | Email string `json:"email"` // User's email address 44 | } 45 | 46 | type ResetPasswordReq struct { 47 | Email string `json:"email"` // User's email address 48 | NewPassword string `json:"new_password"` // User's new password 49 | } 50 | 51 | type RecoverPasswordReq struct { 52 | Email string `json:"email"` 53 | Code string `json:"code"` 54 | NewPassword string `json:"new_password"` 55 | } 56 | 57 | type UpdatePasswordReq struct { 58 | Email string `json:"email"` 59 | NewPassword string `json:"new_password"` 60 | } 61 | 62 | type ConfirmUserReq struct { 63 | Email string `json:"email"` 64 | } 65 | 66 | type ConfirmRegistrationReq struct { 67 | Email string `json:"email"` 68 | Code string `json:"code"` 69 | } 70 | 71 | type MongoUser struct { 72 | ID string `bson:"user_id"` 73 | Cart []Cart `bson:"cart"` 74 | } 75 | 76 | type Cart struct { 77 | ProductID string `bson:"product_id"` 78 | Quantity int `bson:"quantity"` 79 | } 80 | -------------------------------------------------------------------------------- /api-gateway/api/middleware/middleware.go: -------------------------------------------------------------------------------- 1 | package middleware 2 | 3 | import ( 4 | "auth-service/api/token" 5 | "net/http" 6 | 7 | "github.com/gin-gonic/gin" 8 | "github.com/golang-jwt/jwt" 9 | ) 10 | 11 | func JWTMiddleware() gin.HandlerFunc { 12 | return func(c *gin.Context) { 13 | authHeader := c.GetHeader("Authorization") 14 | if authHeader == "" { 15 | c.JSON(http.StatusUnauthorized, gin.H{"error": "Authorization header required"}) 16 | c.Abort() 17 | return 18 | } 19 | valid, err := token.ValidateToken(authHeader) 20 | if err != nil || !valid { 21 | c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token", "details": err.Error()}) 22 | c.Abort() 23 | return 24 | } 25 | 26 | claims, err := token.ExtractClaim(authHeader) 27 | if err != nil { 28 | c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token claims", "details": err.Error()}) 29 | c.Abort() 30 | return 31 | } 32 | c.Set("claims", claims) 33 | c.Next() 34 | } 35 | } 36 | 37 | func IsAdminMiddleware() gin.HandlerFunc { 38 | return func(c *gin.Context) { 39 | claims, exists := c.Get("claims") 40 | if !exists { 41 | c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"}) 42 | c.Abort() 43 | return 44 | } 45 | role := claims.(jwt.MapClaims)["role"].(string) 46 | if role != "admin" { 47 | c.JSON(http.StatusForbidden, gin.H{"error": "Forbidden"}) 48 | c.Abort() 49 | } 50 | c.Next() 51 | } 52 | } 53 | 54 | func IsUserMiddleware() gin.HandlerFunc { 55 | return func(c *gin.Context) { 56 | claims, exists := c.Get("claims") 57 | if !exists { 58 | c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"}) 59 | c.Abort() 60 | return 61 | } 62 | role := claims.(jwt.MapClaims)["role"].(string) 63 | if role != "user" { 64 | c.JSON(http.StatusForbidden, gin.H{"error": "Forbidden"}) 65 | c.Abort() 66 | } 67 | c.Next() 68 | } 69 | } 70 | 71 | func IsAdminOrUserMiddleware() gin.HandlerFunc { 72 | return func(c *gin.Context) { 73 | claims, exists := c.Get("claims") 74 | if !exists { 75 | c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"}) 76 | c.Abort() 77 | return 78 | } 79 | jwtClaims, ok := claims.(jwt.MapClaims) 80 | if !ok { 81 | c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token claims"}) 82 | c.Abort() 83 | return 84 | } 85 | role, ok := jwtClaims["role"].(string) 86 | if !ok || (role != "user" && role != "admin") { 87 | c.JSON(http.StatusForbidden, gin.H{"error": "Forbidden"}) 88 | c.Abort() 89 | return 90 | } 91 | c.Next() 92 | } 93 | } 94 | 95 | -------------------------------------------------------------------------------- /polling/go.sum: -------------------------------------------------------------------------------- 1 | github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= 2 | github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= 3 | github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= 4 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 5 | github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= 6 | github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 7 | github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= 8 | github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= 9 | github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= 10 | github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= 11 | github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= 12 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 13 | github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= 14 | github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= 15 | github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= 16 | github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= 17 | github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= 18 | github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= 19 | golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= 20 | golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= 21 | golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= 22 | golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= 23 | golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= 24 | golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 25 | golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= 26 | golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= 27 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 h1:Zy9XzmMEflZ/MAaA7vNcoebnRAld7FsPW1EeBB7V0m8= 28 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= 29 | google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= 30 | google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= 31 | google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= 32 | google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= 33 | -------------------------------------------------------------------------------- /api-gateway/api/router.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "net/http" 5 | 6 | "github.com/gin-gonic/gin" 7 | "google.golang.org/grpc" 8 | 9 | swaggerFiles "github.com/swaggo/files" 10 | 11 | ginSwagger "github.com/swaggo/gin-swagger" 12 | 13 | _ "auth-service/api/docs" 14 | "auth-service/api/handlers" 15 | "auth-service/api/middleware" 16 | ) 17 | 18 | // @securityDefinitions.apikey BearerAuth 19 | // @in header 20 | // @name Authorization 21 | func NewRouter(PollConn *grpc.ClientConn) *gin.Engine { 22 | router := gin.Default() 23 | h := handlers.NewHandler(PollConn) 24 | 25 | router.Use(CORSMiddleware()) 26 | 27 | router.GET("/api/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) 28 | 29 | // #################### AUTH SERVICE ######################### // 30 | router.POST("/register", h.Register) 31 | // router.POST("/confirm-registration", h.ConfirmRegistration) 32 | router.POST("/login", h.Login) 33 | // router.POST("/forgot-password", h.ForgotPassword) 34 | // router.POST("/recover-password", h.RecoverPassword) 35 | // router.POST("/resverify", h.SendCodeAgain) 36 | 37 | protected := router.Group("/", middleware.JWTMiddleware()) 38 | protected.GET("/profile", h.Profile) 39 | router.GET("/user/:id", h.GetByID) 40 | 41 | // #################### USER SERVICE ######################### // 42 | for_user := protected.Group("/", middleware.IsUserMiddleware()) 43 | for_user.POST("/send-answers", h.SendAnswers) 44 | 45 | // #################### POLLING SERVICE ######################### // 46 | for_admin := protected.Group("/", middleware.IsAdminMiddleware()) 47 | for_admin_or_user := protected.Group("/", middleware.IsAdminOrUserMiddleware()) 48 | 49 | for_admin.GET(("/results"), h.GetUserResultsInExcel) 50 | 51 | poll := for_admin.Group("/poll") 52 | { 53 | poll.POST("/", h.CreatePoll) 54 | poll.PUT("/:id", h.UpdatePoll) 55 | poll.DELETE("/:id", h.DeletePoll) 56 | for_admin_or_user.GET("/poll/:id", h.GetPollByID) 57 | } 58 | 59 | for_admin_or_user.GET("/polls", h.GetAllPolls) 60 | 61 | question := for_admin.Group("/question") 62 | { 63 | question.POST("/", h.CreateQuestion) 64 | question.PUT("/", h.UpdateQuestion) 65 | question.DELETE("/:id", h.DeleteQuestion) 66 | for_admin_or_user.GET("/question/:id", h.GetQuestionByID) 67 | } 68 | for_admin_or_user.GET("/questions/:poll_id", h.GetAllQuestions) 69 | 70 | return router 71 | } 72 | 73 | func CORSMiddleware() gin.HandlerFunc { 74 | return func(c *gin.Context) { 75 | c.Writer.Header().Set("Access-Control-Allow-Origin", "*") 76 | c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE") 77 | c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization") 78 | 79 | if c.Request.Method == "OPTIONS" { 80 | c.AbortWithStatus(http.StatusOK) 81 | return 82 | } 83 | 84 | c.Next() 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /polling/protos/users.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package polling; 4 | 5 | option go_package = "genprotos/"; 6 | 7 | import "protos/void.proto"; 8 | 9 | service UserService { 10 | rpc Register(RegisterReq) returns (Void); 11 | // rpc ConfirmUser(ConfirmUserReq) returns (Void); 12 | rpc Profile(GetProfileReq) returns (GetProfileResp); 13 | // rpc UpdatePassword(UpdatePasswordReq) returns (Void); 14 | rpc IsEmailExists(IsEmailExistsReq) returns (IsEmailExistsResp); 15 | rpc GetByID(GetProfileByIdReq) returns (GetProfileByIdResp); 16 | rpc GetByEmail(ByEmail) returns (GetProfileByIdResp); 17 | } 18 | 19 | message ByEmail { 20 | string email = 1; 21 | } 22 | 23 | message RegisterReq { 24 | string name = 1; 25 | string surname = 2; 26 | GenderType gender = 3; 27 | string age = 4; 28 | string nation = 5; 29 | string email = 6; 30 | string password = 7; 31 | string phone_number = 8; 32 | int32 working_experience = 9; 33 | string level_type = 10; 34 | } 35 | 36 | message RegisterReqForSwagger{ 37 | string name = 1; 38 | string surname = 2; 39 | string gender = 3; 40 | string age = 4; 41 | string nation = 5; 42 | string email = 6; 43 | string password = 7; 44 | string phone_number = 8; 45 | int32 working_experience = 9; 46 | string level_type = 10; 47 | } 48 | 49 | // message ConfirmUserReq { 50 | // string email = 1; // User's email to confirm 51 | // } 52 | 53 | message GetProfileReq { 54 | string email = 1; // User's email to retrieve the profile 55 | } 56 | 57 | message GetProfileResp { 58 | string id = 1; // User's unique identifier 59 | string email = 2; // User's email address 60 | string password = 3; // User's password (consider if you want to expose this) 61 | string role = 4; // User's role 62 | bool is_confirmed = 5; // Indicates if the user is confirmed 63 | } 64 | 65 | // message UpdatePasswordReq { 66 | // string email = 1; // User's email 67 | // string new_password = 2; // New password to set 68 | // } 69 | 70 | message IsEmailExistsReq { 71 | string email = 1; // User's email to check 72 | } 73 | 74 | message IsEmailExistsResp { 75 | bool exists = 1; // Indicates if the email exists 76 | } 77 | 78 | message GetProfileByIdReq { 79 | string id = 1; // User's unique identifier 80 | } 81 | 82 | message GetProfileByIdResp { 83 | string id = 1; // User's unique identifier 84 | string email = 2; // User's email address 85 | string role = 3; // User's role 86 | } 87 | 88 | enum GenderType { 89 | MALE = 0; 90 | FEMALE = 1; 91 | } 92 | 93 | message UserExcelResp { 94 | string name = 1; 95 | string surname = 2; 96 | string gender = 3; 97 | string age = 4; 98 | string nation = 5; 99 | string email = 6; 100 | string password = 7; 101 | string phone_number = 8; 102 | int32 working_experience = 9; 103 | string level_type = 10; 104 | }; -------------------------------------------------------------------------------- /api-gateway/protos/users.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package polling; 4 | 5 | option go_package = "genprotos/"; 6 | 7 | import "protos/void.proto"; 8 | 9 | service UserService { 10 | rpc Register(RegisterReq) returns (Void); 11 | // rpc ConfirmUser(ConfirmUserReq) returns (Void); 12 | rpc Profile(GetProfileReq) returns (GetProfileResp); 13 | // rpc UpdatePassword(UpdatePasswordReq) returns (Void); 14 | rpc IsEmailExists(IsEmailExistsReq) returns (IsEmailExistsResp); 15 | rpc GetByID(GetProfileByIdReq) returns (GetProfileByIdResp); 16 | rpc GetByEmail(ByEmail) returns (GetProfileByIdResp); 17 | } 18 | 19 | message ByEmail { 20 | string email = 1; 21 | } 22 | 23 | message RegisterReq { 24 | string name = 1; 25 | string surname = 2; 26 | GenderType gender = 3; 27 | string age = 4; 28 | string nation = 5; 29 | string email = 6; 30 | string password = 7; 31 | string phone_number = 8; 32 | int32 working_experience = 9; 33 | string level_type = 10; 34 | } 35 | 36 | message RegisterReqForSwagger{ 37 | string name = 1; 38 | string surname = 2; 39 | string gender = 3; 40 | string age = 4; 41 | string nation = 5; 42 | string email = 6; 43 | string password = 7; 44 | string phone_number = 8; 45 | int32 working_experience = 9; 46 | string level_type = 10; 47 | } 48 | 49 | // message ConfirmUserReq { 50 | // string email = 1; // User's email to confirm 51 | // } 52 | 53 | message GetProfileReq { 54 | string email = 1; // User's email to retrieve the profile 55 | } 56 | 57 | message GetProfileResp { 58 | string id = 1; // User's unique identifier 59 | string email = 2; // User's email address 60 | string password = 3; // User's password (consider if you want to expose this) 61 | string role = 4; // User's role 62 | bool is_confirmed = 5; // Indicates if the user is confirmed 63 | } 64 | 65 | // message UpdatePasswordReq { 66 | // string email = 1; // User's email 67 | // string new_password = 2; // New password to set 68 | // } 69 | 70 | message IsEmailExistsReq { 71 | string email = 1; // User's email to check 72 | } 73 | 74 | message IsEmailExistsResp { 75 | bool exists = 1; // Indicates if the email exists 76 | } 77 | 78 | message GetProfileByIdReq { 79 | string id = 1; // User's unique identifier 80 | } 81 | 82 | message GetProfileByIdResp { 83 | string id = 1; // User's unique identifier 84 | string email = 2; // User's email address 85 | string role = 3; // User's role 86 | } 87 | 88 | enum GenderType { 89 | MALE = 0; 90 | FEMALE = 1; 91 | } 92 | 93 | message UserExcelResp { 94 | string name = 1; 95 | string surname = 2; 96 | string gender = 3; 97 | string age = 4; 98 | string nation = 5; 99 | string email = 6; 100 | string password = 7; 101 | string phone_number = 8; 102 | int32 working_experience = 9; 103 | string level_type = 10; 104 | }; -------------------------------------------------------------------------------- /polling/storage/managers/user.go: -------------------------------------------------------------------------------- 1 | package managers 2 | 3 | import ( 4 | "context" 5 | "database/sql" 6 | "errors" 7 | pb "poll-service/genprotos" 8 | 9 | "github.com/google/uuid" 10 | // "golang.org/x/crypto/bcrypt" 11 | ) 12 | 13 | type UserManager struct { 14 | Conn *sql.DB 15 | } 16 | 17 | func NewUserManager(conn *sql.DB) *UserManager { 18 | return &UserManager{Conn: conn} 19 | } 20 | 21 | func (m *UserManager) Register(context context.Context, req *pb.RegisterReq) (*pb.Void, error) { 22 | var gender string 23 | if req.Gender == 0 { 24 | gender = "male" 25 | } else { 26 | gender = "female" 27 | } 28 | 29 | query := "INSERT INTO users (id, name, surname, gender, age, nation, email, password, phone_number, working_experience, level_type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)" 30 | _, err := m.Conn.Exec(query, uuid.NewString(), req.Name, req.Surname, gender, req.Age, req.Nation, req.Email, req.Password, req.PhoneNumber, req.WorkingExperience, req.LevelType) 31 | return nil, err 32 | } 33 | 34 | // func (m *UserManager) ConfirmUser(context context.Context, req *pb.ConfirmUserReq) (*pb.Void, error) { 35 | // query := "UPDATE users SET is_confirmed = true, confirmed_at = $1 WHERE email = $2" 36 | // _, err := m.Conn.Exec(query, time.Now(), req.Email) 37 | // return nil, err 38 | // } 39 | 40 | func (m *UserManager) Profile(context context.Context, req *pb.GetProfileReq) (*pb.GetProfileResp, error) { 41 | query := "SELECT id, email, password, role, is_confirmed FROM users WHERE email = $1" 42 | row := m.Conn.QueryRow(query, req.Email) 43 | var user pb.GetProfileResp 44 | err := row.Scan(&user.Id, &user.Email, &user.Password, &user.Role, &user.IsConfirmed) 45 | if err != nil { 46 | return nil, err 47 | } 48 | return &user, nil 49 | } 50 | 51 | // func (m *UserManager) UpdatePassword(context context.Context, req *pb.UpdatePasswordReq) (*pb.Void, error) { 52 | // hashedPassword, err := bcrypt.GenerateFromPassword([]byte(req.NewPassword), bcrypt.DefaultCost) 53 | // if err != nil { 54 | // return nil, err 55 | // } 56 | // query := "UPDATE users SET password = $1 WHERE email = $2" 57 | // _, err = m.Conn.Exec(query, string(hashedPassword), req.Email) 58 | // return nil, err 59 | // } 60 | 61 | func (m *UserManager) IsEmailExists(context context.Context, email *pb.IsEmailExistsReq) (*pb.IsEmailExistsResp, error) { 62 | query := "SELECT COUNT(*) FROM users WHERE email = $1" 63 | var count int 64 | err := m.Conn.QueryRow(query, email.Email).Scan(&count) 65 | if err != nil { 66 | return nil, errors.New("server error: " + err.Error()) 67 | } 68 | if count > 0 { 69 | return &pb.IsEmailExistsResp{Exists: true}, nil 70 | } 71 | return &pb.IsEmailExistsResp{Exists: false}, nil 72 | } 73 | 74 | func (m *UserManager) GetByID(context context.Context, id *pb.GetProfileByIdReq) (*pb.GetProfileByIdResp, error) { 75 | query := "SELECT id, email, role FROM users WHERE id = $1" 76 | user := &pb.GetProfileByIdResp{} 77 | err := m.Conn.QueryRow(query, id.Id).Scan(&user.Id, &user, &user.Email, &user.Role) 78 | if err != nil { 79 | return nil, err 80 | } 81 | return user, nil 82 | } 83 | 84 | func (m *UserManager) GetByEmail(context context.Context, id *pb.ByEmail) (*pb.GetProfileByIdResp, error) { 85 | query := "SELECT id, email, role FROM users WHERE email = $1" 86 | user := &pb.GetProfileByIdResp{} 87 | err := m.Conn.QueryRow(query, id.Email).Scan(&user.Id, &user.Email, &user.Role) 88 | if err != nil { 89 | return nil, err 90 | } 91 | return user, nil 92 | } 93 | -------------------------------------------------------------------------------- /api-gateway/go.mod: -------------------------------------------------------------------------------- 1 | module auth-service 2 | 3 | go 1.22.4 4 | 5 | require ( 6 | github.com/gin-gonic/gin v1.10.0 7 | // github.com/go-redis/redis v6.15.9+incompatible 8 | github.com/golang-jwt/jwt v3.2.2+incompatible 9 | github.com/google/uuid v1.6.0 10 | github.com/joho/godotenv v1.5.1 11 | github.com/minio/minio-go/v7 v7.0.75 12 | // github.com/redis/go-redis/v9 v9.6.1 13 | github.com/spf13/cast v1.6.0 14 | github.com/swaggo/files v1.0.1 15 | github.com/swaggo/gin-swagger v1.6.0 16 | github.com/swaggo/swag v1.16.3 17 | github.com/xuri/excelize/v2 v2.8.1 18 | golang.org/x/crypto v0.24.0 19 | google.golang.org/grpc v1.65.0 20 | google.golang.org/protobuf v1.34.1 21 | // gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df 22 | ) 23 | 24 | require ( 25 | github.com/KyleBanks/depth v1.2.1 // indirect 26 | github.com/PuerkitoBio/purell v1.1.1 // indirect 27 | github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect 28 | github.com/bytedance/sonic v1.11.6 // indirect 29 | github.com/bytedance/sonic/loader v0.1.1 // indirect 30 | // github.com/cespare/xxhash/v2 v2.3.0 // indirect 31 | github.com/cloudwego/base64x v0.1.4 // indirect 32 | github.com/cloudwego/iasm v0.2.0 // indirect 33 | // github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect 34 | github.com/dustin/go-humanize v1.0.1 // indirect 35 | github.com/gabriel-vasile/mimetype v1.4.3 // indirect 36 | github.com/gin-contrib/sse v0.1.0 // indirect 37 | github.com/go-ini/ini v1.67.0 // indirect 38 | github.com/go-openapi/jsonpointer v0.19.5 // indirect 39 | github.com/go-openapi/jsonreference v0.19.6 // indirect 40 | github.com/go-openapi/spec v0.20.4 // indirect 41 | github.com/go-openapi/swag v0.19.15 // indirect 42 | github.com/go-playground/locales v0.14.1 // indirect 43 | github.com/go-playground/universal-translator v0.18.1 // indirect 44 | github.com/go-playground/validator/v10 v10.20.0 // indirect 45 | github.com/goccy/go-json v0.10.3 // indirect 46 | github.com/josharian/intern v1.0.0 // indirect 47 | github.com/json-iterator/go v1.1.12 // indirect 48 | github.com/klauspost/compress v1.17.9 // indirect 49 | github.com/klauspost/cpuid/v2 v2.2.8 // indirect 50 | github.com/leodido/go-urn v1.4.0 // indirect 51 | github.com/mailru/easyjson v0.7.6 // indirect 52 | github.com/mattn/go-isatty v0.0.20 // indirect 53 | github.com/minio/md5-simd v1.1.2 // indirect 54 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 55 | github.com/modern-go/reflect2 v1.0.2 // indirect 56 | github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect 57 | // github.com/onsi/ginkgo v1.16.5 // indirect 58 | // github.com/onsi/gomega v1.34.0 // indirect 59 | github.com/pelletier/go-toml/v2 v2.2.2 // indirect 60 | github.com/richardlehane/mscfb v1.0.4 // indirect 61 | github.com/richardlehane/msoleps v1.0.3 // indirect 62 | github.com/rs/xid v1.5.0 // indirect 63 | github.com/twitchyliquid64/golang-asm v0.15.1 // indirect 64 | github.com/ugorji/go/codec v1.2.12 // indirect 65 | github.com/xuri/efp v0.0.0-20231025114914-d1ff6096ae53 // indirect 66 | github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05 // indirect 67 | golang.org/x/arch v0.8.0 // indirect 68 | golang.org/x/net v0.26.0 // indirect 69 | golang.org/x/sys v0.21.0 // indirect 70 | golang.org/x/text v0.16.0 // indirect 71 | golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect 72 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 // indirect 73 | // gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect 74 | gopkg.in/yaml.v2 v2.4.0 // indirect 75 | gopkg.in/yaml.v3 v3.0.1 // indirect 76 | ) 77 | -------------------------------------------------------------------------------- /polling/migrations/000003_trigger_table.up.sql: -------------------------------------------------------------------------------- 1 | -- Polllar uchun keyingi bo'sh raqamni olish funksiyasi 2 | CREATE OR REPLACE FUNCTION get_next_poll_num() RETURNS INT AS $$ 3 | DECLARE 4 | next_num INT; 5 | BEGIN 6 | -- Polllar jadvalidagi eng katta poll_num qiymatini olish va 1 qo'shish 7 | SELECT COALESCE(MAX(poll_num), 0) + 1 INTO next_num FROM polls; 8 | RETURN next_num; 9 | END; 10 | $$ LANGUAGE plpgsql; 11 | 12 | -- Polllar o'chirilgandan so'ng raqamlarni qayta tartiblash funksiyasi 13 | CREATE OR REPLACE FUNCTION renumber_polls() RETURNS TRIGGER AS $$ 14 | BEGIN 15 | -- Polllar jadvalini yangi tartib bilan yangilash 16 | WITH ordered_polls AS ( 17 | SELECT id, ROW_NUMBER() OVER (ORDER BY poll_num) AS new_num 18 | FROM polls 19 | ) 20 | UPDATE polls 21 | SET poll_num = ordered_polls.new_num 22 | FROM ordered_polls 23 | WHERE polls.id = ordered_polls.id; 24 | RETURN NULL; 25 | END; 26 | $$ LANGUAGE plpgsql; 27 | 28 | -- Polllar o'chirilgandan so'ng trigger yaratish 29 | DO $$ 30 | BEGIN 31 | IF NOT EXISTS ( 32 | SELECT 1 33 | FROM pg_trigger 34 | WHERE tgname = 'after_poll_delete' 35 | ) THEN 36 | CREATE TRIGGER after_poll_delete 37 | AFTER DELETE ON polls 38 | FOR EACH STATEMENT 39 | EXECUTE FUNCTION renumber_polls(); 40 | END IF; 41 | END 42 | $$; 43 | 44 | -- Poll qo'shish funksiyasini yaratish (keyingi bo'sh poll_num bilan) 45 | CREATE OR REPLACE FUNCTION insert_poll(p_title VARCHAR, p_subtitle VARCHAR, p_options JSONB, p_feedbacks JSONB) RETURNS VOID AS $$ 46 | DECLARE 47 | next_num INT; 48 | BEGIN 49 | -- Keyingi bo'sh poll raqamini olish 50 | next_num := get_next_poll_num(); 51 | -- Pollni qo'shish 52 | INSERT INTO polls (poll_num, title, subtitle, options, feedbacks) VALUES (next_num, p_title, p_subtitle, p_options, p_feedbacks); 53 | END; 54 | $$ LANGUAGE plpgsql; 55 | 56 | -- Savollar uchun keyingi bo'sh raqamni olish funksiyasi (poll_id bo'yicha) 57 | CREATE OR REPLACE FUNCTION get_next_question_num(p_poll_id UUID) RETURNS INT AS $$ 58 | DECLARE 59 | next_num INT; 60 | BEGIN 61 | -- Berilgan poll_id uchun eng katta num qiymatini olish va 1 qo'shish 62 | SELECT COALESCE(MAX(num), 0) + 1 INTO next_num FROM questions WHERE poll_id = p_poll_id; 63 | RETURN next_num; 64 | END; 65 | $$ LANGUAGE plpgsql; 66 | 67 | -- Savollar o'chirilgandan so'ng raqamlarni qayta tartiblash funksiyasi 68 | CREATE OR REPLACE FUNCTION renumber_questions() RETURNS TRIGGER AS $$ 69 | BEGIN 70 | -- Savollar jadvalini yangi tartib bilan yangilash 71 | WITH ordered_questions AS ( 72 | SELECT id, ROW_NUMBER() OVER (PARTITION BY poll_id ORDER BY num) AS new_num 73 | FROM questions 74 | ) 75 | UPDATE questions 76 | SET num = ordered_questions.new_num 77 | FROM ordered_questions 78 | WHERE questions.id = ordered_questions.id; 79 | RETURN NULL; 80 | END; 81 | $$ LANGUAGE plpgsql; 82 | 83 | -- Savollar o'chirilgandan so'ng trigger yaratish 84 | DO $$ 85 | BEGIN 86 | IF NOT EXISTS ( 87 | SELECT 1 88 | FROM pg_trigger 89 | WHERE tgname = 'after_question_delete' 90 | ) THEN 91 | CREATE TRIGGER after_question_delete 92 | AFTER DELETE ON questions 93 | FOR EACH STATEMENT 94 | EXECUTE FUNCTION renumber_questions(); 95 | END IF; 96 | END 97 | $$; 98 | 99 | -- Savol qo'shish funksiyasini yaratish (keyingi bo'sh num bilan) 100 | CREATE OR REPLACE FUNCTION insert_question(p_content TEXT, p_poll_id UUID) RETURNS VOID AS $$ 101 | DECLARE 102 | next_num INT; 103 | BEGIN 104 | -- Keyingi bo'sh savol raqamini olish 105 | next_num := get_next_question_num(p_poll_id); 106 | -- Savolni qo'shish 107 | INSERT INTO questions (num, content, poll_id) VALUES (next_num, p_content, p_poll_id); 108 | END; 109 | $$ LANGUAGE plpgsql; 110 | -------------------------------------------------------------------------------- /polling/service/result.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | pb "poll-service/genprotos" 7 | 8 | st "poll-service/storage" 9 | ) 10 | 11 | type ResultService struct { 12 | storage st.StorageI 13 | pb.UnimplementedResultServiceServer 14 | } 15 | 16 | func NewResultService(storage st.StorageI) *ResultService { 17 | return &ResultService{storage: storage} 18 | } 19 | 20 | func (s *ResultService) CreateResult(ctx context.Context, req *pb.CreateResultReq) (*pb.CreateResultRes, error) { 21 | return s.storage.Result().CreateResult(ctx, req) 22 | } 23 | 24 | func (s *ResultService) SavePollAnswer(ctx context.Context, req *pb.SavePollAnswerReq) (*pb.Void, error) { 25 | // text := "Ajoyib, surovnomani ishlashda davom eting !" 26 | fmt.Println(">>>>>>>",req.Answer) 27 | return s.storage.Result().SavePollAnswer(ctx, req) 28 | } 29 | 30 | func (s *ResultService) GetResultsInExcel(ctx context.Context, req *pb.Void) (*pb.ExcelResultsRes, error) { 31 | return s.storage.Result().GetResultsInExcel(ctx, req) 32 | } 33 | 34 | func (s *ResultService) GetPollResults(ctx context.Context, req *pb.ByIDs) (*pb.ByIDResponse, error) { 35 | var a, b int32 36 | 37 | resAnswer, err := s.storage.Result().GetByIDRes(ctx, req) 38 | if err != nil { 39 | return nil, err 40 | } 41 | 42 | var extrovert, nevrotizm, total int32 43 | feed := "" 44 | 45 | poll, err := s.storage.Poll().GetByID(ctx, &pb.ByID{Id: *req.PollId}) 46 | if err != nil { 47 | return nil, err 48 | } 49 | 50 | // PollNum shartini tekshirish 51 | if *poll.PollNum == 1 { 52 | for _, v := range resAnswer.Answers { 53 | switch { 54 | case isIn(*v.Num, []int32{1, 3, 8, 10, 13, 17, 22, 25, 27, 39, 44, 46, 49, 53, 56}) && *v.AnswerPoint == int32(1): 55 | extrovert += 1 56 | case isIn(*v.Num, []int32{5, 15, 29, 32, 34, 37, 41, 51}) && *v.AnswerPoint == int32(0): 57 | extrovert += 1 58 | case isIn(*v.Num, []int32{2, 4, 7, 9, 11, 14, 16, 19, 21, 23, 26, 28, 31, 33, 35, 38, 40, 43, 45, 47, 50, 52, 55, 57}) && *v.AnswerPoint == int32(1): 59 | nevrotizm += 1 60 | default: 61 | continue 62 | } 63 | } 64 | 65 | // Extrovert va Nevrotizm natijalarini to'g'ri to'ldirish 66 | if extrovert > 12 && extrovert > nevrotizm { 67 | feed = "Extrovert ekansiz: Ajoyib, surovnomani ishlashda davom eting 😊 !" 68 | } else if extrovert < 12 && nevrotizm < 12 { 69 | feed = "Introvert ekansiz: Ajoyib, surovnomani ishlashda davom eting 😊 !" 70 | } else if extrovert == nevrotizm && extrovert > 12 && nevrotizm < 12 { 71 | feed = "Extrovert va Nevrotizm ekansiz: Ajoyib, surovnomani ishlashda davom eting 😊 !" 72 | } else { 73 | feed = "Nevrotizm ekansiz: Ajoyib, surovnomani ishlashda davom eting 😊 !" 74 | } 75 | 76 | // Javobni qaytarish 77 | resAnswer.Feed = []*pb.Feedback{{From: &a, To: &a, Text: &feed}} 78 | 79 | } else { 80 | for _, v := range resAnswer.Answers { 81 | total += *v.AnswerPoint 82 | } 83 | 84 | // Poll Feedbackni ko'rib chiqish 85 | for _, v := range poll.Feedback { 86 | if total >= *v.From && total < *v.To { 87 | feed = *v.Text 88 | break 89 | } 90 | } 91 | 92 | // Agar pollning `Feed` bo‘limi bo'sh bo'lsa, uni to'ldirish 93 | if feed == "" { 94 | for _, v := range resAnswer.Feed { 95 | if *v.From >= total && *v.To <= total { 96 | feed = *v.Text 97 | a = *v.From 98 | b = *v.To 99 | break 100 | } 101 | } 102 | } 103 | 104 | // Feedback to'ldirish 105 | resAnswer.Feed = []*pb.Feedback{{From: &a, To: &b, Text: &feed}} 106 | } 107 | 108 | text := "Ajoyib, surovnomani ishlashda davom eting !" 109 | if feed == "" { 110 | resAnswer.Feed = []*pb.Feedback{{From: &a, To: &b, Text: &text}} 111 | } 112 | 113 | // Oxirgi natijani chop etish 114 | return resAnswer, nil 115 | } 116 | 117 | func isIn(num int32, ls []int32) bool { 118 | for _, v := range ls { 119 | if v == num { 120 | return true 121 | } 122 | } 123 | return false 124 | } 125 | -------------------------------------------------------------------------------- /polling/storage/managers/question.go: -------------------------------------------------------------------------------- 1 | package managers 2 | 3 | import ( 4 | "context" 5 | "database/sql" 6 | "encoding/json" 7 | "fmt" 8 | pb "poll-service/genprotos" 9 | ) 10 | 11 | type QuestionManager struct { 12 | Conn *sql.DB 13 | } 14 | 15 | func NewQuestionManager(conn *sql.DB) *QuestionManager { 16 | return &QuestionManager{Conn: conn} 17 | } 18 | 19 | func (m *QuestionManager) Create(ctx context.Context, question *pb.QuestionCreateReq) (*pb.Void, error) { 20 | query := "SELECT insert_question($1, $2)" 21 | _, err := m.Conn.ExecContext(ctx, query, question.Content, question.PollId) 22 | if err != nil { 23 | return nil, fmt.Errorf("failed to create question: %w", err) 24 | } 25 | return &pb.Void{}, nil 26 | } 27 | 28 | func (m *QuestionManager) GetByID(ctx context.Context, req *pb.ByID) (*pb.QuestionGetByIDRes, error) { 29 | query := "SELECT id, content, poll_id FROM questions WHERE id = $1" 30 | row := m.Conn.QueryRowContext(ctx, query, req.Id) 31 | 32 | var res pb.QuestionGetByIDRes 33 | err := row.Scan(&res.Id, &res.Content, &res.PollId) 34 | if err != nil { 35 | if err == sql.ErrNoRows { 36 | return nil, fmt.Errorf("question not found: %w", err) 37 | } 38 | return nil, fmt.Errorf("failed to get question by id: %w", err) 39 | } 40 | return &res, nil 41 | } 42 | 43 | func (m *QuestionManager) Update(ctx context.Context, question *pb.QuestionUpdateReq) (*pb.Void, error) { 44 | query := "UPDATE questions SET content = $1 WHERE id = $2" 45 | _, err := m.Conn.ExecContext(ctx, query, question.Content, question.Id) 46 | if err != nil { 47 | return nil, fmt.Errorf("failed to update question: %w", err) 48 | } 49 | return &pb.Void{}, nil 50 | } 51 | 52 | func (m *QuestionManager) Delete(ctx context.Context, req *pb.ByID) (*pb.Void, error) { 53 | query := "DELETE FROM questions WHERE id = $1" 54 | _, err := m.Conn.ExecContext(ctx, query, req.Id) 55 | if err != nil { 56 | return nil, fmt.Errorf("failed to delete question: %w", err) 57 | } 58 | return &pb.Void{}, nil 59 | } 60 | 61 | func (m *QuestionManager) GetAll(ctx context.Context, req *pb.QuestionGetAllReq) (*pb.QuestionGetAllRes, error) { 62 | // Query to get all questions related to a poll 63 | questionQuery := "SELECT id, num, content, poll_id FROM questions WHERE poll_id = $1" 64 | rows, err := m.Conn.QueryContext(ctx, questionQuery, req.PollId) 65 | if err != nil { 66 | return nil, fmt.Errorf("failed to get all questions: %w", err) 67 | } 68 | defer rows.Close() 69 | 70 | var questions []*pb.Question 71 | for rows.Next() { 72 | var question pb.Question 73 | err := rows.Scan(&question.Id, &question.Num, &question.Content, &question.PollId) 74 | if err != nil { 75 | return nil, fmt.Errorf("failed to scan question: %w", err) 76 | } 77 | questions = append(questions, &question) 78 | } 79 | 80 | if err := rows.Err(); err != nil { 81 | return nil, fmt.Errorf("rows error: %w", err) 82 | } 83 | 84 | // Query to get poll details 85 | pollQuery := "SELECT id, poll_num, title, subtitle, options FROM polls WHERE id = $1" 86 | var poll pb.PollGetByIDRes 87 | var pollNum int32 88 | var options []byte 89 | var title, subtitle, pollId string 90 | 91 | err = m.Conn.QueryRowContext(ctx, pollQuery, req.PollId).Scan(&pollId, &pollNum, &title, &subtitle, &options) 92 | if err != nil { 93 | if err == sql.ErrNoRows { 94 | return &pb.QuestionGetAllRes{ 95 | Question: []*pb.Question{}, 96 | Poll: nil, 97 | }, nil 98 | } 99 | return nil, fmt.Errorf("failed to get poll details: %w", err) 100 | } 101 | 102 | // Unmarshalling JSON data for options 103 | var rawOptions []map[string]interface{} 104 | var optionList []*pb.Option 105 | 106 | if len(options) > 0 { 107 | if err := json.Unmarshal(options, &rawOptions); err != nil { 108 | return nil, fmt.Errorf("failed to unmarshal options: %w", err) 109 | } 110 | 111 | for _, rawOption := range rawOptions { 112 | option := &pb.Option{} 113 | if variant, ok := rawOption["variant"].(string); ok { 114 | option.Variant = &variant 115 | } 116 | if ball, ok := rawOption["ball"].(float64); ok { 117 | ballInt := int32(ball) 118 | option.Ball = &ballInt 119 | } 120 | optionList = append(optionList, option) 121 | } 122 | } 123 | 124 | poll.Id = &pollId 125 | poll.PollNum = &pollNum 126 | poll.Title = &title 127 | poll.Subtitle = &subtitle 128 | poll.Options = optionList 129 | 130 | return &pb.QuestionGetAllRes{ 131 | Question: questions, 132 | Poll: &poll, 133 | }, nil 134 | } 135 | -------------------------------------------------------------------------------- /api-gateway/api/handlers/question.go: -------------------------------------------------------------------------------- 1 | package handlers 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "net/http" 7 | 8 | pb "auth-service/genprotos" 9 | 10 | "github.com/gin-gonic/gin" 11 | ) 12 | 13 | // CreateQuestion godoc 14 | // @Summary Create a new question 15 | // @Description Create a new question with the given details 16 | // @Tags question 17 | // @Accept json 18 | // @Produce json 19 | // @Param question body pb.QuestionCreateReq true "Question creation request" 20 | // @Success 200 {object} string "Question created successfully" 21 | // @Failure 400 {object} string "Invalid request payload" 22 | // @Failure 500 {object} string "Server error" 23 | // @Router /question [post] 24 | // @Security BearerAuth 25 | func (h *HTTPHandler) CreateQuestion(c *gin.Context) { 26 | var req pb.QuestionCreateReq 27 | if err := c.ShouldBindJSON(&req); err != nil { 28 | c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) 29 | return 30 | } 31 | _, err := h.Question.Create(context.Background(), &req) 32 | if err != nil { 33 | c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) 34 | return 35 | } 36 | c.JSON(http.StatusOK, gin.H{"message": "Question created successfully"}) 37 | } 38 | 39 | // UpdateQuestion godoc 40 | // @Summary Update an existing question 41 | // @Description Update an existing question with the given details 42 | // @Tags question 43 | // @Accept json 44 | // @Produce json 45 | // @Param question body pb.QuestionUpdateReq true "Question update request" 46 | // @Success 200 {object} string "Question updated successfully" 47 | // @Failure 400 {object} string "Invalid request payload" 48 | // @Failure 500 {object} string "Server error" 49 | // @Router /question [put] 50 | // @Security BearerAuth 51 | func (h *HTTPHandler) UpdateQuestion(c *gin.Context) { 52 | var req pb.QuestionUpdateReq 53 | if err := c.ShouldBindJSON(&req); err != nil { 54 | c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) 55 | return 56 | } 57 | _, err := h.Question.Update(context.Background(), &req) 58 | if err != nil { 59 | c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) 60 | return 61 | } 62 | c.JSON(http.StatusOK, gin.H{"message": "Question updated successfully"}) 63 | } 64 | 65 | // DeleteQuestion godoc 66 | // @Summary Delete a question 67 | // @Description Delete a question by its ID 68 | // @Tags question 69 | // @Accept json 70 | // @Produce json 71 | // @Param id path string true "Question ID" 72 | // @Success 200 {object} string "Question deleted successfully" 73 | // @Failure 500 {object} string "Server error" 74 | // @Router /question/{id} [delete] 75 | // @Security BearerAuth 76 | func (h *HTTPHandler) DeleteQuestion(c *gin.Context) { 77 | id := c.Param("id") 78 | req := pb.ByID{Id: id} 79 | _, err := h.Question.Delete(context.Background(), &req) 80 | if err != nil { 81 | c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) 82 | return 83 | } 84 | c.JSON(http.StatusOK, gin.H{"message": "Question deleted successfully"}) 85 | } 86 | 87 | // GetQuestionByID godoc 88 | // @Summary Get a question by ID 89 | // @Description Get a question by its ID 90 | // @Tags question 91 | // @Accept json 92 | // @Produce json 93 | // @Param id path string true "Question ID" 94 | // @Success 200 {object} pb.QuestionGetByIDRes 95 | // @Failure 500 {object} string "Server error" 96 | // @Router /question/{id} [get] 97 | // @Security BearerAuth 98 | func (h *HTTPHandler) GetQuestionByID(c *gin.Context) { 99 | id := c.Param("id") 100 | req := pb.ByID{Id: id} 101 | res, err := h.Question.GetByID(context.Background(), &req) 102 | if err != nil { 103 | c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) 104 | return 105 | } 106 | c.JSON(http.StatusOK, res) 107 | } 108 | 109 | // GetAllQuestions godoc 110 | // @Summary Get all questions 111 | // @Description Get all questions with pagination 112 | // @Tags question 113 | // @Accept json 114 | // @Produce json 115 | // @Param poll_id path string true "Poll ID" 116 | // @Success 200 {object} pb.QuestionGetAllRes 117 | // @Failure 400 {object} string "Invalid request payload" 118 | // @Failure 500 {object} string "Server error" 119 | // @Router /questions/{poll_id} [get] 120 | // @Security BearerAuth 121 | func (h *HTTPHandler) GetAllQuestions(c *gin.Context) { 122 | poll_id := c.Param("poll_id") 123 | fmt.Println("poll_id: ", poll_id) 124 | req := pb.QuestionGetAllReq{PollId: &poll_id} 125 | 126 | res, err := h.Question.GetAll(c, &req) 127 | if err != nil { 128 | c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) 129 | return 130 | } 131 | c.JSON(http.StatusOK, res) 132 | } 133 | -------------------------------------------------------------------------------- /api-gateway/api/handlers/results.go: -------------------------------------------------------------------------------- 1 | package handlers 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "net/http" 7 | "os" 8 | "path/filepath" 9 | 10 | pb "auth-service/genprotos" 11 | 12 | m "auth-service/drivers" 13 | 14 | "github.com/gin-gonic/gin" 15 | "github.com/minio/minio-go/v7" 16 | "github.com/xuri/excelize/v2" 17 | ) 18 | 19 | // toAlphaString converts a column number to an Excel-style column name (e.g., 1 -> A, 27 -> AA). 20 | func toAlphaString(n int) string { 21 | var columnName string 22 | for n > 0 { 23 | remainder := (n - 1) % 26 24 | columnName = string('A'+remainder) + columnName 25 | n = (n - 1) / 26 26 | } 27 | return columnName 28 | } 29 | 30 | // GetResults godoc 31 | // @Summary Get results in excel file 32 | // @Description Get overall results writing in excel file 33 | // @Tags results 34 | // @Accept json 35 | // @Produce json 36 | // @Success 200 {object} map[string]string "File URL" 37 | // @Failure 404 {object} string "Poll not found" 38 | // @Failure 500 {object} string "Server error" 39 | // @Router /results [GET] 40 | // @Security BearerAuth 41 | func (h *HTTPHandler) GetUserResultsInExcel(c *gin.Context) { 42 | minioClient, err := m.MinIOConnect() 43 | if err != nil { 44 | c.JSON(http.StatusInternalServerError, gin.H{"error": "Couldn't connect to minio", "details": err.Error()}) 45 | } 46 | 47 | results, err := h.Result.GetResultsInExcel(c, nil) 48 | if err != nil { 49 | c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) 50 | return 51 | } 52 | 53 | f := excelize.NewFile() 54 | 55 | pollResults := make(map[int][]*pb.ResultRes) 56 | for _, result := range results.Results { 57 | pollResults[int(*result.PollNum)] = append(pollResults[int(*result.PollNum)], result) 58 | } 59 | 60 | for pollNum, pollRes := range pollResults { 61 | sheetName := fmt.Sprintf("Poll %d", pollNum) 62 | _, err := f.NewSheet(sheetName) 63 | if err != nil { 64 | c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create sheet", "details": err.Error()}) 65 | return 66 | } 67 | 68 | headers := []string{ 69 | "Ismi", "Familiyasi", "Jinsi", "Yoshi", "Millati", "Email", "Telefon raqami", 70 | "Ish tajribasi", "Darajasi", "So'rovnoma raqami", "Jami natijalar", 71 | } 72 | 73 | maxQuestions := 0 74 | for _, result := range pollRes { 75 | if len(result.Answers) > maxQuestions { 76 | maxQuestions = len(result.Answers) 77 | } 78 | } 79 | 80 | for i := 1; i <= maxQuestions; i++ { 81 | headers = append(headers, fmt.Sprintf("%d - savol", i)) 82 | } 83 | 84 | for i, header := range headers { 85 | cell := fmt.Sprintf("%s1", toAlphaString(i+1)) 86 | f.SetCellValue(sheetName, cell, header) 87 | } 88 | 89 | rowNum := 2 90 | for _, result := range pollRes { 91 | row := []interface{}{ 92 | result.User.Name, 93 | result.User.Surname, 94 | result.User.Gender, 95 | result.User.Age, 96 | result.User.Nation, 97 | result.User.Email, 98 | result.User.PhoneNumber, 99 | result.User.WorkingExperience, 100 | result.User.LevelType, 101 | fmt.Sprintf("%d - so'rovnoma", *result.PollNum), 102 | } 103 | 104 | totalPoints := 0 105 | for _, answer := range result.Answers { 106 | if answer.AnswerPoint != nil { 107 | row = append(row, *answer.AnswerPoint) 108 | totalPoints += int(*answer.AnswerPoint) 109 | } else { 110 | row = append(row, nil) // Handle the case where the pointer is nil 111 | } 112 | } 113 | 114 | row = append(row[:10], append([]interface{}{totalPoints}, row[10:]...)...) 115 | 116 | for i, cellValue := range row { 117 | cell := fmt.Sprintf("%s%d", toAlphaString(i+1), rowNum) 118 | f.SetCellValue(sheetName, cell, cellValue) 119 | } 120 | rowNum++ 121 | } 122 | } 123 | 124 | var buffer bytes.Buffer 125 | if err := f.Write(&buffer); err != nil { 126 | c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to write Excel file", "details": err.Error()}) 127 | return 128 | } 129 | dst, _ := os.Getwd() 130 | fileDir := "/files" 131 | if _, err := os.Stat(dst + fileDir); os.IsNotExist(err) { 132 | os.Mkdir(dst+fileDir, os.ModePerm) 133 | } 134 | // Define file path in /files directory 135 | fileName := "results.xlsx" 136 | filePath := filepath.Join(fileDir, fileName) 137 | 138 | // Create /files directory if it doesn't exist 139 | if err := os.MkdirAll(fileDir, os.ModePerm); err != nil { 140 | c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create directory", "details": err.Error()}) 141 | return 142 | } 143 | 144 | // Write buffer to file 145 | if err := os.WriteFile(filePath, buffer.Bytes(), 0644); err != nil { 146 | c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to save Excel file", "details": err.Error()}) 147 | return 148 | } 149 | 150 | info, err := minioClient.FPutObject(c, "another-bucket", fileName, filePath, minio.PutObjectOptions{ContentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}) 151 | if err != nil { 152 | c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to put object into bucket", "details": err.Error()}) 153 | return 154 | } 155 | fileURL := fmt.Sprintf("http://%s/browser/%s/%s", "82.97.253.217:9001", info.Bucket, info.Key) 156 | 157 | c.JSON(http.StatusOK, gin.H{"file_url": fileURL}) 158 | } 159 | -------------------------------------------------------------------------------- /polling/storage/managers/result.go: -------------------------------------------------------------------------------- 1 | package managers 2 | 3 | import ( 4 | "context" 5 | "database/sql" 6 | "encoding/json" 7 | "fmt" 8 | 9 | pb "poll-service/genprotos" 10 | 11 | "github.com/google/uuid" 12 | ) 13 | 14 | type ResultManager struct { 15 | Conn *sql.DB 16 | } 17 | 18 | func NewResultManager(conn *sql.DB) *ResultManager { 19 | return &ResultManager{Conn: conn} 20 | } 21 | 22 | func (m *ResultManager) CreateResult(ctx context.Context, req *pb.CreateResultReq) (*pb.CreateResultRes, error) { 23 | id := uuid.NewString() 24 | query := `INSERT INTO results (id, user_id, poll_id) VALUES ($1, $2, $3)` 25 | _, err := m.Conn.ExecContext(ctx, query, id, req.UserId, req.PollId) 26 | if err != nil { 27 | return nil, err 28 | } 29 | return &pb.CreateResultRes{ResultId: &id}, nil 30 | } 31 | 32 | func (m *ResultManager) SavePollAnswer(ctx context.Context, req *pb.SavePollAnswerReq) (*pb.Void, error) { 33 | query := "INSERT INTO poll_answers (id, result_id, question_id, answer) VALUES ($1, $2, $3, $4)" 34 | _, err := m.Conn.ExecContext(ctx, query, uuid.NewString(), req.ResultId, req.QuestionId, req.Answer) 35 | if err != nil { 36 | return nil, err 37 | } 38 | return nil, nil 39 | } 40 | 41 | func (m *ResultManager) GetResultsInExcel(ctx context.Context, req *pb.Void) (*pb.ExcelResultsRes, error) { 42 | query := ` 43 | SELECT 44 | u.name, u.surname, u.gender, u.age, u.nation, u.email, u.phone_number, u.working_experience, u.level_type, 45 | p.poll_num, 46 | q.num AS question_num, q.id, pa.answer 47 | FROM 48 | results r 49 | JOIN 50 | users u ON r.user_id = u.id 51 | JOIN 52 | poll_answers pa ON r.id = pa.result_id 53 | JOIN 54 | questions q ON pa.question_id = q.id 55 | JOIN 56 | polls p ON r.poll_id = p.id 57 | ORDER BY 58 | u.id, p.poll_num, q.num; 59 | ` 60 | 61 | rows, err := m.Conn.QueryContext(ctx, query) 62 | if err != nil { 63 | return nil, err 64 | } 65 | defer rows.Close() 66 | 67 | resultsMap := make(map[string]*pb.ResultRes) 68 | for rows.Next() { 69 | var name, surname, gender, age, nation, email, phoneNumber, level_type, questionId string 70 | var workingExperience, pollNum, questionNum, answer int32 71 | 72 | err := rows.Scan(&name, &surname, &gender, &age, &nation, &email, &phoneNumber, &workingExperience, &level_type, &pollNum, &questionNum, &questionId, &answer) 73 | if err != nil { 74 | return nil, err 75 | } 76 | 77 | user := &pb.UserExcelResp{ 78 | Name: name, 79 | Surname: surname, 80 | Gender: gender, 81 | Email: email, 82 | Age: age, 83 | Nation: nation, 84 | PhoneNumber: phoneNumber, 85 | WorkingExperience: workingExperience, 86 | LevelType: level_type, 87 | } 88 | 89 | resultKey := name + surname + string(pollNum) 90 | if result, exists := resultsMap[resultKey]; exists { 91 | result.Answers = append(result.Answers, &pb.IncomingAnswer{ 92 | QuestionId: &questionId, 93 | AnswerPoint: &answer, 94 | }) 95 | } else { 96 | resultsMap[resultKey] = &pb.ResultRes{ 97 | User: user, 98 | PollNum: &pollNum, 99 | Answers: []*pb.IncomingAnswer{ 100 | { 101 | QuestionId: &questionId, 102 | AnswerPoint: &answer, 103 | }, 104 | }, 105 | } 106 | } 107 | } 108 | 109 | var results []*pb.ResultRes 110 | for _, result := range resultsMap { 111 | results = append(results, result) 112 | } 113 | 114 | return &pb.ExcelResultsRes{Results: results}, nil 115 | } 116 | 117 | func (m *ResultManager) GetByIDRes(ctx context.Context, req *pb.ByIDs) (*pb.ByIDResponse, error) { 118 | query := ` 119 | SELECT pa.question_id, q.num, pa.answer, p.feedbacks 120 | FROM poll_answers pa 121 | JOIN questions q ON pa.question_id = q.id 122 | JOIN results r ON pa.result_id = r.id 123 | JOIN polls p on r.poll_id = p.id 124 | WHERE result_id = $1 125 | ` 126 | var feedbacks []byte 127 | rows, err := m.Conn.Query(query, req.ResultId) 128 | var res pb.ByIDResponse 129 | if err != nil { 130 | return nil, err 131 | } 132 | defer rows.Close() 133 | for rows.Next() { 134 | var questionId string 135 | var answer, num int32 136 | err := rows.Scan(&questionId, &num, &answer, &feedbacks) 137 | if err != nil { 138 | return nil, err 139 | } 140 | res.Answers = append(res.Answers, &pb.IncomingAnswer{QuestionId: &questionId, AnswerPoint: &answer, Num: &num}) 141 | } 142 | var feedbackList []*pb.Feedback 143 | if len(feedbacks) > 0 { 144 | fmt.Println(string(feedbacks)) 145 | var rawFeedbacks []map[string]interface{} 146 | if err := json.Unmarshal(feedbacks, &rawFeedbacks); err != nil { 147 | return nil, fmt.Errorf("failed to unmarshal feedbacks: %s", err.Error()) 148 | } 149 | 150 | for _, rawFeedback := range rawFeedbacks { 151 | feedback := &pb.Feedback{} 152 | if from, ok := rawFeedback["from"].(float64); ok { 153 | fromInt := int32(from) 154 | feedback.From = &fromInt 155 | } 156 | if to, ok := rawFeedback["to"].(float64); ok { 157 | toInt := int32(to) 158 | feedback.To = &toInt 159 | } 160 | if text, ok := rawFeedback["text"].(string); ok { 161 | feedback.Text = &text 162 | } 163 | feedbackList = append(feedbackList, feedback) 164 | } 165 | } 166 | res.Feed = feedbackList 167 | return &res, nil 168 | } 169 | -------------------------------------------------------------------------------- /api-gateway/api/handlers/poll.go: -------------------------------------------------------------------------------- 1 | package handlers 2 | 3 | import ( 4 | pb "auth-service/genprotos" 5 | "context" 6 | "net/http" 7 | 8 | "github.com/gin-gonic/gin" 9 | ) 10 | 11 | // CreatePoll godoc 12 | // @Summary Create a new poll 13 | // @Description Create a new poll with poll number, title, and options 14 | // @Tags polls 15 | // @Accept json 16 | // @Produce json 17 | // @Param poll body pb.PollCreateReq true "Poll creation request" 18 | // @Success 201 {object} string "Successfully created!" 19 | // @Failure 400 {object} string "Invalid request payload" 20 | // @Failure 500 {object} string "Server error" 21 | // @Router /poll [post] 22 | // @Security BearerAuth 23 | func (h *HTTPHandler) CreatePoll(c *gin.Context) { 24 | var req pb.PollCreateReq 25 | if err := c.BindJSON(&req); err != nil { 26 | c.JSON(http.StatusBadRequest, "Invalid request payload: "+err.Error()) 27 | return 28 | } 29 | 30 | for _, feedback := range req.Feedbacks { 31 | if feedback.From == nil { 32 | defaultFrom := int32(0) 33 | feedback.From = &defaultFrom 34 | } 35 | if feedback.To == nil { 36 | defaultTo := int32(0) 37 | feedback.To = &defaultTo 38 | } 39 | if feedback.Text == nil { 40 | defaultText := "" 41 | feedback.Text = &defaultText 42 | } 43 | } 44 | 45 | for _, option := range req.Options { 46 | if option.Variant == nil { 47 | defaultVariant := "" 48 | option.Variant = &defaultVariant 49 | } 50 | if option.Ball == nil { 51 | defaultBall := int32(0) 52 | option.Ball = &defaultBall 53 | } 54 | } 55 | _, err := h.Poll.Create(context.Background(), &req) 56 | if err != nil { 57 | c.JSON(http.StatusInternalServerError, "Server error: "+err.Error()) 58 | return 59 | } 60 | 61 | c.JSON(http.StatusCreated, gin.H{"message": "Successfully created!"}) 62 | } 63 | 64 | // UpdatePoll godoc 65 | // @Summary Update an existing poll 66 | // @Description Update an existing poll with poll number, title, and options 67 | // @Tags polls 68 | // @Accept json 69 | // @Produce json 70 | // @Param id path string true "Poll ID" 71 | // @Param poll body pb.PollUpdateReqSwag true "Poll update request" 72 | // @Success 200 {object} string "Successfully updated" 73 | // @Failure 400 {object} string "Invalid request payload" 74 | // @Failure 404 {object} string "Poll not found" 75 | // @Failure 500 {object} string "Server error" 76 | // @Router /poll/{id} [put] 77 | // @Security BearerAuth 78 | func (h *HTTPHandler) UpdatePoll(c *gin.Context) { 79 | id := c.Param("id") 80 | req := pb.PollUpdateReq{Id: &id} 81 | if err := c.BindJSON(&req); err != nil { 82 | c.JSON(http.StatusBadRequest, gin.H{"Invalid request payload": err.Error()}) 83 | return 84 | } 85 | 86 | _, err := h.Poll.Update(context.Background(), &req) 87 | if err != nil { 88 | c.JSON(http.StatusInternalServerError, gin.H{"error": "Server error", "details": err.Error()}) 89 | return 90 | } 91 | 92 | c.JSON(http.StatusOK, gin.H{"message": "Successfully updated"}) 93 | } 94 | 95 | // DeletePoll godoc 96 | // @Summary Delete an existing poll 97 | // @Description Delete a poll by its ID 98 | // @Tags polls 99 | // @Accept json 100 | // @Produce json 101 | // @Param id path string true "Poll ID" 102 | // @Success 200 {object} string "Successfully deleted!" 103 | // @Failure 400 {object} string "Invalid request payload" 104 | // @Failure 404 {object} string "Poll not found" 105 | // @Failure 500 {object} string "Server error" 106 | // @Router /poll/{id} [delete] 107 | // @Security BearerAuth 108 | func (h *HTTPHandler) DeletePoll(c *gin.Context) { 109 | id := c.Param("id") 110 | req := pb.ByID{Id: id} 111 | 112 | _, err := h.Poll.Delete(context.Background(), &req) 113 | if err != nil { 114 | c.JSON(http.StatusInternalServerError, gin.H{"error": "Server error", "details": err.Error()}) 115 | return 116 | } 117 | 118 | c.JSON(http.StatusOK, gin.H{"message": "Successfully deleted!"}) 119 | } 120 | 121 | // GetPollByID godoc 122 | // @Summary Get a poll by ID 123 | // @Description Get a poll by its ID 124 | // @Tags polls 125 | // @Accept json 126 | // @Produce json 127 | // @Param id path string true "Poll ID" 128 | // @Success 200 {object} pb.PollGetByIDRes 129 | // @Failure 404 {object} string "Poll not found" 130 | // @Failure 500 {object} string "Server error" 131 | // @Router /poll/{id} [get] 132 | // @Security BearerAuth 133 | func (h *HTTPHandler) GetPollByID(c *gin.Context) { 134 | id := c.Param("id") 135 | req := pb.ByID{Id: id} 136 | 137 | res, err := h.Poll.GetByID(context.Background(), &req) 138 | if err != nil { 139 | c.JSON(http.StatusInternalServerError, gin.H{"error": "Server error", "details": err.Error()}) 140 | return 141 | } 142 | 143 | c.JSON(http.StatusOK, res) 144 | } 145 | 146 | // GetAllPolls godoc 147 | // @Summary Get all polls 148 | // @Description Get all polls with pagination 149 | // @Tags polls 150 | // @Accept json 151 | // @Produce json 152 | // @Success 200 {object} pb.PollGetAllRes 153 | // @Failure 500 {object} string "Server error" 154 | // @Router /polls [get] 155 | // @Security BearerAuth 156 | func (h *HTTPHandler) GetAllPolls(c *gin.Context) { 157 | var req pb.PollGetAllReq 158 | 159 | res, err := h.Poll.GetAll(context.Background(), &req) 160 | if err != nil { 161 | c.JSON(http.StatusInternalServerError, gin.H{"error": "Server error", "details": err.Error()}) 162 | return 163 | } 164 | c.JSON(http.StatusOK, res) 165 | } 166 | -------------------------------------------------------------------------------- /api-gateway/genprotos/void.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. DO NOT EDIT. 2 | // versions: 3 | // protoc-gen-go v1.34.2 4 | // protoc v3.12.4 5 | // source: protos/void.proto 6 | 7 | package genprotos 8 | 9 | import ( 10 | protoreflect "google.golang.org/protobuf/reflect/protoreflect" 11 | protoimpl "google.golang.org/protobuf/runtime/protoimpl" 12 | reflect "reflect" 13 | sync "sync" 14 | ) 15 | 16 | const ( 17 | // Verify that this generated code is sufficiently up-to-date. 18 | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) 19 | // Verify that runtime/protoimpl is sufficiently up-to-date. 20 | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) 21 | ) 22 | 23 | type Void struct { 24 | state protoimpl.MessageState 25 | sizeCache protoimpl.SizeCache 26 | unknownFields protoimpl.UnknownFields 27 | } 28 | 29 | func (x *Void) Reset() { 30 | *x = Void{} 31 | if protoimpl.UnsafeEnabled { 32 | mi := &file_protos_void_proto_msgTypes[0] 33 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 34 | ms.StoreMessageInfo(mi) 35 | } 36 | } 37 | 38 | func (x *Void) String() string { 39 | return protoimpl.X.MessageStringOf(x) 40 | } 41 | 42 | func (*Void) ProtoMessage() {} 43 | 44 | func (x *Void) ProtoReflect() protoreflect.Message { 45 | mi := &file_protos_void_proto_msgTypes[0] 46 | if protoimpl.UnsafeEnabled && x != nil { 47 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 48 | if ms.LoadMessageInfo() == nil { 49 | ms.StoreMessageInfo(mi) 50 | } 51 | return ms 52 | } 53 | return mi.MessageOf(x) 54 | } 55 | 56 | // Deprecated: Use Void.ProtoReflect.Descriptor instead. 57 | func (*Void) Descriptor() ([]byte, []int) { 58 | return file_protos_void_proto_rawDescGZIP(), []int{0} 59 | } 60 | 61 | type ByID struct { 62 | state protoimpl.MessageState 63 | sizeCache protoimpl.SizeCache 64 | unknownFields protoimpl.UnknownFields 65 | 66 | Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` 67 | } 68 | 69 | func (x *ByID) Reset() { 70 | *x = ByID{} 71 | if protoimpl.UnsafeEnabled { 72 | mi := &file_protos_void_proto_msgTypes[1] 73 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 74 | ms.StoreMessageInfo(mi) 75 | } 76 | } 77 | 78 | func (x *ByID) String() string { 79 | return protoimpl.X.MessageStringOf(x) 80 | } 81 | 82 | func (*ByID) ProtoMessage() {} 83 | 84 | func (x *ByID) ProtoReflect() protoreflect.Message { 85 | mi := &file_protos_void_proto_msgTypes[1] 86 | if protoimpl.UnsafeEnabled && x != nil { 87 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 88 | if ms.LoadMessageInfo() == nil { 89 | ms.StoreMessageInfo(mi) 90 | } 91 | return ms 92 | } 93 | return mi.MessageOf(x) 94 | } 95 | 96 | // Deprecated: Use ByID.ProtoReflect.Descriptor instead. 97 | func (*ByID) Descriptor() ([]byte, []int) { 98 | return file_protos_void_proto_rawDescGZIP(), []int{1} 99 | } 100 | 101 | func (x *ByID) GetId() string { 102 | if x != nil { 103 | return x.Id 104 | } 105 | return "" 106 | } 107 | 108 | var File_protos_void_proto protoreflect.FileDescriptor 109 | 110 | var file_protos_void_proto_rawDesc = []byte{ 111 | 0x0a, 0x11, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x76, 0x6f, 0x69, 0x64, 0x2e, 0x70, 0x72, 112 | 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x70, 0x6f, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x22, 0x06, 0x0a, 0x04, 113 | 0x56, 0x6f, 0x69, 0x64, 0x22, 0x16, 0x0a, 0x04, 0x42, 0x79, 0x49, 0x44, 0x12, 0x0e, 0x0a, 0x02, 114 | 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x42, 0x0c, 0x5a, 0x0a, 115 | 0x67, 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 116 | 0x6f, 0x33, 117 | } 118 | 119 | var ( 120 | file_protos_void_proto_rawDescOnce sync.Once 121 | file_protos_void_proto_rawDescData = file_protos_void_proto_rawDesc 122 | ) 123 | 124 | func file_protos_void_proto_rawDescGZIP() []byte { 125 | file_protos_void_proto_rawDescOnce.Do(func() { 126 | file_protos_void_proto_rawDescData = protoimpl.X.CompressGZIP(file_protos_void_proto_rawDescData) 127 | }) 128 | return file_protos_void_proto_rawDescData 129 | } 130 | 131 | var file_protos_void_proto_msgTypes = make([]protoimpl.MessageInfo, 2) 132 | var file_protos_void_proto_goTypes = []any{ 133 | (*Void)(nil), // 0: polling.Void 134 | (*ByID)(nil), // 1: polling.ByID 135 | } 136 | var file_protos_void_proto_depIdxs = []int32{ 137 | 0, // [0:0] is the sub-list for method output_type 138 | 0, // [0:0] is the sub-list for method input_type 139 | 0, // [0:0] is the sub-list for extension type_name 140 | 0, // [0:0] is the sub-list for extension extendee 141 | 0, // [0:0] is the sub-list for field type_name 142 | } 143 | 144 | func init() { file_protos_void_proto_init() } 145 | func file_protos_void_proto_init() { 146 | if File_protos_void_proto != nil { 147 | return 148 | } 149 | if !protoimpl.UnsafeEnabled { 150 | file_protos_void_proto_msgTypes[0].Exporter = func(v any, i int) any { 151 | switch v := v.(*Void); i { 152 | case 0: 153 | return &v.state 154 | case 1: 155 | return &v.sizeCache 156 | case 2: 157 | return &v.unknownFields 158 | default: 159 | return nil 160 | } 161 | } 162 | file_protos_void_proto_msgTypes[1].Exporter = func(v any, i int) any { 163 | switch v := v.(*ByID); i { 164 | case 0: 165 | return &v.state 166 | case 1: 167 | return &v.sizeCache 168 | case 2: 169 | return &v.unknownFields 170 | default: 171 | return nil 172 | } 173 | } 174 | } 175 | type x struct{} 176 | out := protoimpl.TypeBuilder{ 177 | File: protoimpl.DescBuilder{ 178 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), 179 | RawDescriptor: file_protos_void_proto_rawDesc, 180 | NumEnums: 0, 181 | NumMessages: 2, 182 | NumExtensions: 0, 183 | NumServices: 0, 184 | }, 185 | GoTypes: file_protos_void_proto_goTypes, 186 | DependencyIndexes: file_protos_void_proto_depIdxs, 187 | MessageInfos: file_protos_void_proto_msgTypes, 188 | }.Build() 189 | File_protos_void_proto = out.File 190 | file_protos_void_proto_rawDesc = nil 191 | file_protos_void_proto_goTypes = nil 192 | file_protos_void_proto_depIdxs = nil 193 | } 194 | -------------------------------------------------------------------------------- /polling/genprotos/void.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. DO NOT EDIT. 2 | // versions: 3 | // protoc-gen-go v1.34.2 4 | // protoc v3.12.4 5 | // source: protos/void.proto 6 | 7 | package genprotos 8 | 9 | import ( 10 | protoreflect "google.golang.org/protobuf/reflect/protoreflect" 11 | protoimpl "google.golang.org/protobuf/runtime/protoimpl" 12 | reflect "reflect" 13 | sync "sync" 14 | ) 15 | 16 | const ( 17 | // Verify that this generated code is sufficiently up-to-date. 18 | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) 19 | // Verify that runtime/protoimpl is sufficiently up-to-date. 20 | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) 21 | ) 22 | 23 | type Void struct { 24 | state protoimpl.MessageState 25 | sizeCache protoimpl.SizeCache 26 | unknownFields protoimpl.UnknownFields 27 | } 28 | 29 | func (x *Void) Reset() { 30 | *x = Void{} 31 | if protoimpl.UnsafeEnabled { 32 | mi := &file_protos_void_proto_msgTypes[0] 33 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 34 | ms.StoreMessageInfo(mi) 35 | } 36 | } 37 | 38 | func (x *Void) String() string { 39 | return protoimpl.X.MessageStringOf(x) 40 | } 41 | 42 | func (*Void) ProtoMessage() {} 43 | 44 | func (x *Void) ProtoReflect() protoreflect.Message { 45 | mi := &file_protos_void_proto_msgTypes[0] 46 | if protoimpl.UnsafeEnabled && x != nil { 47 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 48 | if ms.LoadMessageInfo() == nil { 49 | ms.StoreMessageInfo(mi) 50 | } 51 | return ms 52 | } 53 | return mi.MessageOf(x) 54 | } 55 | 56 | // Deprecated: Use Void.ProtoReflect.Descriptor instead. 57 | func (*Void) Descriptor() ([]byte, []int) { 58 | return file_protos_void_proto_rawDescGZIP(), []int{0} 59 | } 60 | 61 | type ByID struct { 62 | state protoimpl.MessageState 63 | sizeCache protoimpl.SizeCache 64 | unknownFields protoimpl.UnknownFields 65 | 66 | Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` 67 | } 68 | 69 | func (x *ByID) Reset() { 70 | *x = ByID{} 71 | if protoimpl.UnsafeEnabled { 72 | mi := &file_protos_void_proto_msgTypes[1] 73 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 74 | ms.StoreMessageInfo(mi) 75 | } 76 | } 77 | 78 | func (x *ByID) String() string { 79 | return protoimpl.X.MessageStringOf(x) 80 | } 81 | 82 | func (*ByID) ProtoMessage() {} 83 | 84 | func (x *ByID) ProtoReflect() protoreflect.Message { 85 | mi := &file_protos_void_proto_msgTypes[1] 86 | if protoimpl.UnsafeEnabled && x != nil { 87 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 88 | if ms.LoadMessageInfo() == nil { 89 | ms.StoreMessageInfo(mi) 90 | } 91 | return ms 92 | } 93 | return mi.MessageOf(x) 94 | } 95 | 96 | // Deprecated: Use ByID.ProtoReflect.Descriptor instead. 97 | func (*ByID) Descriptor() ([]byte, []int) { 98 | return file_protos_void_proto_rawDescGZIP(), []int{1} 99 | } 100 | 101 | func (x *ByID) GetId() string { 102 | if x != nil { 103 | return x.Id 104 | } 105 | return "" 106 | } 107 | 108 | var File_protos_void_proto protoreflect.FileDescriptor 109 | 110 | var file_protos_void_proto_rawDesc = []byte{ 111 | 0x0a, 0x11, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x76, 0x6f, 0x69, 0x64, 0x2e, 0x70, 0x72, 112 | 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x70, 0x6f, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x22, 0x06, 0x0a, 0x04, 113 | 0x56, 0x6f, 0x69, 0x64, 0x22, 0x16, 0x0a, 0x04, 0x42, 0x79, 0x49, 0x44, 0x12, 0x0e, 0x0a, 0x02, 114 | 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x42, 0x0c, 0x5a, 0x0a, 115 | 0x67, 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 116 | 0x6f, 0x33, 117 | } 118 | 119 | var ( 120 | file_protos_void_proto_rawDescOnce sync.Once 121 | file_protos_void_proto_rawDescData = file_protos_void_proto_rawDesc 122 | ) 123 | 124 | func file_protos_void_proto_rawDescGZIP() []byte { 125 | file_protos_void_proto_rawDescOnce.Do(func() { 126 | file_protos_void_proto_rawDescData = protoimpl.X.CompressGZIP(file_protos_void_proto_rawDescData) 127 | }) 128 | return file_protos_void_proto_rawDescData 129 | } 130 | 131 | var file_protos_void_proto_msgTypes = make([]protoimpl.MessageInfo, 2) 132 | var file_protos_void_proto_goTypes = []any{ 133 | (*Void)(nil), // 0: polling.Void 134 | (*ByID)(nil), // 1: polling.ByID 135 | } 136 | var file_protos_void_proto_depIdxs = []int32{ 137 | 0, // [0:0] is the sub-list for method output_type 138 | 0, // [0:0] is the sub-list for method input_type 139 | 0, // [0:0] is the sub-list for extension type_name 140 | 0, // [0:0] is the sub-list for extension extendee 141 | 0, // [0:0] is the sub-list for field type_name 142 | } 143 | 144 | func init() { file_protos_void_proto_init() } 145 | func file_protos_void_proto_init() { 146 | if File_protos_void_proto != nil { 147 | return 148 | } 149 | if !protoimpl.UnsafeEnabled { 150 | file_protos_void_proto_msgTypes[0].Exporter = func(v any, i int) any { 151 | switch v := v.(*Void); i { 152 | case 0: 153 | return &v.state 154 | case 1: 155 | return &v.sizeCache 156 | case 2: 157 | return &v.unknownFields 158 | default: 159 | return nil 160 | } 161 | } 162 | file_protos_void_proto_msgTypes[1].Exporter = func(v any, i int) any { 163 | switch v := v.(*ByID); i { 164 | case 0: 165 | return &v.state 166 | case 1: 167 | return &v.sizeCache 168 | case 2: 169 | return &v.unknownFields 170 | default: 171 | return nil 172 | } 173 | } 174 | } 175 | type x struct{} 176 | out := protoimpl.TypeBuilder{ 177 | File: protoimpl.DescBuilder{ 178 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), 179 | RawDescriptor: file_protos_void_proto_rawDesc, 180 | NumEnums: 0, 181 | NumMessages: 2, 182 | NumExtensions: 0, 183 | NumServices: 0, 184 | }, 185 | GoTypes: file_protos_void_proto_goTypes, 186 | DependencyIndexes: file_protos_void_proto_depIdxs, 187 | MessageInfos: file_protos_void_proto_msgTypes, 188 | }.Build() 189 | File_protos_void_proto = out.File 190 | file_protos_void_proto_rawDesc = nil 191 | file_protos_void_proto_goTypes = nil 192 | file_protos_void_proto_depIdxs = nil 193 | } 194 | -------------------------------------------------------------------------------- /api-gateway/api/handlers/auth.go: -------------------------------------------------------------------------------- 1 | package handlers 2 | 3 | import ( 4 | "auth-service/api/token" 5 | "auth-service/config" 6 | "auth-service/models" 7 | // "context" 8 | "net/http" 9 | 10 | pb "auth-service/genprotos" 11 | 12 | "github.com/gin-gonic/gin" 13 | // "github.com/go-redis/redis" 14 | "github.com/golang-jwt/jwt" 15 | _ "github.com/swaggo/swag" 16 | ) 17 | 18 | // Register godoc 19 | // @Summary Register a new user 20 | // @Description Register a new user with email, username, and password 21 | // @Tags registration 22 | // @Accept json 23 | // @Produce json 24 | // @Param user body pb.RegisterReqForSwagger true "User registration request" 25 | // @Success 201 {object} token.Tokens "JWT tokens" 26 | // @Failure 400 {object} string "Invalid request payload" 27 | // @Failure 500 {object} string "Server error" 28 | // @Router /register [post] 29 | func (h *HTTPHandler) Register(c *gin.Context) { 30 | var req pb.RegisterReqForSwagger 31 | if err := c.BindJSON(&req); err != nil { 32 | c.JSON(http.StatusBadRequest, gin.H{"Invalid request payload": err.Error()}) 33 | return 34 | } 35 | 36 | if !config.IsValidEmail(req.Email) { 37 | c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid email format"}) 38 | return 39 | } 40 | 41 | if _, err := h.User.IsEmailExists(c, &pb.IsEmailExistsReq{Email: req.Email}); err != nil { 42 | c.JSON(http.StatusBadRequest, gin.H{"message": "Email already registered", "error": "email"}) 43 | return 44 | } 45 | 46 | if err := config.IsValidPassword(req.Password); err != nil { 47 | c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) 48 | return 49 | } 50 | 51 | hashedPassword, err := config.HashPassword(req.Password) 52 | if err != nil { 53 | c.JSON(http.StatusInternalServerError, gin.H{"error": "Server error", "err": err.Error()}) 54 | return 55 | } 56 | 57 | req.Password = string(hashedPassword) 58 | 59 | var gender int 60 | if req.Gender == "male" { 61 | gender = 0 62 | } else if req.Gender == "female" { 63 | gender = 1 64 | } else { 65 | c.JSON(400, gin.H{"message": "Invalid gender format", "error": "gender"}) 66 | return 67 | } 68 | 69 | // err = h.SendConfirmationCode(req.Email) 70 | // if err != nil { 71 | // c.JSON(http.StatusInternalServerError, gin.H{"error": "Server error sending confirmation code", "err": err.Error()}) 72 | // return 73 | // } 74 | 75 | _, err = h.User.Register(c, 76 | &pb.RegisterReq{ 77 | Name: req.Name, 78 | Surname: req.Surname, 79 | Gender: pb.GenderType(gender), 80 | Age: req.Age, 81 | Nation: req.Nation, 82 | Email: req.Email, 83 | Password: req.Password, 84 | PhoneNumber: req.PhoneNumber, 85 | WorkingExperience: req.WorkingExperience, 86 | LevelType: req.LevelType, 87 | }) 88 | if err != nil { 89 | c.JSON(http.StatusInternalServerError, gin.H{"error": "Server error", "err": err.Error()}) 90 | return 91 | } 92 | c.JSON(http.StatusOK, gin.H{"message": "Successfully registered."}) 93 | } 94 | 95 | // // ConfirmRegistration godoc 96 | // // @Summary Confirm registration with code 97 | // // @Description Confirms a user's registration using the code sent to their email. 98 | // // @Tags registration 99 | // // @Accept json 100 | // // @Produce json 101 | // // @Param confirmation body models.ConfirmRegistrationReq true "Confirmation request" 102 | // // @Success 200 {object} token.Tokens "JWT tokens" 103 | // // @Failure 400 {object} string "Invalid request payload" 104 | // // @Failure 401 {object} string "Incorrect verification code" 105 | // // @Failure 404 {object} string "Verification code expired or email not found" 106 | // // @Router /confirm-registration [post] 107 | // func (h *HTTPHandler) ConfirmRegistration(c *gin.Context) { 108 | // var req models.ConfirmRegistrationReq 109 | // if err := c.BindJSON(&req); err != nil { 110 | // c.JSON(http.StatusBadRequest, gin.H{"Invalid request payload": err.Error()}) 111 | // return 112 | // } 113 | 114 | // // storedCode, err := rdb.Get(context.Background(), req.Email).Result() 115 | // // if err == redis.Nil { 116 | // // c.JSON(http.StatusNotFound, gin.H{"message": "Verification code expired or email not found", "error": "code"}) 117 | // // return 118 | // // } else if err != nil { 119 | // // c.JSON(http.StatusInternalServerError, gin.H{"message": "This email not found in confirmation requests!", "error": "email"}) 120 | // // return 121 | // // } 122 | 123 | // // if storedCode != req.Code { 124 | // // c.JSON(http.StatusUnauthorized, gin.H{"message": "Incorrect verification code", "error": "code"}) 125 | // // return 126 | // // } 127 | 128 | // // _, err = h.User.ConfirmUser(c, &pb.ConfirmUserReq{Email: req.Email}) 129 | // // if err != nil { 130 | // // c.JSON(http.StatusInternalServerError, gin.H{"error": "Error confirming user", "details": err.Error()}) 131 | // // return 132 | // // } 133 | 134 | // user, err := h.User.Profile(c, &pb.GetProfileReq{Email: req.Email}) 135 | // if err != nil { 136 | // c.JSON(http.StatusInternalServerError, gin.H{"error": "Error fetching user", "details": err.Error()}) 137 | // return 138 | // } 139 | 140 | // tokens := token.GenerateJWTToken(user.Id, user.Email, user.Role) 141 | 142 | // // rdb.Del(context.Background(), req.Email) 143 | 144 | // c.JSON(http.StatusOK, tokens) 145 | // } 146 | 147 | // Login godoc 148 | // @Summary Login a user 149 | // @Description Authenticate user with email and password 150 | // @Tags login 151 | // @Accept json 152 | // @Produce json 153 | // @Param credentials body models.LoginReq true "User login credentials" 154 | // @Success 200 {object} token.Tokens "JWT tokens" 155 | // @Failure 400 {object} string "Invalid request payload" 156 | // @Failure 401 {object} string "Invalid email or password" 157 | // @Router /login [post] 158 | func (h *HTTPHandler) Login(c *gin.Context) { 159 | req := models.LoginReq{} 160 | if err := c.BindJSON(&req); err != nil { 161 | c.JSON(http.StatusBadRequest, gin.H{"Invalid request payload": err.Error()}) 162 | return 163 | } 164 | 165 | user, err := h.User.Profile(c, &pb.GetProfileReq{Email: req.Email}) 166 | if err != nil { 167 | c.JSON(http.StatusUnauthorized, gin.H{"message": "User registered with this email not found", "error": "email"}) 168 | return 169 | } 170 | 171 | if !config.CheckPasswordHash(req.Password, user.Password) { 172 | c.JSON(http.StatusUnauthorized, gin.H{"message": "Invalid password", "error": "password"}) 173 | return 174 | } 175 | 176 | // if !user.IsConfirmed { 177 | // err = h.SendConfirmationCode(req.Email) 178 | // if err != nil { 179 | // c.JSON(http.StatusInternalServerError, gin.H{"error": "Server error sending confirmation code", "err": err.Error()}) 180 | // return 181 | // } 182 | 183 | // c.JSON(http.StatusUnauthorized, gin.H{"error": "Your account is not verified. Please check your email for a confirmation link."}) 184 | // return 185 | // } 186 | 187 | tokens := token.GenerateJWTToken(user.Id, user.Email, user.Role) 188 | 189 | c.JSON(http.StatusOK, tokens) 190 | } 191 | 192 | // GetProfile godoc 193 | // @Summary Get user profile 194 | // @Description Get the profile of the authenticated user 195 | // @Tags user 196 | // @Accept json 197 | // @Produce json 198 | // @Success 200 {object} models.GetProfileResp 199 | // @Failure 401 {object} string "Unauthorized" 200 | // @Failure 404 {object} string "User not found" 201 | // @Failure 500 {object} string "Server error" 202 | // @Security BearerAuth 203 | // @Router /profile [get] 204 | func (h *HTTPHandler) Profile(c *gin.Context) { 205 | claims, exists := c.Get("claims") 206 | if !exists { 207 | c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"}) 208 | return 209 | } 210 | 211 | email := claims.(jwt.MapClaims)["email"].(string) 212 | user, err := h.User.Profile(c, &pb.GetProfileReq{Email: email}) 213 | if err != nil { 214 | c.JSON(http.StatusInternalServerError, gin.H{"Server error": err.Error()}) 215 | return 216 | } 217 | 218 | if user == nil { 219 | c.JSON(http.StatusNotFound, gin.H{"error": "User not found"}) 220 | return 221 | } 222 | 223 | c.JSON(http.StatusOK, user) 224 | } 225 | 226 | func (h *HTTPHandler) GetByID(c *gin.Context) { 227 | id := &models.GetProfileByIdReq{ID: c.Param("id")} 228 | user, err := h.User.GetByID(c, &pb.GetProfileByIdReq{Id: id.ID}) 229 | if err != nil { 230 | c.JSON(http.StatusInternalServerError, gin.H{"Couldn't get the user": err.Error()}) 231 | return 232 | } 233 | c.JSON(http.StatusOK, user) 234 | } 235 | -------------------------------------------------------------------------------- /polling/storage/managers/poll.go: -------------------------------------------------------------------------------- 1 | package managers 2 | 3 | import ( 4 | "context" 5 | "database/sql" 6 | "encoding/json" 7 | "fmt" 8 | pb "poll-service/genprotos" 9 | ) 10 | 11 | type PollManager struct { 12 | Conn *sql.DB 13 | } 14 | 15 | func NewPollManager(conn *sql.DB) *PollManager { 16 | return &PollManager{Conn: conn} 17 | } 18 | 19 | func (m *PollManager) Create(ctx context.Context, poll *pb.PollCreateReq) (*pb.Void, error) { 20 | query := "SELECT insert_poll($1, $2, $3, $4)" 21 | optionsJSON, err := json.Marshal(poll.Options) 22 | if err != nil { 23 | return nil, fmt.Errorf("failed to marshal options to JSON: %w", err) 24 | } 25 | feedbackJSON, err := json.Marshal(poll.Feedbacks) 26 | if err != nil { 27 | return nil, fmt.Errorf("failed to marshal feedback to JSON: %w", err) 28 | } 29 | 30 | _, err = m.Conn.ExecContext(ctx, query, poll.Title, poll.Subtitle, optionsJSON, feedbackJSON) 31 | if err != nil { 32 | return nil, fmt.Errorf("failed to create poll: %w", err) 33 | } 34 | return &pb.Void{}, nil 35 | } 36 | 37 | func (m *PollManager) Update(ctx context.Context, poll *pb.PollUpdateReq) (*pb.Void, error) { 38 | // Eski pollni bazadan olish 39 | var existingPoll struct { 40 | Title string `db:"title"` 41 | Subtitle string `db:"subtitle"` 42 | Options json.RawMessage `db:"options"` 43 | Feedbacks json.RawMessage `db:"feedbacks"` 44 | } 45 | err := m.Conn.QueryRowContext(ctx, "SELECT title, subtitle, options, feedbacks FROM polls WHERE id = $1", poll.Id).Scan(&existingPoll.Title, &existingPoll.Subtitle, &existingPoll.Options, &existingPoll.Feedbacks) 46 | if err != nil { 47 | return nil, fmt.Errorf("failed to get existing poll: %w", err) 48 | } 49 | // Title yangilash yoki eski title saqlash 50 | title := poll.Title 51 | if title == nil { 52 | title = &existingPoll.Title 53 | } 54 | 55 | // Subtitle yangilash yoki eski subtitle saqlash 56 | subtitle := poll.Subtitle 57 | if subtitle == nil { 58 | subtitle = &existingPoll.Subtitle 59 | } 60 | 61 | // Options yangilash yoki eski options saqlash 62 | options := poll.Options 63 | if len(options) == 0 { 64 | options = []*pb.Option{} 65 | json.Unmarshal(existingPoll.Options, &options) 66 | } 67 | 68 | // Feedbacks yangilash yoki eski feedbacks saqlash 69 | feedbacks := poll.Feedbacks 70 | if len(feedbacks) == 0 { 71 | feedbacks = []*pb.Feedback{} 72 | json.Unmarshal(existingPoll.Feedbacks, &feedbacks) 73 | } 74 | 75 | // Yangilangan options va feedbacklarni JSON formatida saqlash 76 | optionsJSON, err := json.Marshal(options) 77 | if err != nil { 78 | return nil, fmt.Errorf("failed to marshal options: %w", err) 79 | } 80 | 81 | feedbacksJSON, err := json.Marshal(feedbacks) 82 | if err != nil { 83 | return nil, fmt.Errorf("failed to marshal feedbacks: %w", err) 84 | } 85 | 86 | // Yangilanishni amalga oshirish 87 | query := ` 88 | UPDATE polls 89 | SET title = $1, subtitle = $2, options = $3, feedbacks = $4 90 | WHERE id = $5 91 | ` 92 | _, err = m.Conn.ExecContext(ctx, query, title, subtitle, optionsJSON, feedbacksJSON, poll.Id) 93 | if err != nil { 94 | return nil, fmt.Errorf("failed to update poll: %w", err) 95 | } 96 | 97 | return &pb.Void{}, nil 98 | } 99 | 100 | func (m *PollManager) GetByID(ctx context.Context, req *pb.ByID) (*pb.PollGetByIDRes, error) { 101 | query := "SELECT id, poll_num, title, subtitle, options, feedbacks FROM polls WHERE id = $1" 102 | row := m.Conn.QueryRowContext(ctx, query, req.Id) 103 | var ( 104 | id string 105 | pollNum int32 106 | title string 107 | subtitle string 108 | options []byte 109 | feedbacks []byte 110 | ) 111 | 112 | err := row.Scan(&id, &pollNum, &title, &subtitle, &options, &feedbacks) 113 | fmt.Println("databaza>>>>>>>>>>>>>", row) 114 | if err != nil { 115 | if err == sql.ErrNoRows { 116 | return nil, fmt.Errorf("poll not found: %w", err) 117 | } 118 | return nil, fmt.Errorf("failed to get poll by id: %w", err) 119 | } 120 | 121 | // Unmarshal Options JSON 122 | var optionList []*pb.Option 123 | if len(options) > 0 { 124 | var rawOptions []map[string]interface{} 125 | if err := json.Unmarshal(options, &rawOptions); err != nil { 126 | return nil, fmt.Errorf("failed to unmarshal options: %s", err.Error()) 127 | } 128 | 129 | for _, rawOption := range rawOptions { 130 | option := &pb.Option{} 131 | if variant, ok := rawOption["variant"].(string); ok { 132 | option.Variant = &variant 133 | } 134 | if ball, ok := rawOption["ball"].(float64); ok { 135 | ballInt := int32(ball) 136 | option.Ball = &ballInt 137 | } 138 | optionList = append(optionList, option) 139 | } 140 | } 141 | 142 | // Unmarshal Feedbacks JSON 143 | var feedbackList []*pb.Feedback 144 | if len(feedbacks) > 0 { 145 | fmt.Println("fedbak>>>>>>>>>",string(feedbacks)) 146 | var rawFeedbacks []map[string]interface{} 147 | if err := json.Unmarshal(feedbacks, &rawFeedbacks); err != nil { 148 | return nil, fmt.Errorf("failed to unmarshal feedbacks: %s", err.Error()) 149 | } 150 | 151 | for _, rawFeedback := range rawFeedbacks { 152 | feedback := &pb.Feedback{} 153 | if from, ok := rawFeedback["from"].(float64); ok { 154 | fromInt := int32(from) 155 | feedback.From = &fromInt 156 | } 157 | if to, ok := rawFeedback["to"].(float64); ok { 158 | toInt := int32(to) 159 | feedback.To = &toInt 160 | } 161 | if text, ok := rawFeedback["text"].(string); ok { 162 | feedback.Text = &text 163 | } 164 | feedbackList = append(feedbackList, feedback) 165 | } 166 | } 167 | fmt.Println("fedbaklistlari>>>>>>>>>", feedbackList) 168 | 169 | return &pb.PollGetByIDRes{ 170 | Id: &id, 171 | PollNum: &pollNum, 172 | Title: &title, 173 | Subtitle: &subtitle, 174 | Options: optionList, 175 | Feedback: feedbackList, 176 | }, nil 177 | } 178 | 179 | func (m *PollManager) Delete(ctx context.Context, req *pb.ByID) (*pb.Void, error) { 180 | query := "DELETE FROM polls WHERE id = $1" 181 | _, err := m.Conn.ExecContext(ctx, query, req.Id) 182 | if err != nil { 183 | return nil, fmt.Errorf("failed to delete poll: %w", err) 184 | } 185 | return &pb.Void{}, nil 186 | } 187 | 188 | // PollGetAll method with fixed JSON unmarshaling. 189 | func (m *PollManager) GetAll(ctx context.Context, req *pb.PollGetAllReq) (*pb.PollGetAllRes, error) { 190 | query := "SELECT id, poll_num, title, subtitle, options, feedbacks FROM polls WHERE 1 = 1" 191 | var args []interface{} 192 | paramIndex := 1 193 | 194 | // Agar user_id mavjud bo'lsa, shart qo'shish 195 | if req.UserId != nil && *req.UserId != "" { 196 | query += fmt.Sprintf(" AND user_id = $%d", paramIndex) 197 | args = append(args, *req.UserId) 198 | paramIndex++ 199 | } 200 | 201 | // So'rovni bajarish 202 | rows, err := m.Conn.QueryContext(ctx, query, args...) 203 | if err != nil { 204 | return nil, fmt.Errorf("failed to get all polls: %w", err) 205 | } 206 | defer rows.Close() 207 | 208 | var polls []*pb.PollGetByIDRes 209 | for rows.Next() { 210 | var ( 211 | id string 212 | pollNum int32 213 | title string 214 | subtitle string 215 | options []byte 216 | feedbacks []byte 217 | ) 218 | 219 | // Ma'lumotlarni o'qib olish 220 | err := rows.Scan(&id, &pollNum, &title, &subtitle, &options, &feedbacks) 221 | if err != nil { 222 | return nil, fmt.Errorf("failed to scan poll: %s", err.Error()) 223 | } 224 | 225 | // Optionsni JSON ob'ekti sifatida unmarshaling qilish 226 | var optionList []*pb.Option 227 | if len(options) > 0 { 228 | if err := json.Unmarshal(options, &optionList); err != nil { 229 | return nil, fmt.Errorf("failed to unmarshal options: %s", err.Error()) 230 | } 231 | } 232 | 233 | // Feedbacksni JSON ob'ekti sifatida unmarshaling qilish 234 | var feedbackList []*pb.Feedback 235 | if len(feedbacks) > 0 { 236 | if err := json.Unmarshal(feedbacks, &feedbackList); err != nil { 237 | return nil, fmt.Errorf("failed to unmarshal feedbacks: %s", err.Error()) 238 | } 239 | } 240 | 241 | // Har bir poll uchun javobni yig'ish 242 | polls = append(polls, &pb.PollGetByIDRes{ 243 | Id: &id, 244 | PollNum: &pollNum, 245 | Title: &title, 246 | Subtitle: &subtitle, 247 | Options: optionList, 248 | Feedback: feedbackList, 249 | }) 250 | } 251 | 252 | // Xatoliklarni tekshirish 253 | if err := rows.Err(); err != nil { 254 | return nil, fmt.Errorf("rows error: %s", err.Error()) 255 | } 256 | 257 | // Javobni qaytarish 258 | return &pb.PollGetAllRes{ 259 | Poll: polls, 260 | }, nil 261 | } 262 | 263 | -------------------------------------------------------------------------------- /polling/genprotos/result_grpc.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go-grpc. DO NOT EDIT. 2 | // versions: 3 | // - protoc-gen-go-grpc v1.4.0 4 | // - protoc v3.12.4 5 | // source: protos/result.proto 6 | 7 | package genprotos 8 | 9 | import ( 10 | context "context" 11 | grpc "google.golang.org/grpc" 12 | codes "google.golang.org/grpc/codes" 13 | status "google.golang.org/grpc/status" 14 | ) 15 | 16 | // This is a compile-time assertion to ensure that this generated file 17 | // is compatible with the grpc package it is being compiled against. 18 | // Requires gRPC-Go v1.62.0 or later. 19 | const _ = grpc.SupportPackageIsVersion8 20 | 21 | const ( 22 | ResultService_CreateResult_FullMethodName = "/polling.ResultService/CreateResult" 23 | ResultService_SavePollAnswer_FullMethodName = "/polling.ResultService/SavePollAnswer" 24 | ResultService_GetResultsInExcel_FullMethodName = "/polling.ResultService/GetResultsInExcel" 25 | ResultService_GetPollResults_FullMethodName = "/polling.ResultService/GetPollResults" 26 | ) 27 | 28 | // ResultServiceClient is the client API for ResultService service. 29 | // 30 | // 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. 31 | type ResultServiceClient interface { 32 | CreateResult(ctx context.Context, in *CreateResultReq, opts ...grpc.CallOption) (*CreateResultRes, error) 33 | SavePollAnswer(ctx context.Context, in *SavePollAnswerReq, opts ...grpc.CallOption) (*Void, error) 34 | GetResultsInExcel(ctx context.Context, in *Void, opts ...grpc.CallOption) (*ExcelResultsRes, error) 35 | GetPollResults(ctx context.Context, in *ByIDs, opts ...grpc.CallOption) (*ByIDResponse, error) 36 | } 37 | 38 | type resultServiceClient struct { 39 | cc grpc.ClientConnInterface 40 | } 41 | 42 | func NewResultServiceClient(cc grpc.ClientConnInterface) ResultServiceClient { 43 | return &resultServiceClient{cc} 44 | } 45 | 46 | func (c *resultServiceClient) CreateResult(ctx context.Context, in *CreateResultReq, opts ...grpc.CallOption) (*CreateResultRes, error) { 47 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 48 | out := new(CreateResultRes) 49 | err := c.cc.Invoke(ctx, ResultService_CreateResult_FullMethodName, in, out, cOpts...) 50 | if err != nil { 51 | return nil, err 52 | } 53 | return out, nil 54 | } 55 | 56 | func (c *resultServiceClient) SavePollAnswer(ctx context.Context, in *SavePollAnswerReq, opts ...grpc.CallOption) (*Void, error) { 57 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 58 | out := new(Void) 59 | err := c.cc.Invoke(ctx, ResultService_SavePollAnswer_FullMethodName, in, out, cOpts...) 60 | if err != nil { 61 | return nil, err 62 | } 63 | return out, nil 64 | } 65 | 66 | func (c *resultServiceClient) GetResultsInExcel(ctx context.Context, in *Void, opts ...grpc.CallOption) (*ExcelResultsRes, error) { 67 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 68 | out := new(ExcelResultsRes) 69 | err := c.cc.Invoke(ctx, ResultService_GetResultsInExcel_FullMethodName, in, out, cOpts...) 70 | if err != nil { 71 | return nil, err 72 | } 73 | return out, nil 74 | } 75 | 76 | func (c *resultServiceClient) GetPollResults(ctx context.Context, in *ByIDs, opts ...grpc.CallOption) (*ByIDResponse, error) { 77 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 78 | out := new(ByIDResponse) 79 | err := c.cc.Invoke(ctx, ResultService_GetPollResults_FullMethodName, in, out, cOpts...) 80 | if err != nil { 81 | return nil, err 82 | } 83 | return out, nil 84 | } 85 | 86 | // ResultServiceServer is the server API for ResultService service. 87 | // All implementations must embed UnimplementedResultServiceServer 88 | // for forward compatibility 89 | type ResultServiceServer interface { 90 | CreateResult(context.Context, *CreateResultReq) (*CreateResultRes, error) 91 | SavePollAnswer(context.Context, *SavePollAnswerReq) (*Void, error) 92 | GetResultsInExcel(context.Context, *Void) (*ExcelResultsRes, error) 93 | GetPollResults(context.Context, *ByIDs) (*ByIDResponse, error) 94 | mustEmbedUnimplementedResultServiceServer() 95 | } 96 | 97 | // UnimplementedResultServiceServer must be embedded to have forward compatible implementations. 98 | type UnimplementedResultServiceServer struct { 99 | } 100 | 101 | func (UnimplementedResultServiceServer) CreateResult(context.Context, *CreateResultReq) (*CreateResultRes, error) { 102 | return nil, status.Errorf(codes.Unimplemented, "method CreateResult not implemented") 103 | } 104 | func (UnimplementedResultServiceServer) SavePollAnswer(context.Context, *SavePollAnswerReq) (*Void, error) { 105 | return nil, status.Errorf(codes.Unimplemented, "method SavePollAnswer not implemented") 106 | } 107 | func (UnimplementedResultServiceServer) GetResultsInExcel(context.Context, *Void) (*ExcelResultsRes, error) { 108 | return nil, status.Errorf(codes.Unimplemented, "method GetResultsInExcel not implemented") 109 | } 110 | func (UnimplementedResultServiceServer) GetPollResults(context.Context, *ByIDs) (*ByIDResponse, error) { 111 | return nil, status.Errorf(codes.Unimplemented, "method GetPollResults not implemented") 112 | } 113 | func (UnimplementedResultServiceServer) mustEmbedUnimplementedResultServiceServer() {} 114 | 115 | // UnsafeResultServiceServer may be embedded to opt out of forward compatibility for this service. 116 | // Use of this interface is not recommended, as added methods to ResultServiceServer will 117 | // result in compilation errors. 118 | type UnsafeResultServiceServer interface { 119 | mustEmbedUnimplementedResultServiceServer() 120 | } 121 | 122 | func RegisterResultServiceServer(s grpc.ServiceRegistrar, srv ResultServiceServer) { 123 | s.RegisterService(&ResultService_ServiceDesc, srv) 124 | } 125 | 126 | func _ResultService_CreateResult_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 127 | in := new(CreateResultReq) 128 | if err := dec(in); err != nil { 129 | return nil, err 130 | } 131 | if interceptor == nil { 132 | return srv.(ResultServiceServer).CreateResult(ctx, in) 133 | } 134 | info := &grpc.UnaryServerInfo{ 135 | Server: srv, 136 | FullMethod: ResultService_CreateResult_FullMethodName, 137 | } 138 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 139 | return srv.(ResultServiceServer).CreateResult(ctx, req.(*CreateResultReq)) 140 | } 141 | return interceptor(ctx, in, info, handler) 142 | } 143 | 144 | func _ResultService_SavePollAnswer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 145 | in := new(SavePollAnswerReq) 146 | if err := dec(in); err != nil { 147 | return nil, err 148 | } 149 | if interceptor == nil { 150 | return srv.(ResultServiceServer).SavePollAnswer(ctx, in) 151 | } 152 | info := &grpc.UnaryServerInfo{ 153 | Server: srv, 154 | FullMethod: ResultService_SavePollAnswer_FullMethodName, 155 | } 156 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 157 | return srv.(ResultServiceServer).SavePollAnswer(ctx, req.(*SavePollAnswerReq)) 158 | } 159 | return interceptor(ctx, in, info, handler) 160 | } 161 | 162 | func _ResultService_GetResultsInExcel_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 163 | in := new(Void) 164 | if err := dec(in); err != nil { 165 | return nil, err 166 | } 167 | if interceptor == nil { 168 | return srv.(ResultServiceServer).GetResultsInExcel(ctx, in) 169 | } 170 | info := &grpc.UnaryServerInfo{ 171 | Server: srv, 172 | FullMethod: ResultService_GetResultsInExcel_FullMethodName, 173 | } 174 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 175 | return srv.(ResultServiceServer).GetResultsInExcel(ctx, req.(*Void)) 176 | } 177 | return interceptor(ctx, in, info, handler) 178 | } 179 | 180 | func _ResultService_GetPollResults_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 181 | in := new(ByIDs) 182 | if err := dec(in); err != nil { 183 | return nil, err 184 | } 185 | if interceptor == nil { 186 | return srv.(ResultServiceServer).GetPollResults(ctx, in) 187 | } 188 | info := &grpc.UnaryServerInfo{ 189 | Server: srv, 190 | FullMethod: ResultService_GetPollResults_FullMethodName, 191 | } 192 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 193 | return srv.(ResultServiceServer).GetPollResults(ctx, req.(*ByIDs)) 194 | } 195 | return interceptor(ctx, in, info, handler) 196 | } 197 | 198 | // ResultService_ServiceDesc is the grpc.ServiceDesc for ResultService service. 199 | // It's only intended for direct use with grpc.RegisterService, 200 | // and not to be introspected or modified (even as a copy) 201 | var ResultService_ServiceDesc = grpc.ServiceDesc{ 202 | ServiceName: "polling.ResultService", 203 | HandlerType: (*ResultServiceServer)(nil), 204 | Methods: []grpc.MethodDesc{ 205 | { 206 | MethodName: "CreateResult", 207 | Handler: _ResultService_CreateResult_Handler, 208 | }, 209 | { 210 | MethodName: "SavePollAnswer", 211 | Handler: _ResultService_SavePollAnswer_Handler, 212 | }, 213 | { 214 | MethodName: "GetResultsInExcel", 215 | Handler: _ResultService_GetResultsInExcel_Handler, 216 | }, 217 | { 218 | MethodName: "GetPollResults", 219 | Handler: _ResultService_GetPollResults_Handler, 220 | }, 221 | }, 222 | Streams: []grpc.StreamDesc{}, 223 | Metadata: "protos/result.proto", 224 | } 225 | -------------------------------------------------------------------------------- /api-gateway/genprotos/result_grpc.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go-grpc. DO NOT EDIT. 2 | // versions: 3 | // - protoc-gen-go-grpc v1.4.0 4 | // - protoc v3.12.4 5 | // source: protos/result.proto 6 | 7 | package genprotos 8 | 9 | import ( 10 | context "context" 11 | grpc "google.golang.org/grpc" 12 | codes "google.golang.org/grpc/codes" 13 | status "google.golang.org/grpc/status" 14 | ) 15 | 16 | // This is a compile-time assertion to ensure that this generated file 17 | // is compatible with the grpc package it is being compiled against. 18 | // Requires gRPC-Go v1.62.0 or later. 19 | const _ = grpc.SupportPackageIsVersion8 20 | 21 | const ( 22 | ResultService_CreateResult_FullMethodName = "/polling.ResultService/CreateResult" 23 | ResultService_SavePollAnswer_FullMethodName = "/polling.ResultService/SavePollAnswer" 24 | ResultService_GetResultsInExcel_FullMethodName = "/polling.ResultService/GetResultsInExcel" 25 | ResultService_GetPollResults_FullMethodName = "/polling.ResultService/GetPollResults" 26 | ) 27 | 28 | // ResultServiceClient is the client API for ResultService service. 29 | // 30 | // 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. 31 | type ResultServiceClient interface { 32 | CreateResult(ctx context.Context, in *CreateResultReq, opts ...grpc.CallOption) (*CreateResultRes, error) 33 | SavePollAnswer(ctx context.Context, in *SavePollAnswerReq, opts ...grpc.CallOption) (*Void, error) 34 | GetResultsInExcel(ctx context.Context, in *Void, opts ...grpc.CallOption) (*ExcelResultsRes, error) 35 | GetPollResults(ctx context.Context, in *ByIDs, opts ...grpc.CallOption) (*ByIDResponse, error) 36 | } 37 | 38 | type resultServiceClient struct { 39 | cc grpc.ClientConnInterface 40 | } 41 | 42 | func NewResultServiceClient(cc grpc.ClientConnInterface) ResultServiceClient { 43 | return &resultServiceClient{cc} 44 | } 45 | 46 | func (c *resultServiceClient) CreateResult(ctx context.Context, in *CreateResultReq, opts ...grpc.CallOption) (*CreateResultRes, error) { 47 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 48 | out := new(CreateResultRes) 49 | err := c.cc.Invoke(ctx, ResultService_CreateResult_FullMethodName, in, out, cOpts...) 50 | if err != nil { 51 | return nil, err 52 | } 53 | return out, nil 54 | } 55 | 56 | func (c *resultServiceClient) SavePollAnswer(ctx context.Context, in *SavePollAnswerReq, opts ...grpc.CallOption) (*Void, error) { 57 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 58 | out := new(Void) 59 | err := c.cc.Invoke(ctx, ResultService_SavePollAnswer_FullMethodName, in, out, cOpts...) 60 | if err != nil { 61 | return nil, err 62 | } 63 | return out, nil 64 | } 65 | 66 | func (c *resultServiceClient) GetResultsInExcel(ctx context.Context, in *Void, opts ...grpc.CallOption) (*ExcelResultsRes, error) { 67 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 68 | out := new(ExcelResultsRes) 69 | err := c.cc.Invoke(ctx, ResultService_GetResultsInExcel_FullMethodName, in, out, cOpts...) 70 | if err != nil { 71 | return nil, err 72 | } 73 | return out, nil 74 | } 75 | 76 | func (c *resultServiceClient) GetPollResults(ctx context.Context, in *ByIDs, opts ...grpc.CallOption) (*ByIDResponse, error) { 77 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 78 | out := new(ByIDResponse) 79 | err := c.cc.Invoke(ctx, ResultService_GetPollResults_FullMethodName, in, out, cOpts...) 80 | if err != nil { 81 | return nil, err 82 | } 83 | return out, nil 84 | } 85 | 86 | // ResultServiceServer is the server API for ResultService service. 87 | // All implementations must embed UnimplementedResultServiceServer 88 | // for forward compatibility 89 | type ResultServiceServer interface { 90 | CreateResult(context.Context, *CreateResultReq) (*CreateResultRes, error) 91 | SavePollAnswer(context.Context, *SavePollAnswerReq) (*Void, error) 92 | GetResultsInExcel(context.Context, *Void) (*ExcelResultsRes, error) 93 | GetPollResults(context.Context, *ByIDs) (*ByIDResponse, error) 94 | mustEmbedUnimplementedResultServiceServer() 95 | } 96 | 97 | // UnimplementedResultServiceServer must be embedded to have forward compatible implementations. 98 | type UnimplementedResultServiceServer struct { 99 | } 100 | 101 | func (UnimplementedResultServiceServer) CreateResult(context.Context, *CreateResultReq) (*CreateResultRes, error) { 102 | return nil, status.Errorf(codes.Unimplemented, "method CreateResult not implemented") 103 | } 104 | func (UnimplementedResultServiceServer) SavePollAnswer(context.Context, *SavePollAnswerReq) (*Void, error) { 105 | return nil, status.Errorf(codes.Unimplemented, "method SavePollAnswer not implemented") 106 | } 107 | func (UnimplementedResultServiceServer) GetResultsInExcel(context.Context, *Void) (*ExcelResultsRes, error) { 108 | return nil, status.Errorf(codes.Unimplemented, "method GetResultsInExcel not implemented") 109 | } 110 | func (UnimplementedResultServiceServer) GetPollResults(context.Context, *ByIDs) (*ByIDResponse, error) { 111 | return nil, status.Errorf(codes.Unimplemented, "method GetPollResults not implemented") 112 | } 113 | func (UnimplementedResultServiceServer) mustEmbedUnimplementedResultServiceServer() {} 114 | 115 | // UnsafeResultServiceServer may be embedded to opt out of forward compatibility for this service. 116 | // Use of this interface is not recommended, as added methods to ResultServiceServer will 117 | // result in compilation errors. 118 | type UnsafeResultServiceServer interface { 119 | mustEmbedUnimplementedResultServiceServer() 120 | } 121 | 122 | func RegisterResultServiceServer(s grpc.ServiceRegistrar, srv ResultServiceServer) { 123 | s.RegisterService(&ResultService_ServiceDesc, srv) 124 | } 125 | 126 | func _ResultService_CreateResult_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 127 | in := new(CreateResultReq) 128 | if err := dec(in); err != nil { 129 | return nil, err 130 | } 131 | if interceptor == nil { 132 | return srv.(ResultServiceServer).CreateResult(ctx, in) 133 | } 134 | info := &grpc.UnaryServerInfo{ 135 | Server: srv, 136 | FullMethod: ResultService_CreateResult_FullMethodName, 137 | } 138 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 139 | return srv.(ResultServiceServer).CreateResult(ctx, req.(*CreateResultReq)) 140 | } 141 | return interceptor(ctx, in, info, handler) 142 | } 143 | 144 | func _ResultService_SavePollAnswer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 145 | in := new(SavePollAnswerReq) 146 | if err := dec(in); err != nil { 147 | return nil, err 148 | } 149 | if interceptor == nil { 150 | return srv.(ResultServiceServer).SavePollAnswer(ctx, in) 151 | } 152 | info := &grpc.UnaryServerInfo{ 153 | Server: srv, 154 | FullMethod: ResultService_SavePollAnswer_FullMethodName, 155 | } 156 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 157 | return srv.(ResultServiceServer).SavePollAnswer(ctx, req.(*SavePollAnswerReq)) 158 | } 159 | return interceptor(ctx, in, info, handler) 160 | } 161 | 162 | func _ResultService_GetResultsInExcel_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 163 | in := new(Void) 164 | if err := dec(in); err != nil { 165 | return nil, err 166 | } 167 | if interceptor == nil { 168 | return srv.(ResultServiceServer).GetResultsInExcel(ctx, in) 169 | } 170 | info := &grpc.UnaryServerInfo{ 171 | Server: srv, 172 | FullMethod: ResultService_GetResultsInExcel_FullMethodName, 173 | } 174 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 175 | return srv.(ResultServiceServer).GetResultsInExcel(ctx, req.(*Void)) 176 | } 177 | return interceptor(ctx, in, info, handler) 178 | } 179 | 180 | func _ResultService_GetPollResults_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 181 | in := new(ByIDs) 182 | if err := dec(in); err != nil { 183 | return nil, err 184 | } 185 | if interceptor == nil { 186 | return srv.(ResultServiceServer).GetPollResults(ctx, in) 187 | } 188 | info := &grpc.UnaryServerInfo{ 189 | Server: srv, 190 | FullMethod: ResultService_GetPollResults_FullMethodName, 191 | } 192 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 193 | return srv.(ResultServiceServer).GetPollResults(ctx, req.(*ByIDs)) 194 | } 195 | return interceptor(ctx, in, info, handler) 196 | } 197 | 198 | // ResultService_ServiceDesc is the grpc.ServiceDesc for ResultService service. 199 | // It's only intended for direct use with grpc.RegisterService, 200 | // and not to be introspected or modified (even as a copy) 201 | var ResultService_ServiceDesc = grpc.ServiceDesc{ 202 | ServiceName: "polling.ResultService", 203 | HandlerType: (*ResultServiceServer)(nil), 204 | Methods: []grpc.MethodDesc{ 205 | { 206 | MethodName: "CreateResult", 207 | Handler: _ResultService_CreateResult_Handler, 208 | }, 209 | { 210 | MethodName: "SavePollAnswer", 211 | Handler: _ResultService_SavePollAnswer_Handler, 212 | }, 213 | { 214 | MethodName: "GetResultsInExcel", 215 | Handler: _ResultService_GetResultsInExcel_Handler, 216 | }, 217 | { 218 | MethodName: "GetPollResults", 219 | Handler: _ResultService_GetPollResults_Handler, 220 | }, 221 | }, 222 | Streams: []grpc.StreamDesc{}, 223 | Metadata: "protos/result.proto", 224 | } 225 | -------------------------------------------------------------------------------- /api-gateway/genprotos/poll_grpc.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go-grpc. DO NOT EDIT. 2 | // versions: 3 | // - protoc-gen-go-grpc v1.4.0 4 | // - protoc v3.12.4 5 | // source: protos/poll.proto 6 | 7 | package genprotos 8 | 9 | import ( 10 | context "context" 11 | grpc "google.golang.org/grpc" 12 | codes "google.golang.org/grpc/codes" 13 | status "google.golang.org/grpc/status" 14 | ) 15 | 16 | // This is a compile-time assertion to ensure that this generated file 17 | // is compatible with the grpc package it is being compiled against. 18 | // Requires gRPC-Go v1.62.0 or later. 19 | const _ = grpc.SupportPackageIsVersion8 20 | 21 | const ( 22 | PollService_Create_FullMethodName = "/polling.PollService/Create" 23 | PollService_Update_FullMethodName = "/polling.PollService/Update" 24 | PollService_Delete_FullMethodName = "/polling.PollService/Delete" 25 | PollService_GetByID_FullMethodName = "/polling.PollService/GetByID" 26 | PollService_GetAll_FullMethodName = "/polling.PollService/GetAll" 27 | ) 28 | 29 | // PollServiceClient is the client API for PollService service. 30 | // 31 | // 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. 32 | type PollServiceClient interface { 33 | Create(ctx context.Context, in *PollCreateReq, opts ...grpc.CallOption) (*Void, error) 34 | Update(ctx context.Context, in *PollUpdateReq, opts ...grpc.CallOption) (*Void, error) 35 | Delete(ctx context.Context, in *ByID, opts ...grpc.CallOption) (*Void, error) 36 | GetByID(ctx context.Context, in *ByID, opts ...grpc.CallOption) (*PollGetByIDRes, error) 37 | GetAll(ctx context.Context, in *PollGetAllReq, opts ...grpc.CallOption) (*PollGetAllRes, error) 38 | } 39 | 40 | type pollServiceClient struct { 41 | cc grpc.ClientConnInterface 42 | } 43 | 44 | func NewPollServiceClient(cc grpc.ClientConnInterface) PollServiceClient { 45 | return &pollServiceClient{cc} 46 | } 47 | 48 | func (c *pollServiceClient) Create(ctx context.Context, in *PollCreateReq, opts ...grpc.CallOption) (*Void, error) { 49 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 50 | out := new(Void) 51 | err := c.cc.Invoke(ctx, PollService_Create_FullMethodName, in, out, cOpts...) 52 | if err != nil { 53 | return nil, err 54 | } 55 | return out, nil 56 | } 57 | 58 | func (c *pollServiceClient) Update(ctx context.Context, in *PollUpdateReq, opts ...grpc.CallOption) (*Void, error) { 59 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 60 | out := new(Void) 61 | err := c.cc.Invoke(ctx, PollService_Update_FullMethodName, in, out, cOpts...) 62 | if err != nil { 63 | return nil, err 64 | } 65 | return out, nil 66 | } 67 | 68 | func (c *pollServiceClient) Delete(ctx context.Context, in *ByID, opts ...grpc.CallOption) (*Void, error) { 69 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 70 | out := new(Void) 71 | err := c.cc.Invoke(ctx, PollService_Delete_FullMethodName, in, out, cOpts...) 72 | if err != nil { 73 | return nil, err 74 | } 75 | return out, nil 76 | } 77 | 78 | func (c *pollServiceClient) GetByID(ctx context.Context, in *ByID, opts ...grpc.CallOption) (*PollGetByIDRes, error) { 79 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 80 | out := new(PollGetByIDRes) 81 | err := c.cc.Invoke(ctx, PollService_GetByID_FullMethodName, in, out, cOpts...) 82 | if err != nil { 83 | return nil, err 84 | } 85 | return out, nil 86 | } 87 | 88 | func (c *pollServiceClient) GetAll(ctx context.Context, in *PollGetAllReq, opts ...grpc.CallOption) (*PollGetAllRes, error) { 89 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 90 | out := new(PollGetAllRes) 91 | err := c.cc.Invoke(ctx, PollService_GetAll_FullMethodName, in, out, cOpts...) 92 | if err != nil { 93 | return nil, err 94 | } 95 | return out, nil 96 | } 97 | 98 | // PollServiceServer is the server API for PollService service. 99 | // All implementations must embed UnimplementedPollServiceServer 100 | // for forward compatibility 101 | type PollServiceServer interface { 102 | Create(context.Context, *PollCreateReq) (*Void, error) 103 | Update(context.Context, *PollUpdateReq) (*Void, error) 104 | Delete(context.Context, *ByID) (*Void, error) 105 | GetByID(context.Context, *ByID) (*PollGetByIDRes, error) 106 | GetAll(context.Context, *PollGetAllReq) (*PollGetAllRes, error) 107 | mustEmbedUnimplementedPollServiceServer() 108 | } 109 | 110 | // UnimplementedPollServiceServer must be embedded to have forward compatible implementations. 111 | type UnimplementedPollServiceServer struct { 112 | } 113 | 114 | func (UnimplementedPollServiceServer) Create(context.Context, *PollCreateReq) (*Void, error) { 115 | return nil, status.Errorf(codes.Unimplemented, "method Create not implemented") 116 | } 117 | func (UnimplementedPollServiceServer) Update(context.Context, *PollUpdateReq) (*Void, error) { 118 | return nil, status.Errorf(codes.Unimplemented, "method Update not implemented") 119 | } 120 | func (UnimplementedPollServiceServer) Delete(context.Context, *ByID) (*Void, error) { 121 | return nil, status.Errorf(codes.Unimplemented, "method Delete not implemented") 122 | } 123 | func (UnimplementedPollServiceServer) GetByID(context.Context, *ByID) (*PollGetByIDRes, error) { 124 | return nil, status.Errorf(codes.Unimplemented, "method GetByID not implemented") 125 | } 126 | func (UnimplementedPollServiceServer) GetAll(context.Context, *PollGetAllReq) (*PollGetAllRes, error) { 127 | return nil, status.Errorf(codes.Unimplemented, "method GetAll not implemented") 128 | } 129 | func (UnimplementedPollServiceServer) mustEmbedUnimplementedPollServiceServer() {} 130 | 131 | // UnsafePollServiceServer may be embedded to opt out of forward compatibility for this service. 132 | // Use of this interface is not recommended, as added methods to PollServiceServer will 133 | // result in compilation errors. 134 | type UnsafePollServiceServer interface { 135 | mustEmbedUnimplementedPollServiceServer() 136 | } 137 | 138 | func RegisterPollServiceServer(s grpc.ServiceRegistrar, srv PollServiceServer) { 139 | s.RegisterService(&PollService_ServiceDesc, srv) 140 | } 141 | 142 | func _PollService_Create_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 143 | in := new(PollCreateReq) 144 | if err := dec(in); err != nil { 145 | return nil, err 146 | } 147 | if interceptor == nil { 148 | return srv.(PollServiceServer).Create(ctx, in) 149 | } 150 | info := &grpc.UnaryServerInfo{ 151 | Server: srv, 152 | FullMethod: PollService_Create_FullMethodName, 153 | } 154 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 155 | return srv.(PollServiceServer).Create(ctx, req.(*PollCreateReq)) 156 | } 157 | return interceptor(ctx, in, info, handler) 158 | } 159 | 160 | func _PollService_Update_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 161 | in := new(PollUpdateReq) 162 | if err := dec(in); err != nil { 163 | return nil, err 164 | } 165 | if interceptor == nil { 166 | return srv.(PollServiceServer).Update(ctx, in) 167 | } 168 | info := &grpc.UnaryServerInfo{ 169 | Server: srv, 170 | FullMethod: PollService_Update_FullMethodName, 171 | } 172 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 173 | return srv.(PollServiceServer).Update(ctx, req.(*PollUpdateReq)) 174 | } 175 | return interceptor(ctx, in, info, handler) 176 | } 177 | 178 | func _PollService_Delete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 179 | in := new(ByID) 180 | if err := dec(in); err != nil { 181 | return nil, err 182 | } 183 | if interceptor == nil { 184 | return srv.(PollServiceServer).Delete(ctx, in) 185 | } 186 | info := &grpc.UnaryServerInfo{ 187 | Server: srv, 188 | FullMethod: PollService_Delete_FullMethodName, 189 | } 190 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 191 | return srv.(PollServiceServer).Delete(ctx, req.(*ByID)) 192 | } 193 | return interceptor(ctx, in, info, handler) 194 | } 195 | 196 | func _PollService_GetByID_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 197 | in := new(ByID) 198 | if err := dec(in); err != nil { 199 | return nil, err 200 | } 201 | if interceptor == nil { 202 | return srv.(PollServiceServer).GetByID(ctx, in) 203 | } 204 | info := &grpc.UnaryServerInfo{ 205 | Server: srv, 206 | FullMethod: PollService_GetByID_FullMethodName, 207 | } 208 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 209 | return srv.(PollServiceServer).GetByID(ctx, req.(*ByID)) 210 | } 211 | return interceptor(ctx, in, info, handler) 212 | } 213 | 214 | func _PollService_GetAll_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 215 | in := new(PollGetAllReq) 216 | if err := dec(in); err != nil { 217 | return nil, err 218 | } 219 | if interceptor == nil { 220 | return srv.(PollServiceServer).GetAll(ctx, in) 221 | } 222 | info := &grpc.UnaryServerInfo{ 223 | Server: srv, 224 | FullMethod: PollService_GetAll_FullMethodName, 225 | } 226 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 227 | return srv.(PollServiceServer).GetAll(ctx, req.(*PollGetAllReq)) 228 | } 229 | return interceptor(ctx, in, info, handler) 230 | } 231 | 232 | // PollService_ServiceDesc is the grpc.ServiceDesc for PollService service. 233 | // It's only intended for direct use with grpc.RegisterService, 234 | // and not to be introspected or modified (even as a copy) 235 | var PollService_ServiceDesc = grpc.ServiceDesc{ 236 | ServiceName: "polling.PollService", 237 | HandlerType: (*PollServiceServer)(nil), 238 | Methods: []grpc.MethodDesc{ 239 | { 240 | MethodName: "Create", 241 | Handler: _PollService_Create_Handler, 242 | }, 243 | { 244 | MethodName: "Update", 245 | Handler: _PollService_Update_Handler, 246 | }, 247 | { 248 | MethodName: "Delete", 249 | Handler: _PollService_Delete_Handler, 250 | }, 251 | { 252 | MethodName: "GetByID", 253 | Handler: _PollService_GetByID_Handler, 254 | }, 255 | { 256 | MethodName: "GetAll", 257 | Handler: _PollService_GetAll_Handler, 258 | }, 259 | }, 260 | Streams: []grpc.StreamDesc{}, 261 | Metadata: "protos/poll.proto", 262 | } 263 | -------------------------------------------------------------------------------- /polling/genprotos/poll_grpc.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go-grpc. DO NOT EDIT. 2 | // versions: 3 | // - protoc-gen-go-grpc v1.4.0 4 | // - protoc v3.12.4 5 | // source: protos/poll.proto 6 | 7 | package genprotos 8 | 9 | import ( 10 | context "context" 11 | grpc "google.golang.org/grpc" 12 | codes "google.golang.org/grpc/codes" 13 | status "google.golang.org/grpc/status" 14 | ) 15 | 16 | // This is a compile-time assertion to ensure that this generated file 17 | // is compatible with the grpc package it is being compiled against. 18 | // Requires gRPC-Go v1.62.0 or later. 19 | const _ = grpc.SupportPackageIsVersion8 20 | 21 | const ( 22 | PollService_Create_FullMethodName = "/polling.PollService/Create" 23 | PollService_Update_FullMethodName = "/polling.PollService/Update" 24 | PollService_Delete_FullMethodName = "/polling.PollService/Delete" 25 | PollService_GetByID_FullMethodName = "/polling.PollService/GetByID" 26 | PollService_GetAll_FullMethodName = "/polling.PollService/GetAll" 27 | ) 28 | 29 | // PollServiceClient is the client API for PollService service. 30 | // 31 | // 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. 32 | type PollServiceClient interface { 33 | Create(ctx context.Context, in *PollCreateReq, opts ...grpc.CallOption) (*Void, error) 34 | Update(ctx context.Context, in *PollUpdateReq, opts ...grpc.CallOption) (*Void, error) 35 | Delete(ctx context.Context, in *ByID, opts ...grpc.CallOption) (*Void, error) 36 | GetByID(ctx context.Context, in *ByID, opts ...grpc.CallOption) (*PollGetByIDRes, error) 37 | GetAll(ctx context.Context, in *PollGetAllReq, opts ...grpc.CallOption) (*PollGetAllRes, error) 38 | } 39 | 40 | type pollServiceClient struct { 41 | cc grpc.ClientConnInterface 42 | } 43 | 44 | func NewPollServiceClient(cc grpc.ClientConnInterface) PollServiceClient { 45 | return &pollServiceClient{cc} 46 | } 47 | 48 | func (c *pollServiceClient) Create(ctx context.Context, in *PollCreateReq, opts ...grpc.CallOption) (*Void, error) { 49 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 50 | out := new(Void) 51 | err := c.cc.Invoke(ctx, PollService_Create_FullMethodName, in, out, cOpts...) 52 | if err != nil { 53 | return nil, err 54 | } 55 | return out, nil 56 | } 57 | 58 | func (c *pollServiceClient) Update(ctx context.Context, in *PollUpdateReq, opts ...grpc.CallOption) (*Void, error) { 59 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 60 | out := new(Void) 61 | err := c.cc.Invoke(ctx, PollService_Update_FullMethodName, in, out, cOpts...) 62 | if err != nil { 63 | return nil, err 64 | } 65 | return out, nil 66 | } 67 | 68 | func (c *pollServiceClient) Delete(ctx context.Context, in *ByID, opts ...grpc.CallOption) (*Void, error) { 69 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 70 | out := new(Void) 71 | err := c.cc.Invoke(ctx, PollService_Delete_FullMethodName, in, out, cOpts...) 72 | if err != nil { 73 | return nil, err 74 | } 75 | return out, nil 76 | } 77 | 78 | func (c *pollServiceClient) GetByID(ctx context.Context, in *ByID, opts ...grpc.CallOption) (*PollGetByIDRes, error) { 79 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 80 | out := new(PollGetByIDRes) 81 | err := c.cc.Invoke(ctx, PollService_GetByID_FullMethodName, in, out, cOpts...) 82 | if err != nil { 83 | return nil, err 84 | } 85 | return out, nil 86 | } 87 | 88 | func (c *pollServiceClient) GetAll(ctx context.Context, in *PollGetAllReq, opts ...grpc.CallOption) (*PollGetAllRes, error) { 89 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 90 | out := new(PollGetAllRes) 91 | err := c.cc.Invoke(ctx, PollService_GetAll_FullMethodName, in, out, cOpts...) 92 | if err != nil { 93 | return nil, err 94 | } 95 | return out, nil 96 | } 97 | 98 | // PollServiceServer is the server API for PollService service. 99 | // All implementations must embed UnimplementedPollServiceServer 100 | // for forward compatibility 101 | type PollServiceServer interface { 102 | Create(context.Context, *PollCreateReq) (*Void, error) 103 | Update(context.Context, *PollUpdateReq) (*Void, error) 104 | Delete(context.Context, *ByID) (*Void, error) 105 | GetByID(context.Context, *ByID) (*PollGetByIDRes, error) 106 | GetAll(context.Context, *PollGetAllReq) (*PollGetAllRes, error) 107 | mustEmbedUnimplementedPollServiceServer() 108 | } 109 | 110 | // UnimplementedPollServiceServer must be embedded to have forward compatible implementations. 111 | type UnimplementedPollServiceServer struct { 112 | } 113 | 114 | func (UnimplementedPollServiceServer) Create(context.Context, *PollCreateReq) (*Void, error) { 115 | return nil, status.Errorf(codes.Unimplemented, "method Create not implemented") 116 | } 117 | func (UnimplementedPollServiceServer) Update(context.Context, *PollUpdateReq) (*Void, error) { 118 | return nil, status.Errorf(codes.Unimplemented, "method Update not implemented") 119 | } 120 | func (UnimplementedPollServiceServer) Delete(context.Context, *ByID) (*Void, error) { 121 | return nil, status.Errorf(codes.Unimplemented, "method Delete not implemented") 122 | } 123 | func (UnimplementedPollServiceServer) GetByID(context.Context, *ByID) (*PollGetByIDRes, error) { 124 | return nil, status.Errorf(codes.Unimplemented, "method GetByID not implemented") 125 | } 126 | func (UnimplementedPollServiceServer) GetAll(context.Context, *PollGetAllReq) (*PollGetAllRes, error) { 127 | return nil, status.Errorf(codes.Unimplemented, "method GetAll not implemented") 128 | } 129 | func (UnimplementedPollServiceServer) mustEmbedUnimplementedPollServiceServer() {} 130 | 131 | // UnsafePollServiceServer may be embedded to opt out of forward compatibility for this service. 132 | // Use of this interface is not recommended, as added methods to PollServiceServer will 133 | // result in compilation errors. 134 | type UnsafePollServiceServer interface { 135 | mustEmbedUnimplementedPollServiceServer() 136 | } 137 | 138 | func RegisterPollServiceServer(s grpc.ServiceRegistrar, srv PollServiceServer) { 139 | s.RegisterService(&PollService_ServiceDesc, srv) 140 | } 141 | 142 | func _PollService_Create_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 143 | in := new(PollCreateReq) 144 | if err := dec(in); err != nil { 145 | return nil, err 146 | } 147 | if interceptor == nil { 148 | return srv.(PollServiceServer).Create(ctx, in) 149 | } 150 | info := &grpc.UnaryServerInfo{ 151 | Server: srv, 152 | FullMethod: PollService_Create_FullMethodName, 153 | } 154 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 155 | return srv.(PollServiceServer).Create(ctx, req.(*PollCreateReq)) 156 | } 157 | return interceptor(ctx, in, info, handler) 158 | } 159 | 160 | func _PollService_Update_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 161 | in := new(PollUpdateReq) 162 | if err := dec(in); err != nil { 163 | return nil, err 164 | } 165 | if interceptor == nil { 166 | return srv.(PollServiceServer).Update(ctx, in) 167 | } 168 | info := &grpc.UnaryServerInfo{ 169 | Server: srv, 170 | FullMethod: PollService_Update_FullMethodName, 171 | } 172 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 173 | return srv.(PollServiceServer).Update(ctx, req.(*PollUpdateReq)) 174 | } 175 | return interceptor(ctx, in, info, handler) 176 | } 177 | 178 | func _PollService_Delete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 179 | in := new(ByID) 180 | if err := dec(in); err != nil { 181 | return nil, err 182 | } 183 | if interceptor == nil { 184 | return srv.(PollServiceServer).Delete(ctx, in) 185 | } 186 | info := &grpc.UnaryServerInfo{ 187 | Server: srv, 188 | FullMethod: PollService_Delete_FullMethodName, 189 | } 190 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 191 | return srv.(PollServiceServer).Delete(ctx, req.(*ByID)) 192 | } 193 | return interceptor(ctx, in, info, handler) 194 | } 195 | 196 | func _PollService_GetByID_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 197 | in := new(ByID) 198 | if err := dec(in); err != nil { 199 | return nil, err 200 | } 201 | if interceptor == nil { 202 | return srv.(PollServiceServer).GetByID(ctx, in) 203 | } 204 | info := &grpc.UnaryServerInfo{ 205 | Server: srv, 206 | FullMethod: PollService_GetByID_FullMethodName, 207 | } 208 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 209 | return srv.(PollServiceServer).GetByID(ctx, req.(*ByID)) 210 | } 211 | return interceptor(ctx, in, info, handler) 212 | } 213 | 214 | func _PollService_GetAll_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 215 | in := new(PollGetAllReq) 216 | if err := dec(in); err != nil { 217 | return nil, err 218 | } 219 | if interceptor == nil { 220 | return srv.(PollServiceServer).GetAll(ctx, in) 221 | } 222 | info := &grpc.UnaryServerInfo{ 223 | Server: srv, 224 | FullMethod: PollService_GetAll_FullMethodName, 225 | } 226 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 227 | return srv.(PollServiceServer).GetAll(ctx, req.(*PollGetAllReq)) 228 | } 229 | return interceptor(ctx, in, info, handler) 230 | } 231 | 232 | // PollService_ServiceDesc is the grpc.ServiceDesc for PollService service. 233 | // It's only intended for direct use with grpc.RegisterService, 234 | // and not to be introspected or modified (even as a copy) 235 | var PollService_ServiceDesc = grpc.ServiceDesc{ 236 | ServiceName: "polling.PollService", 237 | HandlerType: (*PollServiceServer)(nil), 238 | Methods: []grpc.MethodDesc{ 239 | { 240 | MethodName: "Create", 241 | Handler: _PollService_Create_Handler, 242 | }, 243 | { 244 | MethodName: "Update", 245 | Handler: _PollService_Update_Handler, 246 | }, 247 | { 248 | MethodName: "Delete", 249 | Handler: _PollService_Delete_Handler, 250 | }, 251 | { 252 | MethodName: "GetByID", 253 | Handler: _PollService_GetByID_Handler, 254 | }, 255 | { 256 | MethodName: "GetAll", 257 | Handler: _PollService_GetAll_Handler, 258 | }, 259 | }, 260 | Streams: []grpc.StreamDesc{}, 261 | Metadata: "protos/poll.proto", 262 | } 263 | -------------------------------------------------------------------------------- /polling/genprotos/question_grpc.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go-grpc. DO NOT EDIT. 2 | // versions: 3 | // - protoc-gen-go-grpc v1.4.0 4 | // - protoc v3.12.4 5 | // source: protos/question.proto 6 | 7 | package genprotos 8 | 9 | import ( 10 | context "context" 11 | grpc "google.golang.org/grpc" 12 | codes "google.golang.org/grpc/codes" 13 | status "google.golang.org/grpc/status" 14 | ) 15 | 16 | // This is a compile-time assertion to ensure that this generated file 17 | // is compatible with the grpc package it is being compiled against. 18 | // Requires gRPC-Go v1.62.0 or later. 19 | const _ = grpc.SupportPackageIsVersion8 20 | 21 | const ( 22 | QuestionService_Create_FullMethodName = "/polling.QuestionService/Create" 23 | QuestionService_Update_FullMethodName = "/polling.QuestionService/Update" 24 | QuestionService_Delete_FullMethodName = "/polling.QuestionService/Delete" 25 | QuestionService_GetByID_FullMethodName = "/polling.QuestionService/GetByID" 26 | QuestionService_GetAll_FullMethodName = "/polling.QuestionService/GetAll" 27 | ) 28 | 29 | // QuestionServiceClient is the client API for QuestionService service. 30 | // 31 | // 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. 32 | type QuestionServiceClient interface { 33 | Create(ctx context.Context, in *QuestionCreateReq, opts ...grpc.CallOption) (*Void, error) 34 | Update(ctx context.Context, in *QuestionUpdateReq, opts ...grpc.CallOption) (*Void, error) 35 | Delete(ctx context.Context, in *ByID, opts ...grpc.CallOption) (*Void, error) 36 | GetByID(ctx context.Context, in *ByID, opts ...grpc.CallOption) (*QuestionGetByIDRes, error) 37 | GetAll(ctx context.Context, in *QuestionGetAllReq, opts ...grpc.CallOption) (*QuestionGetAllRes, error) 38 | } 39 | 40 | type questionServiceClient struct { 41 | cc grpc.ClientConnInterface 42 | } 43 | 44 | func NewQuestionServiceClient(cc grpc.ClientConnInterface) QuestionServiceClient { 45 | return &questionServiceClient{cc} 46 | } 47 | 48 | func (c *questionServiceClient) Create(ctx context.Context, in *QuestionCreateReq, opts ...grpc.CallOption) (*Void, error) { 49 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 50 | out := new(Void) 51 | err := c.cc.Invoke(ctx, QuestionService_Create_FullMethodName, in, out, cOpts...) 52 | if err != nil { 53 | return nil, err 54 | } 55 | return out, nil 56 | } 57 | 58 | func (c *questionServiceClient) Update(ctx context.Context, in *QuestionUpdateReq, opts ...grpc.CallOption) (*Void, error) { 59 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 60 | out := new(Void) 61 | err := c.cc.Invoke(ctx, QuestionService_Update_FullMethodName, in, out, cOpts...) 62 | if err != nil { 63 | return nil, err 64 | } 65 | return out, nil 66 | } 67 | 68 | func (c *questionServiceClient) Delete(ctx context.Context, in *ByID, opts ...grpc.CallOption) (*Void, error) { 69 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 70 | out := new(Void) 71 | err := c.cc.Invoke(ctx, QuestionService_Delete_FullMethodName, in, out, cOpts...) 72 | if err != nil { 73 | return nil, err 74 | } 75 | return out, nil 76 | } 77 | 78 | func (c *questionServiceClient) GetByID(ctx context.Context, in *ByID, opts ...grpc.CallOption) (*QuestionGetByIDRes, error) { 79 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 80 | out := new(QuestionGetByIDRes) 81 | err := c.cc.Invoke(ctx, QuestionService_GetByID_FullMethodName, in, out, cOpts...) 82 | if err != nil { 83 | return nil, err 84 | } 85 | return out, nil 86 | } 87 | 88 | func (c *questionServiceClient) GetAll(ctx context.Context, in *QuestionGetAllReq, opts ...grpc.CallOption) (*QuestionGetAllRes, error) { 89 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 90 | out := new(QuestionGetAllRes) 91 | err := c.cc.Invoke(ctx, QuestionService_GetAll_FullMethodName, in, out, cOpts...) 92 | if err != nil { 93 | return nil, err 94 | } 95 | return out, nil 96 | } 97 | 98 | // QuestionServiceServer is the server API for QuestionService service. 99 | // All implementations must embed UnimplementedQuestionServiceServer 100 | // for forward compatibility 101 | type QuestionServiceServer interface { 102 | Create(context.Context, *QuestionCreateReq) (*Void, error) 103 | Update(context.Context, *QuestionUpdateReq) (*Void, error) 104 | Delete(context.Context, *ByID) (*Void, error) 105 | GetByID(context.Context, *ByID) (*QuestionGetByIDRes, error) 106 | GetAll(context.Context, *QuestionGetAllReq) (*QuestionGetAllRes, error) 107 | mustEmbedUnimplementedQuestionServiceServer() 108 | } 109 | 110 | // UnimplementedQuestionServiceServer must be embedded to have forward compatible implementations. 111 | type UnimplementedQuestionServiceServer struct { 112 | } 113 | 114 | func (UnimplementedQuestionServiceServer) Create(context.Context, *QuestionCreateReq) (*Void, error) { 115 | return nil, status.Errorf(codes.Unimplemented, "method Create not implemented") 116 | } 117 | func (UnimplementedQuestionServiceServer) Update(context.Context, *QuestionUpdateReq) (*Void, error) { 118 | return nil, status.Errorf(codes.Unimplemented, "method Update not implemented") 119 | } 120 | func (UnimplementedQuestionServiceServer) Delete(context.Context, *ByID) (*Void, error) { 121 | return nil, status.Errorf(codes.Unimplemented, "method Delete not implemented") 122 | } 123 | func (UnimplementedQuestionServiceServer) GetByID(context.Context, *ByID) (*QuestionGetByIDRes, error) { 124 | return nil, status.Errorf(codes.Unimplemented, "method GetByID not implemented") 125 | } 126 | func (UnimplementedQuestionServiceServer) GetAll(context.Context, *QuestionGetAllReq) (*QuestionGetAllRes, error) { 127 | return nil, status.Errorf(codes.Unimplemented, "method GetAll not implemented") 128 | } 129 | func (UnimplementedQuestionServiceServer) mustEmbedUnimplementedQuestionServiceServer() {} 130 | 131 | // UnsafeQuestionServiceServer may be embedded to opt out of forward compatibility for this service. 132 | // Use of this interface is not recommended, as added methods to QuestionServiceServer will 133 | // result in compilation errors. 134 | type UnsafeQuestionServiceServer interface { 135 | mustEmbedUnimplementedQuestionServiceServer() 136 | } 137 | 138 | func RegisterQuestionServiceServer(s grpc.ServiceRegistrar, srv QuestionServiceServer) { 139 | s.RegisterService(&QuestionService_ServiceDesc, srv) 140 | } 141 | 142 | func _QuestionService_Create_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 143 | in := new(QuestionCreateReq) 144 | if err := dec(in); err != nil { 145 | return nil, err 146 | } 147 | if interceptor == nil { 148 | return srv.(QuestionServiceServer).Create(ctx, in) 149 | } 150 | info := &grpc.UnaryServerInfo{ 151 | Server: srv, 152 | FullMethod: QuestionService_Create_FullMethodName, 153 | } 154 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 155 | return srv.(QuestionServiceServer).Create(ctx, req.(*QuestionCreateReq)) 156 | } 157 | return interceptor(ctx, in, info, handler) 158 | } 159 | 160 | func _QuestionService_Update_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 161 | in := new(QuestionUpdateReq) 162 | if err := dec(in); err != nil { 163 | return nil, err 164 | } 165 | if interceptor == nil { 166 | return srv.(QuestionServiceServer).Update(ctx, in) 167 | } 168 | info := &grpc.UnaryServerInfo{ 169 | Server: srv, 170 | FullMethod: QuestionService_Update_FullMethodName, 171 | } 172 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 173 | return srv.(QuestionServiceServer).Update(ctx, req.(*QuestionUpdateReq)) 174 | } 175 | return interceptor(ctx, in, info, handler) 176 | } 177 | 178 | func _QuestionService_Delete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 179 | in := new(ByID) 180 | if err := dec(in); err != nil { 181 | return nil, err 182 | } 183 | if interceptor == nil { 184 | return srv.(QuestionServiceServer).Delete(ctx, in) 185 | } 186 | info := &grpc.UnaryServerInfo{ 187 | Server: srv, 188 | FullMethod: QuestionService_Delete_FullMethodName, 189 | } 190 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 191 | return srv.(QuestionServiceServer).Delete(ctx, req.(*ByID)) 192 | } 193 | return interceptor(ctx, in, info, handler) 194 | } 195 | 196 | func _QuestionService_GetByID_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 197 | in := new(ByID) 198 | if err := dec(in); err != nil { 199 | return nil, err 200 | } 201 | if interceptor == nil { 202 | return srv.(QuestionServiceServer).GetByID(ctx, in) 203 | } 204 | info := &grpc.UnaryServerInfo{ 205 | Server: srv, 206 | FullMethod: QuestionService_GetByID_FullMethodName, 207 | } 208 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 209 | return srv.(QuestionServiceServer).GetByID(ctx, req.(*ByID)) 210 | } 211 | return interceptor(ctx, in, info, handler) 212 | } 213 | 214 | func _QuestionService_GetAll_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 215 | in := new(QuestionGetAllReq) 216 | if err := dec(in); err != nil { 217 | return nil, err 218 | } 219 | if interceptor == nil { 220 | return srv.(QuestionServiceServer).GetAll(ctx, in) 221 | } 222 | info := &grpc.UnaryServerInfo{ 223 | Server: srv, 224 | FullMethod: QuestionService_GetAll_FullMethodName, 225 | } 226 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 227 | return srv.(QuestionServiceServer).GetAll(ctx, req.(*QuestionGetAllReq)) 228 | } 229 | return interceptor(ctx, in, info, handler) 230 | } 231 | 232 | // QuestionService_ServiceDesc is the grpc.ServiceDesc for QuestionService service. 233 | // It's only intended for direct use with grpc.RegisterService, 234 | // and not to be introspected or modified (even as a copy) 235 | var QuestionService_ServiceDesc = grpc.ServiceDesc{ 236 | ServiceName: "polling.QuestionService", 237 | HandlerType: (*QuestionServiceServer)(nil), 238 | Methods: []grpc.MethodDesc{ 239 | { 240 | MethodName: "Create", 241 | Handler: _QuestionService_Create_Handler, 242 | }, 243 | { 244 | MethodName: "Update", 245 | Handler: _QuestionService_Update_Handler, 246 | }, 247 | { 248 | MethodName: "Delete", 249 | Handler: _QuestionService_Delete_Handler, 250 | }, 251 | { 252 | MethodName: "GetByID", 253 | Handler: _QuestionService_GetByID_Handler, 254 | }, 255 | { 256 | MethodName: "GetAll", 257 | Handler: _QuestionService_GetAll_Handler, 258 | }, 259 | }, 260 | Streams: []grpc.StreamDesc{}, 261 | Metadata: "protos/question.proto", 262 | } 263 | -------------------------------------------------------------------------------- /api-gateway/genprotos/question_grpc.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go-grpc. DO NOT EDIT. 2 | // versions: 3 | // - protoc-gen-go-grpc v1.4.0 4 | // - protoc v3.12.4 5 | // source: protos/question.proto 6 | 7 | package genprotos 8 | 9 | import ( 10 | context "context" 11 | grpc "google.golang.org/grpc" 12 | codes "google.golang.org/grpc/codes" 13 | status "google.golang.org/grpc/status" 14 | ) 15 | 16 | // This is a compile-time assertion to ensure that this generated file 17 | // is compatible with the grpc package it is being compiled against. 18 | // Requires gRPC-Go v1.62.0 or later. 19 | const _ = grpc.SupportPackageIsVersion8 20 | 21 | const ( 22 | QuestionService_Create_FullMethodName = "/polling.QuestionService/Create" 23 | QuestionService_Update_FullMethodName = "/polling.QuestionService/Update" 24 | QuestionService_Delete_FullMethodName = "/polling.QuestionService/Delete" 25 | QuestionService_GetByID_FullMethodName = "/polling.QuestionService/GetByID" 26 | QuestionService_GetAll_FullMethodName = "/polling.QuestionService/GetAll" 27 | ) 28 | 29 | // QuestionServiceClient is the client API for QuestionService service. 30 | // 31 | // 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. 32 | type QuestionServiceClient interface { 33 | Create(ctx context.Context, in *QuestionCreateReq, opts ...grpc.CallOption) (*Void, error) 34 | Update(ctx context.Context, in *QuestionUpdateReq, opts ...grpc.CallOption) (*Void, error) 35 | Delete(ctx context.Context, in *ByID, opts ...grpc.CallOption) (*Void, error) 36 | GetByID(ctx context.Context, in *ByID, opts ...grpc.CallOption) (*QuestionGetByIDRes, error) 37 | GetAll(ctx context.Context, in *QuestionGetAllReq, opts ...grpc.CallOption) (*QuestionGetAllRes, error) 38 | } 39 | 40 | type questionServiceClient struct { 41 | cc grpc.ClientConnInterface 42 | } 43 | 44 | func NewQuestionServiceClient(cc grpc.ClientConnInterface) QuestionServiceClient { 45 | return &questionServiceClient{cc} 46 | } 47 | 48 | func (c *questionServiceClient) Create(ctx context.Context, in *QuestionCreateReq, opts ...grpc.CallOption) (*Void, error) { 49 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 50 | out := new(Void) 51 | err := c.cc.Invoke(ctx, QuestionService_Create_FullMethodName, in, out, cOpts...) 52 | if err != nil { 53 | return nil, err 54 | } 55 | return out, nil 56 | } 57 | 58 | func (c *questionServiceClient) Update(ctx context.Context, in *QuestionUpdateReq, opts ...grpc.CallOption) (*Void, error) { 59 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 60 | out := new(Void) 61 | err := c.cc.Invoke(ctx, QuestionService_Update_FullMethodName, in, out, cOpts...) 62 | if err != nil { 63 | return nil, err 64 | } 65 | return out, nil 66 | } 67 | 68 | func (c *questionServiceClient) Delete(ctx context.Context, in *ByID, opts ...grpc.CallOption) (*Void, error) { 69 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 70 | out := new(Void) 71 | err := c.cc.Invoke(ctx, QuestionService_Delete_FullMethodName, in, out, cOpts...) 72 | if err != nil { 73 | return nil, err 74 | } 75 | return out, nil 76 | } 77 | 78 | func (c *questionServiceClient) GetByID(ctx context.Context, in *ByID, opts ...grpc.CallOption) (*QuestionGetByIDRes, error) { 79 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 80 | out := new(QuestionGetByIDRes) 81 | err := c.cc.Invoke(ctx, QuestionService_GetByID_FullMethodName, in, out, cOpts...) 82 | if err != nil { 83 | return nil, err 84 | } 85 | return out, nil 86 | } 87 | 88 | func (c *questionServiceClient) GetAll(ctx context.Context, in *QuestionGetAllReq, opts ...grpc.CallOption) (*QuestionGetAllRes, error) { 89 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 90 | out := new(QuestionGetAllRes) 91 | err := c.cc.Invoke(ctx, QuestionService_GetAll_FullMethodName, in, out, cOpts...) 92 | if err != nil { 93 | return nil, err 94 | } 95 | return out, nil 96 | } 97 | 98 | // QuestionServiceServer is the server API for QuestionService service. 99 | // All implementations must embed UnimplementedQuestionServiceServer 100 | // for forward compatibility 101 | type QuestionServiceServer interface { 102 | Create(context.Context, *QuestionCreateReq) (*Void, error) 103 | Update(context.Context, *QuestionUpdateReq) (*Void, error) 104 | Delete(context.Context, *ByID) (*Void, error) 105 | GetByID(context.Context, *ByID) (*QuestionGetByIDRes, error) 106 | GetAll(context.Context, *QuestionGetAllReq) (*QuestionGetAllRes, error) 107 | mustEmbedUnimplementedQuestionServiceServer() 108 | } 109 | 110 | // UnimplementedQuestionServiceServer must be embedded to have forward compatible implementations. 111 | type UnimplementedQuestionServiceServer struct { 112 | } 113 | 114 | func (UnimplementedQuestionServiceServer) Create(context.Context, *QuestionCreateReq) (*Void, error) { 115 | return nil, status.Errorf(codes.Unimplemented, "method Create not implemented") 116 | } 117 | func (UnimplementedQuestionServiceServer) Update(context.Context, *QuestionUpdateReq) (*Void, error) { 118 | return nil, status.Errorf(codes.Unimplemented, "method Update not implemented") 119 | } 120 | func (UnimplementedQuestionServiceServer) Delete(context.Context, *ByID) (*Void, error) { 121 | return nil, status.Errorf(codes.Unimplemented, "method Delete not implemented") 122 | } 123 | func (UnimplementedQuestionServiceServer) GetByID(context.Context, *ByID) (*QuestionGetByIDRes, error) { 124 | return nil, status.Errorf(codes.Unimplemented, "method GetByID not implemented") 125 | } 126 | func (UnimplementedQuestionServiceServer) GetAll(context.Context, *QuestionGetAllReq) (*QuestionGetAllRes, error) { 127 | return nil, status.Errorf(codes.Unimplemented, "method GetAll not implemented") 128 | } 129 | func (UnimplementedQuestionServiceServer) mustEmbedUnimplementedQuestionServiceServer() {} 130 | 131 | // UnsafeQuestionServiceServer may be embedded to opt out of forward compatibility for this service. 132 | // Use of this interface is not recommended, as added methods to QuestionServiceServer will 133 | // result in compilation errors. 134 | type UnsafeQuestionServiceServer interface { 135 | mustEmbedUnimplementedQuestionServiceServer() 136 | } 137 | 138 | func RegisterQuestionServiceServer(s grpc.ServiceRegistrar, srv QuestionServiceServer) { 139 | s.RegisterService(&QuestionService_ServiceDesc, srv) 140 | } 141 | 142 | func _QuestionService_Create_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 143 | in := new(QuestionCreateReq) 144 | if err := dec(in); err != nil { 145 | return nil, err 146 | } 147 | if interceptor == nil { 148 | return srv.(QuestionServiceServer).Create(ctx, in) 149 | } 150 | info := &grpc.UnaryServerInfo{ 151 | Server: srv, 152 | FullMethod: QuestionService_Create_FullMethodName, 153 | } 154 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 155 | return srv.(QuestionServiceServer).Create(ctx, req.(*QuestionCreateReq)) 156 | } 157 | return interceptor(ctx, in, info, handler) 158 | } 159 | 160 | func _QuestionService_Update_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 161 | in := new(QuestionUpdateReq) 162 | if err := dec(in); err != nil { 163 | return nil, err 164 | } 165 | if interceptor == nil { 166 | return srv.(QuestionServiceServer).Update(ctx, in) 167 | } 168 | info := &grpc.UnaryServerInfo{ 169 | Server: srv, 170 | FullMethod: QuestionService_Update_FullMethodName, 171 | } 172 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 173 | return srv.(QuestionServiceServer).Update(ctx, req.(*QuestionUpdateReq)) 174 | } 175 | return interceptor(ctx, in, info, handler) 176 | } 177 | 178 | func _QuestionService_Delete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 179 | in := new(ByID) 180 | if err := dec(in); err != nil { 181 | return nil, err 182 | } 183 | if interceptor == nil { 184 | return srv.(QuestionServiceServer).Delete(ctx, in) 185 | } 186 | info := &grpc.UnaryServerInfo{ 187 | Server: srv, 188 | FullMethod: QuestionService_Delete_FullMethodName, 189 | } 190 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 191 | return srv.(QuestionServiceServer).Delete(ctx, req.(*ByID)) 192 | } 193 | return interceptor(ctx, in, info, handler) 194 | } 195 | 196 | func _QuestionService_GetByID_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 197 | in := new(ByID) 198 | if err := dec(in); err != nil { 199 | return nil, err 200 | } 201 | if interceptor == nil { 202 | return srv.(QuestionServiceServer).GetByID(ctx, in) 203 | } 204 | info := &grpc.UnaryServerInfo{ 205 | Server: srv, 206 | FullMethod: QuestionService_GetByID_FullMethodName, 207 | } 208 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 209 | return srv.(QuestionServiceServer).GetByID(ctx, req.(*ByID)) 210 | } 211 | return interceptor(ctx, in, info, handler) 212 | } 213 | 214 | func _QuestionService_GetAll_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 215 | in := new(QuestionGetAllReq) 216 | if err := dec(in); err != nil { 217 | return nil, err 218 | } 219 | if interceptor == nil { 220 | return srv.(QuestionServiceServer).GetAll(ctx, in) 221 | } 222 | info := &grpc.UnaryServerInfo{ 223 | Server: srv, 224 | FullMethod: QuestionService_GetAll_FullMethodName, 225 | } 226 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 227 | return srv.(QuestionServiceServer).GetAll(ctx, req.(*QuestionGetAllReq)) 228 | } 229 | return interceptor(ctx, in, info, handler) 230 | } 231 | 232 | // QuestionService_ServiceDesc is the grpc.ServiceDesc for QuestionService service. 233 | // It's only intended for direct use with grpc.RegisterService, 234 | // and not to be introspected or modified (even as a copy) 235 | var QuestionService_ServiceDesc = grpc.ServiceDesc{ 236 | ServiceName: "polling.QuestionService", 237 | HandlerType: (*QuestionServiceServer)(nil), 238 | Methods: []grpc.MethodDesc{ 239 | { 240 | MethodName: "Create", 241 | Handler: _QuestionService_Create_Handler, 242 | }, 243 | { 244 | MethodName: "Update", 245 | Handler: _QuestionService_Update_Handler, 246 | }, 247 | { 248 | MethodName: "Delete", 249 | Handler: _QuestionService_Delete_Handler, 250 | }, 251 | { 252 | MethodName: "GetByID", 253 | Handler: _QuestionService_GetByID_Handler, 254 | }, 255 | { 256 | MethodName: "GetAll", 257 | Handler: _QuestionService_GetAll_Handler, 258 | }, 259 | }, 260 | Streams: []grpc.StreamDesc{}, 261 | Metadata: "protos/question.proto", 262 | } 263 | -------------------------------------------------------------------------------- /polling/genprotos/users_grpc.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go-grpc. DO NOT EDIT. 2 | // versions: 3 | // - protoc-gen-go-grpc v1.4.0 4 | // - protoc v3.12.4 5 | // source: protos/users.proto 6 | 7 | package genprotos 8 | 9 | import ( 10 | context "context" 11 | grpc "google.golang.org/grpc" 12 | codes "google.golang.org/grpc/codes" 13 | status "google.golang.org/grpc/status" 14 | ) 15 | 16 | // This is a compile-time assertion to ensure that this generated file 17 | // is compatible with the grpc package it is being compiled against. 18 | // Requires gRPC-Go v1.62.0 or later. 19 | const _ = grpc.SupportPackageIsVersion8 20 | 21 | const ( 22 | UserService_Register_FullMethodName = "/polling.UserService/Register" 23 | UserService_Profile_FullMethodName = "/polling.UserService/Profile" 24 | UserService_IsEmailExists_FullMethodName = "/polling.UserService/IsEmailExists" 25 | UserService_GetByID_FullMethodName = "/polling.UserService/GetByID" 26 | UserService_GetByEmail_FullMethodName = "/polling.UserService/GetByEmail" 27 | ) 28 | 29 | // UserServiceClient is the client API for UserService service. 30 | // 31 | // 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. 32 | type UserServiceClient interface { 33 | Register(ctx context.Context, in *RegisterReq, opts ...grpc.CallOption) (*Void, error) 34 | // rpc ConfirmUser(ConfirmUserReq) returns (Void); 35 | Profile(ctx context.Context, in *GetProfileReq, opts ...grpc.CallOption) (*GetProfileResp, error) 36 | // rpc UpdatePassword(UpdatePasswordReq) returns (Void); 37 | IsEmailExists(ctx context.Context, in *IsEmailExistsReq, opts ...grpc.CallOption) (*IsEmailExistsResp, error) 38 | GetByID(ctx context.Context, in *GetProfileByIdReq, opts ...grpc.CallOption) (*GetProfileByIdResp, error) 39 | GetByEmail(ctx context.Context, in *ByEmail, opts ...grpc.CallOption) (*GetProfileByIdResp, error) 40 | } 41 | 42 | type userServiceClient struct { 43 | cc grpc.ClientConnInterface 44 | } 45 | 46 | func NewUserServiceClient(cc grpc.ClientConnInterface) UserServiceClient { 47 | return &userServiceClient{cc} 48 | } 49 | 50 | func (c *userServiceClient) Register(ctx context.Context, in *RegisterReq, opts ...grpc.CallOption) (*Void, error) { 51 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 52 | out := new(Void) 53 | err := c.cc.Invoke(ctx, UserService_Register_FullMethodName, in, out, cOpts...) 54 | if err != nil { 55 | return nil, err 56 | } 57 | return out, nil 58 | } 59 | 60 | func (c *userServiceClient) Profile(ctx context.Context, in *GetProfileReq, opts ...grpc.CallOption) (*GetProfileResp, error) { 61 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 62 | out := new(GetProfileResp) 63 | err := c.cc.Invoke(ctx, UserService_Profile_FullMethodName, in, out, cOpts...) 64 | if err != nil { 65 | return nil, err 66 | } 67 | return out, nil 68 | } 69 | 70 | func (c *userServiceClient) IsEmailExists(ctx context.Context, in *IsEmailExistsReq, opts ...grpc.CallOption) (*IsEmailExistsResp, error) { 71 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 72 | out := new(IsEmailExistsResp) 73 | err := c.cc.Invoke(ctx, UserService_IsEmailExists_FullMethodName, in, out, cOpts...) 74 | if err != nil { 75 | return nil, err 76 | } 77 | return out, nil 78 | } 79 | 80 | func (c *userServiceClient) GetByID(ctx context.Context, in *GetProfileByIdReq, opts ...grpc.CallOption) (*GetProfileByIdResp, error) { 81 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 82 | out := new(GetProfileByIdResp) 83 | err := c.cc.Invoke(ctx, UserService_GetByID_FullMethodName, in, out, cOpts...) 84 | if err != nil { 85 | return nil, err 86 | } 87 | return out, nil 88 | } 89 | 90 | func (c *userServiceClient) GetByEmail(ctx context.Context, in *ByEmail, opts ...grpc.CallOption) (*GetProfileByIdResp, error) { 91 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 92 | out := new(GetProfileByIdResp) 93 | err := c.cc.Invoke(ctx, UserService_GetByEmail_FullMethodName, in, out, cOpts...) 94 | if err != nil { 95 | return nil, err 96 | } 97 | return out, nil 98 | } 99 | 100 | // UserServiceServer is the server API for UserService service. 101 | // All implementations must embed UnimplementedUserServiceServer 102 | // for forward compatibility 103 | type UserServiceServer interface { 104 | Register(context.Context, *RegisterReq) (*Void, error) 105 | // rpc ConfirmUser(ConfirmUserReq) returns (Void); 106 | Profile(context.Context, *GetProfileReq) (*GetProfileResp, error) 107 | // rpc UpdatePassword(UpdatePasswordReq) returns (Void); 108 | IsEmailExists(context.Context, *IsEmailExistsReq) (*IsEmailExistsResp, error) 109 | GetByID(context.Context, *GetProfileByIdReq) (*GetProfileByIdResp, error) 110 | GetByEmail(context.Context, *ByEmail) (*GetProfileByIdResp, error) 111 | mustEmbedUnimplementedUserServiceServer() 112 | } 113 | 114 | // UnimplementedUserServiceServer must be embedded to have forward compatible implementations. 115 | type UnimplementedUserServiceServer struct { 116 | } 117 | 118 | func (UnimplementedUserServiceServer) Register(context.Context, *RegisterReq) (*Void, error) { 119 | return nil, status.Errorf(codes.Unimplemented, "method Register not implemented") 120 | } 121 | func (UnimplementedUserServiceServer) Profile(context.Context, *GetProfileReq) (*GetProfileResp, error) { 122 | return nil, status.Errorf(codes.Unimplemented, "method Profile not implemented") 123 | } 124 | func (UnimplementedUserServiceServer) IsEmailExists(context.Context, *IsEmailExistsReq) (*IsEmailExistsResp, error) { 125 | return nil, status.Errorf(codes.Unimplemented, "method IsEmailExists not implemented") 126 | } 127 | func (UnimplementedUserServiceServer) GetByID(context.Context, *GetProfileByIdReq) (*GetProfileByIdResp, error) { 128 | return nil, status.Errorf(codes.Unimplemented, "method GetByID not implemented") 129 | } 130 | func (UnimplementedUserServiceServer) GetByEmail(context.Context, *ByEmail) (*GetProfileByIdResp, error) { 131 | return nil, status.Errorf(codes.Unimplemented, "method GetByEmail not implemented") 132 | } 133 | func (UnimplementedUserServiceServer) mustEmbedUnimplementedUserServiceServer() {} 134 | 135 | // UnsafeUserServiceServer may be embedded to opt out of forward compatibility for this service. 136 | // Use of this interface is not recommended, as added methods to UserServiceServer will 137 | // result in compilation errors. 138 | type UnsafeUserServiceServer interface { 139 | mustEmbedUnimplementedUserServiceServer() 140 | } 141 | 142 | func RegisterUserServiceServer(s grpc.ServiceRegistrar, srv UserServiceServer) { 143 | s.RegisterService(&UserService_ServiceDesc, srv) 144 | } 145 | 146 | func _UserService_Register_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 147 | in := new(RegisterReq) 148 | if err := dec(in); err != nil { 149 | return nil, err 150 | } 151 | if interceptor == nil { 152 | return srv.(UserServiceServer).Register(ctx, in) 153 | } 154 | info := &grpc.UnaryServerInfo{ 155 | Server: srv, 156 | FullMethod: UserService_Register_FullMethodName, 157 | } 158 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 159 | return srv.(UserServiceServer).Register(ctx, req.(*RegisterReq)) 160 | } 161 | return interceptor(ctx, in, info, handler) 162 | } 163 | 164 | func _UserService_Profile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 165 | in := new(GetProfileReq) 166 | if err := dec(in); err != nil { 167 | return nil, err 168 | } 169 | if interceptor == nil { 170 | return srv.(UserServiceServer).Profile(ctx, in) 171 | } 172 | info := &grpc.UnaryServerInfo{ 173 | Server: srv, 174 | FullMethod: UserService_Profile_FullMethodName, 175 | } 176 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 177 | return srv.(UserServiceServer).Profile(ctx, req.(*GetProfileReq)) 178 | } 179 | return interceptor(ctx, in, info, handler) 180 | } 181 | 182 | func _UserService_IsEmailExists_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 183 | in := new(IsEmailExistsReq) 184 | if err := dec(in); err != nil { 185 | return nil, err 186 | } 187 | if interceptor == nil { 188 | return srv.(UserServiceServer).IsEmailExists(ctx, in) 189 | } 190 | info := &grpc.UnaryServerInfo{ 191 | Server: srv, 192 | FullMethod: UserService_IsEmailExists_FullMethodName, 193 | } 194 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 195 | return srv.(UserServiceServer).IsEmailExists(ctx, req.(*IsEmailExistsReq)) 196 | } 197 | return interceptor(ctx, in, info, handler) 198 | } 199 | 200 | func _UserService_GetByID_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 201 | in := new(GetProfileByIdReq) 202 | if err := dec(in); err != nil { 203 | return nil, err 204 | } 205 | if interceptor == nil { 206 | return srv.(UserServiceServer).GetByID(ctx, in) 207 | } 208 | info := &grpc.UnaryServerInfo{ 209 | Server: srv, 210 | FullMethod: UserService_GetByID_FullMethodName, 211 | } 212 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 213 | return srv.(UserServiceServer).GetByID(ctx, req.(*GetProfileByIdReq)) 214 | } 215 | return interceptor(ctx, in, info, handler) 216 | } 217 | 218 | func _UserService_GetByEmail_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 219 | in := new(ByEmail) 220 | if err := dec(in); err != nil { 221 | return nil, err 222 | } 223 | if interceptor == nil { 224 | return srv.(UserServiceServer).GetByEmail(ctx, in) 225 | } 226 | info := &grpc.UnaryServerInfo{ 227 | Server: srv, 228 | FullMethod: UserService_GetByEmail_FullMethodName, 229 | } 230 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 231 | return srv.(UserServiceServer).GetByEmail(ctx, req.(*ByEmail)) 232 | } 233 | return interceptor(ctx, in, info, handler) 234 | } 235 | 236 | // UserService_ServiceDesc is the grpc.ServiceDesc for UserService service. 237 | // It's only intended for direct use with grpc.RegisterService, 238 | // and not to be introspected or modified (even as a copy) 239 | var UserService_ServiceDesc = grpc.ServiceDesc{ 240 | ServiceName: "polling.UserService", 241 | HandlerType: (*UserServiceServer)(nil), 242 | Methods: []grpc.MethodDesc{ 243 | { 244 | MethodName: "Register", 245 | Handler: _UserService_Register_Handler, 246 | }, 247 | { 248 | MethodName: "Profile", 249 | Handler: _UserService_Profile_Handler, 250 | }, 251 | { 252 | MethodName: "IsEmailExists", 253 | Handler: _UserService_IsEmailExists_Handler, 254 | }, 255 | { 256 | MethodName: "GetByID", 257 | Handler: _UserService_GetByID_Handler, 258 | }, 259 | { 260 | MethodName: "GetByEmail", 261 | Handler: _UserService_GetByEmail_Handler, 262 | }, 263 | }, 264 | Streams: []grpc.StreamDesc{}, 265 | Metadata: "protos/users.proto", 266 | } 267 | -------------------------------------------------------------------------------- /api-gateway/genprotos/users_grpc.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go-grpc. DO NOT EDIT. 2 | // versions: 3 | // - protoc-gen-go-grpc v1.4.0 4 | // - protoc v3.12.4 5 | // source: protos/users.proto 6 | 7 | package genprotos 8 | 9 | import ( 10 | context "context" 11 | grpc "google.golang.org/grpc" 12 | codes "google.golang.org/grpc/codes" 13 | status "google.golang.org/grpc/status" 14 | ) 15 | 16 | // This is a compile-time assertion to ensure that this generated file 17 | // is compatible with the grpc package it is being compiled against. 18 | // Requires gRPC-Go v1.62.0 or later. 19 | const _ = grpc.SupportPackageIsVersion8 20 | 21 | const ( 22 | UserService_Register_FullMethodName = "/polling.UserService/Register" 23 | UserService_Profile_FullMethodName = "/polling.UserService/Profile" 24 | UserService_IsEmailExists_FullMethodName = "/polling.UserService/IsEmailExists" 25 | UserService_GetByID_FullMethodName = "/polling.UserService/GetByID" 26 | UserService_GetByEmail_FullMethodName = "/polling.UserService/GetByEmail" 27 | ) 28 | 29 | // UserServiceClient is the client API for UserService service. 30 | // 31 | // 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. 32 | type UserServiceClient interface { 33 | Register(ctx context.Context, in *RegisterReq, opts ...grpc.CallOption) (*Void, error) 34 | // rpc ConfirmUser(ConfirmUserReq) returns (Void); 35 | Profile(ctx context.Context, in *GetProfileReq, opts ...grpc.CallOption) (*GetProfileResp, error) 36 | // rpc UpdatePassword(UpdatePasswordReq) returns (Void); 37 | IsEmailExists(ctx context.Context, in *IsEmailExistsReq, opts ...grpc.CallOption) (*IsEmailExistsResp, error) 38 | GetByID(ctx context.Context, in *GetProfileByIdReq, opts ...grpc.CallOption) (*GetProfileByIdResp, error) 39 | GetByEmail(ctx context.Context, in *ByEmail, opts ...grpc.CallOption) (*GetProfileByIdResp, error) 40 | } 41 | 42 | type userServiceClient struct { 43 | cc grpc.ClientConnInterface 44 | } 45 | 46 | func NewUserServiceClient(cc grpc.ClientConnInterface) UserServiceClient { 47 | return &userServiceClient{cc} 48 | } 49 | 50 | func (c *userServiceClient) Register(ctx context.Context, in *RegisterReq, opts ...grpc.CallOption) (*Void, error) { 51 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 52 | out := new(Void) 53 | err := c.cc.Invoke(ctx, UserService_Register_FullMethodName, in, out, cOpts...) 54 | if err != nil { 55 | return nil, err 56 | } 57 | return out, nil 58 | } 59 | 60 | func (c *userServiceClient) Profile(ctx context.Context, in *GetProfileReq, opts ...grpc.CallOption) (*GetProfileResp, error) { 61 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 62 | out := new(GetProfileResp) 63 | err := c.cc.Invoke(ctx, UserService_Profile_FullMethodName, in, out, cOpts...) 64 | if err != nil { 65 | return nil, err 66 | } 67 | return out, nil 68 | } 69 | 70 | func (c *userServiceClient) IsEmailExists(ctx context.Context, in *IsEmailExistsReq, opts ...grpc.CallOption) (*IsEmailExistsResp, error) { 71 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 72 | out := new(IsEmailExistsResp) 73 | err := c.cc.Invoke(ctx, UserService_IsEmailExists_FullMethodName, in, out, cOpts...) 74 | if err != nil { 75 | return nil, err 76 | } 77 | return out, nil 78 | } 79 | 80 | func (c *userServiceClient) GetByID(ctx context.Context, in *GetProfileByIdReq, opts ...grpc.CallOption) (*GetProfileByIdResp, error) { 81 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 82 | out := new(GetProfileByIdResp) 83 | err := c.cc.Invoke(ctx, UserService_GetByID_FullMethodName, in, out, cOpts...) 84 | if err != nil { 85 | return nil, err 86 | } 87 | return out, nil 88 | } 89 | 90 | func (c *userServiceClient) GetByEmail(ctx context.Context, in *ByEmail, opts ...grpc.CallOption) (*GetProfileByIdResp, error) { 91 | cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) 92 | out := new(GetProfileByIdResp) 93 | err := c.cc.Invoke(ctx, UserService_GetByEmail_FullMethodName, in, out, cOpts...) 94 | if err != nil { 95 | return nil, err 96 | } 97 | return out, nil 98 | } 99 | 100 | // UserServiceServer is the server API for UserService service. 101 | // All implementations must embed UnimplementedUserServiceServer 102 | // for forward compatibility 103 | type UserServiceServer interface { 104 | Register(context.Context, *RegisterReq) (*Void, error) 105 | // rpc ConfirmUser(ConfirmUserReq) returns (Void); 106 | Profile(context.Context, *GetProfileReq) (*GetProfileResp, error) 107 | // rpc UpdatePassword(UpdatePasswordReq) returns (Void); 108 | IsEmailExists(context.Context, *IsEmailExistsReq) (*IsEmailExistsResp, error) 109 | GetByID(context.Context, *GetProfileByIdReq) (*GetProfileByIdResp, error) 110 | GetByEmail(context.Context, *ByEmail) (*GetProfileByIdResp, error) 111 | mustEmbedUnimplementedUserServiceServer() 112 | } 113 | 114 | // UnimplementedUserServiceServer must be embedded to have forward compatible implementations. 115 | type UnimplementedUserServiceServer struct { 116 | } 117 | 118 | func (UnimplementedUserServiceServer) Register(context.Context, *RegisterReq) (*Void, error) { 119 | return nil, status.Errorf(codes.Unimplemented, "method Register not implemented") 120 | } 121 | func (UnimplementedUserServiceServer) Profile(context.Context, *GetProfileReq) (*GetProfileResp, error) { 122 | return nil, status.Errorf(codes.Unimplemented, "method Profile not implemented") 123 | } 124 | func (UnimplementedUserServiceServer) IsEmailExists(context.Context, *IsEmailExistsReq) (*IsEmailExistsResp, error) { 125 | return nil, status.Errorf(codes.Unimplemented, "method IsEmailExists not implemented") 126 | } 127 | func (UnimplementedUserServiceServer) GetByID(context.Context, *GetProfileByIdReq) (*GetProfileByIdResp, error) { 128 | return nil, status.Errorf(codes.Unimplemented, "method GetByID not implemented") 129 | } 130 | func (UnimplementedUserServiceServer) GetByEmail(context.Context, *ByEmail) (*GetProfileByIdResp, error) { 131 | return nil, status.Errorf(codes.Unimplemented, "method GetByEmail not implemented") 132 | } 133 | func (UnimplementedUserServiceServer) mustEmbedUnimplementedUserServiceServer() {} 134 | 135 | // UnsafeUserServiceServer may be embedded to opt out of forward compatibility for this service. 136 | // Use of this interface is not recommended, as added methods to UserServiceServer will 137 | // result in compilation errors. 138 | type UnsafeUserServiceServer interface { 139 | mustEmbedUnimplementedUserServiceServer() 140 | } 141 | 142 | func RegisterUserServiceServer(s grpc.ServiceRegistrar, srv UserServiceServer) { 143 | s.RegisterService(&UserService_ServiceDesc, srv) 144 | } 145 | 146 | func _UserService_Register_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 147 | in := new(RegisterReq) 148 | if err := dec(in); err != nil { 149 | return nil, err 150 | } 151 | if interceptor == nil { 152 | return srv.(UserServiceServer).Register(ctx, in) 153 | } 154 | info := &grpc.UnaryServerInfo{ 155 | Server: srv, 156 | FullMethod: UserService_Register_FullMethodName, 157 | } 158 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 159 | return srv.(UserServiceServer).Register(ctx, req.(*RegisterReq)) 160 | } 161 | return interceptor(ctx, in, info, handler) 162 | } 163 | 164 | func _UserService_Profile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 165 | in := new(GetProfileReq) 166 | if err := dec(in); err != nil { 167 | return nil, err 168 | } 169 | if interceptor == nil { 170 | return srv.(UserServiceServer).Profile(ctx, in) 171 | } 172 | info := &grpc.UnaryServerInfo{ 173 | Server: srv, 174 | FullMethod: UserService_Profile_FullMethodName, 175 | } 176 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 177 | return srv.(UserServiceServer).Profile(ctx, req.(*GetProfileReq)) 178 | } 179 | return interceptor(ctx, in, info, handler) 180 | } 181 | 182 | func _UserService_IsEmailExists_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 183 | in := new(IsEmailExistsReq) 184 | if err := dec(in); err != nil { 185 | return nil, err 186 | } 187 | if interceptor == nil { 188 | return srv.(UserServiceServer).IsEmailExists(ctx, in) 189 | } 190 | info := &grpc.UnaryServerInfo{ 191 | Server: srv, 192 | FullMethod: UserService_IsEmailExists_FullMethodName, 193 | } 194 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 195 | return srv.(UserServiceServer).IsEmailExists(ctx, req.(*IsEmailExistsReq)) 196 | } 197 | return interceptor(ctx, in, info, handler) 198 | } 199 | 200 | func _UserService_GetByID_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 201 | in := new(GetProfileByIdReq) 202 | if err := dec(in); err != nil { 203 | return nil, err 204 | } 205 | if interceptor == nil { 206 | return srv.(UserServiceServer).GetByID(ctx, in) 207 | } 208 | info := &grpc.UnaryServerInfo{ 209 | Server: srv, 210 | FullMethod: UserService_GetByID_FullMethodName, 211 | } 212 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 213 | return srv.(UserServiceServer).GetByID(ctx, req.(*GetProfileByIdReq)) 214 | } 215 | return interceptor(ctx, in, info, handler) 216 | } 217 | 218 | func _UserService_GetByEmail_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 219 | in := new(ByEmail) 220 | if err := dec(in); err != nil { 221 | return nil, err 222 | } 223 | if interceptor == nil { 224 | return srv.(UserServiceServer).GetByEmail(ctx, in) 225 | } 226 | info := &grpc.UnaryServerInfo{ 227 | Server: srv, 228 | FullMethod: UserService_GetByEmail_FullMethodName, 229 | } 230 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 231 | return srv.(UserServiceServer).GetByEmail(ctx, req.(*ByEmail)) 232 | } 233 | return interceptor(ctx, in, info, handler) 234 | } 235 | 236 | // UserService_ServiceDesc is the grpc.ServiceDesc for UserService service. 237 | // It's only intended for direct use with grpc.RegisterService, 238 | // and not to be introspected or modified (even as a copy) 239 | var UserService_ServiceDesc = grpc.ServiceDesc{ 240 | ServiceName: "polling.UserService", 241 | HandlerType: (*UserServiceServer)(nil), 242 | Methods: []grpc.MethodDesc{ 243 | { 244 | MethodName: "Register", 245 | Handler: _UserService_Register_Handler, 246 | }, 247 | { 248 | MethodName: "Profile", 249 | Handler: _UserService_Profile_Handler, 250 | }, 251 | { 252 | MethodName: "IsEmailExists", 253 | Handler: _UserService_IsEmailExists_Handler, 254 | }, 255 | { 256 | MethodName: "GetByID", 257 | Handler: _UserService_GetByID_Handler, 258 | }, 259 | { 260 | MethodName: "GetByEmail", 261 | Handler: _UserService_GetByEmail_Handler, 262 | }, 263 | }, 264 | Streams: []grpc.StreamDesc{}, 265 | Metadata: "protos/users.proto", 266 | } 267 | --------------------------------------------------------------------------------