feat: enhance Admin and report services with CRUD operations and intervention links

This commit is contained in:
gabdevele
2026-06-15 11:47:44 +02:00 Unverified
parent d684477ac3
commit 170fadbfe0
13 changed files with 1258 additions and 164 deletions
+49 -24
View File
@@ -69,18 +69,14 @@ void sendAdmin(Json::Value body,
{
status = drogon::k409Conflict;
}
else if (error == "invalid_reference" || error.starts_with("invalid_"))
{
status = drogon::k422UnprocessableEntity;
}
callback(visione::http::json(std::move(body), status));
}
} // namespace
void AdminController::listCategories(
const drogon::HttpRequestPtr &,
std::function<void(const HttpResponsePtr &)> &&callback)
{
visione::services::AdminService service;
callback(visione::http::json(service.listCategories()));
}
void AdminController::createCategory(
const drogon::HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback)
@@ -95,14 +91,6 @@ void AdminController::createCategory(
std::move(callback));
}
void AdminController::listAreas(
const drogon::HttpRequestPtr &,
std::function<void(const HttpResponsePtr &)> &&callback)
{
visione::services::AdminService service;
callback(visione::http::json(service.listAreas()));
}
void AdminController::createArea(
const drogon::HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback)
@@ -117,14 +105,6 @@ void AdminController::createArea(
std::move(callback));
}
void AdminController::listTeams(
const drogon::HttpRequestPtr &,
std::function<void(const HttpResponsePtr &)> &&callback)
{
visione::services::AdminService service;
callback(visione::http::json(service.listTeams()));
}
void AdminController::createTeam(
const drogon::HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback)
@@ -139,6 +119,51 @@ void AdminController::createTeam(
std::move(callback));
}
void AdminController::updateCategory(
const drogon::HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback,
long long categoryId)
{
auto user = requireUser(req, callback);
if (!user || blockPasswordChangeRequired(*user, callback))
{
return;
}
visione::services::AdminService service;
sendAdmin(service.updateCategory(*user, categoryId, visione::http::requireJson(req)),
std::move(callback));
}
void AdminController::updateArea(
const drogon::HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback,
long long areaId)
{
auto user = requireUser(req, callback);
if (!user || blockPasswordChangeRequired(*user, callback))
{
return;
}
visione::services::AdminService service;
sendAdmin(service.updateArea(*user, areaId, visione::http::requireJson(req)),
std::move(callback));
}
void AdminController::updateTeam(
const drogon::HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback,
long long teamId)
{
auto user = requireUser(req, callback);
if (!user || blockPasswordChangeRequired(*user, callback))
{
return;
}
visione::services::AdminService service;
sendAdmin(service.updateTeam(*user, teamId, visione::http::requireJson(req)),
std::move(callback));
}
void AdminController::overviewStats(
const drogon::HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback)
+21 -14
View File
@@ -6,16 +6,20 @@ class AdminController : public drogon::HttpController<AdminController>
{
public:
METHOD_LIST_BEGIN
ADD_METHOD_TO(AdminController::listCategories,
"/api/v1/admin/categories",
drogon::Get);
ADD_METHOD_TO(AdminController::createCategory,
"/api/v1/admin/categories",
drogon::Post);
ADD_METHOD_TO(AdminController::listAreas, "/api/v1/admin/areas", drogon::Get);
ADD_METHOD_TO(AdminController::createArea, "/api/v1/admin/areas", drogon::Post);
ADD_METHOD_TO(AdminController::listTeams, "/api/v1/admin/teams", drogon::Get);
ADD_METHOD_TO(AdminController::createTeam, "/api/v1/admin/teams", drogon::Post);
ADD_METHOD_TO(AdminController::updateCategory,
"/api/v1/admin/categories/{1}",
drogon::Patch);
ADD_METHOD_TO(AdminController::updateArea,
"/api/v1/admin/areas/{1}",
drogon::Patch);
ADD_METHOD_TO(AdminController::updateTeam,
"/api/v1/admin/teams/{1}",
drogon::Patch);
ADD_METHOD_TO(AdminController::overviewStats,
"/api/v1/admin/stats/overview",
drogon::Get);
@@ -34,24 +38,27 @@ class AdminController : public drogon::HttpController<AdminController>
drogon::Patch);
METHOD_LIST_END
void listCategories(
const drogon::HttpRequestPtr &req,
std::function<void(const drogon::HttpResponsePtr &)> &&callback);
void createCategory(
const drogon::HttpRequestPtr &req,
std::function<void(const drogon::HttpResponsePtr &)> &&callback);
void listAreas(
const drogon::HttpRequestPtr &req,
std::function<void(const drogon::HttpResponsePtr &)> &&callback);
void createArea(
const drogon::HttpRequestPtr &req,
std::function<void(const drogon::HttpResponsePtr &)> &&callback);
void listTeams(
const drogon::HttpRequestPtr &req,
std::function<void(const drogon::HttpResponsePtr &)> &&callback);
void createTeam(
const drogon::HttpRequestPtr &req,
std::function<void(const drogon::HttpResponsePtr &)> &&callback);
void updateCategory(
const drogon::HttpRequestPtr &req,
std::function<void(const drogon::HttpResponsePtr &)> &&callback,
long long categoryId);
void updateArea(
const drogon::HttpRequestPtr &req,
std::function<void(const drogon::HttpResponsePtr &)> &&callback,
long long areaId);
void updateTeam(
const drogon::HttpRequestPtr &req,
std::function<void(const drogon::HttpResponsePtr &)> &&callback,
long long teamId);
void overviewStats(
const drogon::HttpRequestPtr &req,
std::function<void(const drogon::HttpResponsePtr &)> &&callback);
+20
View File
@@ -21,6 +21,14 @@ std::optional<std::string> queryValue(const drogon::HttpRequestPtr &req,
}
} // namespace
void PublicController::listAreas(
const drogon::HttpRequestPtr &,
std::function<void(const HttpResponsePtr &)> &&callback)
{
visione::services::ReportService service;
callback(visione::http::json(service.listAreas()));
}
void PublicController::openDataReports(
const drogon::HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback)
@@ -29,3 +37,15 @@ void PublicController::openDataReports(
callback(visione::http::json(service.openDataReports(queryValue(req, "page"),
queryValue(req, "per_page"))));
}
void PublicController::interventionSummary(
const drogon::HttpRequestPtr &,
std::function<void(const HttpResponsePtr &)> &&callback,
const std::string &token)
{
visione::services::ReportService service;
auto body = service.publicInterventionSummary(token);
const auto status = body.get("ok", false).asBool() ? drogon::k200OK
: drogon::k404NotFound;
callback(visione::http::json(std::move(body), status));
}
+10
View File
@@ -6,12 +6,22 @@ class PublicController : public drogon::HttpController<PublicController>
{
public:
METHOD_LIST_BEGIN
ADD_METHOD_TO(PublicController::listAreas, "/api/v1/areas", drogon::Get);
ADD_METHOD_TO(PublicController::openDataReports,
"/api/v1/open-data/reports",
drogon::Get);
ADD_METHOD_TO(PublicController::interventionSummary,
"/api/v1/interventions/{1}",
drogon::Get);
METHOD_LIST_END
void listAreas(const drogon::HttpRequestPtr &req,
std::function<void(const drogon::HttpResponsePtr &)> &&callback);
void openDataReports(
const drogon::HttpRequestPtr &req,
std::function<void(const drogon::HttpResponsePtr &)> &&callback);
void interventionSummary(
const drogon::HttpRequestPtr &req,
std::function<void(const drogon::HttpResponsePtr &)> &&callback,
const std::string &token);
};
+77 -2
View File
@@ -68,10 +68,17 @@ void sendService(Json::Value body,
status = drogon::k404NotFound;
}
else if (error == "invalid_status_transition" ||
error == "media_limit_reached")
error == "media_limit_reached" ||
error == "report_not_open" ||
error == "report_owned_by_other_operator")
{
status = drogon::k409Conflict;
}
else if (error == "invalid_reference" || error.starts_with("invalid_") ||
error == "missing_rating")
{
status = drogon::k422UnprocessableEntity;
}
callback(visione::http::json(std::move(body), status));
}
@@ -141,6 +148,32 @@ void ReportController::list(
std::move(callback));
}
void ReportController::listCategories(
const drogon::HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback)
{
auto user = requireUser(req, callback);
if (!user || blockPasswordChangeRequired(*user, callback))
{
return;
}
visione::services::ReportService service;
sendService(service.listCategories(*user), std::move(callback));
}
void ReportController::listTeams(
const drogon::HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback)
{
auto user = requireUser(req, callback);
if (!user || blockPasswordChangeRequired(*user, callback))
{
return;
}
visione::services::ReportService service;
sendService(service.listOperatorTeams(*user), std::move(callback));
}
void ReportController::assignedReports(
const drogon::HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback)
@@ -217,6 +250,48 @@ void ReportController::interventionSummary(
sendService(service.interventionSummary(*user, reportId), std::move(callback));
}
void ReportController::teamSuggestions(
const drogon::HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback,
long long reportId)
{
auto user = requireUser(req, callback);
if (!user || blockPasswordChangeRequired(*user, callback))
{
return;
}
visione::services::ReportService service;
sendService(service.teamSuggestions(*user, reportId), std::move(callback));
}
void ReportController::createInterventionLink(
const drogon::HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback,
long long reportId)
{
auto user = requireUser(req, callback);
if (!user || blockPasswordChangeRequired(*user, callback))
{
return;
}
visione::services::ReportService service;
sendService(service.createInterventionLink(*user, reportId), std::move(callback));
}
void ReportController::revokeInterventionLink(
const drogon::HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback,
long long reportId)
{
auto user = requireUser(req, callback);
if (!user || blockPasswordChangeRequired(*user, callback))
{
return;
}
visione::services::ReportService service;
sendService(service.revokeInterventionLink(*user, reportId), std::move(callback));
}
void ReportController::updateStatus(
const drogon::HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback,
@@ -368,7 +443,7 @@ void ReportController::uploadMedia(
auto allowed = service.canAddMedia(*user, reportId);
if (!allowed.get("ok", false).asBool())
{
callback(visione::http::json(std::move(allowed), drogon::k403Forbidden));
sendService(std::move(allowed), std::move(callback));
return;
}
+32
View File
@@ -8,6 +8,12 @@ class ReportController : public drogon::HttpController<ReportController>
METHOD_LIST_BEGIN
ADD_METHOD_TO(ReportController::create, "/api/v1/reports", drogon::Post);
ADD_METHOD_TO(ReportController::list, "/api/v1/reports", drogon::Get);
ADD_METHOD_TO(ReportController::listCategories,
"/api/v1/report-categories",
drogon::Get);
ADD_METHOD_TO(ReportController::listTeams,
"/api/v1/operator/teams",
drogon::Get);
ADD_METHOD_TO(ReportController::assignedReports,
"/api/v1/operator/reports/assigned",
drogon::Get);
@@ -21,6 +27,15 @@ class ReportController : public drogon::HttpController<ReportController>
ADD_METHOD_TO(ReportController::interventionSummary,
"/api/v1/reports/{1}/intervention-summary",
drogon::Get);
ADD_METHOD_TO(ReportController::teamSuggestions,
"/api/v1/reports/{1}/team-suggestions",
drogon::Get);
ADD_METHOD_TO(ReportController::createInterventionLink,
"/api/v1/reports/{1}/intervention-link",
drogon::Post);
ADD_METHOD_TO(ReportController::revokeInterventionLink,
"/api/v1/reports/{1}/intervention-link",
drogon::Delete);
ADD_METHOD_TO(ReportController::updateStatus,
"/api/v1/reports/{1}/status",
drogon::Patch);
@@ -54,6 +69,11 @@ class ReportController : public drogon::HttpController<ReportController>
std::function<void(const drogon::HttpResponsePtr &)> &&callback);
void list(const drogon::HttpRequestPtr &req,
std::function<void(const drogon::HttpResponsePtr &)> &&callback);
void listCategories(
const drogon::HttpRequestPtr &req,
std::function<void(const drogon::HttpResponsePtr &)> &&callback);
void listTeams(const drogon::HttpRequestPtr &req,
std::function<void(const drogon::HttpResponsePtr &)> &&callback);
void assignedReports(
const drogon::HttpRequestPtr &req,
std::function<void(const drogon::HttpResponsePtr &)> &&callback);
@@ -70,6 +90,18 @@ class ReportController : public drogon::HttpController<ReportController>
const drogon::HttpRequestPtr &req,
std::function<void(const drogon::HttpResponsePtr &)> &&callback,
long long reportId);
void teamSuggestions(
const drogon::HttpRequestPtr &req,
std::function<void(const drogon::HttpResponsePtr &)> &&callback,
long long reportId);
void createInterventionLink(
const drogon::HttpRequestPtr &req,
std::function<void(const drogon::HttpResponsePtr &)> &&callback,
long long reportId);
void revokeInterventionLink(
const drogon::HttpRequestPtr &req,
std::function<void(const drogon::HttpResponsePtr &)> &&callback,
long long reportId);
void updateStatus(
const drogon::HttpRequestPtr &req,
std::function<void(const drogon::HttpResponsePtr &)> &&callback,