[Server] Serve report mutations through the database interface

cmdReportAssign, cmdReportResolve, cmdReportReopen and cmdReportAddComment still
ran their lookups and updates inline through Servatrice_DatabaseInterface. Add
assignReport, resolveReport, reopenReport, getUserNameById,
getReportNotificationTarget, countReportCommentsInLastHour,
getReportCommentTarget and addReportComment to Server_DatabaseInterface with
fail-closed defaults, and model the outcomes as ReportAssignResult and
ReportUpdateResult so "no such report", "wrong state" and "query failed" stay
distinguishable. Authorization checks, audit records, notification recipients
and every response code stay in the handler.
This commit is contained in:
Lukas Brübach 2026-11-10 01:26:12 +01:00
parent 3f9e53eb2f
commit e59dd24711
4 changed files with 339 additions and 148 deletions

View file

@ -484,6 +484,72 @@ public:
{
return false;
}
/** @brief Outcome of a report state change. */
enum class ReportUpdateResult
{
Ok,
InvalidState,
Failed
};
/** @brief Outcome of claiming an open report for a moderator. */
enum class ReportAssignResult
{
Ok,
NotFound,
NotOpen,
Failed
};
virtual ReportAssignResult assignReport(int /* reportId */, int /* moderatorId */)
{
return ReportAssignResult::Failed;
}
virtual ReportUpdateResult
resolveReport(int /* reportId */, const QString & /* status */, const QString & /* note */, int /* moderatorId */)
{
return ReportUpdateResult::Failed;
}
virtual ReportUpdateResult reopenReport(int /* reportId */)
{
return ReportUpdateResult::Failed;
}
/** @brief The user name behind a database user id; false when the lookup fails or finds no row. */
virtual bool getUserNameById(int /* userId */, QString & /* userName */)
{
return false;
}
/** @brief The reporter and reported user of a report, for the resolve notification. */
virtual bool
getReportNotificationTarget(int /* reportId */, int & /* reporterId */, QString & /* reportedUserName */)
{
return false;
}
/** @brief Comments the author wrote in the last hour, for the hourly cap. */
virtual int countReportCommentsInLastHour(int /* authorId */)
{
return 0;
}
/** @brief One report's reporter, assignee and status, for the comment checks. */
struct ReportCommentTargetRecord
{
bool found = false;
int reporterId = 0;
QString reporterName;
int assignedToId = 0;
QString status;
};
virtual bool getReportCommentTarget(int /* reportId */, ReportCommentTargetRecord & /* target */)
{
return false;
}
virtual bool addReportComment(int /* reportId */,
const QString & /* authorName */,
int /* authorId */,
const QString & /* commentText */,
bool /* isModerator */,
qlonglong & /* commentId */)
{
return false;
}
/** @brief One resolved or dismissed report whose reporter has not been told yet. */
struct PendingReportNotification
{