Skip to content

Commit b301111

Browse files
Enhance user management in RESTART module by adding user creation functionality and updating user class structure. Implement server-side handling for new user requests, including validation and error handling.
1 parent 65613d3 commit b301111

File tree

4 files changed

+90
-18
lines changed

4 files changed

+90
-18
lines changed

include/restart.hpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@
22

33
#include "coco_module.hpp"
44
#include <functional>
5+
#include <memory>
56

67
namespace restart
78
{
9+
constexpr const char *next_id_defglobal = "(defglobal ?*next-id* = 1)";
10+
constexpr const char *exercise_deftemplate = "(deftemplate exercise (slot id) (slot exercise-type (type SYMBOL)) (slot exercise-level (type INTEGER) (range 0 6)))";
11+
812
class user;
913

1014
class restart : public coco::coco_module
@@ -13,20 +17,25 @@ namespace restart
1317
restart(coco::coco &cc) noexcept;
1418

1519
[[nodiscard]] std::vector<std::reference_wrapper<user>> get_users() noexcept;
16-
void create_user(std::string_view name, json::json &&tests = json::json(), bool infere = true);
20+
user &create_user(std::string_view name, json::json &&tests = json::json(), bool infere = true);
21+
22+
private:
23+
std::unordered_map<std::string, std::unique_ptr<user>> users; // Map of user ID to user object
1724
};
1825

1926
class user final
2027
{
2128
public:
22-
user(std::string_view name, json::json &&tests = json::json());
29+
user(std::string_view id, std::string_view name, json::json &&tests = json::json());
2330

31+
[[nodiscard]] const std::string &get_id() const { return id; }
2432
[[nodiscard]] const std::string &get_name() const { return name; }
2533
[[nodiscard]] const json::json &get_tests() const { return tests; }
2634

2735
[[nodiscard]] json::json to_json() const noexcept;
2836

2937
private:
38+
std::string id; // The unique identifier for the user
3039
std::string name; // The name of the user
3140
json::json tests; // The tests associated with the user
3241
};

src/main.cpp

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,20 +38,26 @@ int main()
3838
auto &general_cd = cc.create_item(cd_type, json::json{{"name", "General"}});
3939

4040
auto &ct_type = cc.create_type("CognitiveTest", {}, json::json{{"name", {"type", "string"}}, {"domain", {{"type", "item"}, {"domain", "CognitiveDomain"}}}}, json::json());
41-
auto &moca_ct = cc.create_item(ct_type, json::json{{"name", "MoCA"}, {"domain", general_cd.get_id()}});
42-
auto &attention_matrices_ct = cc.create_item(ct_type, json::json{{"name", "AttentionMatrices"}, {"domain", attention_cd.get_id()}});
43-
auto &trial_making_test_a_ct = cc.create_item(ct_type, json::json{{"name", "TrialMakingTestA"}, {"domain", executive_functions_cd.get_id()}});
44-
auto &trial_making_test_b_ct = cc.create_item(ct_type, json::json{{"name", "TrialMakingTestB"}, {"domain", executive_functions_cd.get_id()}});
45-
auto &trial_making_test_b_a_ct = cc.create_item(ct_type, json::json{{"name", "TrialMakingTestBA"}, {"domain", executive_functions_cd.get_id()}});
46-
auto &semantic_fluency_ct = cc.create_item(ct_type, json::json{{"name", "SemanticFluency"}, {"domain", executive_functions_cd.get_id()}});
47-
auto &phonological_fluency_ct = cc.create_item(ct_type, json::json{{"name", "PhonologicalFluency"}, {"domain", executive_functions_cd.get_id()}});
48-
auto &modified_wisconsin_card_sorting_test_ct = cc.create_item(ct_type, json::json{{"name", "ModifiedWisconsinCardSortingTest"}, {"domain", executive_functions_cd.get_id()}});
49-
auto &short_story_ct = cc.create_item(ct_type, json::json{{"name", "ShortStory"}, {"domain", memory_cd.get_id()}});
41+
[[maybe_unused]] auto &moca_ct = cc.create_item(ct_type, json::json{{"name", "MoCA"}, {"domain", general_cd.get_id()}});
42+
[[maybe_unused]] auto &attention_matrices_ct = cc.create_item(ct_type, json::json{{"name", "AttentionMatrices"}, {"domain", attention_cd.get_id()}});
43+
[[maybe_unused]] auto &trial_making_test_a_ct = cc.create_item(ct_type, json::json{{"name", "TrialMakingTestA"}, {"domain", executive_functions_cd.get_id()}});
44+
[[maybe_unused]] auto &trial_making_test_b_ct = cc.create_item(ct_type, json::json{{"name", "TrialMakingTestB"}, {"domain", executive_functions_cd.get_id()}});
45+
[[maybe_unused]] auto &trial_making_test_b_a_ct = cc.create_item(ct_type, json::json{{"name", "TrialMakingTestBA"}, {"domain", executive_functions_cd.get_id()}});
46+
[[maybe_unused]] auto &semantic_fluency_ct = cc.create_item(ct_type, json::json{{"name", "SemanticFluency"}, {"domain", executive_functions_cd.get_id()}});
47+
[[maybe_unused]] auto &phonological_fluency_ct = cc.create_item(ct_type, json::json{{"name", "PhonologicalFluency"}, {"domain", executive_functions_cd.get_id()}});
48+
[[maybe_unused]] auto &modified_wisconsin_card_sorting_test_ct = cc.create_item(ct_type, json::json{{"name", "ModifiedWisconsinCardSortingTest"}, {"domain", executive_functions_cd.get_id()}});
49+
[[maybe_unused]] auto &short_story_ct = cc.create_item(ct_type, json::json{{"name", "ShortStory"}, {"domain", memory_cd.get_id()}});
5050

