Compare commits
18 Commits
20652b127c
..
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 0ed38b7cc0 | |||
| 26ca649e8e | |||
| 675c2884b7 | |||
| 130a3236e0 | |||
| 95fe8b530e | |||
| bf85f31056 | |||
| 866009cf09 | |||
| f2011b953c | |||
| 66df21c6c9 | |||
| a8b6e9ab9b | |||
| 2078e008f3 | |||
| f4523de5a4 | |||
| 0d6bd456d6 | |||
| ee3e10d46d | |||
| 6c99309caf | |||
| bd6b5fe4a8 | |||
| 074a202dc2 | |||
| 718d2e5e98 |
Vendored
+5
-1
@@ -5,7 +5,11 @@
|
||||
"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"
|
||||
]
|
||||
}
|
||||
+212
-18
@@ -10,16 +10,74 @@ 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"
|
||||
};
|
||||
}
|
||||
|
||||
// categories
|
||||
rpc AddCategory(CreateCategoryReq) returns (Category) {
|
||||
// login
|
||||
rpc Login(LoginReq) returns (User) {
|
||||
option (google.api.http) = {
|
||||
post: "/categories"
|
||||
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) {
|
||||
@@ -27,9 +85,35 @@ service SmmCore {
|
||||
put: "/categories/{id}"
|
||||
};
|
||||
}
|
||||
rpc GetCategories(CategoryFilterReq) returns (Categories) {
|
||||
rpc DeleteCategories(DeleteCategoriesReq) returns (Category) {
|
||||
option (google.api.http) = {
|
||||
get: "/categories"
|
||||
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"
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -38,13 +122,91 @@ message PingReq {}
|
||||
|
||||
message PingRsp {}
|
||||
|
||||
message CreateCategoryReq {
|
||||
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 user_id = 2;
|
||||
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;
|
||||
@@ -52,17 +214,49 @@ message UpdateCategoryReq {
|
||||
int32 monthly_limit = 4;
|
||||
}
|
||||
|
||||
message Category {
|
||||
int32 id = 1;
|
||||
string name = 2;
|
||||
bool favorite = 4;
|
||||
int32 monthly_limit = 5;
|
||||
}
|
||||
|
||||
message CategoryFilterReq {
|
||||
bool favorite = 1;
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
@@ -10,9 +10,18 @@ require (
|
||||
)
|
||||
|
||||
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,13 +1,55 @@
|
||||
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=
|
||||
@@ -21,5 +63,6 @@ google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojt
|
||||
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,
|
||||
}
|
||||
}
|
||||
+172
-7
@@ -3,28 +3,193 @@ 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() proto.SmmCoreServer {
|
||||
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
|
||||
}
|
||||
|
||||
// AddCategory implements proto.SmmCoreServer.
|
||||
func (s *Server) AddCategory(context.Context, *proto.CreateCategoryReq) (*proto.Category, error) {
|
||||
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")
|
||||
}
|
||||
|
||||
// GetCategories implements proto.SmmCoreServer.
|
||||
func (s *Server) GetCategories(context.Context, *proto.CategoryFilterReq) (*proto.Categories, error) {
|
||||
// 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")
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
+3
-1
@@ -2,7 +2,9 @@
|
||||
-- +goose StatementBegin
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id SERIAL PRIMARY KEY,
|
||||
chat_id TEXT NOT NULL
|
||||
username TEXT UNIQUE NOT NULL,
|
||||
password TEXT NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
-- +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
|
||||
+4
-2
@@ -3,9 +3,11 @@
|
||||
CREATE TABLE IF NOT EXISTS categories (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
user_id INT REFERENCES users(id),
|
||||
budget_id INT REFERENCES budgets(id) ON DELETE CASCADE,
|
||||
favorite BOOLEAN DEFAULT FALSE,
|
||||
monthly_limit INT DEFAULT 0
|
||||
monthly_limit INT DEFAULT 0,
|
||||
UNIQUE (budget_id, name),
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
-- +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
|
||||
+1629
-214
File diff suppressed because it is too large
Load Diff
+1266
-39
File diff suppressed because it is too large
Load Diff
+530
-24
@@ -19,21 +19,53 @@ import (
|
||||
const _ = grpc.SupportPackageIsVersion9
|
||||
|
||||
const (
|
||||
SmmCore_Ping_FullMethodName = "/crabs.smm_core.SmmCore/Ping"
|
||||
SmmCore_AddCategory_FullMethodName = "/crabs.smm_core.SmmCore/AddCategory"
|
||||
SmmCore_UpdateCategory_FullMethodName = "/crabs.smm_core.SmmCore/UpdateCategory"
|
||||
SmmCore_GetCategories_FullMethodName = "/crabs.smm_core.SmmCore/GetCategories"
|
||||
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 *CreateCategoryReq, opts ...grpc.CallOption) (*Category, error)
|
||||
AddCategory(ctx context.Context, in *AddCategoryReq, opts ...grpc.CallOption) (*Category, error)
|
||||
UpdateCategory(ctx context.Context, in *UpdateCategoryReq, opts ...grpc.CallOption) (*Category, error)
|
||||
GetCategories(ctx context.Context, in *CategoryFilterReq, opts ...grpc.CallOption) (*Categories, 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 {
|
||||
@@ -54,7 +86,97 @@ func (c *smmCoreClient) Ping(ctx context.Context, in *PingReq, opts ...grpc.Call
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *smmCoreClient) AddCategory(ctx context.Context, in *CreateCategoryReq, opts ...grpc.CallOption) (*Category, error) {
|
||||
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...)
|
||||
@@ -74,10 +196,50 @@ func (c *smmCoreClient) UpdateCategory(ctx context.Context, in *UpdateCategoryRe
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *smmCoreClient) GetCategories(ctx context.Context, in *CategoryFilterReq, opts ...grpc.CallOption) (*Categories, error) {
|
||||
func (c *smmCoreClient) DeleteCategories(ctx context.Context, in *DeleteCategoriesReq, opts ...grpc.CallOption) (*Category, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(Categories)
|
||||
err := c.cc.Invoke(ctx, SmmCore_GetCategories_FullMethodName, in, out, cOpts...)
|
||||
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
|
||||
}
|
||||
@@ -88,11 +250,30 @@ func (c *smmCoreClient) GetCategories(ctx context.Context, in *CategoryFilterReq
|
||||
// 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, *CreateCategoryReq) (*Category, error)
|
||||
AddCategory(context.Context, *AddCategoryReq) (*Category, error)
|
||||
UpdateCategory(context.Context, *UpdateCategoryReq) (*Category, error)
|
||||
GetCategories(context.Context, *CategoryFilterReq) (*Categories, 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()
|
||||
}
|
||||
|
||||
@@ -106,14 +287,53 @@ type UnimplementedSmmCoreServer struct{}
|
||||
func (UnimplementedSmmCoreServer) Ping(context.Context, *PingReq) (*PingRsp, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Ping not implemented")
|
||||
}
|
||||
func (UnimplementedSmmCoreServer) AddCategory(context.Context, *CreateCategoryReq) (*Category, error) {
|
||||
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) GetCategories(context.Context, *CategoryFilterReq) (*Categories, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetCategories 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() {}
|
||||
@@ -154,8 +374,170 @@ 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(CreateCategoryReq)
|
||||
in := new(AddCategoryReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -167,7 +549,7 @@ func _SmmCore_AddCategory_Handler(srv interface{}, ctx context.Context, dec func
|
||||
FullMethod: SmmCore_AddCategory_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SmmCoreServer).AddCategory(ctx, req.(*CreateCategoryReq))
|
||||
return srv.(SmmCoreServer).AddCategory(ctx, req.(*AddCategoryReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
@@ -190,20 +572,92 @@ func _SmmCore_UpdateCategory_Handler(srv interface{}, ctx context.Context, dec f
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SmmCore_GetCategories_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(CategoryFilterReq)
|
||||
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).GetCategories(ctx, in)
|
||||
return srv.(SmmCoreServer).DeleteCategories(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: SmmCore_GetCategories_FullMethodName,
|
||||
FullMethod: SmmCore_DeleteCategories_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SmmCoreServer).GetCategories(ctx, req.(*CategoryFilterReq))
|
||||
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)
|
||||
}
|
||||
@@ -219,6 +673,42 @@ 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,
|
||||
@@ -228,8 +718,24 @@ var SmmCore_ServiceDesc = grpc.ServiceDesc{
|
||||
Handler: _SmmCore_UpdateCategory_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetCategories",
|
||||
Handler: _SmmCore_GetCategories_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{},
|
||||
|
||||
+653
-30
@@ -16,9 +16,62 @@
|
||||
"application/json"
|
||||
],
|
||||
"paths": {
|
||||
"/categories": {
|
||||
"/budgets": {
|
||||
"get": {
|
||||
"operationId": "SmmCore_GetCategories",
|
||||
"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.",
|
||||
@@ -35,16 +88,196 @@
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "favorite",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"type": "boolean"
|
||||
"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",
|
||||
@@ -64,30 +297,12 @@
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "name",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "userId",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
{
|
||||
"name": "favorite",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"name": "monthlyLimit",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/smm_coreAddCategoryReq"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
@@ -96,6 +311,35 @@
|
||||
}
|
||||
},
|
||||
"/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": {
|
||||
@@ -145,8 +389,42 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"/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": {
|
||||
@@ -166,9 +444,166 @@
|
||||
"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": {
|
||||
@@ -197,6 +632,120 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"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": {
|
||||
@@ -209,6 +758,18 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"smm_coreCategoriesStat": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"stat": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/smm_coreCategoriesStat"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"smm_coreCategory": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -219,6 +780,10 @@
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"budgetId": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"favorite": {
|
||||
"type": "boolean"
|
||||
},
|
||||
@@ -228,8 +793,66 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"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