Add HelpServ: a help-desk ticket queue

Users open tickets with REQUEST (or HELPME); the queue is event-sourced
and, because a request is an event, the audit feed announces it to staff
and records it in the searchable log — so OperServ LOGSEARCH finds a ticket
by any word, the same trail as reports. A user can CANCEL their own open
ticket. Operators work the queue: LIST [ALL], VIEW, TAKE (claim), NEXT
(claim the oldest unassigned), CLOSE. Filing is rate-limited. Opt-in.

That completes the six third-party modules — all interconnected: they
share the account/channel/oper identity, the event-sourced store, and the
one audit/incident trail.
This commit is contained in:
Jean Chevronnet 2026-07-14 04:39:45 +00:00
parent 06227e73da
commit a47dd6bda3
No known key found for this signature in database
9 changed files with 385 additions and 2 deletions

View file

@ -640,6 +640,17 @@ pub struct NewsView {
pub ts: u64,
}
// A help-desk ticket held by HelpServ.
#[derive(Debug, Clone)]
pub struct HelpView {
pub id: u64,
pub requester: String,
pub message: String,
pub ts: u64,
pub handler: Option<String>,
pub open: bool,
}
// An abuse report held by ReportServ.
#[derive(Debug, Clone)]
pub struct ReportView {
@ -934,6 +945,13 @@ pub trait Store {
fn report_del(&mut self, id: u64) -> bool;
fn reports(&self, open_only: bool) -> Vec<ReportView>;
fn report(&self, id: u64) -> Option<ReportView>;
// Help-desk tickets (HelpServ). `help_request` is rate-limited (None = too soon).
fn help_request(&mut self, requester: &str, message: &str) -> Option<u64>;
fn help_take(&mut self, id: u64, handler: &str) -> bool;
fn help_close(&mut self, id: u64) -> bool;
fn help_tickets(&self, open_only: bool) -> Vec<HelpView>;
fn help_ticket(&self, id: u64) -> Option<HelpView>;
fn help_next_open(&self) -> Option<u64>;
// User groups (GroupServ).
fn group_register(&mut self, name: &str, founder: &str) -> Result<(), ChanError>;
fn group_drop(&mut self, name: &str) -> Result<(), ChanError>;