Compare commits
24 Commits
9a51201678
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 0ed38b7cc0 | |||
| 26ca649e8e | |||
| 675c2884b7 | |||
| 130a3236e0 | |||
| 95fe8b530e | |||
| bf85f31056 | |||
| 866009cf09 | |||
| f2011b953c | |||
| 66df21c6c9 | |||
| a8b6e9ab9b | |||
| 2078e008f3 | |||
| f4523de5a4 | |||
| 0d6bd456d6 | |||
| ee3e10d46d | |||
| 6c99309caf | |||
| bd6b5fe4a8 | |||
| 074a202dc2 | |||
| 718d2e5e98 | |||
| 20652b127c | |||
| fdb92455ba | |||
| be0ce71de6 | |||
| 55ee2bccbc | |||
| d9bcceb367 | |||
| 6cfab72b9c |
Vendored
+6
-2
@@ -1,11 +1,15 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Launch eparser",
|
||||
"name": "Launch",
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "debug",
|
||||
"program": "${workspaceFolder}/cmd/smm_core"
|
||||
"program": "${workspaceFolder}/cmd/smm_core",
|
||||
"env": {
|
||||
"DATABASE_URL": "user=crab password=crab dbname=smm-core host=localhost port=5432 sslmode=disable",
|
||||
"AUTHORIZATION": "Y3JhYjpjcmFi"
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
Vendored
+22
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"sqltools.connections": [
|
||||
{
|
||||
"previewLimit": 50,
|
||||
"server": "localhost",
|
||||
"port": 5432,
|
||||
"driver": "PostgreSQL",
|
||||
"name": "smm",
|
||||
"database": "smm-core",
|
||||
"username": "crab",
|
||||
"password": "crab"
|
||||
}
|
||||
],
|
||||
"cSpell.words": [
|
||||
"рублей",
|
||||
"caser",
|
||||
"dbpool",
|
||||
"jackc",
|
||||
"pgconn",
|
||||
"pgxpool"
|
||||
]
|
||||
}
|
||||
@@ -7,11 +7,22 @@ ifeq (local-migrations-create,$(firstword $(MAKECMDGOALS)))
|
||||
endif
|
||||
|
||||
local-migrate-up:
|
||||
@goose -allow-missing -dir ./migrations postgres "user=crab dbname=smm-core host=localhost port=5432 sslmode=disable" up
|
||||
@goose -allow-missing -dir ./migrations postgres "user=crab password=crab dbname=smm-core host=localhost port=5432 sslmode=disable" up
|
||||
|
||||
local-migrations-create:
|
||||
@goose -dir ./migrations postgres "user=crab dbname=smm-core host=localhost port=5432 sslmode=disable" create "${migrationName}" sql
|
||||
|
||||
local-up:
|
||||
docker-compose -f docker-compose-local.yml up -d --force-recreate --build
|
||||
|
||||
local-down:
|
||||
docker-compose -f docker-compose-local.yml down
|
||||
|
||||
local-wait_db:
|
||||
timeout 10s bash -c "until docker exec db pg_isready; do sleep 1; done"
|
||||
|
||||
local-restart: local-down local-up local-wait_db local-migrate-up
|
||||
|
||||
local-go-init: export GOBIN := $(LOCAL_BIN)
|
||||
local-go-init:
|
||||
go get github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway
|
||||
@@ -23,6 +34,7 @@ local-go-init:
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2 \
|
||||
google.golang.org/protobuf/cmd/protoc-gen-go \
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc
|
||||
go install github.com/pressly/goose/v3/cmd/goose@latest
|
||||
|
||||
generate:
|
||||
rm -rf proto resources
|
||||
|
||||
+240
-1
@@ -3,7 +3,6 @@ syntax = "proto3";
|
||||
package crabs.smm_core;
|
||||
|
||||
import "google/api/annotations.proto";
|
||||
import "google/api/httpbody.proto";
|
||||
import "protoc-gen-openapiv2/options/annotations.proto";
|
||||
|
||||
option go_package = "pkg/proto";
|
||||
@@ -11,13 +10,253 @@ option go_package = "pkg/proto";
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {};
|
||||
|
||||
service SmmCore {
|
||||
|
||||
// ping
|
||||
rpc Ping(PingReq) returns (PingRsp) {
|
||||
option (google.api.http) = {
|
||||
get: "/ping"
|
||||
};
|
||||
}
|
||||
|
||||
// login
|
||||
rpc Login(LoginReq) returns (User) {
|
||||
option (google.api.http) = {
|
||||
post: "/login",
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
|
||||
// budgets
|
||||
rpc AddBudget(AddBudgetReq) returns (Budget) {
|
||||
option (google.api.http) = {
|
||||
post: "/budgets",
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
rpc UpdateBudget(UpdateBudgetReq) returns (Budget) {
|
||||
option (google.api.http) = {
|
||||
put: "/budgets/{id}",
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
rpc GetBudgets(GetBudgetsReq) returns (Budgets) {
|
||||
option (google.api.http) = {
|
||||
get: "/budgets"
|
||||
};
|
||||
}
|
||||
rpc DeleteBudget(DeleteBudgetReq) returns (Budget) {
|
||||
option (google.api.http) = {
|
||||
delete: "/budgets/{id}"
|
||||
};
|
||||
}
|
||||
|
||||
// budget users
|
||||
rpc AddUserToBudget(AddUserToBudgetReq) returns (OK) {
|
||||
option (google.api.http) = {
|
||||
put: "/budgets/{budget_id}/users",
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
rpc GetBudgetUsers(GetBudgetUsersReq) returns (Users) {
|
||||
option (google.api.http) = {
|
||||
get: "/budgets/{id}/users"
|
||||
};
|
||||
}
|
||||
rpc RemoveUserFromBudget(RemoveUserFromBudgetReq) returns (Budget) {
|
||||
option (google.api.http) = {
|
||||
delete: "/budgets/{budget_id}/users/{user_id}"
|
||||
};
|
||||
}
|
||||
rpc GetBudgetCategories(GetBudgetCategoriesReq) returns (Categories) {
|
||||
option (google.api.http) = {
|
||||
get: "/budgets/{budget_id}/categories"
|
||||
};
|
||||
}
|
||||
|
||||
// categories
|
||||
rpc AddCategory(AddCategoryReq) returns (Category) {
|
||||
option (google.api.http) = {
|
||||
post: "/categories",
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
rpc UpdateCategory(UpdateCategoryReq) returns (Category) {
|
||||
option (google.api.http) = {
|
||||
put: "/categories/{id}"
|
||||
};
|
||||
}
|
||||
rpc DeleteCategories(DeleteCategoriesReq) returns (Category) {
|
||||
option (google.api.http) = {
|
||||
delete: "/categories/{id}"
|
||||
};
|
||||
}
|
||||
|
||||
// wastes
|
||||
rpc AddWaste(AddWasteReq) returns (Waste) {
|
||||
option (google.api.http) = {
|
||||
post: "/wastes",
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
rpc AddWasteByText(AddWasteTextReq) returns (Waste) {
|
||||
option (google.api.http) = {
|
||||
post: "/wastes/text",
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
rpc DeleteWaste(DeleteWasteReq) returns (Waste) {
|
||||
option (google.api.http) = {
|
||||
delete: "/wastes/{id}"
|
||||
};
|
||||
}
|
||||
|
||||
// stat
|
||||
rpc GetCategoriesStat(GetCategoriesStatReq) returns (CategoriesStat) {
|
||||
option (google.api.http) = {
|
||||
get: "/stat"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
message PingReq {}
|
||||
|
||||
message PingRsp {}
|
||||
|
||||
message OK {}
|
||||
|
||||
message AddUserReq {
|
||||
string username = 1;
|
||||
string password = 2;
|
||||
}
|
||||
|
||||
message User {
|
||||
int32 id = 1;
|
||||
string username = 2;
|
||||
}
|
||||
|
||||
message LoginReq {
|
||||
string username = 1;
|
||||
string password = 2;
|
||||
}
|
||||
|
||||
message AddBudgetReq {
|
||||
string name = 1;
|
||||
int32 start_day = 2;
|
||||
int32 monthly_limit = 3;
|
||||
}
|
||||
|
||||
message Budget {
|
||||
int32 id = 1;
|
||||
string name = 2;
|
||||
int32 start_day = 3;
|
||||
int32 monthly_limit = 4;
|
||||
repeated Category categories = 5;
|
||||
}
|
||||
|
||||
message UpdateBudgetReq {
|
||||
int32 id = 1;
|
||||
string name = 2;
|
||||
int32 start_day = 3;
|
||||
int32 monthly_limit = 4;
|
||||
}
|
||||
|
||||
message GetBudgetsReq {}
|
||||
|
||||
message Budgets {
|
||||
repeated Budget budgets = 1;
|
||||
}
|
||||
|
||||
message DeleteBudgetReq {
|
||||
int32 id = 1;
|
||||
}
|
||||
|
||||
message AddUserToBudgetReq {
|
||||
int32 user_id = 1;
|
||||
int32 budget_id = 2;
|
||||
}
|
||||
|
||||
message GetBudgetUsersReq {
|
||||
int32 id = 1;
|
||||
}
|
||||
|
||||
message Users {
|
||||
repeated User users = 1;
|
||||
}
|
||||
|
||||
message RemoveUserFromBudgetReq {
|
||||
int32 user_id = 1;
|
||||
int32 budget_id = 2;
|
||||
}
|
||||
|
||||
message GetBudgetCategoriesReq {
|
||||
int32 budget_id = 2;
|
||||
}
|
||||
|
||||
message AddCategoryReq {
|
||||
string name = 1;
|
||||
int32 budget_id = 2;
|
||||
bool favorite = 3;
|
||||
int32 monthly_limit = 4;
|
||||
}
|
||||
|
||||
message Category {
|
||||
int32 id = 1;
|
||||
string name = 2;
|
||||
int32 budget_id = 3;
|
||||
bool favorite = 4;
|
||||
int32 monthly_limit = 5;
|
||||
}
|
||||
|
||||
message UpdateCategoryReq {
|
||||
int32 id = 1;
|
||||
string name = 2;
|
||||
bool favorite = 3;
|
||||
int32 monthly_limit = 4;
|
||||
}
|
||||
|
||||
message Categories {
|
||||
repeated Category categories = 1;
|
||||
}
|
||||
|
||||
message DeleteCategoriesReq {
|
||||
int32 id = 1;
|
||||
}
|
||||
|
||||
message AddWasteReq {
|
||||
string name = 1;
|
||||
int32 price = 2;
|
||||
float amount = 3;
|
||||
int32 category_id = 4;
|
||||
int32 budget_id = 5;
|
||||
}
|
||||
|
||||
message AddWasteTextReq {
|
||||
string text = 1;
|
||||
int32 category_id = 2;
|
||||
int32 budget_id = 3;
|
||||
}
|
||||
|
||||
message Waste {
|
||||
int32 id = 1;
|
||||
string name = 2;
|
||||
int32 price = 3;
|
||||
float amount = 4;
|
||||
}
|
||||
|
||||
message DeleteWasteReq {
|
||||
int32 id = 1;
|
||||
}
|
||||
|
||||
message GetCategoriesStatReq {
|
||||
repeated int32 ids = 1;
|
||||
}
|
||||
|
||||
message CategoriesStat {
|
||||
repeated CategoriesStat stat = 1;
|
||||
}
|
||||
|
||||
message CategoryStat {
|
||||
string name = 1;
|
||||
int32 monthly_limit = 2;
|
||||
int32 amount = 3;
|
||||
}
|
||||
|
||||
+56
-3
@@ -2,15 +2,24 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"git.3crabs.ru/save_my_money/smm_core/internal/app"
|
||||
"git.3crabs.ru/save_my_money/smm_core/internal/services/budget"
|
||||
"git.3crabs.ru/save_my_money/smm_core/internal/services/category"
|
||||
"git.3crabs.ru/save_my_money/smm_core/internal/services/user"
|
||||
"git.3crabs.ru/save_my_money/smm_core/internal/services/waste"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"google.golang.org/grpc/metadata"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
proto "git.3crabs.ru/save_my_money/smm_core/proto"
|
||||
)
|
||||
@@ -22,10 +31,49 @@ func main() {
|
||||
log.Fatalln("Failed to listen:", err)
|
||||
}
|
||||
|
||||
dbpool, err := pgxpool.New(context.Background(), os.Getenv("DATABASE_URL"))
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Unable to create connection pool: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
defer dbpool.Close()
|
||||
|
||||
categoryService := category.NewCategoryService(dbpool)
|
||||
userService := user.NewUserService(dbpool)
|
||||
budgetService := budget.NewBudgetService(dbpool, categoryService)
|
||||
wasteService := waste.NewWasteService(dbpool, categoryService)
|
||||
|
||||
// Create a gRPC server object
|
||||
s := grpc.NewServer()
|
||||
s := grpc.NewServer(
|
||||
grpc.UnaryInterceptor(
|
||||
func(
|
||||
ctx context.Context,
|
||||
req any,
|
||||
info *grpc.UnaryServerInfo,
|
||||
handler grpc.UnaryHandler,
|
||||
) (resp any, err error) {
|
||||
md, ok := metadata.FromIncomingContext(ctx)
|
||||
if !ok || len(md["authorization"]) == 0 {
|
||||
return nil, status.Errorf(codes.Unauthenticated, "no auth token")
|
||||
}
|
||||
authToken := md["authorization"][0]
|
||||
if authToken != os.Getenv("AUTHORIZATION") {
|
||||
return nil, status.Errorf(codes.Unauthenticated, "invalid token")
|
||||
}
|
||||
return handler(ctx, req)
|
||||
},
|
||||
),
|
||||
)
|
||||
// Attach the Greeter service to the server
|
||||
proto.RegisterSmmCoreServer(s, app.NewServer())
|
||||
proto.RegisterSmmCoreServer(
|
||||
s,
|
||||
app.NewServer(
|
||||
categoryService,
|
||||
userService,
|
||||
budgetService,
|
||||
wasteService,
|
||||
),
|
||||
)
|
||||
// Serve gRPC server
|
||||
log.Println("Serving gRPC on 0.0.0.0:8080")
|
||||
go func() {
|
||||
@@ -42,7 +90,12 @@ func main() {
|
||||
log.Fatalln("Failed to dial server:", err)
|
||||
}
|
||||
|
||||
mux := runtime.NewServeMux()
|
||||
mux := runtime.NewServeMux(
|
||||
runtime.WithMetadata(func(ctx context.Context, request *http.Request) metadata.MD {
|
||||
header := request.Header.Get("User-Id")
|
||||
return metadata.Pairs("user-id", header)
|
||||
}),
|
||||
)
|
||||
// Register Greeter
|
||||
err = proto.RegisterSmmCoreHandler(context.Background(), mux, conn)
|
||||
if err != nil {
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
version: '3.9'
|
||||
|
||||
services:
|
||||
|
||||
db:
|
||||
container_name: db
|
||||
image: postgres
|
||||
restart: always
|
||||
shm_size: 128mb
|
||||
environment:
|
||||
POSTGRES_USER: crab
|
||||
POSTGRES_PASSWORD: crab
|
||||
POSTGRES_DB: smm-core
|
||||
ports:
|
||||
- 5432:5432
|
||||
|
||||
adminer:
|
||||
container_name: adminer
|
||||
image: adminer
|
||||
restart: always
|
||||
ports:
|
||||
- 8100:8080
|
||||
+1
-1
@@ -12,4 +12,4 @@ services:
|
||||
|
||||
networks:
|
||||
common-network:
|
||||
external: true
|
||||
external: true
|
||||
|
||||
@@ -6,12 +6,23 @@ require (
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241021214115-324edc3d5d38
|
||||
google.golang.org/grpc v1.67.1
|
||||
google.golang.org/protobuf v1.35.1
|
||||
google.golang.org/protobuf v1.35.2
|
||||
)
|
||||
|
||||
require (
|
||||
golang.org/x/net v0.28.0 // indirect
|
||||
golang.org/x/sys v0.24.0 // indirect
|
||||
golang.org/x/text v0.19.0 // indirect
|
||||
github.com/cweill/gotests v1.6.0 // indirect
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
||||
github.com/jackc/pgx/v5 v5.7.1 // indirect
|
||||
github.com/jackc/puddle/v2 v2.2.2 // indirect
|
||||
golang.org/x/crypto v0.29.0 // indirect
|
||||
golang.org/x/mod v0.22.0 // indirect
|
||||
golang.org/x/net v0.31.0 // indirect
|
||||
golang.org/x/sync v0.9.0 // indirect
|
||||
golang.org/x/sys v0.27.0 // indirect
|
||||
golang.org/x/text v0.20.0 // indirect
|
||||
golang.org/x/tools v0.27.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38 // indirect
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
@@ -1,18 +1,68 @@
|
||||
github.com/cweill/gotests v1.6.0 h1:KJx+/p4EweijYzqPb4Y/8umDCip1Cv6hEVyOx0mE9W8=
|
||||
github.com/cweill/gotests v1.6.0/go.mod h1:CaRYbxQZGQOxXDvM9l0XJVV2Tjb2E5H53vq+reR2GrA=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
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.23.0 h1:ad0vkEBuk23VJzZR9nkLVG0YAoN9coASF1GusYX6AlU=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0/go.mod h1:igFoXX2ELCW06bol23DWPB5BEWfZISOzSP5K2sbLea0=
|
||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||
github.com/jackc/pgx/v5 v5.7.1 h1:x7SYsPBYDkHDksogeSmZZ5xzThcTgRz++I5E+ePFUcs=
|
||||
github.com/jackc/pgx/v5 v5.7.1/go.mod h1:e7O26IywZZ+naJtWWos6i6fvWK+29etgITqrqHLfoZA=
|
||||
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
|
||||
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
|
||||
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
|
||||
golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ=
|
||||
golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg=
|
||||
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
|
||||
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
|
||||
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
|
||||
golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo=
|
||||
golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
|
||||
golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
|
||||
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
|
||||
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
|
||||
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
|
||||
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
|
||||
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
|
||||
golang.org/x/tools v0.0.0-20191109212701-97ad0ed33101/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.27.0 h1:qEKojBykQkQ4EynWy4S8Weg69NumxKdn40Fce3uc/8o=
|
||||
golang.org/x/tools v0.27.0/go.mod h1:sUi0ZgbwW9ZPAq26Ekut+weQPR5eIM6GQLQ1Yjm1H0Q=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241021214115-324edc3d5d38 h1:2oV8dfuIkM1Ti7DwXc0BJfnwr9csz4TDXI9EmiI+Rbw=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241021214115-324edc3d5d38/go.mod h1:vuAjtvlwkDKF6L1GQ0SokiRLCGFfeBUXWr/aFFkHACc=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38 h1:zciRKQ4kBpFgpfC5QQCVtnnNAcLIqweL7plyZRQHVpI=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI=
|
||||
google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E=
|
||||
google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 h1:F29+wU6Ee6qgu9TddPgooOdaqsxTMunOoj8KA5yuS5A=
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1/go.mod h1:5KF+wpkbTSbGcR9zteSqZV6fqFOWBl4Yde8En8MryZA=
|
||||
google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
|
||||
google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io=
|
||||
google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"git.3crabs.ru/save_my_money/smm_core/internal/services/budget"
|
||||
"git.3crabs.ru/save_my_money/smm_core/internal/services/category"
|
||||
"git.3crabs.ru/save_my_money/smm_core/internal/services/user"
|
||||
"git.3crabs.ru/save_my_money/smm_core/internal/services/waste"
|
||||
proto "git.3crabs.ru/save_my_money/smm_core/proto"
|
||||
)
|
||||
|
||||
func mapUser(user *user.UserEntity) *proto.User {
|
||||
return &proto.User{
|
||||
Id: int32(user.Id),
|
||||
Username: user.Username,
|
||||
}
|
||||
}
|
||||
|
||||
func mapBudget(budget *budget.BudgetEntity) *proto.Budget {
|
||||
return &proto.Budget{
|
||||
Id: int32(budget.Id),
|
||||
Name: budget.Name,
|
||||
StartDay: int32(budget.StartDay),
|
||||
MonthlyLimit: int32(budget.MonthlyLimit),
|
||||
Categories: mapCategories(budget.Categories),
|
||||
}
|
||||
}
|
||||
|
||||
func mapCategory(category *category.CategoryEntity) *proto.Category {
|
||||
return &proto.Category{
|
||||
Id: int32(category.Id),
|
||||
Name: category.Name,
|
||||
Favorite: category.Favorite,
|
||||
MonthlyLimit: int32(category.MonthlyLimit),
|
||||
}
|
||||
}
|
||||
|
||||
func mapCategories(categories []*category.CategoryEntity) []*proto.Category {
|
||||
res := make([]*proto.Category, 0, len(categories))
|
||||
for _, item := range categories {
|
||||
res = append(res, mapCategory(item))
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func mapWaste(waste *waste.WasteEntity) *proto.Waste {
|
||||
return &proto.Waste{
|
||||
Id: int32(waste.Id),
|
||||
Name: waste.Name,
|
||||
Price: int32(waste.Price),
|
||||
Amount: waste.Amount,
|
||||
}
|
||||
}
|
||||
+183
-3
@@ -3,17 +3,197 @@ package app
|
||||
import (
|
||||
"context"
|
||||
|
||||
"git.3crabs.ru/save_my_money/smm_core/internal/services/budget"
|
||||
"git.3crabs.ru/save_my_money/smm_core/internal/services/category"
|
||||
"git.3crabs.ru/save_my_money/smm_core/internal/services/user"
|
||||
"git.3crabs.ru/save_my_money/smm_core/internal/services/waste"
|
||||
proto "git.3crabs.ru/save_my_money/smm_core/proto"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
proto.UnsafeSmmCoreServer
|
||||
categoryService *category.CategoryService
|
||||
userService *user.UserService
|
||||
budgetService *budget.BudgetService
|
||||
wasteService *waste.WasteService
|
||||
}
|
||||
|
||||
func NewServer() *Server {
|
||||
return &Server{}
|
||||
func NewServer(
|
||||
categoryService *category.CategoryService,
|
||||
userService *user.UserService,
|
||||
budgetService *budget.BudgetService,
|
||||
wasteService *waste.WasteService,
|
||||
) proto.SmmCoreServer {
|
||||
return &Server{
|
||||
categoryService: categoryService,
|
||||
userService: userService,
|
||||
budgetService: budgetService,
|
||||
wasteService: wasteService,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) Ping(_ context.Context, _ *proto.PingReq) (*proto.PingRsp, error) {
|
||||
func (s *Server) Ping(context.Context, *proto.PingReq) (*proto.PingRsp, error) {
|
||||
return &proto.PingRsp{}, nil
|
||||
}
|
||||
|
||||
func (s *Server) Login(ctx context.Context, req *proto.LoginReq) (*proto.User, error) {
|
||||
user, err := s.userService.Login(
|
||||
ctx,
|
||||
&user.UserEntity{
|
||||
Username: req.Username,
|
||||
Password: req.Password,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return mapUser(user), nil
|
||||
}
|
||||
|
||||
func (s *Server) AddBudget(ctx context.Context, req *proto.AddBudgetReq) (*proto.Budget, error) {
|
||||
budget, err := s.budgetService.AddBudget(
|
||||
ctx,
|
||||
&budget.BudgetEntity{
|
||||
Name: req.Name,
|
||||
StartDay: int(req.StartDay),
|
||||
MonthlyLimit: int(req.MonthlyLimit),
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return mapBudget(budget), nil
|
||||
}
|
||||
|
||||
func (s *Server) GetBudgets(ctx context.Context, req *proto.GetBudgetsReq) (*proto.Budgets, error) {
|
||||
budgets, err := s.budgetService.GetBudgets(
|
||||
ctx,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res := make([]*proto.Budget, 0, len(budgets))
|
||||
for _, budget := range budgets {
|
||||
res = append(res, mapBudget(budget))
|
||||
}
|
||||
return &proto.Budgets{
|
||||
Budgets: res,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) AddUserToBudget(ctx context.Context, req *proto.AddUserToBudgetReq) (*proto.OK, error) {
|
||||
_, err := s.budgetService.AddUserToBudget(
|
||||
ctx,
|
||||
int(req.BudgetId),
|
||||
int(req.UserId),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &proto.OK{}, nil
|
||||
}
|
||||
|
||||
func (s *Server) AddCategory(ctx context.Context, req *proto.AddCategoryReq) (*proto.Category, error) {
|
||||
category, err := s.categoryService.AddCategory(
|
||||
ctx,
|
||||
&category.CategoryEntity{
|
||||
Name: req.Name,
|
||||
BudgetId: int(req.BudgetId),
|
||||
Favorite: req.Favorite,
|
||||
MonthlyLimit: int(req.MonthlyLimit),
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return mapCategory(category), nil
|
||||
}
|
||||
|
||||
func (s *Server) GetBudgetCategories(ctx context.Context, req *proto.GetBudgetCategoriesReq) (*proto.Categories, error) {
|
||||
categories, err := s.budgetService.GetBudgetCategories(
|
||||
ctx,
|
||||
int(req.BudgetId),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res := make([]*proto.Category, 0, len(categories))
|
||||
for _, category := range categories {
|
||||
res = append(res, mapCategory(category))
|
||||
}
|
||||
return &proto.Categories{
|
||||
Categories: res,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) AddWaste(ctx context.Context, req *proto.AddWasteReq) (*proto.Waste, error) {
|
||||
waste, err := s.wasteService.AddWaste(
|
||||
ctx,
|
||||
&waste.WasteEntity{
|
||||
Name: req.Name,
|
||||
Price: int(req.Price),
|
||||
Amount: req.Amount,
|
||||
CategoryId: int(req.CategoryId),
|
||||
BudgetId: int(req.BudgetId),
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return mapWaste(waste), nil
|
||||
}
|
||||
|
||||
func (s *Server) AddWasteByText(ctx context.Context, req *proto.AddWasteTextReq) (*proto.Waste, error) {
|
||||
waste, err := s.wasteService.AddWasteByText(
|
||||
ctx,
|
||||
&waste.WasteTextEntity{
|
||||
Text: req.Text,
|
||||
CategoryId: int(req.CategoryId),
|
||||
BudgetId: int(req.BudgetId),
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return mapWaste(waste), nil
|
||||
}
|
||||
|
||||
// GetCategoriesStat implements proto.SmmCoreServer.
|
||||
func (s *Server) GetCategoriesStat(context.Context, *proto.GetCategoriesStatReq) (*proto.CategoriesStat, error) {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
// DeleteBudget implements proto.SmmCoreServer.
|
||||
func (s *Server) DeleteBudget(context.Context, *proto.DeleteBudgetReq) (*proto.Budget, error) {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
// DeleteCategories implements proto.SmmCoreServer.
|
||||
func (s *Server) DeleteCategories(context.Context, *proto.DeleteCategoriesReq) (*proto.Category, error) {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
// DeleteWaste implements proto.SmmCoreServer.
|
||||
func (s *Server) DeleteWaste(context.Context, *proto.DeleteWasteReq) (*proto.Waste, error) {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
// GetBudgetUsers implements proto.SmmCoreServer.
|
||||
func (s *Server) GetBudgetUsers(context.Context, *proto.GetBudgetUsersReq) (*proto.Users, error) {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
// RemoveUserFromBudget implements proto.SmmCoreServer.
|
||||
func (s *Server) RemoveUserFromBudget(context.Context, *proto.RemoveUserFromBudgetReq) (*proto.Budget, error) {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
// UpdateBudget implements proto.SmmCoreServer.
|
||||
func (s *Server) UpdateBudget(context.Context, *proto.UpdateBudgetReq) (*proto.Budget, error) {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
// UpdateCategory implements proto.SmmCoreServer.
|
||||
func (s *Server) UpdateCategory(context.Context, *proto.UpdateCategoryReq) (*proto.Category, error) {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
package budget
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"git.3crabs.ru/save_my_money/smm_core/internal/services/category"
|
||||
"git.3crabs.ru/save_my_money/smm_core/internal/services/context_utils"
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
)
|
||||
|
||||
type BudgetEntity struct {
|
||||
Id int
|
||||
Name string
|
||||
StartDay int
|
||||
MonthlyLimit int
|
||||
Categories []*category.CategoryEntity
|
||||
}
|
||||
|
||||
type BudgetService struct {
|
||||
db *pgxpool.Pool
|
||||
categoryService *category.CategoryService
|
||||
}
|
||||
|
||||
func NewBudgetService(
|
||||
db *pgxpool.Pool,
|
||||
categoryService *category.CategoryService,
|
||||
) *BudgetService {
|
||||
return &BudgetService{
|
||||
db: db,
|
||||
categoryService: categoryService,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *BudgetService) AddBudget(ctx context.Context, budget *BudgetEntity) (*BudgetEntity, error) {
|
||||
userId, err := context_utils.GetUserId(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tx, err := s.db.Begin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer tx.Rollback(ctx)
|
||||
|
||||
query := `INSERT INTO budgets (name, start_day, monthly_limit) VALUES (@name, @start_day, @monthly_limit) RETURNING id`
|
||||
args := pgx.NamedArgs{
|
||||
"name": budget.Name,
|
||||
"start_day": budget.StartDay,
|
||||
"monthly_limit": budget.MonthlyLimit,
|
||||
}
|
||||
if err := s.db.QueryRow(ctx, query, args).Scan(&budget.Id); err != nil {
|
||||
return nil, fmt.Errorf("unable to insert row: %w", err)
|
||||
}
|
||||
|
||||
_, err = s.AddUserToBudget(ctx, budget.Id, userId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = tx.Commit(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return budget, nil
|
||||
}
|
||||
|
||||
func (s *BudgetService) GetBudgets(ctx context.Context) ([]*BudgetEntity, error) {
|
||||
userId, err := context_utils.GetUserId(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
query := `SELECT b.id, b.name, b.start_day, b.monthly_limit FROM budgets b JOIN users_budgets ub ON ub.budget_id = b.id WHERE ub.user_id = @user_id`
|
||||
args := pgx.NamedArgs{
|
||||
"user_id": userId,
|
||||
}
|
||||
rows, err := s.db.Query(ctx, query, args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
budgets := []*BudgetEntity{}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
budget := &BudgetEntity{}
|
||||
err = rows.Scan(&budget.Id, &budget.Name, &budget.StartDay, &budget.MonthlyLimit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
budget.Categories, err = s.GetBudgetCategories(ctx, budget.Id)
|
||||
budgets = append(budgets, budget)
|
||||
}
|
||||
|
||||
return budgets, nil
|
||||
}
|
||||
|
||||
func (s *BudgetService) AddUserToBudget(
|
||||
ctx context.Context,
|
||||
budgetId int,
|
||||
userId int,
|
||||
) (int, error) {
|
||||
query := `INSERT INTO users_budgets (user_id, budget_id) VALUES (@user_id, @budget_id) RETURNING id`
|
||||
args := pgx.NamedArgs{
|
||||
"user_id": userId,
|
||||
"budget_id": budgetId,
|
||||
}
|
||||
id := 0
|
||||
if err := s.db.QueryRow(ctx, query, args).Scan(&id); err != nil {
|
||||
return 0, fmt.Errorf("unable to insert row: %w", err)
|
||||
}
|
||||
return id, nil
|
||||
}
|
||||
|
||||
func (s *BudgetService) GetBudgetCategories(
|
||||
ctx context.Context,
|
||||
budgetId int,
|
||||
) ([]*category.CategoryEntity, error) {
|
||||
query := `SELECT id, name, favorite, monthly_limit FROM categories WHERE budget_id = @budget_id`
|
||||
args := pgx.NamedArgs{
|
||||
"budget_id": budgetId,
|
||||
}
|
||||
rows, err := s.db.Query(ctx, query, args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
categories := []*category.CategoryEntity{}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
category := &category.CategoryEntity{}
|
||||
err = rows.Scan(&category.Id, &category.Name, &category.Favorite, &category.MonthlyLimit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
categories = append(categories, category)
|
||||
}
|
||||
|
||||
return categories, nil
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package category
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
)
|
||||
|
||||
type CategoryEntity struct {
|
||||
Id int
|
||||
Name string
|
||||
BudgetId int
|
||||
Favorite bool
|
||||
MonthlyLimit int
|
||||
}
|
||||
|
||||
type CategoryService struct {
|
||||
db *pgxpool.Pool
|
||||
}
|
||||
|
||||
func NewCategoryService(
|
||||
db *pgxpool.Pool,
|
||||
) *CategoryService {
|
||||
return &CategoryService{
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *CategoryService) AddCategory(ctx context.Context, category *CategoryEntity) (*CategoryEntity, error) {
|
||||
query := `INSERT INTO categories (name, budget_id, favorite, monthly_limit) VALUES (@name, @budget_id, @favorite, @monthly_limit) RETURNING id`
|
||||
args := pgx.NamedArgs{
|
||||
"name": category.Name,
|
||||
"budget_id": category.BudgetId,
|
||||
"favorite": category.Favorite,
|
||||
"monthly_limit": category.MonthlyLimit,
|
||||
}
|
||||
if err := s.db.QueryRow(ctx, query, args).Scan(&category.Id); err != nil {
|
||||
return nil, fmt.Errorf("unable to insert row: %w", err)
|
||||
}
|
||||
return category, nil
|
||||
}
|
||||
|
||||
func (s *CategoryService) GetCategory(ctx context.Context, budgetId int, name string) (*CategoryEntity, error) {
|
||||
query := `SELECT id, name, budget_id, favorite, monthly_limit FROM categories WHERE LOWER(name) = LOWER(@name)`
|
||||
args := pgx.NamedArgs{
|
||||
"name": name,
|
||||
}
|
||||
rows, err := s.db.Query(ctx, query, args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
categories := []*CategoryEntity{}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
category := &CategoryEntity{}
|
||||
err = rows.Scan(&category.Id, &category.Name, &category.BudgetId, &category.Favorite, &category.MonthlyLimit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
categories = append(categories, category)
|
||||
}
|
||||
if len(categories) > 0 {
|
||||
return categories[0], nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package context_utils
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
|
||||
"google.golang.org/grpc/metadata"
|
||||
)
|
||||
|
||||
type UnauthorizedErr struct{}
|
||||
|
||||
func (e *UnauthorizedErr) Error() string {
|
||||
return "user not autorize"
|
||||
}
|
||||
|
||||
func GetUserId(ctx context.Context) (int, error) {
|
||||
md, ok := metadata.FromIncomingContext(ctx)
|
||||
if !ok {
|
||||
return 0, &UnauthorizedErr{}
|
||||
}
|
||||
id, err := strconv.Atoi(md["user-id"][0])
|
||||
if err != nil {
|
||||
return 0, &UnauthorizedErr{}
|
||||
}
|
||||
return id, nil
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,66 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
)
|
||||
|
||||
type UserEntity struct {
|
||||
Id int
|
||||
Username string
|
||||
Password string
|
||||
}
|
||||
|
||||
type UsernameAlreadyExistsErr struct{}
|
||||
|
||||
func (e *UsernameAlreadyExistsErr) Error() string {
|
||||
return "username already exists error"
|
||||
}
|
||||
|
||||
type UserNotFoundErr struct{}
|
||||
|
||||
func (e *UserNotFoundErr) Error() string {
|
||||
return "user not found error"
|
||||
}
|
||||
|
||||
type UserService struct {
|
||||
db *pgxpool.Pool
|
||||
}
|
||||
|
||||
func NewUserService(
|
||||
db *pgxpool.Pool,
|
||||
) *UserService {
|
||||
return &UserService{
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *UserService) Login(ctx context.Context, user *UserEntity) (*UserEntity, error) {
|
||||
args := pgx.NamedArgs{
|
||||
"username": user.Username,
|
||||
"password": hashPassword(user.Username, user.Password, "crab"),
|
||||
}
|
||||
|
||||
query := `SELECT id FROM users WHERE username = @username AND password = @password LIMIT 1`
|
||||
if err := s.db.QueryRow(ctx, query, args).Scan(&user.Id); err != nil {
|
||||
query := `INSERT INTO users (username, password) VALUES (@username, @password) RETURNING id`
|
||||
if err := s.db.QueryRow(ctx, query, args).Scan(&user.Id); err != nil {
|
||||
return user, err
|
||||
}
|
||||
}
|
||||
|
||||
return user, nil
|
||||
}
|
||||
|
||||
func hashPassword(username string, password string, salt string) string {
|
||||
return getMD5Hash(username + password + salt)
|
||||
}
|
||||
|
||||
func getMD5Hash(text string) string {
|
||||
hash := md5.Sum([]byte(text))
|
||||
return hex.EncodeToString(hash[:])
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
package waste
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"git.3crabs.ru/save_my_money/smm_core/internal/services/category"
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
"golang.org/x/text/cases"
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
type WasteEntity struct {
|
||||
Id int
|
||||
Name string
|
||||
Price int
|
||||
Amount float32
|
||||
CategoryId int
|
||||
CategoryName string
|
||||
BudgetId int
|
||||
}
|
||||
|
||||
type WasteTextEntity struct {
|
||||
Text string
|
||||
CategoryId int
|
||||
BudgetId int
|
||||
}
|
||||
|
||||
type WasteService struct {
|
||||
db *pgxpool.Pool
|
||||
categoryService *category.CategoryService
|
||||
}
|
||||
|
||||
func NewWasteService(
|
||||
db *pgxpool.Pool,
|
||||
categoryService *category.CategoryService,
|
||||
) *WasteService {
|
||||
return &WasteService{
|
||||
db: db,
|
||||
categoryService: categoryService,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *WasteService) AddWaste(ctx context.Context, waste *WasteEntity) (*WasteEntity, error) {
|
||||
query := `INSERT INTO wastes (name, price, amount, budget_id, category_id) VALUES (@name, @price, @amount, @budget_id, @category_id) RETURNING id`
|
||||
args := pgx.NamedArgs{
|
||||
"name": waste.Name,
|
||||
"price": waste.Price,
|
||||
"amount": waste.Amount,
|
||||
"budget_id": waste.BudgetId,
|
||||
"category_id": waste.CategoryId,
|
||||
}
|
||||
if err := s.db.QueryRow(ctx, query, args).Scan(&waste.Id); err != nil {
|
||||
return nil, fmt.Errorf("unable to insert row: %w", err)
|
||||
}
|
||||
return waste, nil
|
||||
}
|
||||
|
||||
func (s *WasteService) GetWaste(ctx context.Context, budgetId int, name string) (*WasteEntity, error) {
|
||||
query := `SELECT id, name, price, amount, budget_id, category_id FROM wastes WHERE budget_id = @budget_id AND LOWER(name) = LOWER(@name) LIMIT 1`
|
||||
args := pgx.NamedArgs{
|
||||
"name": name,
|
||||
"budget_id": budgetId,
|
||||
}
|
||||
rows, err := s.db.Query(ctx, query, args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
wastes := []*WasteEntity{}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
waste := &WasteEntity{}
|
||||
err = rows.Scan(&waste.Id, &waste.Name, &waste.Price, &waste.Amount, &waste.BudgetId, &waste.CategoryId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
wastes = append(wastes, waste)
|
||||
}
|
||||
if len(wastes) > 0 {
|
||||
return wastes[0], nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (s *WasteService) AddWasteByText(ctx context.Context, wasteText *WasteTextEntity) (*WasteEntity, error) {
|
||||
waste := s.parseWaste(wasteText.Text)
|
||||
|
||||
var categoryId *int
|
||||
if waste.CategoryName != "" {
|
||||
c, err := s.categoryService.GetCategory(ctx, wasteText.BudgetId, waste.CategoryName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if c == nil {
|
||||
c, err = s.categoryService.AddCategory(ctx, &category.CategoryEntity{
|
||||
Name: waste.CategoryName,
|
||||
BudgetId: int(wasteText.BudgetId),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
categoryId = &c.Id
|
||||
}
|
||||
if categoryId == nil {
|
||||
w, err := s.GetWaste(ctx, wasteText.BudgetId, waste.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if w != nil {
|
||||
categoryId = &w.CategoryId
|
||||
}
|
||||
}
|
||||
|
||||
if categoryId == nil {
|
||||
return nil, fmt.Errorf("bad request")
|
||||
}
|
||||
|
||||
query := `INSERT INTO wastes (name, price, amount, budget_id, category_id) VALUES (@name, @price, @amount, @budget_id, @category_id) RETURNING id`
|
||||
args := pgx.NamedArgs{
|
||||
"name": waste.Name,
|
||||
"price": waste.Price,
|
||||
"amount": waste.Amount,
|
||||
"budget_id": wasteText.BudgetId,
|
||||
"category_id": *categoryId,
|
||||
}
|
||||
if err := s.db.QueryRow(ctx, query, args).Scan(&waste.Id); err != nil {
|
||||
return nil, fmt.Errorf("unable to insert row: %w", err)
|
||||
}
|
||||
return waste, nil
|
||||
}
|
||||
|
||||
func (s *WasteService) parseWaste(text string) *WasteEntity {
|
||||
text = strings.TrimSpace(text)
|
||||
arr := strings.Split(text, ":")
|
||||
|
||||
waste := &WasteEntity{}
|
||||
switch len(arr) {
|
||||
case 1:
|
||||
arr = strings.Split(strings.TrimSpace(arr[0]), " ")
|
||||
case 2:
|
||||
waste.CategoryName = strToName(arr[0])
|
||||
arr = strings.Split(strings.TrimSpace(arr[1]), " ")
|
||||
}
|
||||
|
||||
switch len(arr) {
|
||||
case 2:
|
||||
waste.Name = strToName(arr[0])
|
||||
waste.Amount = 1
|
||||
waste.Price = strToPrice(arr[1])
|
||||
case 3:
|
||||
waste.Name = strToName(arr[0])
|
||||
waste.Amount = strToAmount(arr[1])
|
||||
waste.Price = strToPrice(arr[2])
|
||||
}
|
||||
return waste
|
||||
}
|
||||
|
||||
func strToFloat(s string) float32 {
|
||||
a, err := strconv.ParseFloat(s, 32)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return float32(a)
|
||||
}
|
||||
|
||||
func strToPrice(s string) int {
|
||||
s = strings.TrimSpace(s)
|
||||
s = strings.TrimSuffix(s, "/кг")
|
||||
s = strings.TrimSuffix(s, "/шт")
|
||||
s = strings.TrimSuffix(s, "р")
|
||||
s = strings.TrimSuffix(s, "руб")
|
||||
s = strings.TrimSuffix(s, "рублей")
|
||||
return int(strToFloat(s) * 100)
|
||||
}
|
||||
|
||||
func strToAmount(s string) float32 {
|
||||
s = strings.TrimSpace(s)
|
||||
s = strings.TrimSuffix(s, "шт")
|
||||
s = strings.TrimSuffix(s, "кг")
|
||||
return strToFloat(s)
|
||||
}
|
||||
|
||||
func strToName(s string) string {
|
||||
caser := cases.Title(language.Russian)
|
||||
return caser.String(strings.TrimSpace(strings.ToLower(s)))
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package waste
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestWasteService_parseWaste(t *testing.T) {
|
||||
type args struct {
|
||||
text string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want *WasteEntity
|
||||
}{
|
||||
{
|
||||
name: "full",
|
||||
args: args{
|
||||
text: "Транспорт: такси 2 200",
|
||||
},
|
||||
want: &WasteEntity{
|
||||
CategoryName: "транспорт",
|
||||
Name: "такси",
|
||||
Amount: 2,
|
||||
Price: 20000,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "full without amount",
|
||||
args: args{
|
||||
text: "Транспорт: такси 200",
|
||||
},
|
||||
want: &WasteEntity{
|
||||
CategoryName: "транспорт",
|
||||
Name: "такси",
|
||||
Amount: 1,
|
||||
Price: 20000,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "without category",
|
||||
args: args{
|
||||
text: "такси 2 200",
|
||||
},
|
||||
want: &WasteEntity{
|
||||
Name: "такси",
|
||||
Amount: 2,
|
||||
Price: 20000,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "without amount",
|
||||
args: args{
|
||||
text: "такси 200",
|
||||
},
|
||||
want: &WasteEntity{
|
||||
Name: "такси",
|
||||
Amount: 1,
|
||||
Price: 20000,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "р",
|
||||
args: args{
|
||||
text: "такси 200р",
|
||||
},
|
||||
want: &WasteEntity{
|
||||
Name: "такси",
|
||||
Amount: 1,
|
||||
Price: 20000,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
s := &WasteService{}
|
||||
if got := s.parseWaste(tt.args.text); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("WasteService.parseWaste() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
CREATE TABLE IF NOT EXISTS "user" (
|
||||
id SERIAL PRIMARY KEY,
|
||||
chat_id TEXT NOT NULL
|
||||
);
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DROP TABLE IF EXISTS "user";
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,14 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id SERIAL PRIMARY KEY,
|
||||
username TEXT UNIQUE NOT NULL,
|
||||
password TEXT NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DROP TABLE IF EXISTS users;
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,15 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
CREATE TABLE IF NOT EXISTS budgets (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
start_day INT NOT NULL,
|
||||
monthly_limit INT DEFAULT 0,
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DROP TABLE IF EXISTS budgets;
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,17 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
CREATE TABLE IF NOT EXISTS categories (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
budget_id INT REFERENCES budgets(id) ON DELETE CASCADE,
|
||||
favorite BOOLEAN DEFAULT FALSE,
|
||||
monthly_limit INT DEFAULT 0,
|
||||
UNIQUE (budget_id, name),
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DROP TABLE IF EXISTS categories;
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,18 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
CREATE TABLE IF NOT EXISTS wastes (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
price INT NOT NULL,
|
||||
amount FLOAT NOT NULL,
|
||||
budget_id INT REFERENCES budgets(id) ON DELETE CASCADE,
|
||||
category_id INT REFERENCES categories(id) ON DELETE RESTRICT,
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DROP TABLE IF EXISTS wastes;
|
||||
-- +goose StatementEnd
|
||||
А
|
||||
@@ -0,0 +1,14 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
CREATE TABLE IF NOT EXISTS users_budgets (
|
||||
id SERIAL PRIMARY KEY,
|
||||
user_id INT REFERENCES users(id) ON DELETE CASCADE,
|
||||
budget_id INT REFERENCES budgets(id) ON DELETE RESTRICT,
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
DROP TABLE IF EXISTS users_budgets;
|
||||
-- +goose StatementEnd
|
||||
+1798
-27
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+623
-1
@@ -19,14 +19,53 @@ import (
|
||||
const _ = grpc.SupportPackageIsVersion9
|
||||
|
||||
const (
|
||||
SmmCore_Ping_FullMethodName = "/crabs.smm_core.SmmCore/Ping"
|
||||
SmmCore_Ping_FullMethodName = "/crabs.smm_core.SmmCore/Ping"
|
||||
SmmCore_Login_FullMethodName = "/crabs.smm_core.SmmCore/Login"
|
||||
SmmCore_AddBudget_FullMethodName = "/crabs.smm_core.SmmCore/AddBudget"
|
||||
SmmCore_UpdateBudget_FullMethodName = "/crabs.smm_core.SmmCore/UpdateBudget"
|
||||
SmmCore_GetBudgets_FullMethodName = "/crabs.smm_core.SmmCore/GetBudgets"
|
||||
SmmCore_DeleteBudget_FullMethodName = "/crabs.smm_core.SmmCore/DeleteBudget"
|
||||
SmmCore_AddUserToBudget_FullMethodName = "/crabs.smm_core.SmmCore/AddUserToBudget"
|
||||
SmmCore_GetBudgetUsers_FullMethodName = "/crabs.smm_core.SmmCore/GetBudgetUsers"
|
||||
SmmCore_RemoveUserFromBudget_FullMethodName = "/crabs.smm_core.SmmCore/RemoveUserFromBudget"
|
||||
SmmCore_GetBudgetCategories_FullMethodName = "/crabs.smm_core.SmmCore/GetBudgetCategories"
|
||||
SmmCore_AddCategory_FullMethodName = "/crabs.smm_core.SmmCore/AddCategory"
|
||||
SmmCore_UpdateCategory_FullMethodName = "/crabs.smm_core.SmmCore/UpdateCategory"
|
||||
SmmCore_DeleteCategories_FullMethodName = "/crabs.smm_core.SmmCore/DeleteCategories"
|
||||
SmmCore_AddWaste_FullMethodName = "/crabs.smm_core.SmmCore/AddWaste"
|
||||
SmmCore_AddWasteByText_FullMethodName = "/crabs.smm_core.SmmCore/AddWasteByText"
|
||||
SmmCore_DeleteWaste_FullMethodName = "/crabs.smm_core.SmmCore/DeleteWaste"
|
||||
SmmCore_GetCategoriesStat_FullMethodName = "/crabs.smm_core.SmmCore/GetCategoriesStat"
|
||||
)
|
||||
|
||||
// SmmCoreClient is the client API for SmmCore service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type SmmCoreClient interface {
|
||||
// ping
|
||||
Ping(ctx context.Context, in *PingReq, opts ...grpc.CallOption) (*PingRsp, error)
|
||||
// login
|
||||
Login(ctx context.Context, in *LoginReq, opts ...grpc.CallOption) (*User, error)
|
||||
// budgets
|
||||
AddBudget(ctx context.Context, in *AddBudgetReq, opts ...grpc.CallOption) (*Budget, error)
|
||||
UpdateBudget(ctx context.Context, in *UpdateBudgetReq, opts ...grpc.CallOption) (*Budget, error)
|
||||
GetBudgets(ctx context.Context, in *GetBudgetsReq, opts ...grpc.CallOption) (*Budgets, error)
|
||||
DeleteBudget(ctx context.Context, in *DeleteBudgetReq, opts ...grpc.CallOption) (*Budget, error)
|
||||
// budget users
|
||||
AddUserToBudget(ctx context.Context, in *AddUserToBudgetReq, opts ...grpc.CallOption) (*OK, error)
|
||||
GetBudgetUsers(ctx context.Context, in *GetBudgetUsersReq, opts ...grpc.CallOption) (*Users, error)
|
||||
RemoveUserFromBudget(ctx context.Context, in *RemoveUserFromBudgetReq, opts ...grpc.CallOption) (*Budget, error)
|
||||
GetBudgetCategories(ctx context.Context, in *GetBudgetCategoriesReq, opts ...grpc.CallOption) (*Categories, error)
|
||||
// categories
|
||||
AddCategory(ctx context.Context, in *AddCategoryReq, opts ...grpc.CallOption) (*Category, error)
|
||||
UpdateCategory(ctx context.Context, in *UpdateCategoryReq, opts ...grpc.CallOption) (*Category, error)
|
||||
DeleteCategories(ctx context.Context, in *DeleteCategoriesReq, opts ...grpc.CallOption) (*Category, error)
|
||||
// wastes
|
||||
AddWaste(ctx context.Context, in *AddWasteReq, opts ...grpc.CallOption) (*Waste, error)
|
||||
AddWasteByText(ctx context.Context, in *AddWasteTextReq, opts ...grpc.CallOption) (*Waste, error)
|
||||
DeleteWaste(ctx context.Context, in *DeleteWasteReq, opts ...grpc.CallOption) (*Waste, error)
|
||||
// stat
|
||||
GetCategoriesStat(ctx context.Context, in *GetCategoriesStatReq, opts ...grpc.CallOption) (*CategoriesStat, error)
|
||||
}
|
||||
|
||||
type smmCoreClient struct {
|
||||
@@ -47,11 +86,194 @@ func (c *smmCoreClient) Ping(ctx context.Context, in *PingReq, opts ...grpc.Call
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *smmCoreClient) Login(ctx context.Context, in *LoginReq, opts ...grpc.CallOption) (*User, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(User)
|
||||
err := c.cc.Invoke(ctx, SmmCore_Login_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *smmCoreClient) AddBudget(ctx context.Context, in *AddBudgetReq, opts ...grpc.CallOption) (*Budget, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(Budget)
|
||||
err := c.cc.Invoke(ctx, SmmCore_AddBudget_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *smmCoreClient) UpdateBudget(ctx context.Context, in *UpdateBudgetReq, opts ...grpc.CallOption) (*Budget, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(Budget)
|
||||
err := c.cc.Invoke(ctx, SmmCore_UpdateBudget_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *smmCoreClient) GetBudgets(ctx context.Context, in *GetBudgetsReq, opts ...grpc.CallOption) (*Budgets, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(Budgets)
|
||||
err := c.cc.Invoke(ctx, SmmCore_GetBudgets_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *smmCoreClient) DeleteBudget(ctx context.Context, in *DeleteBudgetReq, opts ...grpc.CallOption) (*Budget, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(Budget)
|
||||
err := c.cc.Invoke(ctx, SmmCore_DeleteBudget_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *smmCoreClient) AddUserToBudget(ctx context.Context, in *AddUserToBudgetReq, opts ...grpc.CallOption) (*OK, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(OK)
|
||||
err := c.cc.Invoke(ctx, SmmCore_AddUserToBudget_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *smmCoreClient) GetBudgetUsers(ctx context.Context, in *GetBudgetUsersReq, opts ...grpc.CallOption) (*Users, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(Users)
|
||||
err := c.cc.Invoke(ctx, SmmCore_GetBudgetUsers_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *smmCoreClient) RemoveUserFromBudget(ctx context.Context, in *RemoveUserFromBudgetReq, opts ...grpc.CallOption) (*Budget, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(Budget)
|
||||
err := c.cc.Invoke(ctx, SmmCore_RemoveUserFromBudget_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *smmCoreClient) GetBudgetCategories(ctx context.Context, in *GetBudgetCategoriesReq, opts ...grpc.CallOption) (*Categories, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(Categories)
|
||||
err := c.cc.Invoke(ctx, SmmCore_GetBudgetCategories_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *smmCoreClient) AddCategory(ctx context.Context, in *AddCategoryReq, opts ...grpc.CallOption) (*Category, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(Category)
|
||||
err := c.cc.Invoke(ctx, SmmCore_AddCategory_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *smmCoreClient) UpdateCategory(ctx context.Context, in *UpdateCategoryReq, opts ...grpc.CallOption) (*Category, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(Category)
|
||||
err := c.cc.Invoke(ctx, SmmCore_UpdateCategory_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *smmCoreClient) DeleteCategories(ctx context.Context, in *DeleteCategoriesReq, opts ...grpc.CallOption) (*Category, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(Category)
|
||||
err := c.cc.Invoke(ctx, SmmCore_DeleteCategories_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *smmCoreClient) AddWaste(ctx context.Context, in *AddWasteReq, opts ...grpc.CallOption) (*Waste, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(Waste)
|
||||
err := c.cc.Invoke(ctx, SmmCore_AddWaste_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *smmCoreClient) AddWasteByText(ctx context.Context, in *AddWasteTextReq, opts ...grpc.CallOption) (*Waste, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(Waste)
|
||||
err := c.cc.Invoke(ctx, SmmCore_AddWasteByText_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *smmCoreClient) DeleteWaste(ctx context.Context, in *DeleteWasteReq, opts ...grpc.CallOption) (*Waste, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(Waste)
|
||||
err := c.cc.Invoke(ctx, SmmCore_DeleteWaste_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *smmCoreClient) GetCategoriesStat(ctx context.Context, in *GetCategoriesStatReq, opts ...grpc.CallOption) (*CategoriesStat, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(CategoriesStat)
|
||||
err := c.cc.Invoke(ctx, SmmCore_GetCategoriesStat_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// SmmCoreServer is the server API for SmmCore service.
|
||||
// All implementations must embed UnimplementedSmmCoreServer
|
||||
// for forward compatibility.
|
||||
type SmmCoreServer interface {
|
||||
// ping
|
||||
Ping(context.Context, *PingReq) (*PingRsp, error)
|
||||
// login
|
||||
Login(context.Context, *LoginReq) (*User, error)
|
||||
// budgets
|
||||
AddBudget(context.Context, *AddBudgetReq) (*Budget, error)
|
||||
UpdateBudget(context.Context, *UpdateBudgetReq) (*Budget, error)
|
||||
GetBudgets(context.Context, *GetBudgetsReq) (*Budgets, error)
|
||||
DeleteBudget(context.Context, *DeleteBudgetReq) (*Budget, error)
|
||||
// budget users
|
||||
AddUserToBudget(context.Context, *AddUserToBudgetReq) (*OK, error)
|
||||
GetBudgetUsers(context.Context, *GetBudgetUsersReq) (*Users, error)
|
||||
RemoveUserFromBudget(context.Context, *RemoveUserFromBudgetReq) (*Budget, error)
|
||||
GetBudgetCategories(context.Context, *GetBudgetCategoriesReq) (*Categories, error)
|
||||
// categories
|
||||
AddCategory(context.Context, *AddCategoryReq) (*Category, error)
|
||||
UpdateCategory(context.Context, *UpdateCategoryReq) (*Category, error)
|
||||
DeleteCategories(context.Context, *DeleteCategoriesReq) (*Category, error)
|
||||
// wastes
|
||||
AddWaste(context.Context, *AddWasteReq) (*Waste, error)
|
||||
AddWasteByText(context.Context, *AddWasteTextReq) (*Waste, error)
|
||||
DeleteWaste(context.Context, *DeleteWasteReq) (*Waste, error)
|
||||
// stat
|
||||
GetCategoriesStat(context.Context, *GetCategoriesStatReq) (*CategoriesStat, error)
|
||||
mustEmbedUnimplementedSmmCoreServer()
|
||||
}
|
||||
|
||||
@@ -65,6 +287,54 @@ type UnimplementedSmmCoreServer struct{}
|
||||
func (UnimplementedSmmCoreServer) Ping(context.Context, *PingReq) (*PingRsp, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Ping not implemented")
|
||||
}
|
||||
func (UnimplementedSmmCoreServer) Login(context.Context, *LoginReq) (*User, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Login not implemented")
|
||||
}
|
||||
func (UnimplementedSmmCoreServer) AddBudget(context.Context, *AddBudgetReq) (*Budget, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method AddBudget not implemented")
|
||||
}
|
||||
func (UnimplementedSmmCoreServer) UpdateBudget(context.Context, *UpdateBudgetReq) (*Budget, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method UpdateBudget not implemented")
|
||||
}
|
||||
func (UnimplementedSmmCoreServer) GetBudgets(context.Context, *GetBudgetsReq) (*Budgets, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetBudgets not implemented")
|
||||
}
|
||||
func (UnimplementedSmmCoreServer) DeleteBudget(context.Context, *DeleteBudgetReq) (*Budget, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method DeleteBudget not implemented")
|
||||
}
|
||||
func (UnimplementedSmmCoreServer) AddUserToBudget(context.Context, *AddUserToBudgetReq) (*OK, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method AddUserToBudget not implemented")
|
||||
}
|
||||
func (UnimplementedSmmCoreServer) GetBudgetUsers(context.Context, *GetBudgetUsersReq) (*Users, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetBudgetUsers not implemented")
|
||||
}
|
||||
func (UnimplementedSmmCoreServer) RemoveUserFromBudget(context.Context, *RemoveUserFromBudgetReq) (*Budget, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method RemoveUserFromBudget not implemented")
|
||||
}
|
||||
func (UnimplementedSmmCoreServer) GetBudgetCategories(context.Context, *GetBudgetCategoriesReq) (*Categories, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetBudgetCategories not implemented")
|
||||
}
|
||||
func (UnimplementedSmmCoreServer) AddCategory(context.Context, *AddCategoryReq) (*Category, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method AddCategory not implemented")
|
||||
}
|
||||
func (UnimplementedSmmCoreServer) UpdateCategory(context.Context, *UpdateCategoryReq) (*Category, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method UpdateCategory not implemented")
|
||||
}
|
||||
func (UnimplementedSmmCoreServer) DeleteCategories(context.Context, *DeleteCategoriesReq) (*Category, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method DeleteCategories not implemented")
|
||||
}
|
||||
func (UnimplementedSmmCoreServer) AddWaste(context.Context, *AddWasteReq) (*Waste, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method AddWaste not implemented")
|
||||
}
|
||||
func (UnimplementedSmmCoreServer) AddWasteByText(context.Context, *AddWasteTextReq) (*Waste, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method AddWasteByText not implemented")
|
||||
}
|
||||
func (UnimplementedSmmCoreServer) DeleteWaste(context.Context, *DeleteWasteReq) (*Waste, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method DeleteWaste not implemented")
|
||||
}
|
||||
func (UnimplementedSmmCoreServer) GetCategoriesStat(context.Context, *GetCategoriesStatReq) (*CategoriesStat, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetCategoriesStat not implemented")
|
||||
}
|
||||
func (UnimplementedSmmCoreServer) mustEmbedUnimplementedSmmCoreServer() {}
|
||||
func (UnimplementedSmmCoreServer) testEmbeddedByValue() {}
|
||||
|
||||
@@ -104,6 +374,294 @@ func _SmmCore_Ping_Handler(srv interface{}, ctx context.Context, dec func(interf
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SmmCore_Login_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(LoginReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SmmCoreServer).Login(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: SmmCore_Login_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SmmCoreServer).Login(ctx, req.(*LoginReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SmmCore_AddBudget_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(AddBudgetReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SmmCoreServer).AddBudget(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: SmmCore_AddBudget_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SmmCoreServer).AddBudget(ctx, req.(*AddBudgetReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SmmCore_UpdateBudget_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(UpdateBudgetReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SmmCoreServer).UpdateBudget(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: SmmCore_UpdateBudget_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SmmCoreServer).UpdateBudget(ctx, req.(*UpdateBudgetReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SmmCore_GetBudgets_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetBudgetsReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SmmCoreServer).GetBudgets(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: SmmCore_GetBudgets_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SmmCoreServer).GetBudgets(ctx, req.(*GetBudgetsReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SmmCore_DeleteBudget_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(DeleteBudgetReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SmmCoreServer).DeleteBudget(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: SmmCore_DeleteBudget_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SmmCoreServer).DeleteBudget(ctx, req.(*DeleteBudgetReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SmmCore_AddUserToBudget_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(AddUserToBudgetReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SmmCoreServer).AddUserToBudget(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: SmmCore_AddUserToBudget_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SmmCoreServer).AddUserToBudget(ctx, req.(*AddUserToBudgetReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SmmCore_GetBudgetUsers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetBudgetUsersReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SmmCoreServer).GetBudgetUsers(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: SmmCore_GetBudgetUsers_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SmmCoreServer).GetBudgetUsers(ctx, req.(*GetBudgetUsersReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SmmCore_RemoveUserFromBudget_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(RemoveUserFromBudgetReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SmmCoreServer).RemoveUserFromBudget(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: SmmCore_RemoveUserFromBudget_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SmmCoreServer).RemoveUserFromBudget(ctx, req.(*RemoveUserFromBudgetReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SmmCore_GetBudgetCategories_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetBudgetCategoriesReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SmmCoreServer).GetBudgetCategories(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: SmmCore_GetBudgetCategories_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SmmCoreServer).GetBudgetCategories(ctx, req.(*GetBudgetCategoriesReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SmmCore_AddCategory_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(AddCategoryReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SmmCoreServer).AddCategory(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: SmmCore_AddCategory_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SmmCoreServer).AddCategory(ctx, req.(*AddCategoryReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SmmCore_UpdateCategory_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(UpdateCategoryReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SmmCoreServer).UpdateCategory(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: SmmCore_UpdateCategory_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SmmCoreServer).UpdateCategory(ctx, req.(*UpdateCategoryReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SmmCore_DeleteCategories_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(DeleteCategoriesReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SmmCoreServer).DeleteCategories(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: SmmCore_DeleteCategories_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SmmCoreServer).DeleteCategories(ctx, req.(*DeleteCategoriesReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SmmCore_AddWaste_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(AddWasteReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SmmCoreServer).AddWaste(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: SmmCore_AddWaste_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SmmCoreServer).AddWaste(ctx, req.(*AddWasteReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SmmCore_AddWasteByText_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(AddWasteTextReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SmmCoreServer).AddWasteByText(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: SmmCore_AddWasteByText_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SmmCoreServer).AddWasteByText(ctx, req.(*AddWasteTextReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SmmCore_DeleteWaste_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(DeleteWasteReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SmmCoreServer).DeleteWaste(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: SmmCore_DeleteWaste_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SmmCoreServer).DeleteWaste(ctx, req.(*DeleteWasteReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SmmCore_GetCategoriesStat_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetCategoriesStatReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SmmCoreServer).GetCategoriesStat(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: SmmCore_GetCategoriesStat_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SmmCoreServer).GetCategoriesStat(ctx, req.(*GetCategoriesStatReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// SmmCore_ServiceDesc is the grpc.ServiceDesc for SmmCore service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
@@ -115,6 +673,70 @@ var SmmCore_ServiceDesc = grpc.ServiceDesc{
|
||||
MethodName: "Ping",
|
||||
Handler: _SmmCore_Ping_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Login",
|
||||
Handler: _SmmCore_Login_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "AddBudget",
|
||||
Handler: _SmmCore_AddBudget_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "UpdateBudget",
|
||||
Handler: _SmmCore_UpdateBudget_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetBudgets",
|
||||
Handler: _SmmCore_GetBudgets_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "DeleteBudget",
|
||||
Handler: _SmmCore_DeleteBudget_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "AddUserToBudget",
|
||||
Handler: _SmmCore_AddUserToBudget_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetBudgetUsers",
|
||||
Handler: _SmmCore_GetBudgetUsers_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "RemoveUserFromBudget",
|
||||
Handler: _SmmCore_RemoveUserFromBudget_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetBudgetCategories",
|
||||
Handler: _SmmCore_GetBudgetCategories_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "AddCategory",
|
||||
Handler: _SmmCore_AddCategory_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "UpdateCategory",
|
||||
Handler: _SmmCore_UpdateCategory_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "DeleteCategories",
|
||||
Handler: _SmmCore_DeleteCategories_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "AddWaste",
|
||||
Handler: _SmmCore_AddWaste_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "AddWasteByText",
|
||||
Handler: _SmmCore_AddWasteByText_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "DeleteWaste",
|
||||
Handler: _SmmCore_DeleteWaste_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetCategoriesStat",
|
||||
Handler: _SmmCore_GetCategoriesStat_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "smm_core.proto",
|
||||
|
||||
@@ -16,8 +16,415 @@
|
||||
"application/json"
|
||||
],
|
||||
"paths": {
|
||||
"/budgets": {
|
||||
"get": {
|
||||
"operationId": "SmmCore_GetBudgets",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/smm_coreBudgets"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"SmmCore"
|
||||
]
|
||||
},
|
||||
"post": {
|
||||
"summary": "budgets",
|
||||
"operationId": "SmmCore_AddBudget",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/smm_coreBudget"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/smm_coreAddBudgetReq"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"SmmCore"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/budgets/{budgetId}/categories": {
|
||||
"get": {
|
||||
"operationId": "SmmCore_GetBudgetCategories",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/smm_coreCategories"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "budgetId",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"SmmCore"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/budgets/{budgetId}/users": {
|
||||
"put": {
|
||||
"summary": "budget users",
|
||||
"operationId": "SmmCore_AddUserToBudget",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/smm_coreOK"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "budgetId",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/SmmCoreAddUserToBudgetBody"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"SmmCore"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/budgets/{budgetId}/users/{userId}": {
|
||||
"delete": {
|
||||
"operationId": "SmmCore_RemoveUserFromBudget",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/smm_coreBudget"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "budgetId",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
{
|
||||
"name": "userId",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"SmmCore"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/budgets/{id}": {
|
||||
"delete": {
|
||||
"operationId": "SmmCore_DeleteBudget",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/smm_coreBudget"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"SmmCore"
|
||||
]
|
||||
},
|
||||
"put": {
|
||||
"operationId": "SmmCore_UpdateBudget",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/smm_coreBudget"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/SmmCoreUpdateBudgetBody"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"SmmCore"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/budgets/{id}/users": {
|
||||
"get": {
|
||||
"operationId": "SmmCore_GetBudgetUsers",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/smm_coreUsers"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"SmmCore"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/categories": {
|
||||
"post": {
|
||||
"summary": "categories",
|
||||
"operationId": "SmmCore_AddCategory",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/smm_coreCategory"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/smm_coreAddCategoryReq"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"SmmCore"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/categories/{id}": {
|
||||
"delete": {
|
||||
"operationId": "SmmCore_DeleteCategories",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/smm_coreCategory"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"SmmCore"
|
||||
]
|
||||
},
|
||||
"put": {
|
||||
"operationId": "SmmCore_UpdateCategory",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/smm_coreCategory"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "favorite",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"name": "monthlyLimit",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"SmmCore"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/login": {
|
||||
"post": {
|
||||
"summary": "login",
|
||||
"operationId": "SmmCore_Login",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/smm_coreUser"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/smm_coreLoginReq"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"SmmCore"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/ping": {
|
||||
"get": {
|
||||
"summary": "ping",
|
||||
"operationId": "SmmCore_Ping",
|
||||
"responses": {
|
||||
"200": {
|
||||
@@ -37,19 +444,174 @@
|
||||
"SmmCore"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/stat": {
|
||||
"get": {
|
||||
"summary": "stat",
|
||||
"operationId": "SmmCore_GetCategoriesStat",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/smm_coreCategoriesStat"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "ids",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"collectionFormat": "multi"
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"SmmCore"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/wastes": {
|
||||
"post": {
|
||||
"summary": "wastes",
|
||||
"operationId": "SmmCore_AddWaste",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/smm_coreWaste"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/smm_coreAddWasteReq"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"SmmCore"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/wastes/text": {
|
||||
"post": {
|
||||
"operationId": "SmmCore_AddWasteByText",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/smm_coreWaste"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/smm_coreAddWasteTextReq"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"SmmCore"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/wastes/{id}": {
|
||||
"delete": {
|
||||
"operationId": "SmmCore_DeleteWaste",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/smm_coreWaste"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"SmmCore"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"SmmCoreAddUserToBudgetBody": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"userId": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
}
|
||||
},
|
||||
"SmmCoreUpdateBudgetBody": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"startDay": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"monthlyLimit": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
}
|
||||
},
|
||||
"protobufAny": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"@type": {
|
||||
"type": "string",
|
||||
"description": "A URL/resource name that uniquely identifies the type of the serialized\nprotocol buffer message. This string must contain at least\none \"/\" character. The last segment of the URL's path must represent\nthe fully qualified name of the type (as in\n`path/google.protobuf.Duration`). The name should be in a canonical form\n(e.g., leading \".\" is not accepted).\n\nIn practice, teams usually precompile into the binary all types that they\nexpect it to use in the context of Any. However, for URLs which use the\nscheme `http`, `https`, or no scheme, one can optionally set up a type\nserver that maps type URLs to message definitions as follows:\n\n* If no scheme is provided, `https` is assumed.\n* An HTTP GET on the URL must yield a [google.protobuf.Type][]\n value in binary format, or produce an error.\n* Applications are allowed to cache lookup results based on the\n URL, or have them precompiled into a binary to avoid any\n lookup. Therefore, binary compatibility needs to be preserved\n on changes to types. (Use versioned type names to manage\n breaking changes.)\n\nNote: this functionality is not currently available in the official\nprotobuf release, and it is not used for type URLs beginning with\ntype.googleapis.com. As of May 2023, there are no widely used type server\nimplementations and no plans to implement one.\n\nSchemes other than `http`, `https` (or the empty scheme) might be\nused with implementation specific semantics."
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": {},
|
||||
"description": "`Any` contains an arbitrary serialized protocol buffer message along with a\nURL that describes the type of the serialized message.\n\nProtobuf library provides support to pack/unpack Any values in the form\nof utility functions or additional generated methods of the Any type.\n\nExample 1: Pack and unpack a message in C++.\n\n Foo foo = ...;\n Any any;\n any.PackFrom(foo);\n ...\n if (any.UnpackTo(\u0026foo)) {\n ...\n }\n\nExample 2: Pack and unpack a message in Java.\n\n Foo foo = ...;\n Any any = Any.pack(foo);\n ...\n if (any.is(Foo.class)) {\n foo = any.unpack(Foo.class);\n }\n // or ...\n if (any.isSameTypeAs(Foo.getDefaultInstance())) {\n foo = any.unpack(Foo.getDefaultInstance());\n }\n\n Example 3: Pack and unpack a message in Python.\n\n foo = Foo(...)\n any = Any()\n any.Pack(foo)\n ...\n if any.Is(Foo.DESCRIPTOR):\n any.Unpack(foo)\n ...\n\n Example 4: Pack and unpack a message in Go\n\n foo := \u0026pb.Foo{...}\n any, err := anypb.New(foo)\n if err != nil {\n ...\n }\n ...\n foo := \u0026pb.Foo{}\n if err := any.UnmarshalTo(foo); err != nil {\n ...\n }\n\nThe pack methods provided by protobuf library will by default use\n'type.googleapis.com/full.type.name' as the type URL and the unpack\nmethods only use the fully qualified type name after the last '/'\nin the type URL, for example \"foo.bar.com/x/y.z\" will yield type\nname \"y.z\".\n\nJSON\n====\nThe JSON representation of an `Any` value uses the regular\nrepresentation of the deserialized, embedded message, with an\nadditional field `@type` which contains the type URL. Example:\n\n package google.profile;\n message Person {\n string first_name = 1;\n string last_name = 2;\n }\n\n {\n \"@type\": \"type.googleapis.com/google.profile.Person\",\n \"firstName\": \u003cstring\u003e,\n \"lastName\": \u003cstring\u003e\n }\n\nIf the embedded message type is well-known and has a custom JSON\nrepresentation, that representation will be embedded adding a field\n`value` which holds the custom JSON in addition to the `@type`\nfield. Example (for message [google.protobuf.Duration][]):\n\n {\n \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n \"value\": \"1.212s\"\n }"
|
||||
"additionalProperties": {}
|
||||
},
|
||||
"rpcStatus": {
|
||||
"type": "object",
|
||||
@@ -70,8 +632,227 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"smm_coreAddBudgetReq": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"startDay": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"monthlyLimit": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
}
|
||||
},
|
||||
"smm_coreAddCategoryReq": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"budgetId": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"favorite": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"monthlyLimit": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
}
|
||||
},
|
||||
"smm_coreAddWasteReq": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"price": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"amount": {
|
||||
"type": "number",
|
||||
"format": "float"
|
||||
},
|
||||
"categoryId": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"budgetId": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
}
|
||||
},
|
||||
"smm_coreAddWasteTextReq": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
"categoryId": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"budgetId": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
}
|
||||
},
|
||||
"smm_coreBudget": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"startDay": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"monthlyLimit": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"categories": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/smm_coreCategory"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"smm_coreBudgets": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"budgets": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/smm_coreBudget"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"smm_coreCategories": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"categories": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/smm_coreCategory"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"smm_coreCategoriesStat": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"stat": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/smm_coreCategoriesStat"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"smm_coreCategory": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"budgetId": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"favorite": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"monthlyLimit": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
}
|
||||
},
|
||||
"smm_coreLoginReq": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"username": {
|
||||
"type": "string"
|
||||
},
|
||||
"password": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"smm_coreOK": {
|
||||
"type": "object"
|
||||
},
|
||||
"smm_corePingRsp": {
|
||||
"type": "object"
|
||||
},
|
||||
"smm_coreUser": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"username": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"smm_coreUsers": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"users": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/smm_coreUser"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"smm_coreWaste": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"price": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"amount": {
|
||||
"type": "number",
|
||||
"format": "float"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
SELECT b.id, b.name, b.start_day, b.monthly_limit FROM budgets b JOIN users_budgets ub ON ub.budget_id = b.id WHERE ub.user_id = 1;
|
||||
Reference in New Issue
Block a user