Add tarot readings, encrypted quote wall, display name resolution, and uptime reporting

New features:
- !tarot and !tarotspread commands with LLM-powered readings (zodiac-aware)
- !quote system with AES-256-GCM encryption at rest, reply-to-save, search, and quoteboard
- Shared crypto utility (internal/crypto) for AES-256-GCM encrypt/decrypt/HMAC
- ResolveUser now matches display names via room membership as fallback
- !vibe and !tldr show bot uptime when insufficient messages buffered

Bug fixes:
- Fix duplicate quotes table schema that would crash quotewall at runtime
- Fix biased random selection in quote retrieval (use rand.Intn)
- Fix XP rank calculation to handle tied scores with COUNT(DISTINCT xp)
- Scope all leaderboards to room members (repboard, pottyboard, insultboard, firstboard, rankings, emojiboard)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
prosolis
2026-03-10 18:08:05 -07:00
parent 03def6463f
commit 1c02732445
19 changed files with 914 additions and 34 deletions

View File

@@ -303,14 +303,16 @@ CREATE TABLE IF NOT EXISTS achievements (
PRIMARY KEY (user_id, achievement_id)
);
-- Quotes
-- Quotes (encrypted at rest)
CREATE TABLE IF NOT EXISTS quotes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
room_id TEXT NOT NULL,
user_id TEXT NOT NULL,
quote_text TEXT NOT NULL,
saved_by TEXT NOT NULL,
created_at INTEGER DEFAULT (unixepoch())
id INTEGER PRIMARY KEY AUTOINCREMENT,
room_id TEXT NOT NULL,
submitted_by TEXT NOT NULL,
saved_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
content_hmac TEXT NOT NULL UNIQUE,
quote_text BLOB NOT NULL,
attributed_to BLOB NOT NULL,
context BLOB
);
-- Now Playing
@@ -618,6 +620,7 @@ CREATE TABLE IF NOT EXISTS api_cache (
data TEXT NOT NULL,
cached_at INTEGER DEFAULT (unixepoch())
);
`
// SeedSchedulerDefaults inserts default scheduler jobs if they don't exist.