Compare commits
30 Commits
0960f3e9dc
..
orders
| Author | SHA1 | Date | |
|---|---|---|---|
| c1f9809718 | |||
| 90bd963e00 | |||
| d49b4e9037 | |||
| 8fbeae6fc1 | |||
| 4bd82a34a1 | |||
| 5b7744080c | |||
| 1ea3b427bd | |||
| ffd1396739 | |||
| 30af992172 | |||
| 69b35863e5 | |||
| d65fac53f2 | |||
| 31dcb5708b | |||
| 311c66a861 | |||
| f450407405 | |||
| 2ef4c079e1 | |||
| fc04dcc259 | |||
| ec832194a7 | |||
| 681a67a292 | |||
| 6e4cc2280d | |||
| fe6d333e04 | |||
| 05b10895d3 | |||
| 4f6af5cae9 | |||
| 64eb0569ae | |||
| b9fdfb584b | |||
| 0387e78db8 | |||
| 073d2b2761 | |||
| 0bea4180a1 | |||
| db4419dc81 | |||
| 6b3306bb96 | |||
| afd5536246 |
+64
@@ -0,0 +1,64 @@
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: default
|
||||
|
||||
steps:
|
||||
- name: build
|
||||
image: golang:1.22
|
||||
commands:
|
||||
- CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o cake_crm cmd/cake_crm/main.go
|
||||
|
||||
- name: test
|
||||
image: golang:1.22
|
||||
environment:
|
||||
order_bot_token:
|
||||
from_secret: order_bot_token
|
||||
telegram_order_chat_id:
|
||||
from_secret: telegram_order_chat_id
|
||||
settings:
|
||||
envs: [ order_bot_token, telegram_order_chat_id ]
|
||||
commands:
|
||||
- go test ./...
|
||||
- echo $${order_bot_token} >> order_bot_token.txt
|
||||
- echo $${telegram_order_chat_id} >> telegram_order_chat_id.txt
|
||||
|
||||
- name: scp
|
||||
image: appleboy/drone-scp
|
||||
settings:
|
||||
host:
|
||||
from_secret: server_ip
|
||||
username:
|
||||
from_secret: ssh_user
|
||||
key:
|
||||
from_secret: ssh_key
|
||||
port:
|
||||
from_secret: ssh_port
|
||||
target:
|
||||
- deploys/cake_crm
|
||||
source:
|
||||
- resources
|
||||
- cake_crm
|
||||
- docker-compose.yml
|
||||
- Dockerfile
|
||||
rm: true
|
||||
|
||||
- name: deploy
|
||||
image: appleboy/drone-ssh
|
||||
settings:
|
||||
host:
|
||||
from_secret: server_ip
|
||||
username:
|
||||
from_secret: ssh_user
|
||||
key:
|
||||
from_secret: ssh_key
|
||||
port:
|
||||
from_secret: ssh_port
|
||||
command_timeout: 10s
|
||||
script:
|
||||
- cd deploys/cake_crm
|
||||
- docker-compose up -d --build --force-recreate
|
||||
|
||||
trigger:
|
||||
event:
|
||||
- push
|
||||
|
||||
@@ -1 +1,6 @@
|
||||
.idea
|
||||
|
||||
bin
|
||||
|
||||
resources/order_bot_token.txt
|
||||
resources/telegram_order_chat_id.txt
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
FROM golang:1.22.3-alpine3.19
|
||||
COPY cake_crm /usr/local/bin/cake_crm
|
||||
COPY resources /go/resources
|
||||
RUN chmod +x /usr/local/bin/cake_crm
|
||||
CMD ["cake_crm"]
|
||||
@@ -1,10 +1,17 @@
|
||||
generate:
|
||||
rm -rf proto
|
||||
mkdir -p proto
|
||||
|
||||
protoc -I ./api \
|
||||
protoc \
|
||||
-I ./api \
|
||||
-I ./third_party \
|
||||
--go_out ./proto --go_opt paths=source_relative \
|
||||
--go-grpc_out ./proto --go-grpc_opt paths=source_relative \
|
||||
--grpc-gateway_out ./proto --grpc-gateway_opt paths=source_relative \
|
||||
--swagger_out=allow_merge=true,merge_file_name=main:./proto \
|
||||
--openapiv2_out=./resources \
|
||||
./api/main.proto
|
||||
|
||||
run:
|
||||
go run ./cmd/cake_crm/main.go
|
||||
|
||||
build:
|
||||
go build -o bin/cake_crm cmd/cake_crm/main.go
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
# cake_crm
|
||||
|
||||
Генерация контракта
|
||||
|
||||
```shell
|
||||
make generate
|
||||
```
|
||||
|
||||
Запуск
|
||||
|
||||
```shell
|
||||
make run
|
||||
```
|
||||
+135
-8
@@ -3,8 +3,11 @@ syntax = "proto3";
|
||||
package crabs.crm;
|
||||
|
||||
import "google/api/annotations.proto";
|
||||
import "protoc-gen-openapiv2/options/annotations.proto";
|
||||
|
||||
option go_package = "pkg/crm";
|
||||
option go_package = "pkg/proto";
|
||||
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {};
|
||||
|
||||
service CRM {
|
||||
rpc GetCatalog(GetCatalogReq) returns (CatalogRsp) {
|
||||
@@ -12,17 +15,141 @@ service CRM {
|
||||
get: "/catalog"
|
||||
};
|
||||
}
|
||||
rpc GetPositions(GetPositionsReq) returns (PositionsRsp) {
|
||||
option (google.api.http) = {
|
||||
get: "/positions/{id}"
|
||||
};
|
||||
}
|
||||
rpc GetProduct(GetProductReq) returns (ProductRsp) {
|
||||
option (google.api.http) = {
|
||||
get: "/products/{id}"
|
||||
};
|
||||
}
|
||||
rpc GetBreadcrumbs(GetBreadcrumbsReq) returns (BreadcrumbsRsp) {
|
||||
option (google.api.http) = {
|
||||
get: "/breadcrumbs/{id}"
|
||||
};
|
||||
}
|
||||
rpc Order(OrderReq) returns (OrderRsp) {
|
||||
option (google.api.http) = {
|
||||
post: "/orders"
|
||||
body: "order"
|
||||
};
|
||||
}
|
||||
rpc GetCard(CardReq) returns (CardRsp) {
|
||||
option (google.api.http) = {
|
||||
post: "/card"
|
||||
body: "items"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
message GetCatalogReq {}
|
||||
|
||||
message CatalogRsp {
|
||||
message Category {
|
||||
int64 id = 1;
|
||||
string name = 2;
|
||||
string uri = 3;
|
||||
repeated Category children = 4;
|
||||
}
|
||||
|
||||
repeated Category categories = 1;
|
||||
}
|
||||
|
||||
message Category {
|
||||
int64 id = 1;
|
||||
string name = 2;
|
||||
string uri = 3;
|
||||
repeated Category children = 4;
|
||||
}
|
||||
|
||||
message GetPositionsReq {
|
||||
int64 id = 1;
|
||||
}
|
||||
|
||||
message PositionsRsp {
|
||||
repeated Product products = 1;
|
||||
}
|
||||
|
||||
message Product {
|
||||
int64 id = 1;
|
||||
string article = 2;
|
||||
string name = 3;
|
||||
string uri = 4;
|
||||
repeated string images = 5;
|
||||
string description = 6;
|
||||
repeated GroupedProduct grouped_products = 7;
|
||||
string unit = 8;
|
||||
double inventory = 9;
|
||||
repeated Variant variants = 10;
|
||||
repeated Characteristic characteristics = 11;
|
||||
int64 category = 12;
|
||||
}
|
||||
|
||||
message GroupedProduct {
|
||||
string name = 1;
|
||||
string uri = 2;
|
||||
string image = 3;
|
||||
}
|
||||
|
||||
message Variant {
|
||||
int64 price = 1;
|
||||
repeated Property properties = 2;
|
||||
}
|
||||
|
||||
message Property {
|
||||
string name = 1;
|
||||
string value = 2;
|
||||
}
|
||||
|
||||
message Characteristic {
|
||||
string name = 1;
|
||||
string value = 2;
|
||||
}
|
||||
|
||||
message GetProductReq {
|
||||
int64 id = 1;
|
||||
}
|
||||
|
||||
message ProductRsp {
|
||||
Product product = 1;
|
||||
}
|
||||
|
||||
message GetBreadcrumbsReq {
|
||||
int64 id = 1;
|
||||
}
|
||||
|
||||
message BreadcrumbsRsp {
|
||||
repeated Category categories = 1;
|
||||
}
|
||||
|
||||
message OrderReq {
|
||||
Order order = 1;
|
||||
string name = 2;
|
||||
string phone = 3;
|
||||
}
|
||||
|
||||
message OrderRsp {}
|
||||
|
||||
message Order {
|
||||
repeated OrderItem items = 1;
|
||||
}
|
||||
|
||||
message OrderItem {
|
||||
int64 product_id = 1;
|
||||
int64 count = 2;
|
||||
}
|
||||
|
||||
message CardItem {
|
||||
int64 id = 1;
|
||||
string article = 2;
|
||||
string name = 3;
|
||||
string uri = 4;
|
||||
repeated string images = 5;
|
||||
string unit = 8;
|
||||
double inventory = 9;
|
||||
int64 count = 10;
|
||||
int64 amount = 11;
|
||||
}
|
||||
|
||||
message CardReq {
|
||||
repeated OrderItem items = 1;
|
||||
}
|
||||
|
||||
message CardRsp {
|
||||
repeated CardItem items = 1;
|
||||
}
|
||||
|
||||
+50
-10
@@ -2,8 +2,10 @@ package main
|
||||
|
||||
import (
|
||||
"cake_crm/internal/app"
|
||||
"cake_crm/internal/models/storage/storage_file"
|
||||
crm "cake_crm/proto"
|
||||
"cake_crm/internal/modules/messenger/telegram"
|
||||
"cake_crm/internal/modules/storage/storage_file"
|
||||
"cake_crm/internal/services/card"
|
||||
proto "cake_crm/proto"
|
||||
"context"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
|
||||
"google.golang.org/grpc"
|
||||
@@ -11,14 +13,28 @@ import (
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func main() {
|
||||
//ctx, cancel := context.WithCancel(context.Background())
|
||||
//defer cancel()
|
||||
|
||||
storage := storage_file.NewStorageFile()
|
||||
_ = storage
|
||||
|
||||
cardService := card.NewService(storage)
|
||||
|
||||
tokenData, err := os.ReadFile("resources/order_bot_token.txt")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
token := string(tokenData)
|
||||
|
||||
chatIdData, err := os.ReadFile("resources/telegram_order_chat_id.txt")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
chatID, err := strconv.ParseInt(string(chatIdData), 10, 64)
|
||||
|
||||
messenger, err := telegram.NewMessenger(chatID, token)
|
||||
|
||||
// Create a listener on TCP port
|
||||
lis, err := net.Listen("tcp", ":8080")
|
||||
@@ -29,7 +45,7 @@ func main() {
|
||||
// Create a gRPC server object
|
||||
s := grpc.NewServer()
|
||||
// Attach the Greeter service to the server
|
||||
crm.RegisterCRMServer(s, app.NewServer(storage))
|
||||
proto.RegisterCRMServer(s, app.NewServer(storage, messenger, cardService))
|
||||
// Serve gRPC server
|
||||
log.Println("Serving gRPC on 0.0.0.0:8080")
|
||||
go func() {
|
||||
@@ -46,18 +62,42 @@ func main() {
|
||||
log.Fatalln("Failed to dial server:", err)
|
||||
}
|
||||
|
||||
gwmux := runtime.NewServeMux()
|
||||
mux := runtime.NewServeMux()
|
||||
// Register Greeter
|
||||
err = crm.RegisterCRMHandler(context.Background(), gwmux, conn)
|
||||
err = proto.RegisterCRMHandler(context.Background(), mux, conn)
|
||||
if err != nil {
|
||||
log.Fatalln("Failed to register gateway:", err)
|
||||
}
|
||||
|
||||
err = mux.HandlePath("GET", "/swagger", func(w http.ResponseWriter, r *http.Request, pathParams map[string]string) {
|
||||
data, err := os.ReadFile("resources/main.swagger.json")
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
}
|
||||
_, _ = w.Write(data)
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
log.Println("Serving swagger json on http://0.0.0.0:8090/swagger")
|
||||
|
||||
gwServer := &http.Server{
|
||||
Addr: ":8090",
|
||||
Handler: gwmux,
|
||||
Handler: cors(mux),
|
||||
}
|
||||
|
||||
log.Println("Serving gRPC-Gateway on http://0.0.0.0:8090")
|
||||
log.Fatalln(gwServer.ListenAndServe())
|
||||
}
|
||||
|
||||
func cors(h http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PATCH, DELETE")
|
||||
w.Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, Authorization, ResponseType")
|
||||
if r.Method == "OPTIONS" {
|
||||
return
|
||||
}
|
||||
h.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
cake_crm:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
ports:
|
||||
- "8080:8090"
|
||||
|
||||
@@ -3,7 +3,7 @@ module cake_crm
|
||||
go 1.22
|
||||
|
||||
require (
|
||||
github.com/go-pkgz/routegroup v1.1.1
|
||||
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240513163218-0867130af1f8
|
||||
google.golang.org/grpc v1.64.0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
github.com/go-pkgz/routegroup v1.1.1 h1:Dm5IBiEmUbQT+3rliBimhX0SifnZp/uRF/WOu3XPmms=
|
||||
github.com/go-pkgz/routegroup v1.1.1/go.mod h1:kDDPDRLRiRY1vnENrZJw1jQAzQX7fvsbsHGRQFNQfKc=
|
||||
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 h1:wG8n/XJQ07TmjbITcGiUaOtXxdrINDz1b0J1w0SzqDc=
|
||||
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1/go.mod h1:A2S0CWkNylc2phvKXWBBdD3K0iGnDBGbzRpISP2zBl8=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0=
|
||||
|
||||
+93
-8
@@ -1,26 +1,111 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"cake_crm/internal/models/storage"
|
||||
crm "cake_crm/proto"
|
||||
"bytes"
|
||||
"cake_crm/internal/modules/messenger"
|
||||
"cake_crm/internal/modules/storage"
|
||||
"cake_crm/internal/services/card"
|
||||
proto "cake_crm/proto"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
crm.UnimplementedCRMServer
|
||||
storage storage.IStorage
|
||||
proto.UnsafeCRMServer
|
||||
storage storage.IStorage
|
||||
messenger messenger.IMessenger
|
||||
cardService *card.Service
|
||||
}
|
||||
|
||||
func NewServer(storage storage.IStorage) *Server {
|
||||
func NewServer(storage storage.IStorage, messenger messenger.IMessenger, cardService *card.Service) proto.CRMServer {
|
||||
return &Server{
|
||||
storage: storage,
|
||||
storage: storage,
|
||||
messenger: messenger,
|
||||
cardService: cardService,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) GetCatalog(ctx context.Context, _ *crm.GetCatalogReq) (*crm.CatalogRsp, error) {
|
||||
func (s *Server) GetCatalog(ctx context.Context, _ *proto.GetCatalogReq) (*proto.CatalogRsp, error) {
|
||||
categories, err := s.storage.GetCatalog(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &crm.CatalogRsp{Categories: categories}, nil
|
||||
return &proto.CatalogRsp{Categories: categories}, nil
|
||||
}
|
||||
|
||||
func (s *Server) GetPositions(ctx context.Context, req *proto.GetPositionsReq) (*proto.PositionsRsp, error) {
|
||||
products, err := s.storage.GetPositions(ctx, req.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &proto.PositionsRsp{Products: products}, nil
|
||||
}
|
||||
|
||||
func (s *Server) GetProduct(ctx context.Context, req *proto.GetProductReq) (*proto.ProductRsp, error) {
|
||||
product, err := s.storage.GetProduct(ctx, req.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &proto.ProductRsp{Product: product}, nil
|
||||
}
|
||||
|
||||
func (s *Server) GetBreadcrumbs(ctx context.Context, req *proto.GetBreadcrumbsReq) (*proto.BreadcrumbsRsp, error) {
|
||||
breadcrumbs, err := s.storage.GetBreadcrumbs(ctx, req.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &proto.BreadcrumbsRsp{Categories: breadcrumbs}, nil
|
||||
}
|
||||
|
||||
func (s *Server) Order(ctx context.Context, req *proto.OrderReq) (*proto.OrderRsp, error) {
|
||||
enrichItems, err := s.cardService.GetCard(ctx, req.Order.Items)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
text, err := createOrderText(req, enrichItems)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &proto.OrderRsp{}, s.messenger.SendMessage(text)
|
||||
}
|
||||
|
||||
func createOrderText(req *proto.OrderReq, items []*proto.CardItem) (string, error) {
|
||||
buffer := bytes.Buffer{}
|
||||
var orderAmount int64
|
||||
buffer.WriteString(fmt.Sprintf("Заказ от:\n%s\n%s\n", req.Name, req.Phone))
|
||||
buffer.WriteString("\n")
|
||||
for _, item := range items {
|
||||
buffer.WriteString(item.Name)
|
||||
buffer.WriteString("\n")
|
||||
unit, err := unitToText(item.Unit)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
buffer.WriteString(fmt.Sprintf("Количество: %d%s\n", item.Count, unit))
|
||||
orderAmount += item.Amount
|
||||
buffer.WriteString(fmt.Sprintf("Сумма: %.00fр\n", float64(item.Amount)/100))
|
||||
buffer.WriteString("\n")
|
||||
}
|
||||
buffer.WriteString("\n")
|
||||
buffer.WriteString(fmt.Sprintf("ИТОГО: %.00fр\n", float64(orderAmount)/100))
|
||||
return buffer.String(), nil
|
||||
}
|
||||
|
||||
func unitToText(unit string) (string, error) {
|
||||
switch unit {
|
||||
case "kg":
|
||||
return "кг", nil
|
||||
case "piece":
|
||||
return "шт", nil
|
||||
}
|
||||
return "", errors.New("unit not found")
|
||||
}
|
||||
|
||||
func (s *Server) GetCard(ctx context.Context, req *proto.CardReq) (*proto.CardRsp, error) {
|
||||
enrichItems, err := s.cardService.GetCard(ctx, req.Items)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &proto.CardRsp{Items: enrichItems}, nil
|
||||
}
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
crm "cake_crm/proto"
|
||||
"context"
|
||||
)
|
||||
|
||||
type Product struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
// todo
|
||||
}
|
||||
|
||||
type Breadcrumb struct {
|
||||
Name string `json:"name"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
type IStorage interface {
|
||||
GetAllProducts(ctx context.Context) ([]Product, error)
|
||||
GetProductByID(ctx context.Context, id int) (Product, error)
|
||||
GetBreadcrumbs(ctx context.Context, id int) ([]Breadcrumb, error)
|
||||
GetCatalog(ctx context.Context) ([]*crm.CatalogRsp_Category, error)
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
package storage_file
|
||||
|
||||
import (
|
||||
"cake_crm/internal/models/storage"
|
||||
crm "cake_crm/proto"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"os"
|
||||
)
|
||||
|
||||
type storageFile struct{}
|
||||
|
||||
func NewStorageFile() storage.IStorage {
|
||||
return &storageFile{}
|
||||
}
|
||||
|
||||
func (s *storageFile) GetCatalog(_ context.Context) ([]*crm.CatalogRsp_Category, error) {
|
||||
data, err := os.ReadFile("resources/catalog.json")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var res []*crm.CatalogRsp_Category
|
||||
if err := json.Unmarshal(data, &res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (s *storageFile) GetAllProducts(ctx context.Context) ([]storage.Product, error) {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (s *storageFile) GetProductByID(ctx context.Context, id int) (storage.Product, error) {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (s *storageFile) GetBreadcrumbs(ctx context.Context, id int) ([]storage.Breadcrumb, error) {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package messenger
|
||||
|
||||
type IMessenger interface {
|
||||
SendMessage(message string) error
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package telegram
|
||||
|
||||
import (
|
||||
"cake_crm/internal/modules/messenger"
|
||||
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
|
||||
)
|
||||
|
||||
type messengerTelegram struct {
|
||||
chatID int64
|
||||
bot *tgbotapi.BotAPI
|
||||
}
|
||||
|
||||
func NewMessenger(
|
||||
chatID int64,
|
||||
token string,
|
||||
) (messenger.IMessenger, error) {
|
||||
bot, err := tgbotapi.NewBotAPI(token)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &messengerTelegram{
|
||||
chatID: chatID,
|
||||
bot: bot,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (m *messengerTelegram) SendMessage(message string) error {
|
||||
_, err := m.bot.Send(tgbotapi.NewMessage(m.chatID, message))
|
||||
return err
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
crm "cake_crm/proto"
|
||||
"context"
|
||||
)
|
||||
|
||||
type IStorage interface {
|
||||
GetCatalog(ctx context.Context) ([]*crm.Category, error)
|
||||
GetPositions(ctx context.Context, id int64) ([]*crm.Product, error)
|
||||
GetProduct(ctx context.Context, id int64) (*crm.Product, error)
|
||||
GetBreadcrumbs(ctx context.Context, id int64) ([]*crm.Category, error)
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package storage_file
|
||||
|
||||
import (
|
||||
"cake_crm/internal/modules/storage"
|
||||
crm "cake_crm/proto"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"os"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrProductNotFound = errors.New("product not found")
|
||||
)
|
||||
|
||||
type storageFile struct{}
|
||||
|
||||
func NewStorageFile() storage.IStorage {
|
||||
return &storageFile{}
|
||||
}
|
||||
|
||||
func (s *storageFile) GetCatalog(_ context.Context) ([]*crm.Category, error) {
|
||||
data, err := os.ReadFile("resources/catalog.json")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var res []*crm.Category
|
||||
if err := json.Unmarshal(data, &res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (s *storageFile) GetPositions(_ context.Context, id int64) ([]*crm.Product, error) {
|
||||
data, err := os.ReadFile("resources/products.json")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var products []*crm.Product
|
||||
if err := json.Unmarshal(data, &products); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res := make([]*crm.Product, 0, len(products))
|
||||
for _, product := range products {
|
||||
if id == 0 || product.Category == id {
|
||||
res = append(res, product)
|
||||
}
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (s *storageFile) GetProduct(_ context.Context, id int64) (*crm.Product, error) {
|
||||
data, err := os.ReadFile("resources/products.json")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var products []*crm.Product
|
||||
if err := json.Unmarshal(data, &products); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, product := range products {
|
||||
if product.Id == id {
|
||||
return product, nil
|
||||
}
|
||||
}
|
||||
return nil, ErrProductNotFound
|
||||
}
|
||||
|
||||
func (s *storageFile) GetBreadcrumbs(_ context.Context, id int64) ([]*crm.Category, error) {
|
||||
data, err := os.ReadFile("resources/catalog.json")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var categories []*crm.Category
|
||||
if err := json.Unmarshal(data, &categories); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return getBreadcrumbs(categories, id), nil
|
||||
}
|
||||
|
||||
func getBreadcrumbs(categories []*crm.Category, id int64) []*crm.Category {
|
||||
for _, category := range categories {
|
||||
if category.Id == id {
|
||||
category.Children = nil
|
||||
return []*crm.Category{category}
|
||||
}
|
||||
breadcrumbs := getBreadcrumbs(category.Children, id)
|
||||
if len(breadcrumbs) != 0 {
|
||||
res := make([]*crm.Category, 0, len(breadcrumbs)+1)
|
||||
category.Children = nil
|
||||
res = append(res, category)
|
||||
res = append(res, breadcrumbs...)
|
||||
return res
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package card
|
||||
|
||||
import (
|
||||
"cake_crm/internal/modules/storage"
|
||||
"cake_crm/proto"
|
||||
"context"
|
||||
"errors"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type ProductAndCount struct {
|
||||
product *proto.Product
|
||||
count int64
|
||||
}
|
||||
|
||||
type Service struct {
|
||||
storage storage.IStorage
|
||||
}
|
||||
|
||||
func NewService(storage storage.IStorage) *Service {
|
||||
return &Service{
|
||||
storage: storage,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) GetCard(ctx context.Context, items []*proto.OrderItem) ([]*proto.CardItem, error) {
|
||||
res := make([]*proto.CardItem, 0, len(items))
|
||||
for _, item := range items {
|
||||
product, err := s.storage.GetProduct(ctx, item.ProductId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
amount, err := calcItemAmount(
|
||||
&ProductAndCount{
|
||||
product: product,
|
||||
count: item.Count,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res = append(
|
||||
res,
|
||||
&proto.CardItem{
|
||||
Id: product.Id,
|
||||
Article: product.Article,
|
||||
Name: product.Name,
|
||||
Uri: product.Uri,
|
||||
Images: product.Images,
|
||||
Unit: product.Unit,
|
||||
Inventory: product.Inventory,
|
||||
Count: item.Count,
|
||||
Amount: amount,
|
||||
},
|
||||
)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func calcItemAmount(item *ProductAndCount) (int64, error) {
|
||||
var variant *proto.Variant
|
||||
for _, v := range item.product.Variants {
|
||||
check := true
|
||||
for _, property := range v.Properties {
|
||||
if property.Name == "min" {
|
||||
minBorder, err := strconv.ParseInt(property.Value, 10, 64)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if item.count < minBorder {
|
||||
check = false
|
||||
}
|
||||
}
|
||||
if property.Name == "max" {
|
||||
maxBorder, err := strconv.ParseInt(property.Value, 10, 64)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if item.count > maxBorder {
|
||||
check = false
|
||||
}
|
||||
}
|
||||
if check {
|
||||
variant = v
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if variant == nil {
|
||||
return 0, errors.New("variant not found")
|
||||
}
|
||||
return variant.Price * item.count, nil
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package server_web
|
||||
|
||||
import "context"
|
||||
|
||||
type IServer interface {
|
||||
Run(ctx context.Context) error
|
||||
Stop(ctx context.Context) error
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
package server_web
|
||||
|
||||
import (
|
||||
"cake_crm/internal/models/storage"
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/go-pkgz/routegroup"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type server struct {
|
||||
storage storage.IStorage
|
||||
port int
|
||||
}
|
||||
|
||||
func NewServer(
|
||||
storage storage.IStorage,
|
||||
port int,
|
||||
) IServer {
|
||||
return &server{
|
||||
storage: storage,
|
||||
port: port,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *server) Run(ctx context.Context) error {
|
||||
router := routegroup.New(http.NewServeMux())
|
||||
router.HandleFunc("GET /products", s.getAllProductsHandler)
|
||||
router.HandleFunc("GET /products/:id", s.getProductById)
|
||||
router.HandleFunc("GET /category/:id/breadcrumbs", s.getBreadcrumbsByCategoryId)
|
||||
return http.ListenAndServe(fmt.Sprintf(":%d", s.port), router)
|
||||
}
|
||||
|
||||
func (s *server) Stop(ctx context.Context) error {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (s *server) getAllProductsHandler(w http.ResponseWriter, r *http.Request) {}
|
||||
|
||||
func (s *server) getProductById(w http.ResponseWriter, r *http.Request) {}
|
||||
|
||||
func (s *server) getBreadcrumbsByCategoryId(w http.ResponseWriter, r *http.Request) {}
|
||||
+1489
-55
File diff suppressed because it is too large
Load Diff
+483
-2
@@ -2,11 +2,11 @@
|
||||
// source: main.proto
|
||||
|
||||
/*
|
||||
Package crm is a reverse proxy.
|
||||
Package proto is a reverse proxy.
|
||||
|
||||
It translates gRPC into RESTful JSON APIs.
|
||||
*/
|
||||
package crm
|
||||
package proto
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -49,6 +49,232 @@ func local_request_CRM_GetCatalog_0(ctx context.Context, marshaler runtime.Marsh
|
||||
|
||||
}
|
||||
|
||||
func request_CRM_GetPositions_0(ctx context.Context, marshaler runtime.Marshaler, client CRMClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq GetPositionsReq
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
|
||||
}
|
||||
|
||||
protoReq.Id, err = runtime.Int64(val)
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
|
||||
}
|
||||
|
||||
msg, err := client.GetPositions(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_CRM_GetPositions_0(ctx context.Context, marshaler runtime.Marshaler, server CRMServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq GetPositionsReq
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
|
||||
}
|
||||
|
||||
protoReq.Id, err = runtime.Int64(val)
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
|
||||
}
|
||||
|
||||
msg, err := server.GetPositions(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func request_CRM_GetProduct_0(ctx context.Context, marshaler runtime.Marshaler, client CRMClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq GetProductReq
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
|
||||
}
|
||||
|
||||
protoReq.Id, err = runtime.Int64(val)
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
|
||||
}
|
||||
|
||||
msg, err := client.GetProduct(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_CRM_GetProduct_0(ctx context.Context, marshaler runtime.Marshaler, server CRMServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq GetProductReq
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
|
||||
}
|
||||
|
||||
protoReq.Id, err = runtime.Int64(val)
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
|
||||
}
|
||||
|
||||
msg, err := server.GetProduct(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func request_CRM_GetBreadcrumbs_0(ctx context.Context, marshaler runtime.Marshaler, client CRMClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq GetBreadcrumbsReq
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
|
||||
}
|
||||
|
||||
protoReq.Id, err = runtime.Int64(val)
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
|
||||
}
|
||||
|
||||
msg, err := client.GetBreadcrumbs(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_CRM_GetBreadcrumbs_0(ctx context.Context, marshaler runtime.Marshaler, server CRMServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq GetBreadcrumbsReq
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
|
||||
}
|
||||
|
||||
protoReq.Id, err = runtime.Int64(val)
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
|
||||
}
|
||||
|
||||
msg, err := server.GetBreadcrumbs(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
var (
|
||||
filter_CRM_Order_0 = &utilities.DoubleArray{Encoding: map[string]int{"order": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}}
|
||||
)
|
||||
|
||||
func request_CRM_Order_0(ctx context.Context, marshaler runtime.Marshaler, client CRMClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq OrderReq
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq.Order); err != nil && err != io.EOF {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
if err := req.ParseForm(); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_CRM_Order_0); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := client.Order(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_CRM_Order_0(ctx context.Context, marshaler runtime.Marshaler, server CRMServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq OrderReq
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq.Order); err != nil && err != io.EOF {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
if err := req.ParseForm(); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_CRM_Order_0); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := server.Order(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func request_CRM_GetCard_0(ctx context.Context, marshaler runtime.Marshaler, client CRMClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq CardReq
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq.Items); err != nil && err != io.EOF {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := client.GetCard(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_CRM_GetCard_0(ctx context.Context, marshaler runtime.Marshaler, server CRMServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq CardReq
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq.Items); err != nil && err != io.EOF {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := server.GetCard(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
// RegisterCRMHandlerServer registers the http handlers for service CRM to "mux".
|
||||
// UnaryRPC :call CRMServer directly.
|
||||
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
|
||||
@@ -80,6 +306,131 @@ func RegisterCRMHandlerServer(ctx context.Context, mux *runtime.ServeMux, server
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_CRM_GetPositions_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
var stream runtime.ServerTransportStream
|
||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
var err error
|
||||
var annotatedContext context.Context
|
||||
annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/crabs.crm.CRM/GetPositions", runtime.WithHTTPPathPattern("/positions/{id}"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_CRM_GetPositions_0(annotatedContext, inboundMarshaler, server, req, pathParams)
|
||||
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_CRM_GetPositions_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_CRM_GetProduct_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
var stream runtime.ServerTransportStream
|
||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
var err error
|
||||
var annotatedContext context.Context
|
||||
annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/crabs.crm.CRM/GetProduct", runtime.WithHTTPPathPattern("/products/{id}"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_CRM_GetProduct_0(annotatedContext, inboundMarshaler, server, req, pathParams)
|
||||
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_CRM_GetProduct_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_CRM_GetBreadcrumbs_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
var stream runtime.ServerTransportStream
|
||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
var err error
|
||||
var annotatedContext context.Context
|
||||
annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/crabs.crm.CRM/GetBreadcrumbs", runtime.WithHTTPPathPattern("/breadcrumbs/{id}"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_CRM_GetBreadcrumbs_0(annotatedContext, inboundMarshaler, server, req, pathParams)
|
||||
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_CRM_GetBreadcrumbs_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("POST", pattern_CRM_Order_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
var stream runtime.ServerTransportStream
|
||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
var err error
|
||||
var annotatedContext context.Context
|
||||
annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/crabs.crm.CRM/Order", runtime.WithHTTPPathPattern("/orders"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_CRM_Order_0(annotatedContext, inboundMarshaler, server, req, pathParams)
|
||||
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_CRM_Order_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("POST", pattern_CRM_GetCard_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
var stream runtime.ServerTransportStream
|
||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
var err error
|
||||
var annotatedContext context.Context
|
||||
annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/crabs.crm.CRM/GetCard", runtime.WithHTTPPathPattern("/card"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_CRM_GetCard_0(annotatedContext, inboundMarshaler, server, req, pathParams)
|
||||
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_CRM_GetCard_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -143,13 +494,143 @@ func RegisterCRMHandlerClient(ctx context.Context, mux *runtime.ServeMux, client
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_CRM_GetPositions_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
var err error
|
||||
var annotatedContext context.Context
|
||||
annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/crabs.crm.CRM/GetPositions", runtime.WithHTTPPathPattern("/positions/{id}"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_CRM_GetPositions_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_CRM_GetPositions_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_CRM_GetProduct_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
var err error
|
||||
var annotatedContext context.Context
|
||||
annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/crabs.crm.CRM/GetProduct", runtime.WithHTTPPathPattern("/products/{id}"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_CRM_GetProduct_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_CRM_GetProduct_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_CRM_GetBreadcrumbs_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
var err error
|
||||
var annotatedContext context.Context
|
||||
annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/crabs.crm.CRM/GetBreadcrumbs", runtime.WithHTTPPathPattern("/breadcrumbs/{id}"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_CRM_GetBreadcrumbs_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_CRM_GetBreadcrumbs_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("POST", pattern_CRM_Order_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
var err error
|
||||
var annotatedContext context.Context
|
||||
annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/crabs.crm.CRM/Order", runtime.WithHTTPPathPattern("/orders"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_CRM_Order_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_CRM_Order_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("POST", pattern_CRM_GetCard_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
var err error
|
||||
var annotatedContext context.Context
|
||||
annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/crabs.crm.CRM/GetCard", runtime.WithHTTPPathPattern("/card"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_CRM_GetCard_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_CRM_GetCard_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
pattern_CRM_GetCatalog_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0}, []string{"catalog"}, ""))
|
||||
|
||||
pattern_CRM_GetPositions_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1}, []string{"positions", "id"}, ""))
|
||||
|
||||
pattern_CRM_GetProduct_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1}, []string{"products", "id"}, ""))
|
||||
|
||||
pattern_CRM_GetBreadcrumbs_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1}, []string{"breadcrumbs", "id"}, ""))
|
||||
|
||||
pattern_CRM_Order_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0}, []string{"orders"}, ""))
|
||||
|
||||
pattern_CRM_GetCard_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0}, []string{"card"}, ""))
|
||||
)
|
||||
|
||||
var (
|
||||
forward_CRM_GetCatalog_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_CRM_GetPositions_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_CRM_GetProduct_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_CRM_GetBreadcrumbs_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_CRM_Order_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_CRM_GetCard_0 = runtime.ForwardResponseMessage
|
||||
)
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
{
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"title": "main.proto",
|
||||
"version": "version not set"
|
||||
},
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"paths": {
|
||||
"/catalog": {
|
||||
"get": {
|
||||
"operationId": "CRM_GetCatalog",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/crmCatalogRsp"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/runtimeError"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"CRM"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"CatalogRspCategory": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"format": "int64"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"uri": {
|
||||
"type": "string"
|
||||
},
|
||||
"children": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/CatalogRspCategory"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"crmCatalogRsp": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"categories": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/CatalogRspCategory"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"protobufAny": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type_url": {
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
"type": "string",
|
||||
"format": "byte"
|
||||
}
|
||||
}
|
||||
},
|
||||
"runtimeError": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"error": {
|
||||
"type": "string"
|
||||
},
|
||||
"code": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"details": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/protobufAny"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+187
-2
@@ -4,7 +4,7 @@
|
||||
// - protoc v5.26.1
|
||||
// source: main.proto
|
||||
|
||||
package crm
|
||||
package proto
|
||||
|
||||
import (
|
||||
context "context"
|
||||
@@ -19,7 +19,12 @@ import (
|
||||
const _ = grpc.SupportPackageIsVersion7
|
||||
|
||||
const (
|
||||
CRM_GetCatalog_FullMethodName = "/crabs.crm.CRM/GetCatalog"
|
||||
CRM_GetCatalog_FullMethodName = "/crabs.crm.CRM/GetCatalog"
|
||||
CRM_GetPositions_FullMethodName = "/crabs.crm.CRM/GetPositions"
|
||||
CRM_GetProduct_FullMethodName = "/crabs.crm.CRM/GetProduct"
|
||||
CRM_GetBreadcrumbs_FullMethodName = "/crabs.crm.CRM/GetBreadcrumbs"
|
||||
CRM_Order_FullMethodName = "/crabs.crm.CRM/Order"
|
||||
CRM_GetCard_FullMethodName = "/crabs.crm.CRM/GetCard"
|
||||
)
|
||||
|
||||
// CRMClient is the client API for CRM service.
|
||||
@@ -27,6 +32,11 @@ const (
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type CRMClient interface {
|
||||
GetCatalog(ctx context.Context, in *GetCatalogReq, opts ...grpc.CallOption) (*CatalogRsp, error)
|
||||
GetPositions(ctx context.Context, in *GetPositionsReq, opts ...grpc.CallOption) (*PositionsRsp, error)
|
||||
GetProduct(ctx context.Context, in *GetProductReq, opts ...grpc.CallOption) (*ProductRsp, error)
|
||||
GetBreadcrumbs(ctx context.Context, in *GetBreadcrumbsReq, opts ...grpc.CallOption) (*BreadcrumbsRsp, error)
|
||||
Order(ctx context.Context, in *OrderReq, opts ...grpc.CallOption) (*OrderRsp, error)
|
||||
GetCard(ctx context.Context, in *CardReq, opts ...grpc.CallOption) (*CardRsp, error)
|
||||
}
|
||||
|
||||
type cRMClient struct {
|
||||
@@ -46,11 +56,61 @@ func (c *cRMClient) GetCatalog(ctx context.Context, in *GetCatalogReq, opts ...g
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *cRMClient) GetPositions(ctx context.Context, in *GetPositionsReq, opts ...grpc.CallOption) (*PositionsRsp, error) {
|
||||
out := new(PositionsRsp)
|
||||
err := c.cc.Invoke(ctx, CRM_GetPositions_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *cRMClient) GetProduct(ctx context.Context, in *GetProductReq, opts ...grpc.CallOption) (*ProductRsp, error) {
|
||||
out := new(ProductRsp)
|
||||
err := c.cc.Invoke(ctx, CRM_GetProduct_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *cRMClient) GetBreadcrumbs(ctx context.Context, in *GetBreadcrumbsReq, opts ...grpc.CallOption) (*BreadcrumbsRsp, error) {
|
||||
out := new(BreadcrumbsRsp)
|
||||
err := c.cc.Invoke(ctx, CRM_GetBreadcrumbs_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *cRMClient) Order(ctx context.Context, in *OrderReq, opts ...grpc.CallOption) (*OrderRsp, error) {
|
||||
out := new(OrderRsp)
|
||||
err := c.cc.Invoke(ctx, CRM_Order_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *cRMClient) GetCard(ctx context.Context, in *CardReq, opts ...grpc.CallOption) (*CardRsp, error) {
|
||||
out := new(CardRsp)
|
||||
err := c.cc.Invoke(ctx, CRM_GetCard_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// CRMServer is the server API for CRM service.
|
||||
// All implementations must embed UnimplementedCRMServer
|
||||
// for forward compatibility
|
||||
type CRMServer interface {
|
||||
GetCatalog(context.Context, *GetCatalogReq) (*CatalogRsp, error)
|
||||
GetPositions(context.Context, *GetPositionsReq) (*PositionsRsp, error)
|
||||
GetProduct(context.Context, *GetProductReq) (*ProductRsp, error)
|
||||
GetBreadcrumbs(context.Context, *GetBreadcrumbsReq) (*BreadcrumbsRsp, error)
|
||||
Order(context.Context, *OrderReq) (*OrderRsp, error)
|
||||
GetCard(context.Context, *CardReq) (*CardRsp, error)
|
||||
mustEmbedUnimplementedCRMServer()
|
||||
}
|
||||
|
||||
@@ -61,6 +121,21 @@ type UnimplementedCRMServer struct {
|
||||
func (UnimplementedCRMServer) GetCatalog(context.Context, *GetCatalogReq) (*CatalogRsp, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetCatalog not implemented")
|
||||
}
|
||||
func (UnimplementedCRMServer) GetPositions(context.Context, *GetPositionsReq) (*PositionsRsp, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetPositions not implemented")
|
||||
}
|
||||
func (UnimplementedCRMServer) GetProduct(context.Context, *GetProductReq) (*ProductRsp, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetProduct not implemented")
|
||||
}
|
||||
func (UnimplementedCRMServer) GetBreadcrumbs(context.Context, *GetBreadcrumbsReq) (*BreadcrumbsRsp, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetBreadcrumbs not implemented")
|
||||
}
|
||||
func (UnimplementedCRMServer) Order(context.Context, *OrderReq) (*OrderRsp, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Order not implemented")
|
||||
}
|
||||
func (UnimplementedCRMServer) GetCard(context.Context, *CardReq) (*CardRsp, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetCard not implemented")
|
||||
}
|
||||
func (UnimplementedCRMServer) mustEmbedUnimplementedCRMServer() {}
|
||||
|
||||
// UnsafeCRMServer may be embedded to opt out of forward compatibility for this service.
|
||||
@@ -92,6 +167,96 @@ func _CRM_GetCatalog_Handler(srv interface{}, ctx context.Context, dec func(inte
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _CRM_GetPositions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetPositionsReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(CRMServer).GetPositions(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: CRM_GetPositions_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(CRMServer).GetPositions(ctx, req.(*GetPositionsReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _CRM_GetProduct_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetProductReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(CRMServer).GetProduct(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: CRM_GetProduct_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(CRMServer).GetProduct(ctx, req.(*GetProductReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _CRM_GetBreadcrumbs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetBreadcrumbsReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(CRMServer).GetBreadcrumbs(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: CRM_GetBreadcrumbs_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(CRMServer).GetBreadcrumbs(ctx, req.(*GetBreadcrumbsReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _CRM_Order_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(OrderReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(CRMServer).Order(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: CRM_Order_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(CRMServer).Order(ctx, req.(*OrderReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _CRM_GetCard_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(CardReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(CRMServer).GetCard(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: CRM_GetCard_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(CRMServer).GetCard(ctx, req.(*CardReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// CRM_ServiceDesc is the grpc.ServiceDesc for CRM service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
@@ -103,6 +268,26 @@ var CRM_ServiceDesc = grpc.ServiceDesc{
|
||||
MethodName: "GetCatalog",
|
||||
Handler: _CRM_GetCatalog_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetPositions",
|
||||
Handler: _CRM_GetPositions_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetProduct",
|
||||
Handler: _CRM_GetProduct_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetBreadcrumbs",
|
||||
Handler: _CRM_GetBreadcrumbs_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Order",
|
||||
Handler: _CRM_Order_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetCard",
|
||||
Handler: _CRM_GetCard_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "main.proto",
|
||||
|
||||
@@ -1,128 +0,0 @@
|
||||
{
|
||||
"products": [
|
||||
{
|
||||
"id": 1,
|
||||
"article": "1",
|
||||
"name": "\"Глаголик\" ванильно-сливочный",
|
||||
"url": "/products/1",
|
||||
"images": [
|
||||
"/products/1/image-1-600x600.jpg",
|
||||
"/products/1/image-2-600x600.jpg",
|
||||
"/products/1/image-3-600x600.jpg"
|
||||
],
|
||||
"description": "",
|
||||
"grouped_products": [
|
||||
{
|
||||
"name": "\"Глаголик\" лимонный",
|
||||
"url": "/products/2",
|
||||
"image": "/products/2/image-100x100.jpg"
|
||||
},
|
||||
{
|
||||
"name": "\"Глаголик\" мятный",
|
||||
"url": "/products/3",
|
||||
"image": "/products/3/image-100x100.jpg"
|
||||
}
|
||||
],
|
||||
"unit": "kg",
|
||||
"inventory": 100,
|
||||
"variants": [
|
||||
{
|
||||
"price": 16500,
|
||||
"properties": [
|
||||
{
|
||||
"name": "min",
|
||||
"value": "0"
|
||||
},
|
||||
{
|
||||
"name": "max",
|
||||
"value": "5"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"price": 16000,
|
||||
"properties": [
|
||||
{
|
||||
"name": "min",
|
||||
"value": "6"
|
||||
},
|
||||
{
|
||||
"name": "max",
|
||||
"value": "60"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"price": 15500,
|
||||
"properties": [
|
||||
{
|
||||
"name": "min",
|
||||
"value": "61"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"characteristics": [
|
||||
{
|
||||
"name": "Вкус",
|
||||
"value": "Ванильно-сливочный"
|
||||
}
|
||||
],
|
||||
"category": "1"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"article": "4",
|
||||
"name": "Пахлава ореховая экран 1,5 кг",
|
||||
"url": "/products/4",
|
||||
"images": [
|
||||
"/products/4/image-1-600x600.jpg",
|
||||
"/products/4/image-2-600x600.jpg",
|
||||
"/products/4/image-3-600x600.jpg"
|
||||
],
|
||||
"description": "",
|
||||
"grouped_products": [],
|
||||
"unit": "piece",
|
||||
"inventory": 100,
|
||||
"variants": [
|
||||
{
|
||||
"price": 29000,
|
||||
"properties": [
|
||||
{
|
||||
"name": "min",
|
||||
"value": "0"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"characteristics": [
|
||||
{
|
||||
"name": "Вкус",
|
||||
"value": "Ореховая"
|
||||
}
|
||||
],
|
||||
"category": "2"
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"id": 0,
|
||||
"name": "Главная",
|
||||
"url": "/categories/0",
|
||||
"children": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Пряники",
|
||||
"url": "/categories/1",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "Пахлава",
|
||||
"url": "/categories/2",
|
||||
"children": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,501 @@
|
||||
{
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"title": "main.proto",
|
||||
"version": "version not set"
|
||||
},
|
||||
"tags": [
|
||||
{
|
||||
"name": "CRM"
|
||||
}
|
||||
],
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"paths": {
|
||||
"/breadcrumbs/{id}": {
|
||||
"get": {
|
||||
"operationId": "CRM_GetBreadcrumbs",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/crmBreadcrumbsRsp"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"type": "string",
|
||||
"format": "int64"
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"CRM"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/card": {
|
||||
"post": {
|
||||
"operationId": "CRM_GetCard",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/crmCardRsp"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "items",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/crmOrderItem"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"CRM"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/catalog": {
|
||||
"get": {
|
||||
"operationId": "CRM_GetCatalog",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/crmCatalogRsp"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"CRM"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/orders": {
|
||||
"post": {
|
||||
"operationId": "CRM_Order",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/crmOrderRsp"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "order",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/crabscrmOrder"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "phone",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"CRM"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/positions/{id}": {
|
||||
"get": {
|
||||
"operationId": "CRM_GetPositions",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/crmPositionsRsp"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"type": "string",
|
||||
"format": "int64"
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"CRM"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/products/{id}": {
|
||||
"get": {
|
||||
"operationId": "CRM_GetProduct",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/crmProductRsp"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"type": "string",
|
||||
"format": "int64"
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"CRM"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"crabscrmOrder": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/crmOrderItem"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"crmBreadcrumbsRsp": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"categories": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/crmCategory"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"crmCardItem": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"format": "int64"
|
||||
},
|
||||
"article": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"uri": {
|
||||
"type": "string"
|
||||
},
|
||||
"images": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"unit": {
|
||||
"type": "string"
|
||||
},
|
||||
"inventory": {
|
||||
"type": "number",
|
||||
"format": "double"
|
||||
},
|
||||
"count": {
|
||||
"type": "string",
|
||||
"format": "int64"
|
||||
},
|
||||
"amount": {
|
||||
"type": "string",
|
||||
"format": "int64"
|
||||
}
|
||||
}
|
||||
},
|
||||
"crmCardRsp": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/crmCardItem"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"crmCatalogRsp": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"categories": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/crmCategory"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"crmCategory": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"format": "int64"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"uri": {
|
||||
"type": "string"
|
||||
},
|
||||
"children": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/crmCategory"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"crmCharacteristic": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"crmGroupedProduct": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"uri": {
|
||||
"type": "string"
|
||||
},
|
||||
"image": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"crmOrderItem": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"productId": {
|
||||
"type": "string",
|
||||
"format": "int64"
|
||||
},
|
||||
"count": {
|
||||
"type": "string",
|
||||
"format": "int64"
|
||||
}
|
||||
}
|
||||
},
|
||||
"crmOrderRsp": {
|
||||
"type": "object"
|
||||
},
|
||||
"crmPositionsRsp": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"products": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/crmProduct"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"crmProduct": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"format": "int64"
|
||||
},
|
||||
"article": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"uri": {
|
||||
"type": "string"
|
||||
},
|
||||
"images": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"groupedProducts": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/crmGroupedProduct"
|
||||
}
|
||||
},
|
||||
"unit": {
|
||||
"type": "string"
|
||||
},
|
||||
"inventory": {
|
||||
"type": "number",
|
||||
"format": "double"
|
||||
},
|
||||
"variants": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/crmVariant"
|
||||
}
|
||||
},
|
||||
"characteristics": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/crmCharacteristic"
|
||||
}
|
||||
},
|
||||
"category": {
|
||||
"type": "string",
|
||||
"format": "int64"
|
||||
}
|
||||
}
|
||||
},
|
||||
"crmProductRsp": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"product": {
|
||||
"$ref": "#/definitions/crmProduct"
|
||||
}
|
||||
}
|
||||
},
|
||||
"crmProperty": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"crmVariant": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"price": {
|
||||
"type": "string",
|
||||
"format": "int64"
|
||||
},
|
||||
"properties": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/crmProperty"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"protobufAny": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"@type": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": {}
|
||||
},
|
||||
"rpcStatus": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"code": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"details": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/protobufAny"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"article": "1",
|
||||
"name": "\"Глаголик\" ванильно-сливочный",
|
||||
"uri": "/products/1",
|
||||
"images": [
|
||||
"/products/1/image-1-600x600.jpg",
|
||||
"/products/1/image-2-600x600.jpg",
|
||||
"/products/1/image-3-600x600.jpg"
|
||||
],
|
||||
"description": "",
|
||||
"grouped_products": [
|
||||
{
|
||||
"name": "\"Глаголик\" лимонный",
|
||||
"uri": "/products/2",
|
||||
"image": "/products/2/image-100x100.jpg"
|
||||
},
|
||||
{
|
||||
"name": "\"Глаголик\" мятный",
|
||||
"uri": "/products/3",
|
||||
"image": "/products/3/image-100x100.jpg"
|
||||
}
|
||||
],
|
||||
"unit": "kg",
|
||||
"inventory": 100,
|
||||
"variants": [
|
||||
{
|
||||
"price": 16500,
|
||||
"properties": [
|
||||
{
|
||||
"name": "min",
|
||||
"value": "0"
|
||||
},
|
||||
{
|
||||
"name": "max",
|
||||
"value": "5"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"price": 16000,
|
||||
"properties": [
|
||||
{
|
||||
"name": "min",
|
||||
"value": "6"
|
||||
},
|
||||
{
|
||||
"name": "max",
|
||||
"value": "60"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"price": 15500,
|
||||
"properties": [
|
||||
{
|
||||
"name": "min",
|
||||
"value": "61"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"characteristics": [
|
||||
{
|
||||
"name": "Вкус",
|
||||
"value": "Ванильно-сливочный"
|
||||
}
|
||||
],
|
||||
"category": 1
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"article": "4",
|
||||
"name": "Пахлава ореховая экран 1,5 кг",
|
||||
"uri": "/products/4",
|
||||
"images": [
|
||||
"/products/4/image-1-600x600.jpg",
|
||||
"/products/4/image-2-600x600.jpg",
|
||||
"/products/4/image-3-600x600.jpg"
|
||||
],
|
||||
"description": "",
|
||||
"grouped_products": [],
|
||||
"unit": "piece",
|
||||
"inventory": 100,
|
||||
"variants": [
|
||||
{
|
||||
"price": 29000,
|
||||
"properties": [
|
||||
{
|
||||
"name": "min",
|
||||
"value": "0"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"characteristics": [
|
||||
{
|
||||
"name": "Вкус",
|
||||
"value": "Ореховая"
|
||||
}
|
||||
],
|
||||
"category": 2
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,44 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package grpc.gateway.protoc_gen_openapiv2.options;
|
||||
|
||||
import "google/protobuf/descriptor.proto";
|
||||
import "protoc-gen-openapiv2/options/openapiv2.proto";
|
||||
|
||||
option go_package = "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options";
|
||||
|
||||
extend google.protobuf.FileOptions {
|
||||
// ID assigned by protobuf-global-extension-registry@google.com for gRPC-Gateway project.
|
||||
//
|
||||
// All IDs are the same, as assigned. It is okay that they are the same, as they extend
|
||||
// different descriptor messages.
|
||||
Swagger openapiv2_swagger = 1042;
|
||||
}
|
||||
extend google.protobuf.MethodOptions {
|
||||
// ID assigned by protobuf-global-extension-registry@google.com for gRPC-Gateway project.
|
||||
//
|
||||
// All IDs are the same, as assigned. It is okay that they are the same, as they extend
|
||||
// different descriptor messages.
|
||||
Operation openapiv2_operation = 1042;
|
||||
}
|
||||
extend google.protobuf.MessageOptions {
|
||||
// ID assigned by protobuf-global-extension-registry@google.com for gRPC-Gateway project.
|
||||
//
|
||||
// All IDs are the same, as assigned. It is okay that they are the same, as they extend
|
||||
// different descriptor messages.
|
||||
Schema openapiv2_schema = 1042;
|
||||
}
|
||||
extend google.protobuf.ServiceOptions {
|
||||
// ID assigned by protobuf-global-extension-registry@google.com for gRPC-Gateway project.
|
||||
//
|
||||
// All IDs are the same, as assigned. It is okay that they are the same, as they extend
|
||||
// different descriptor messages.
|
||||
Tag openapiv2_tag = 1042;
|
||||
}
|
||||
extend google.protobuf.FieldOptions {
|
||||
// ID assigned by protobuf-global-extension-registry@google.com for gRPC-Gateway project.
|
||||
//
|
||||
// All IDs are the same, as assigned. It is okay that they are the same, as they extend
|
||||
// different descriptor messages.
|
||||
JSONSchema openapiv2_field = 1042;
|
||||
}
|
||||
@@ -0,0 +1,720 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package grpc.gateway.protoc_gen_openapiv2.options;
|
||||
|
||||
import "google/protobuf/struct.proto";
|
||||
|
||||
option go_package = "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options";
|
||||
|
||||
// Scheme describes the schemes supported by the OpenAPI Swagger
|
||||
// and Operation objects.
|
||||
enum Scheme {
|
||||
UNKNOWN = 0;
|
||||
HTTP = 1;
|
||||
HTTPS = 2;
|
||||
WS = 3;
|
||||
WSS = 4;
|
||||
}
|
||||
|
||||
// `Swagger` is a representation of OpenAPI v2 specification's Swagger object.
|
||||
//
|
||||
// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#swaggerObject
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
|
||||
// info: {
|
||||
// title: "Echo API";
|
||||
// version: "1.0";
|
||||
// description: "";
|
||||
// contact: {
|
||||
// name: "gRPC-Gateway project";
|
||||
// url: "https://github.com/grpc-ecosystem/grpc-gateway";
|
||||
// email: "none@example.com";
|
||||
// };
|
||||
// license: {
|
||||
// name: "BSD 3-Clause License";
|
||||
// url: "https://github.com/grpc-ecosystem/grpc-gateway/blob/main/LICENSE";
|
||||
// };
|
||||
// };
|
||||
// schemes: HTTPS;
|
||||
// consumes: "application/json";
|
||||
// produces: "application/json";
|
||||
// };
|
||||
//
|
||||
message Swagger {
|
||||
// Specifies the OpenAPI Specification version being used. It can be
|
||||
// used by the OpenAPI UI and other clients to interpret the API listing. The
|
||||
// value MUST be "2.0".
|
||||
string swagger = 1;
|
||||
// Provides metadata about the API. The metadata can be used by the
|
||||
// clients if needed.
|
||||
Info info = 2;
|
||||
// The host (name or ip) serving the API. This MUST be the host only and does
|
||||
// not include the scheme nor sub-paths. It MAY include a port. If the host is
|
||||
// not included, the host serving the documentation is to be used (including
|
||||
// the port). The host does not support path templating.
|
||||
string host = 3;
|
||||
// The base path on which the API is served, which is relative to the host. If
|
||||
// it is not included, the API is served directly under the host. The value
|
||||
// MUST start with a leading slash (/). The basePath does not support path
|
||||
// templating.
|
||||
// Note that using `base_path` does not change the endpoint paths that are
|
||||
// generated in the resulting OpenAPI file. If you wish to use `base_path`
|
||||
// with relatively generated OpenAPI paths, the `base_path` prefix must be
|
||||
// manually removed from your `google.api.http` paths and your code changed to
|
||||
// serve the API from the `base_path`.
|
||||
string base_path = 4;
|
||||
// The transfer protocol of the API. Values MUST be from the list: "http",
|
||||
// "https", "ws", "wss". If the schemes is not included, the default scheme to
|
||||
// be used is the one used to access the OpenAPI definition itself.
|
||||
repeated Scheme schemes = 5;
|
||||
// A list of MIME types the APIs can consume. This is global to all APIs but
|
||||
// can be overridden on specific API calls. Value MUST be as described under
|
||||
// Mime Types.
|
||||
repeated string consumes = 6;
|
||||
// A list of MIME types the APIs can produce. This is global to all APIs but
|
||||
// can be overridden on specific API calls. Value MUST be as described under
|
||||
// Mime Types.
|
||||
repeated string produces = 7;
|
||||
// field 8 is reserved for 'paths'.
|
||||
reserved 8;
|
||||
// field 9 is reserved for 'definitions', which at this time are already
|
||||
// exposed as and customizable as proto messages.
|
||||
reserved 9;
|
||||
// An object to hold responses that can be used across operations. This
|
||||
// property does not define global responses for all operations.
|
||||
map<string, Response> responses = 10;
|
||||
// Security scheme definitions that can be used across the specification.
|
||||
SecurityDefinitions security_definitions = 11;
|
||||
// A declaration of which security schemes are applied for the API as a whole.
|
||||
// The list of values describes alternative security schemes that can be used
|
||||
// (that is, there is a logical OR between the security requirements).
|
||||
// Individual operations can override this definition.
|
||||
repeated SecurityRequirement security = 12;
|
||||
// A list of tags for API documentation control. Tags can be used for logical
|
||||
// grouping of operations by resources or any other qualifier.
|
||||
repeated Tag tags = 13;
|
||||
// Additional external documentation.
|
||||
ExternalDocumentation external_docs = 14;
|
||||
// Custom properties that start with "x-" such as "x-foo" used to describe
|
||||
// extra functionality that is not covered by the standard OpenAPI Specification.
|
||||
// See: https://swagger.io/docs/specification/2-0/swagger-extensions/
|
||||
map<string, google.protobuf.Value> extensions = 15;
|
||||
}
|
||||
|
||||
// `Operation` is a representation of OpenAPI v2 specification's Operation object.
|
||||
//
|
||||
// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#operationObject
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// service EchoService {
|
||||
// rpc Echo(SimpleMessage) returns (SimpleMessage) {
|
||||
// option (google.api.http) = {
|
||||
// get: "/v1/example/echo/{id}"
|
||||
// };
|
||||
//
|
||||
// option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||
// summary: "Get a message.";
|
||||
// operation_id: "getMessage";
|
||||
// tags: "echo";
|
||||
// responses: {
|
||||
// key: "200"
|
||||
// value: {
|
||||
// description: "OK";
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
// }
|
||||
// }
|
||||
message Operation {
|
||||
// A list of tags for API documentation control. Tags can be used for logical
|
||||
// grouping of operations by resources or any other qualifier.
|
||||
repeated string tags = 1;
|
||||
// A short summary of what the operation does. For maximum readability in the
|
||||
// swagger-ui, this field SHOULD be less than 120 characters.
|
||||
string summary = 2;
|
||||
// A verbose explanation of the operation behavior. GFM syntax can be used for
|
||||
// rich text representation.
|
||||
string description = 3;
|
||||
// Additional external documentation for this operation.
|
||||
ExternalDocumentation external_docs = 4;
|
||||
// Unique string used to identify the operation. The id MUST be unique among
|
||||
// all operations described in the API. Tools and libraries MAY use the
|
||||
// operationId to uniquely identify an operation, therefore, it is recommended
|
||||
// to follow common programming naming conventions.
|
||||
string operation_id = 5;
|
||||
// A list of MIME types the operation can consume. This overrides the consumes
|
||||
// definition at the OpenAPI Object. An empty value MAY be used to clear the
|
||||
// global definition. Value MUST be as described under Mime Types.
|
||||
repeated string consumes = 6;
|
||||
// A list of MIME types the operation can produce. This overrides the produces
|
||||
// definition at the OpenAPI Object. An empty value MAY be used to clear the
|
||||
// global definition. Value MUST be as described under Mime Types.
|
||||
repeated string produces = 7;
|
||||
// field 8 is reserved for 'parameters'.
|
||||
reserved 8;
|
||||
// The list of possible responses as they are returned from executing this
|
||||
// operation.
|
||||
map<string, Response> responses = 9;
|
||||
// The transfer protocol for the operation. Values MUST be from the list:
|
||||
// "http", "https", "ws", "wss". The value overrides the OpenAPI Object
|
||||
// schemes definition.
|
||||
repeated Scheme schemes = 10;
|
||||
// Declares this operation to be deprecated. Usage of the declared operation
|
||||
// should be refrained. Default value is false.
|
||||
bool deprecated = 11;
|
||||
// A declaration of which security schemes are applied for this operation. The
|
||||
// list of values describes alternative security schemes that can be used
|
||||
// (that is, there is a logical OR between the security requirements). This
|
||||
// definition overrides any declared top-level security. To remove a top-level
|
||||
// security declaration, an empty array can be used.
|
||||
repeated SecurityRequirement security = 12;
|
||||
// Custom properties that start with "x-" such as "x-foo" used to describe
|
||||
// extra functionality that is not covered by the standard OpenAPI Specification.
|
||||
// See: https://swagger.io/docs/specification/2-0/swagger-extensions/
|
||||
map<string, google.protobuf.Value> extensions = 13;
|
||||
// Custom parameters such as HTTP request headers.
|
||||
// See: https://swagger.io/docs/specification/2-0/describing-parameters/
|
||||
// and https://swagger.io/specification/v2/#parameter-object.
|
||||
Parameters parameters = 14;
|
||||
}
|
||||
|
||||
// `Parameters` is a representation of OpenAPI v2 specification's parameters object.
|
||||
// Note: This technically breaks compatibility with the OpenAPI 2 definition structure as we only
|
||||
// allow header parameters to be set here since we do not want users specifying custom non-header
|
||||
// parameters beyond those inferred from the Protobuf schema.
|
||||
// See: https://swagger.io/specification/v2/#parameter-object
|
||||
message Parameters {
|
||||
// `Headers` is one or more HTTP header parameter.
|
||||
// See: https://swagger.io/docs/specification/2-0/describing-parameters/#header-parameters
|
||||
repeated HeaderParameter headers = 1;
|
||||
}
|
||||
|
||||
// `HeaderParameter` a HTTP header parameter.
|
||||
// See: https://swagger.io/specification/v2/#parameter-object
|
||||
message HeaderParameter {
|
||||
// `Type` is a supported HTTP header type.
|
||||
// See https://swagger.io/specification/v2/#parameterType.
|
||||
enum Type {
|
||||
UNKNOWN = 0;
|
||||
STRING = 1;
|
||||
NUMBER = 2;
|
||||
INTEGER = 3;
|
||||
BOOLEAN = 4;
|
||||
}
|
||||
|
||||
// `Name` is the header name.
|
||||
string name = 1;
|
||||
// `Description` is a short description of the header.
|
||||
string description = 2;
|
||||
// `Type` is the type of the object. The value MUST be one of "string", "number", "integer", or "boolean". The "array" type is not supported.
|
||||
// See: https://swagger.io/specification/v2/#parameterType.
|
||||
Type type = 3;
|
||||
// `Format` The extending format for the previously mentioned type.
|
||||
string format = 4;
|
||||
// `Required` indicates if the header is optional
|
||||
bool required = 5;
|
||||
// field 6 is reserved for 'items', but in OpenAPI-specific way.
|
||||
reserved 6;
|
||||
// field 7 is reserved `Collection Format`. Determines the format of the array if type array is used.
|
||||
reserved 7;
|
||||
}
|
||||
|
||||
// `Header` is a representation of OpenAPI v2 specification's Header object.
|
||||
//
|
||||
// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#headerObject
|
||||
//
|
||||
message Header {
|
||||
// `Description` is a short description of the header.
|
||||
string description = 1;
|
||||
// The type of the object. The value MUST be one of "string", "number", "integer", or "boolean". The "array" type is not supported.
|
||||
string type = 2;
|
||||
// `Format` The extending format for the previously mentioned type.
|
||||
string format = 3;
|
||||
// field 4 is reserved for 'items', but in OpenAPI-specific way.
|
||||
reserved 4;
|
||||
// field 5 is reserved `Collection Format` Determines the format of the array if type array is used.
|
||||
reserved 5;
|
||||
// `Default` Declares the value of the header that the server will use if none is provided.
|
||||
// See: https://tools.ietf.org/html/draft-fge-json-schema-validation-00#section-6.2.
|
||||
// Unlike JSON Schema this value MUST conform to the defined type for the header.
|
||||
string default = 6;
|
||||
// field 7 is reserved for 'maximum'.
|
||||
reserved 7;
|
||||
// field 8 is reserved for 'exclusiveMaximum'.
|
||||
reserved 8;
|
||||
// field 9 is reserved for 'minimum'.
|
||||
reserved 9;
|
||||
// field 10 is reserved for 'exclusiveMinimum'.
|
||||
reserved 10;
|
||||
// field 11 is reserved for 'maxLength'.
|
||||
reserved 11;
|
||||
// field 12 is reserved for 'minLength'.
|
||||
reserved 12;
|
||||
// 'Pattern' See https://tools.ietf.org/html/draft-fge-json-schema-validation-00#section-5.2.3.
|
||||
string pattern = 13;
|
||||
// field 14 is reserved for 'maxItems'.
|
||||
reserved 14;
|
||||
// field 15 is reserved for 'minItems'.
|
||||
reserved 15;
|
||||
// field 16 is reserved for 'uniqueItems'.
|
||||
reserved 16;
|
||||
// field 17 is reserved for 'enum'.
|
||||
reserved 17;
|
||||
// field 18 is reserved for 'multipleOf'.
|
||||
reserved 18;
|
||||
}
|
||||
|
||||
// `Response` is a representation of OpenAPI v2 specification's Response object.
|
||||
//
|
||||
// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#responseObject
|
||||
//
|
||||
message Response {
|
||||
// `Description` is a short description of the response.
|
||||
// GFM syntax can be used for rich text representation.
|
||||
string description = 1;
|
||||
// `Schema` optionally defines the structure of the response.
|
||||
// If `Schema` is not provided, it means there is no content to the response.
|
||||
Schema schema = 2;
|
||||
// `Headers` A list of headers that are sent with the response.
|
||||
// `Header` name is expected to be a string in the canonical format of the MIME header key
|
||||
// See: https://golang.org/pkg/net/textproto/#CanonicalMIMEHeaderKey
|
||||
map<string, Header> headers = 3;
|
||||
// `Examples` gives per-mimetype response examples.
|
||||
// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#example-object
|
||||
map<string, string> examples = 4;
|
||||
// Custom properties that start with "x-" such as "x-foo" used to describe
|
||||
// extra functionality that is not covered by the standard OpenAPI Specification.
|
||||
// See: https://swagger.io/docs/specification/2-0/swagger-extensions/
|
||||
map<string, google.protobuf.Value> extensions = 5;
|
||||
}
|
||||
|
||||
// `Info` is a representation of OpenAPI v2 specification's Info object.
|
||||
//
|
||||
// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#infoObject
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
|
||||
// info: {
|
||||
// title: "Echo API";
|
||||
// version: "1.0";
|
||||
// description: "";
|
||||
// contact: {
|
||||
// name: "gRPC-Gateway project";
|
||||
// url: "https://github.com/grpc-ecosystem/grpc-gateway";
|
||||
// email: "none@example.com";
|
||||
// };
|
||||
// license: {
|
||||
// name: "BSD 3-Clause License";
|
||||
// url: "https://github.com/grpc-ecosystem/grpc-gateway/blob/main/LICENSE";
|
||||
// };
|
||||
// };
|
||||
// ...
|
||||
// };
|
||||
//
|
||||
message Info {
|
||||
// The title of the application.
|
||||
string title = 1;
|
||||
// A short description of the application. GFM syntax can be used for rich
|
||||
// text representation.
|
||||
string description = 2;
|
||||
// The Terms of Service for the API.
|
||||
string terms_of_service = 3;
|
||||
// The contact information for the exposed API.
|
||||
Contact contact = 4;
|
||||
// The license information for the exposed API.
|
||||
License license = 5;
|
||||
// Provides the version of the application API (not to be confused
|
||||
// with the specification version).
|
||||
string version = 6;
|
||||
// Custom properties that start with "x-" such as "x-foo" used to describe
|
||||
// extra functionality that is not covered by the standard OpenAPI Specification.
|
||||
// See: https://swagger.io/docs/specification/2-0/swagger-extensions/
|
||||
map<string, google.protobuf.Value> extensions = 7;
|
||||
}
|
||||
|
||||
// `Contact` is a representation of OpenAPI v2 specification's Contact object.
|
||||
//
|
||||
// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#contactObject
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
|
||||
// info: {
|
||||
// ...
|
||||
// contact: {
|
||||
// name: "gRPC-Gateway project";
|
||||
// url: "https://github.com/grpc-ecosystem/grpc-gateway";
|
||||
// email: "none@example.com";
|
||||
// };
|
||||
// ...
|
||||
// };
|
||||
// ...
|
||||
// };
|
||||
//
|
||||
message Contact {
|
||||
// The identifying name of the contact person/organization.
|
||||
string name = 1;
|
||||
// The URL pointing to the contact information. MUST be in the format of a
|
||||
// URL.
|
||||
string url = 2;
|
||||
// The email address of the contact person/organization. MUST be in the format
|
||||
// of an email address.
|
||||
string email = 3;
|
||||
}
|
||||
|
||||
// `License` is a representation of OpenAPI v2 specification's License object.
|
||||
//
|
||||
// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#licenseObject
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
|
||||
// info: {
|
||||
// ...
|
||||
// license: {
|
||||
// name: "BSD 3-Clause License";
|
||||
// url: "https://github.com/grpc-ecosystem/grpc-gateway/blob/main/LICENSE";
|
||||
// };
|
||||
// ...
|
||||
// };
|
||||
// ...
|
||||
// };
|
||||
//
|
||||
message License {
|
||||
// The license name used for the API.
|
||||
string name = 1;
|
||||
// A URL to the license used for the API. MUST be in the format of a URL.
|
||||
string url = 2;
|
||||
}
|
||||
|
||||
// `ExternalDocumentation` is a representation of OpenAPI v2 specification's
|
||||
// ExternalDocumentation object.
|
||||
//
|
||||
// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#externalDocumentationObject
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
|
||||
// ...
|
||||
// external_docs: {
|
||||
// description: "More about gRPC-Gateway";
|
||||
// url: "https://github.com/grpc-ecosystem/grpc-gateway";
|
||||
// }
|
||||
// ...
|
||||
// };
|
||||
//
|
||||
message ExternalDocumentation {
|
||||
// A short description of the target documentation. GFM syntax can be used for
|
||||
// rich text representation.
|
||||
string description = 1;
|
||||
// The URL for the target documentation. Value MUST be in the format
|
||||
// of a URL.
|
||||
string url = 2;
|
||||
}
|
||||
|
||||
// `Schema` is a representation of OpenAPI v2 specification's Schema object.
|
||||
//
|
||||
// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#schemaObject
|
||||
//
|
||||
message Schema {
|
||||
JSONSchema json_schema = 1;
|
||||
// Adds support for polymorphism. The discriminator is the schema property
|
||||
// name that is used to differentiate between other schema that inherit this
|
||||
// schema. The property name used MUST be defined at this schema and it MUST
|
||||
// be in the required property list. When used, the value MUST be the name of
|
||||
// this schema or any schema that inherits it.
|
||||
string discriminator = 2;
|
||||
// Relevant only for Schema "properties" definitions. Declares the property as
|
||||
// "read only". This means that it MAY be sent as part of a response but MUST
|
||||
// NOT be sent as part of the request. Properties marked as readOnly being
|
||||
// true SHOULD NOT be in the required list of the defined schema. Default
|
||||
// value is false.
|
||||
bool read_only = 3;
|
||||
// field 4 is reserved for 'xml'.
|
||||
reserved 4;
|
||||
// Additional external documentation for this schema.
|
||||
ExternalDocumentation external_docs = 5;
|
||||
// A free-form property to include an example of an instance for this schema in JSON.
|
||||
// This is copied verbatim to the output.
|
||||
string example = 6;
|
||||
}
|
||||
|
||||
// `JSONSchema` represents properties from JSON Schema taken, and as used, in
|
||||
// the OpenAPI v2 spec.
|
||||
//
|
||||
// This includes changes made by OpenAPI v2.
|
||||
//
|
||||
// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#schemaObject
|
||||
//
|
||||
// See also: https://cswr.github.io/JsonSchema/spec/basic_types/,
|
||||
// https://github.com/json-schema-org/json-schema-spec/blob/master/schema.json
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// message SimpleMessage {
|
||||
// option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
|
||||
// json_schema: {
|
||||
// title: "SimpleMessage"
|
||||
// description: "A simple message."
|
||||
// required: ["id"]
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// // Id represents the message identifier.
|
||||
// string id = 1; [
|
||||
// (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
// description: "The unique identifier of the simple message."
|
||||
// }];
|
||||
// }
|
||||
//
|
||||
message JSONSchema {
|
||||
// field 1 is reserved for '$id', omitted from OpenAPI v2.
|
||||
reserved 1;
|
||||
// field 2 is reserved for '$schema', omitted from OpenAPI v2.
|
||||
reserved 2;
|
||||
// Ref is used to define an external reference to include in the message.
|
||||
// This could be a fully qualified proto message reference, and that type must
|
||||
// be imported into the protofile. If no message is identified, the Ref will
|
||||
// be used verbatim in the output.
|
||||
// For example:
|
||||
// `ref: ".google.protobuf.Timestamp"`.
|
||||
string ref = 3;
|
||||
// field 4 is reserved for '$comment', omitted from OpenAPI v2.
|
||||
reserved 4;
|
||||
// The title of the schema.
|
||||
string title = 5;
|
||||
// A short description of the schema.
|
||||
string description = 6;
|
||||
string default = 7;
|
||||
bool read_only = 8;
|
||||
// A free-form property to include a JSON example of this field. This is copied
|
||||
// verbatim to the output swagger.json. Quotes must be escaped.
|
||||
// This property is the same for 2.0 and 3.0.0 https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/3.0.0.md#schemaObject https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#schemaObject
|
||||
string example = 9;
|
||||
double multiple_of = 10;
|
||||
// Maximum represents an inclusive upper limit for a numeric instance. The
|
||||
// value of MUST be a number,
|
||||
double maximum = 11;
|
||||
bool exclusive_maximum = 12;
|
||||
// minimum represents an inclusive lower limit for a numeric instance. The
|
||||
// value of MUST be a number,
|
||||
double minimum = 13;
|
||||
bool exclusive_minimum = 14;
|
||||
uint64 max_length = 15;
|
||||
uint64 min_length = 16;
|
||||
string pattern = 17;
|
||||
// field 18 is reserved for 'additionalItems', omitted from OpenAPI v2.
|
||||
reserved 18;
|
||||
// field 19 is reserved for 'items', but in OpenAPI-specific way.
|
||||
// TODO(ivucica): add 'items'?
|
||||
reserved 19;
|
||||
uint64 max_items = 20;
|
||||
uint64 min_items = 21;
|
||||
bool unique_items = 22;
|
||||
// field 23 is reserved for 'contains', omitted from OpenAPI v2.
|
||||
reserved 23;
|
||||
uint64 max_properties = 24;
|
||||
uint64 min_properties = 25;
|
||||
repeated string required = 26;
|
||||
// field 27 is reserved for 'additionalProperties', but in OpenAPI-specific
|
||||
// way. TODO(ivucica): add 'additionalProperties'?
|
||||
reserved 27;
|
||||
// field 28 is reserved for 'definitions', omitted from OpenAPI v2.
|
||||
reserved 28;
|
||||
// field 29 is reserved for 'properties', but in OpenAPI-specific way.
|
||||
// TODO(ivucica): add 'additionalProperties'?
|
||||
reserved 29;
|
||||
// following fields are reserved, as the properties have been omitted from
|
||||
// OpenAPI v2:
|
||||
// patternProperties, dependencies, propertyNames, const
|
||||
reserved 30 to 33;
|
||||
// Items in 'array' must be unique.
|
||||
repeated string array = 34;
|
||||
|
||||
enum JSONSchemaSimpleTypes {
|
||||
UNKNOWN = 0;
|
||||
ARRAY = 1;
|
||||
BOOLEAN = 2;
|
||||
INTEGER = 3;
|
||||
NULL = 4;
|
||||
NUMBER = 5;
|
||||
OBJECT = 6;
|
||||
STRING = 7;
|
||||
}
|
||||
|
||||
repeated JSONSchemaSimpleTypes type = 35;
|
||||
// `Format`
|
||||
string format = 36;
|
||||
// following fields are reserved, as the properties have been omitted from
|
||||
// OpenAPI v2: contentMediaType, contentEncoding, if, then, else
|
||||
reserved 37 to 41;
|
||||
// field 42 is reserved for 'allOf', but in OpenAPI-specific way.
|
||||
// TODO(ivucica): add 'allOf'?
|
||||
reserved 42;
|
||||
// following fields are reserved, as the properties have been omitted from
|
||||
// OpenAPI v2:
|
||||
// anyOf, oneOf, not
|
||||
reserved 43 to 45;
|
||||
// Items in `enum` must be unique https://tools.ietf.org/html/draft-fge-json-schema-validation-00#section-5.5.1
|
||||
repeated string enum = 46;
|
||||
|
||||
// Additional field level properties used when generating the OpenAPI v2 file.
|
||||
FieldConfiguration field_configuration = 1001;
|
||||
|
||||
// 'FieldConfiguration' provides additional field level properties used when generating the OpenAPI v2 file.
|
||||
// These properties are not defined by OpenAPIv2, but they are used to control the generation.
|
||||
message FieldConfiguration {
|
||||
// Alternative parameter name when used as path parameter. If set, this will
|
||||
// be used as the complete parameter name when this field is used as a path
|
||||
// parameter. Use this to avoid having auto generated path parameter names
|
||||
// for overlapping paths.
|
||||
string path_param_name = 47;
|
||||
}
|
||||
// Custom properties that start with "x-" such as "x-foo" used to describe
|
||||
// extra functionality that is not covered by the standard OpenAPI Specification.
|
||||
// See: https://swagger.io/docs/specification/2-0/swagger-extensions/
|
||||
map<string, google.protobuf.Value> extensions = 48;
|
||||
}
|
||||
|
||||
// `Tag` is a representation of OpenAPI v2 specification's Tag object.
|
||||
//
|
||||
// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#tagObject
|
||||
//
|
||||
message Tag {
|
||||
// The name of the tag. Use it to allow override of the name of a
|
||||
// global Tag object, then use that name to reference the tag throughout the
|
||||
// OpenAPI file.
|
||||
string name = 1;
|
||||
// A short description for the tag. GFM syntax can be used for rich text
|
||||
// representation.
|
||||
string description = 2;
|
||||
// Additional external documentation for this tag.
|
||||
ExternalDocumentation external_docs = 3;
|
||||
// Custom properties that start with "x-" such as "x-foo" used to describe
|
||||
// extra functionality that is not covered by the standard OpenAPI Specification.
|
||||
// See: https://swagger.io/docs/specification/2-0/swagger-extensions/
|
||||
map<string, google.protobuf.Value> extensions = 4;
|
||||
}
|
||||
|
||||
// `SecurityDefinitions` is a representation of OpenAPI v2 specification's
|
||||
// Security Definitions object.
|
||||
//
|
||||
// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#securityDefinitionsObject
|
||||
//
|
||||
// A declaration of the security schemes available to be used in the
|
||||
// specification. This does not enforce the security schemes on the operations
|
||||
// and only serves to provide the relevant details for each scheme.
|
||||
message SecurityDefinitions {
|
||||
// A single security scheme definition, mapping a "name" to the scheme it
|
||||
// defines.
|
||||
map<string, SecurityScheme> security = 1;
|
||||
}
|
||||
|
||||
// `SecurityScheme` is a representation of OpenAPI v2 specification's
|
||||
// Security Scheme object.
|
||||
//
|
||||
// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#securitySchemeObject
|
||||
//
|
||||
// Allows the definition of a security scheme that can be used by the
|
||||
// operations. Supported schemes are basic authentication, an API key (either as
|
||||
// a header or as a query parameter) and OAuth2's common flows (implicit,
|
||||
// password, application and access code).
|
||||
message SecurityScheme {
|
||||
// The type of the security scheme. Valid values are "basic",
|
||||
// "apiKey" or "oauth2".
|
||||
enum Type {
|
||||
TYPE_INVALID = 0;
|
||||
TYPE_BASIC = 1;
|
||||
TYPE_API_KEY = 2;
|
||||
TYPE_OAUTH2 = 3;
|
||||
}
|
||||
|
||||
// The location of the API key. Valid values are "query" or "header".
|
||||
enum In {
|
||||
IN_INVALID = 0;
|
||||
IN_QUERY = 1;
|
||||
IN_HEADER = 2;
|
||||
}
|
||||
|
||||
// The flow used by the OAuth2 security scheme. Valid values are
|
||||
// "implicit", "password", "application" or "accessCode".
|
||||
enum Flow {
|
||||
FLOW_INVALID = 0;
|
||||
FLOW_IMPLICIT = 1;
|
||||
FLOW_PASSWORD = 2;
|
||||
FLOW_APPLICATION = 3;
|
||||
FLOW_ACCESS_CODE = 4;
|
||||
}
|
||||
|
||||
// The type of the security scheme. Valid values are "basic",
|
||||
// "apiKey" or "oauth2".
|
||||
Type type = 1;
|
||||
// A short description for security scheme.
|
||||
string description = 2;
|
||||
// The name of the header or query parameter to be used.
|
||||
// Valid for apiKey.
|
||||
string name = 3;
|
||||
// The location of the API key. Valid values are "query" or
|
||||
// "header".
|
||||
// Valid for apiKey.
|
||||
In in = 4;
|
||||
// The flow used by the OAuth2 security scheme. Valid values are
|
||||
// "implicit", "password", "application" or "accessCode".
|
||||
// Valid for oauth2.
|
||||
Flow flow = 5;
|
||||
// The authorization URL to be used for this flow. This SHOULD be in
|
||||
// the form of a URL.
|
||||
// Valid for oauth2/implicit and oauth2/accessCode.
|
||||
string authorization_url = 6;
|
||||
// The token URL to be used for this flow. This SHOULD be in the
|
||||
// form of a URL.
|
||||
// Valid for oauth2/password, oauth2/application and oauth2/accessCode.
|
||||
string token_url = 7;
|
||||
// The available scopes for the OAuth2 security scheme.
|
||||
// Valid for oauth2.
|
||||
Scopes scopes = 8;
|
||||
// Custom properties that start with "x-" such as "x-foo" used to describe
|
||||
// extra functionality that is not covered by the standard OpenAPI Specification.
|
||||
// See: https://swagger.io/docs/specification/2-0/swagger-extensions/
|
||||
map<string, google.protobuf.Value> extensions = 9;
|
||||
}
|
||||
|
||||
// `SecurityRequirement` is a representation of OpenAPI v2 specification's
|
||||
// Security Requirement object.
|
||||
//
|
||||
// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#securityRequirementObject
|
||||
//
|
||||
// Lists the required security schemes to execute this operation. The object can
|
||||
// have multiple security schemes declared in it which are all required (that
|
||||
// is, there is a logical AND between the schemes).
|
||||
//
|
||||
// The name used for each property MUST correspond to a security scheme
|
||||
// declared in the Security Definitions.
|
||||
message SecurityRequirement {
|
||||
// If the security scheme is of type "oauth2", then the value is a list of
|
||||
// scope names required for the execution. For other security scheme types,
|
||||
// the array MUST be empty.
|
||||
message SecurityRequirementValue {
|
||||
repeated string scope = 1;
|
||||
}
|
||||
// Each name must correspond to a security scheme which is declared in
|
||||
// the Security Definitions. If the security scheme is of type "oauth2",
|
||||
// then the value is a list of scope names required for the execution.
|
||||
// For other security scheme types, the array MUST be empty.
|
||||
map<string, SecurityRequirementValue> security_requirement = 1;
|
||||
}
|
||||
|
||||
// `Scopes` is a representation of OpenAPI v2 specification's Scopes object.
|
||||
//
|
||||
// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#scopesObject
|
||||
//
|
||||
// Lists the available scopes for an OAuth2 security scheme.
|
||||
message Scopes {
|
||||
// Maps between a name of a scope to a short description of it (as the value
|
||||
// of the property).
|
||||
map<string, string> scope = 1;
|
||||
}
|
||||
Reference in New Issue
Block a user