OperServ: NEWS — logon and oper announcements

NEWS ADD <LOGON|OPER> <text> / DEL <LOGON|OPER> <number> / LIST. Logon news
is shown to every user as they connect; oper news is shown to an operator
when they log in. Admin-only to manage. Each item carries a stable id
assigned at add time and embedded in the log, so deletion is order-
independent under replay (DEL by number resolves to that id).

Enabling groundwork: the replicated network-wide lists (bans, now news)
are consolidated into one NetData struct threaded through apply() as a
single parameter — this replaces the akill parameter rather than adding
one, so the fold stays within its argument budget as the lists grow.
This commit is contained in:
Jean Chevronnet 2026-07-14 01:26:12 +00:00
parent 51d4ebf789
commit e45eab2cd6
No known key found for this signature in database
6 changed files with 281 additions and 26 deletions

View file

@ -457,6 +457,15 @@ pub struct IgnoreView {
pub expires: Option<u64>,
}
// A news item held by OperServ (its kind is implied by which list it came from).
#[derive(Debug, Clone)]
pub struct NewsView {
pub id: u64,
pub text: String,
pub setter: String,
pub ts: u64,
}
#[derive(Debug, Clone)]
pub struct BotView {
pub nick: String,
@ -718,6 +727,10 @@ pub trait Store {
fn account_note(&self, account: &str) -> Option<String>;
fn set_channel_note(&mut self, channel: &str, note: Option<String>) -> bool;
fn channel_note(&self, channel: &str) -> Option<String>;
// News items shown on connect (logon) / login (oper), oper-only to manage.
fn news_add(&mut self, kind: &str, text: &str, setter: &str) -> u64;
fn news_del(&mut self, id: u64) -> bool;
fn news(&self, kind: &str) -> Vec<NewsView>;
fn register_channel(&mut self, name: &str, founder: &str) -> Result<(), ChanError>;
fn drop_channel(&mut self, name: &str) -> Result<(), ChanError>;
fn set_mlock(&mut self, name: &str, on: &str, off: &str) -> Result<(), ChanError>;