feat: Phase 4 community features - member counter, polls, reminders

- feature/counter: voice channel showing live member count, refreshed every 10min
- feature/poll: /poll slash command, embed + numbered reactions (2-10 options)
- feature/remind: /remind slash command, SQLite-backed personal reminders delivered by background task
- db: V3 migration for reminders table
- ROADMAP: sync checklist with actual implemented features (verify/moderation/ticket/voice/welcome/blog were already done but unchecked); GitHub webhook -> #changelog closed via native Discord integration (no code)
This commit is contained in:
loki5512344 2026-09-11 12:40:37 +02:00
parent 1d49d81fad
commit 8108f5cd27
Signed by: boba
GPG key ID: 253067914055423B
14 changed files with 290 additions and 11 deletions

View file

@ -12,7 +12,8 @@ pub async fn run(pool: &SqlitePool) -> anyhow::Result<()> {
.execute(pool)
.await?;
let migrations = [("V1__initial", V1_INITIAL), ("V2__tickets", V2_TICKETS)];
let migrations =
[("V1__initial", V1_INITIAL), ("V2__tickets", V2_TICKETS), ("V3__reminders", V3_REMINDERS)];
for (name, sql) in migrations {
let exists: i64 = sqlx::query_scalar("SELECT COUNT(*) FROM _migrations WHERE name = ?")
.bind(name)
@ -65,3 +66,13 @@ CREATE TABLE IF NOT EXISTS tickets (
opener_id TEXT NOT NULL
);
";
const V3_REMINDERS: &str = "
CREATE TABLE IF NOT EXISTS reminders (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id TEXT NOT NULL,
channel_id TEXT NOT NULL,
message TEXT NOT NULL,
due_at TEXT NOT NULL,
sent INTEGER NOT NULL DEFAULT 0
);
";