5151
auto &ce_type = cc.create_type("CognitiveExercise", {}, json::json{{"name", {"type", "string"}}, {"duration", {{"type", "int"}, {"min", 0}, {"max", 60}}}, {"domain", {{"type", "item"}, {"domain", "CognitiveTest"}}}}, json::json());
52-
auto &visual_memory_ce = cc.create_item(ce_type, json::json{{"name", "VisualMemory"}, {"duration", 5}, {"domain", memory_cd.get_id()}});
53-
auto &attention_ce = cc.create_item(ce_type, json::json{{"name", "Attention"}, {"duration", 5}, {"domain", attention_cd.get_id()}});
54-
auto &executive_functions_ce = cc.create_item(ce_type, json::json{{"name", "ExecutiveFunctions"}, {"duration", 5}, {"domain", executive_functions_cd.get_id()}});
52+
[[maybe_unused]] auto &visual_memory_ce = cc.create_item(ce_type, json::json{{"name", "VisualMemory"}, {"duration", 5}, {"domain", memory_cd.get_id()}});
53+
[[maybe_unused]] auto &attention_ce = cc.create_item(ce_type, json::json{{"name", "Attention"}, {"duration", 5}, {"domain", attention_cd.get_id()}});
54+
[[maybe_unused]] auto &executive_functions_ce = cc.create_item(ce_type, json::json{{"name", "ExecutiveFunctions"}, {"duration", 5}, {"domain", executive_functions_cd.get_id()}});
55+
56+
[[maybe_unused]] auto &usr_type = cc.create_type("User", {}, json::json{{"name", {"type", "string"}}}, json::json());
57+
[[maybe_unused]] auto &t_done_type = cc.create_type("TestDone", {}, json::json{{"user", {{"type", "item"}, {"domain", "User"}}}, {"test", {{"type", "item"}, {"domain", "CognitiveTest"}}}, {"score", {{"type", "int"}, {"min", 0}, {"max", 6}}}}, json::json());
58+
[[maybe_unused]] auto &ex_done_type = cc.create_type("ExerciseDone", {}, json::json{{"user", {{"type", "item"}, {"domain", "User"}}}, {"exercise", {{"type", "item"}, {"domain", "CognitiveExercise"}}}, {"level", {{"type", "int"}, {"min", 0}, {"max", 6}}}, {"done", {{"type", "int"}, {"min", 0}, {"default", 0}}}, {"performance", {{"type", "float"}, {"min", 0}, {"max", 1}}}}, json::json());
59+
60+
rst.create_user("TestUser", json::json{{"MoCA", 2}, {"AttentionMatrices", 1}, {"TrialMakingTestA", 4}, {"TrialMakingTestB", 3}, {"TrialMakingTestBA", 0}, {"SemanticFluency", 2}, {"PhonologicalFluency", 4}, {"ModifiedWisconsinCardSortingTest", 1}, {"ShortStory", 3}});
5561
}
5662

5763
#ifdef INTERACTIVE_TEST

src/restart.cpp

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,60 @@
11
#include "restart.hpp"
22
#include "coco.hpp"
3+
#include "coco_item.hpp"
4+
#include "logging.hpp"
5+
#include <cassert>
36

