diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..c825599 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,14 @@ +{ + "sqltools.connections": [ + { + "previewLimit": 50, + "server": "localhost", + "port": 5432, + "driver": "PostgreSQL", + "name": "smm", + "database": "smm-core", + "username": "crab", + "password": "crab" + } + ] +} \ No newline at end of file diff --git a/internal/app/server.go b/internal/app/server.go index b921f5d..e47146c 100644 --- a/internal/app/server.go +++ b/internal/app/server.go @@ -43,10 +43,7 @@ func (s *Server) AddUser(ctx context.Context, req *proto.AddUserReq) (*proto.Use if err != nil { return nil, err } - return &proto.User{ - Id: int32(user.Id), - Username: req.Username, - }, nil + return mapUser(user), nil } func (s *Server) Login(ctx context.Context, req *proto.LoginReq) (*proto.User, error) { @@ -60,10 +57,14 @@ func (s *Server) Login(ctx context.Context, req *proto.LoginReq) (*proto.User, e if err != nil { return nil, err } + return mapUser(user), nil +} + +func mapUser(user *user.UserEntity) *proto.User { return &proto.User{ Id: int32(user.Id), - Username: req.Username, - }, nil + Username: user.Username, + } } func (s *Server) AddBudget(ctx context.Context, req *proto.AddBudgetReq) (*proto.Budget, error) { @@ -78,12 +79,32 @@ func (s *Server) AddBudget(ctx context.Context, req *proto.AddBudgetReq) (*proto 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 mapBudget(budget *budget.BudgetEntity) *proto.Budget { return &proto.Budget{ Id: int32(budget.Id), Name: budget.Name, StartDay: int32(budget.StartDay), MonthlyLimit: int32(budget.MonthlyLimit), - }, nil + } } // AddCategory implements proto.SmmCoreServer. @@ -121,11 +142,6 @@ func (s *Server) GetBudgetUsers(context.Context, *proto.GetBudgetUsersReq) (*pro panic("unimplemented") } -// GetBudgets implements proto.SmmCoreServer. -func (s *Server) GetBudgets(context.Context, *proto.GetBudgetsReq) (*proto.Budgets, error) { - panic("unimplemented") -} - // GetCategories implements proto.SmmCoreServer. func (s *Server) GetCategories(context.Context, *proto.GetCategoriesReq) (*proto.Categories, error) { panic("unimplemented") diff --git a/internal/services/budget/budget_service.go b/internal/services/budget/budget_service.go index 4fc660f..02d8cd6 100644 --- a/internal/services/budget/budget_service.go +++ b/internal/services/budget/budget_service.go @@ -64,3 +64,31 @@ func (s *BudgetService) AddBudget(ctx context.Context, budget *BudgetEntity) (*B } 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 + } + budgets = append(budgets, budget) + } + + return budgets, nil +} diff --git a/internal/services/requests.restbook b/internal/services/requests.restbook index 168f936..f3ca531 100644 --- a/internal/services/requests.restbook +++ b/internal/services/requests.restbook @@ -1 +1 @@ -[{"kind":1,"language":"markdown","value":"# Добавление пользователя","outputs":[]},{"kind":2,"language":"rest-book","value":"POST http://localhost:8090/users\nauthorization: Y3JhYjpjcmFi\n\n{\n \"username\": \"foo\",\n \"password\": \"bar\"\n}","outputs":[{"mime":"x-application/rest-book","value":{"status":200,"statusText":"OK","headers":{"Date":"Sun, 24 Nov 2024 08:59:31 GMT","Content-Type":"application/json","Content-Length":"25"},"config":{"timeout":10000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","headers":{"Accept":"application/json, text/plain, */*","Content-Type":"application/json","authorization":"Y3JhYjpjcmFi","User-Agent":"axios/0.21.4","Content-Length":35}},"request":{"method":"POST","httpVersion":"1.1","responseUrl":"http://localhost:8090/users","timeout":10000,"headers":{"authorization":"Y3JhYjpjcmFi"},"data":{"username":"foo","password":"bar"}},"data":{"id":1,"username":"foo"}}},{"mime":"text/x-json","value":{"status":200,"statusText":"OK","headers":{"Date":"Sun, 24 Nov 2024 08:59:31 GMT","Content-Type":"application/json","Content-Length":"25"},"config":{"timeout":10000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","headers":{"Accept":"application/json, text/plain, */*","Content-Type":"application/json","authorization":"Y3JhYjpjcmFi","User-Agent":"axios/0.21.4","Content-Length":35}},"request":{"method":"POST","httpVersion":"1.1","responseUrl":"http://localhost:8090/users","timeout":10000,"headers":{"authorization":"Y3JhYjpjcmFi"},"data":{"username":"foo","password":"bar"}},"data":{"id":1,"username":"foo"}}},{"mime":"text/html","value":"[object Object]"}]},{"kind":1,"language":"markdown","value":"# Авторизация","outputs":[]},{"kind":2,"language":"rest-book","value":"POST http://localhost:8090/login\nauthorization: Y3JhYjpjcmFi\n\n{\n \"username\": \"foo\",\n \"password\": \"bar\"\n}","outputs":[{"mime":"x-application/rest-book","value":{"status":200,"statusText":"OK","headers":{"Date":"Sun, 24 Nov 2024 08:59:35 GMT","Content-Type":"application/json","Content-Length":"25"},"config":{"timeout":10000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","headers":{"Accept":"application/json, text/plain, */*","Content-Type":"application/json","authorization":"Y3JhYjpjcmFi","User-Agent":"axios/0.21.4","Content-Length":35}},"request":{"method":"POST","httpVersion":"1.1","responseUrl":"http://localhost:8090/login","timeout":10000,"headers":{"authorization":"Y3JhYjpjcmFi"},"data":{"username":"foo","password":"bar"}},"data":{"id":1,"username":"foo"}}},{"mime":"text/x-json","value":{"status":200,"statusText":"OK","headers":{"Date":"Sun, 24 Nov 2024 08:59:35 GMT","Content-Type":"application/json","Content-Length":"25"},"config":{"timeout":10000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","headers":{"Accept":"application/json, text/plain, */*","Content-Type":"application/json","authorization":"Y3JhYjpjcmFi","User-Agent":"axios/0.21.4","Content-Length":35}},"request":{"method":"POST","httpVersion":"1.1","responseUrl":"http://localhost:8090/login","timeout":10000,"headers":{"authorization":"Y3JhYjpjcmFi"},"data":{"username":"foo","password":"bar"}},"data":{"id":1,"username":"foo"}}},{"mime":"text/html","value":"[object Object]"}]},{"kind":1,"language":"markdown","value":"# Добавление бюджета","outputs":[]},{"kind":2,"language":"rest-book","value":"POST http://localhost:8090/budgets\nauthorization: Y3JhYjpjcmFi\nUser-Id: 1\n\n{\n \"name\": \"Личный\"\n}","outputs":[{"mime":"x-application/rest-book","value":{"status":200,"statusText":"OK","headers":{"Date":"Sun, 24 Nov 2024 09:00:36 GMT","Content-Type":"application/json","Content-Length":"60"},"config":{"timeout":10000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","headers":{"Accept":"application/json, text/plain, */*","Content-Type":"application/json","authorization":"Y3JhYjpjcmFi","User-Id":"1","User-Agent":"axios/0.21.4","Content-Length":23}},"request":{"method":"POST","httpVersion":"1.1","responseUrl":"http://localhost:8090/budgets","timeout":10000,"headers":{"authorization":"Y3JhYjpjcmFi","User-Id":"1"},"data":{"name":"Личный"}},"data":{"id":1,"name":"Личный","startDay":0,"monthlyLimit":0}}},{"mime":"text/x-json","value":{"status":200,"statusText":"OK","headers":{"Date":"Sun, 24 Nov 2024 09:00:36 GMT","Content-Type":"application/json","Content-Length":"60"},"config":{"timeout":10000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","headers":{"Accept":"application/json, text/plain, */*","Content-Type":"application/json","authorization":"Y3JhYjpjcmFi","User-Id":"1","User-Agent":"axios/0.21.4","Content-Length":23}},"request":{"method":"POST","httpVersion":"1.1","responseUrl":"http://localhost:8090/budgets","timeout":10000,"headers":{"authorization":"Y3JhYjpjcmFi","User-Id":"1"},"data":{"name":"Личный"}},"data":{"id":1,"name":"Личный","startDay":0,"monthlyLimit":0}}},{"mime":"text/html","value":"[object Object]"}]}] \ No newline at end of file +[{"kind":1,"language":"markdown","value":"# Добавление пользователя","outputs":[]},{"kind":2,"language":"rest-book","value":"POST http://localhost:8090/users\nauthorization: Y3JhYjpjcmFi\n\n{\n \"username\": \"foo\",\n \"password\": \"bar\"\n}","outputs":[{"mime":"x-application/rest-book","value":{"status":200,"statusText":"OK","headers":{"Date":"Sun, 24 Nov 2024 08:59:31 GMT","Content-Type":"application/json","Content-Length":"25"},"config":{"timeout":10000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","headers":{"Accept":"application/json, text/plain, */*","Content-Type":"application/json","authorization":"Y3JhYjpjcmFi","User-Agent":"axios/0.21.4","Content-Length":35}},"request":{"method":"POST","httpVersion":"1.1","responseUrl":"http://localhost:8090/users","timeout":10000,"headers":{"authorization":"Y3JhYjpjcmFi"},"data":{"username":"foo","password":"bar"}},"data":{"id":1,"username":"foo"}}},{"mime":"text/x-json","value":{"status":200,"statusText":"OK","headers":{"Date":"Sun, 24 Nov 2024 08:59:31 GMT","Content-Type":"application/json","Content-Length":"25"},"config":{"timeout":10000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","headers":{"Accept":"application/json, text/plain, */*","Content-Type":"application/json","authorization":"Y3JhYjpjcmFi","User-Agent":"axios/0.21.4","Content-Length":35}},"request":{"method":"POST","httpVersion":"1.1","responseUrl":"http://localhost:8090/users","timeout":10000,"headers":{"authorization":"Y3JhYjpjcmFi"},"data":{"username":"foo","password":"bar"}},"data":{"id":1,"username":"foo"}}},{"mime":"text/html","value":"[object Object]"}]},{"kind":1,"language":"markdown","value":"# Авторизация","outputs":[]},{"kind":2,"language":"rest-book","value":"POST http://localhost:8090/login\nauthorization: Y3JhYjpjcmFi\n\n{\n \"username\": \"foo\",\n \"password\": \"bar\"\n}","outputs":[{"mime":"x-application/rest-book","value":{"status":200,"statusText":"OK","headers":{"Date":"Sun, 24 Nov 2024 08:59:35 GMT","Content-Type":"application/json","Content-Length":"25"},"config":{"timeout":10000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","headers":{"Accept":"application/json, text/plain, */*","Content-Type":"application/json","authorization":"Y3JhYjpjcmFi","User-Agent":"axios/0.21.4","Content-Length":35}},"request":{"method":"POST","httpVersion":"1.1","responseUrl":"http://localhost:8090/login","timeout":10000,"headers":{"authorization":"Y3JhYjpjcmFi"},"data":{"username":"foo","password":"bar"}},"data":{"id":1,"username":"foo"}}},{"mime":"text/x-json","value":{"status":200,"statusText":"OK","headers":{"Date":"Sun, 24 Nov 2024 08:59:35 GMT","Content-Type":"application/json","Content-Length":"25"},"config":{"timeout":10000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","headers":{"Accept":"application/json, text/plain, */*","Content-Type":"application/json","authorization":"Y3JhYjpjcmFi","User-Agent":"axios/0.21.4","Content-Length":35}},"request":{"method":"POST","httpVersion":"1.1","responseUrl":"http://localhost:8090/login","timeout":10000,"headers":{"authorization":"Y3JhYjpjcmFi"},"data":{"username":"foo","password":"bar"}},"data":{"id":1,"username":"foo"}}},{"mime":"text/html","value":"[object Object]"}]},{"kind":1,"language":"markdown","value":"# Добавление бюджета","outputs":[]},{"kind":2,"language":"rest-book","value":"POST http://localhost:8090/budgets\nauthorization: Y3JhYjpjcmFi\nUser-Id: 1\n\n{\n \"name\": \"Личный\"\n}","outputs":[{"mime":"x-application/rest-book","value":{"status":200,"statusText":"OK","headers":{"Date":"Sun, 24 Nov 2024 09:00:36 GMT","Content-Type":"application/json","Content-Length":"60"},"config":{"timeout":10000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","headers":{"Accept":"application/json, text/plain, */*","Content-Type":"application/json","authorization":"Y3JhYjpjcmFi","User-Id":"1","User-Agent":"axios/0.21.4","Content-Length":23}},"request":{"method":"POST","httpVersion":"1.1","responseUrl":"http://localhost:8090/budgets","timeout":10000,"headers":{"authorization":"Y3JhYjpjcmFi","User-Id":"1"},"data":{"name":"Личный"}},"data":{"id":1,"name":"Личный","startDay":0,"monthlyLimit":0}}},{"mime":"text/x-json","value":{"status":200,"statusText":"OK","headers":{"Date":"Sun, 24 Nov 2024 09:00:36 GMT","Content-Type":"application/json","Content-Length":"60"},"config":{"timeout":10000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","headers":{"Accept":"application/json, text/plain, */*","Content-Type":"application/json","authorization":"Y3JhYjpjcmFi","User-Id":"1","User-Agent":"axios/0.21.4","Content-Length":23}},"request":{"method":"POST","httpVersion":"1.1","responseUrl":"http://localhost:8090/budgets","timeout":10000,"headers":{"authorization":"Y3JhYjpjcmFi","User-Id":"1"},"data":{"name":"Личный"}},"data":{"id":1,"name":"Личный","startDay":0,"monthlyLimit":0}}},{"mime":"text/html","value":"[object Object]"}]},{"kind":1,"language":"markdown","value":"# Запрос бюджетов","outputs":[]},{"kind":2,"language":"rest-book","value":"GET http://localhost:8090/budgets\nauthorization: Y3JhYjpjcmFi\nUser-Id: 1","outputs":[{"mime":"x-application/rest-book","value":{"status":200,"statusText":"OK","headers":{"Date":"Sun, 24 Nov 2024 09:52:06 GMT","Content-Type":"application/json","Content-Length":"77"},"config":{"timeout":10000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","headers":{"Accept":"application/json, text/plain, */*","authorization":"Y3JhYjpjcmFi","User-Id":"1","User-Agent":"axios/0.21.4"}},"request":{"method":"GET","httpVersion":"1.1","responseUrl":"http://localhost:8090/budgets","timeout":10000,"headers":{"authorization":"Y3JhYjpjcmFi","User-Id":"1"}},"data":{"budgets":[{"id":1,"name":"Личный","startDay":0,"monthlyLimit":0}]}}},{"mime":"text/x-json","value":{"status":200,"statusText":"OK","headers":{"Date":"Sun, 24 Nov 2024 09:52:06 GMT","Content-Type":"application/json","Content-Length":"77"},"config":{"timeout":10000,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","headers":{"Accept":"application/json, text/plain, */*","authorization":"Y3JhYjpjcmFi","User-Id":"1","User-Agent":"axios/0.21.4"}},"request":{"method":"GET","httpVersion":"1.1","responseUrl":"http://localhost:8090/budgets","timeout":10000,"headers":{"authorization":"Y3JhYjpjcmFi","User-Id":"1"}},"data":{"budgets":[{"id":1,"name":"Личный","startDay":0,"monthlyLimit":0}]}}},{"mime":"text/html","value":"[object Object]"}]}] \ No newline at end of file diff --git a/smm.session.sql b/smm.session.sql new file mode 100644 index 0000000..53c99b3 --- /dev/null +++ b/smm.session.sql @@ -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; \ No newline at end of file