From 5a77e9db8a9ca9df518b6ca17e4e90b2ab79459f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D1=82=D0=BE=D0=BD?= Date: Mon, 12 Jan 2026 09:04:27 +0300 Subject: [PATCH] =?UTF-8?q?=D0=91=D0=B0=D0=B7=D0=B0=20=D0=B4=D0=BB=D1=8F?= =?UTF-8?q?=20=D1=80=D1=83=D1=87=D0=BA=D0=B8=20PostUserMedicationsExecutor?= =?UTF-8?q?.h?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/DAO/IAuthDAO.h | 2 + src/DAO/MemoryAuthDAO.cpp | 5 + src/DAO/MemoryAuthDAO.h | 2 + .../GetUserMedicationsExecutor.h | 2 +- .../GetUserTreatmentSchemeExecutor.h | 112 +++++++++++++++++- src/endpoints_handlers/RootExecutor.h | 2 +- 6 files changed, 119 insertions(+), 6 deletions(-) diff --git a/src/DAO/IAuthDAO.h b/src/DAO/IAuthDAO.h index 1a9e17d..3a1f2b2 100644 --- a/src/DAO/IAuthDAO.h +++ b/src/DAO/IAuthDAO.h @@ -16,6 +16,8 @@ public: virtual bool HasAuthorized(const std::string& auth_token) = 0; + virtual std::string_view GetLogin(const std::string& auth_token) = 0; + virtual bool Logout(const std::string& user_token) = 0; virtual ~IAuthDAO() = default; diff --git a/src/DAO/MemoryAuthDAO.cpp b/src/DAO/MemoryAuthDAO.cpp index 3b5561a..ada543a 100644 --- a/src/DAO/MemoryAuthDAO.cpp +++ b/src/DAO/MemoryAuthDAO.cpp @@ -25,6 +25,11 @@ bool MemoryAuthDAO::HasAuthorized(const std::string& auth_token) return auth_tokens_to_users_uuids_.count(auth_token) > 0; } +std::string_view MemoryAuthDAO::GetLogin(const std::string& auth_token) +{ + return auth_tokens_to_users_uuids_.at(auth_token); +} + bool MemoryAuthDAO::Logout(const std::string& auth_token) { if (!HasAuthorized(auth_token)) return false; diff --git a/src/DAO/MemoryAuthDAO.h b/src/DAO/MemoryAuthDAO.h index 8d29ff1..9593a3c 100644 --- a/src/DAO/MemoryAuthDAO.h +++ b/src/DAO/MemoryAuthDAO.h @@ -25,6 +25,8 @@ public: bool HasAuthorized(const std::string& auth_token) override; + std::string_view GetLogin(const std::string& auth_token) override; + bool Logout(const std::string& auth_token) override; }; } diff --git a/src/endpoints_handlers/GetUserMedicationsExecutor.h b/src/endpoints_handlers/GetUserMedicationsExecutor.h index c1093c7..da98276 100644 --- a/src/endpoints_handlers/GetUserMedicationsExecutor.h +++ b/src/endpoints_handlers/GetUserMedicationsExecutor.h @@ -99,7 +99,7 @@ private: arr.emplace_back(ToJSON(m)); } - return arr; + return std::move(arr); } }; } diff --git a/src/endpoints_handlers/GetUserTreatmentSchemeExecutor.h b/src/endpoints_handlers/GetUserTreatmentSchemeExecutor.h index 5716afc..04e786a 100644 --- a/src/endpoints_handlers/GetUserTreatmentSchemeExecutor.h +++ b/src/endpoints_handlers/GetUserTreatmentSchemeExecutor.h @@ -19,14 +19,14 @@ class GetUserTreatmentSchemeExecutor : public IExecutor& auth_dao_; const std::shared_ptr& user_treatment_scheme_dao_; + public: GetUserTreatmentSchemeExecutor( mysqlx::Session& session, const std::shared_ptr& auth_dao, const std::shared_ptr& user_treatment_scheme_dao - ): session_(session), auth_dao_(auth_dao), user_treatment_scheme_dao_(user_treatment_scheme_dao) + ) : session_(session), auth_dao_(auth_dao), user_treatment_scheme_dao_(user_treatment_scheme_dao) { - } boost::beast::http::response operator ()( @@ -40,7 +40,8 @@ public: using namespace std::string_view_literals; constexpr std::string_view auth_prefix = "Bearer "sv; - static const std::string invalid_token_message = "GET /api/v1/User/Medications - Response 401: Unauthorized"s; + static const std::string invalid_token_message = + "GET /api/v1/User/Medications - Response 401: Unauthorized"s; BOOST_LOG_TRIVIAL(info) << "GET /api/v1/User/Medications - Request"; @@ -50,7 +51,10 @@ public: throw session_exception(http::status::unauthorized, "Unauthorized"); } - const std::string auth_token = {req[http::field::authorization].begin() + auth_prefix.size(), req[http::field::authorization].end()}; + const std::string auth_token = { + req[http::field::authorization].begin() + auth_prefix.size(), + req[http::field::authorization].end() + }; if (!auth_dao_->HasAuthorized(auth_token)) { @@ -58,9 +62,109 @@ public: throw session_exception(http::status::unauthorized, "Unauthorized"); } + std::string_view user_login_ref = auth_dao_->GetLogin(auth_token); + const std::string user_uuid{user_login_ref.begin(), user_login_ref.end()}; + + static const std::string query = R"( + SELECT + uts.uuid, + uts.treatment_name, + uts.instructions, + ts.medication_uuid + FROM up_and_down.users u + JOIN up_and_down.user_treatment_schemes uts + ON uts.user_uuid = u.uuid + LEFT JOIN up_and_down.treatment_schemes ts + ON ts.user_treatment_schemes_uuid = uts.uuid + WHERE u.uuid = ? + ORDER BY uts.uuid + )"; + + mysqlx::SqlResult result = session_ + .sql(query) + .bind(user_uuid) + .execute(); + + std::unordered_map scheme_map; + + for (const mysqlx::Row& row : result) + { + const std::string scheme_uuid = row[0].get(); + + if (scheme_map.find(scheme_uuid) == scheme_map.end()) + { + user_treatment_scheme_dto dto; + dto.uuid = scheme_uuid; + dto.treatment_name = row[1].isNull() ? "" : row[1].get(); + dto.instructions = row[2].isNull() ? "" : row[2].get(); + + scheme_map.emplace(scheme_uuid, std::move(dto)); + } + + if (!row[3].isNull()) + { + scheme_map[scheme_uuid] + .medication_uuids + .push_back(row[3].get()); + } + } + + std::vector schemes; + schemes.reserve(scheme_map.size()); + + for (auto& [_, dto] : scheme_map) + { + schemes.push_back(std::move(dto)); + } + http::response res{http::status::ok, req.version()}; + value response_body; + + response_body.emplace_object(); + response_body.as_object().emplace("user_treatment_schemes", toJSONArray(schemes)); + + res.body() = serialize(response_body); + res.set(http::field::content_type, "application/json"); + res.content_length(res.body().size()); return res; } + +private: + boost::json::object ToJSON(const user_treatment_scheme_dto& scheme) + { + boost::json::array medications_json; + medications_json.reserve(scheme.medication_uuids.size()); + + for (const auto& medication_uuid : scheme.medication_uuids) { + medications_json.emplace_back(medication_uuid); + } + + boost::json::object scheme_json; + scheme_json["uuid"] = scheme.uuid; + scheme_json["treatment_name"] = scheme.treatment_name; + scheme_json["instructions"] = scheme.instructions; + scheme_json["medications"] = std::move(medications_json); + + return scheme_json; + } + + boost::json::array toJSONArray(const std::vector& schemes) + { + using namespace boost; + using namespace boost::json; + using namespace boost::beast; + using namespace std::string_literals; + using namespace std::string_view_literals; + + json::array arr; + + for (const auto& m : schemes) + { + arr.emplace_back(ToJSON(m)); + } + + return std::move(arr); + } }; } diff --git a/src/endpoints_handlers/RootExecutor.h b/src/endpoints_handlers/RootExecutor.h index c10aaf4..9880472 100644 --- a/src/endpoints_handlers/RootExecutor.h +++ b/src/endpoints_handlers/RootExecutor.h @@ -105,7 +105,7 @@ public: } ); - routes_pathes_["api/v1/UserTreatmentSchemes"] = std::make_unique( + routes_pathes_["/api/v1/UserTreatmentSchemes"] = std::make_unique( typename RouteController::HTTPMethodsToExecutors{ { boost::beast::http::verb::get,