47
namespace restart
58
{
6-
restart::restart(coco::coco &cc) noexcept : coco_module(cc) {}
9+
restart::restart(coco::coco &cc) noexcept : coco_module(cc)
10+
{
11+
LOG_TRACE(next_id_defglobal);
12+
[[maybe_unused]] auto next_id_dg_err = Build(get_env(), next_id_defglobal);
13+
assert(next_id_dg_err == BE_NO_ERROR);
14+
LOG_TRACE(exercise_deftemplate);
15+
[[maybe_unused]] auto build_exercise_dt_err = Build(get_env(), exercise_deftemplate);
16+
assert(build_exercise_dt_err == BE_NO_ERROR);
17+
}
718

819
std::vector<std::reference_wrapper<user>> restart::get_users() noexcept
920
{
1021
std::vector<std::reference_wrapper<user>> users;
1122
return users;
1223
}
1324

14-
void restart::create_user(std::string_view name, json::json &&tests, bool infere)
25+
user &restart::create_user(std::string_view name, json::json &&tests, bool infere)
1526
{
1627
std::lock_guard<std::recursive_mutex> lock(get_mtx());
1728
auto &usr_type = get_coco().get_type("User");
1829
auto &ct_type = get_coco().get_type("CognitiveTest");
30+
auto &t_done_type = get_coco().get_type("TestDone");
31+
auto &ex_type = get_coco().get_type("CognitiveExercise");
32+
auto &ex_done_type = get_coco().get_type("ExerciseDone");
33+
34+
auto &usr = get_coco().create_item(usr_type, json::json{{"name", name.data()}});
35+
for (const auto &[test_name, test_score] : tests.as_object())
36+
{
37+
std::string test_id;
38+
for (const auto &ct : get_coco().get_items(ct_type))
39+
if (ct.get().get_properties()["name"] == test_name)
40+
{
41+
test_id = ct.get().get_id();
42+
break;
43+
}
44+
[[maybe_unused]] auto &t_done = get_coco().create_item(t_done_type, json::json{{"user", usr.get_id()}, {"test", test_id}, {"score", test_score.get<int>()}});
45+
}
46+
for (const auto &ce : get_coco().get_items(ex_type))
47+
[[maybe_unused]]
48+
auto &ex_done = get_coco().create_item(ex_done_type, json::json{{"user", usr.get_id()}, {"exercise", ce.get().get_id()}});
49+
50+
users.emplace(usr.get_id(), std::make_unique<user>(usr.get_id(), name, std::move(tests)));
51+
52+
if (infere)
53+
Run(get_env(), -1);
54+
55+
return *users.at(usr.get_id());
1956
}
2057

21-
user::user(std::string_view name, json::json &&tests) : name(name), tests(std::move(tests)) {}
58+
user::user(std::string_view id, std::string_view name, json::json &&tests) : id(id), name(name), tests(std::move(tests)) {}
2259
json::json user::to_json() const noexcept { return json::json{{"name", name}, {"tests", tests}}; }
2360
} // namespace restart

src/restart_server.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,27 @@ namespace restart
2323
{"400", {{"description", "Invalid request."}}}}}}}};
2424
}
2525

26-
std::unique_ptr<network::response> restart_server::new_user(const network::request &req) {}
26+
std::unique_ptr<network::response> restart_server::new_user(const network::request &req)
27+
{
28+
auto &body = static_cast<const network::json_request &>(req).get_body();
29+
if (!body.is_object() || !body.contains("name") || !body["name"].is_string())
30+
return std::make_unique<network::json_response>(json::json({{"message", "Invalid request"}}), network::status_code::bad_request);
31+
32+
std::string name = body["name"];
33+
json::json tests;
34+
for (const auto &[test_name, test_score] : body.as_object())
35+
if (test_name != "name")
36+
tests[test_name] = test_score.get<int>();
37+
try
38+
{
39+
auto &usr = rst.create_user(name, std::move(tests));
40+
return std::make_unique<network::string_response>(std::string(usr.get_id()), network::status_code::created);
41+
}
42+
catch (const std::exception &e)
43+
{
44+
return std::make_unique<network::json_response>(json::json({{"message", e.what()}}), network::status_code::conflict);
45+
}
46+
}
2747
std::unique_ptr<network::response> restart_server::new_test(const network::request &req) {}
2848
std::unique_ptr<network::response> restart_server::new_exercise(const network::request &req) {}
2949
} // namespace restart

0 commit comments

Comments
 (0)