User feedback + expanded privacy-respecting admin stats
Feedback: - feedback table; POST /api/feedback (anonymous-ok, optional category/email, honeypot + per-day flood cap) stores + emails the admin; GET /api/admin/feedback. - Shared feedback store + FeedbackModal; a speech-bubble opens it from the desktop header, the mobile top bar (logo moves left), the footer, and /account. Feedback section in /admin. Stats (additive, same privacy model — no IP/UA/referrer/raw terms): - Event vocab: summary_viewed (fired on /a load), full_story (card → source), not_today/less_like_this/hide_topic, replace_used/replace_none, paywall_replace, paywalled_source_open. Card title/image opens /a (no double-count); history records via keepalive so it survives the nav. - Dashboard: Accounts card (counts only), reading funnel (summary→source rate), emotional-mix & friction, paywall, returning-visitor buckets. (Health metrics deferred to a future monitoring dashboard.) 131 tests pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -224,6 +224,21 @@ CREATE TABLE IF NOT EXISTS events (
|
||||
CREATE INDEX IF NOT EXISTS idx_events_day ON events(day);
|
||||
CREATE INDEX IF NOT EXISTS idx_events_kind ON events(kind);
|
||||
CREATE INDEX IF NOT EXISTS idx_events_article ON events(article_id);
|
||||
|
||||
-- User feedback (idea / concern / bug / praise). Anonymous-friendly; optional
|
||||
-- contact email only if the person wants a reply. visitor_hash is for rate-limit
|
||||
-- only (the same hashed anonymous token used by analytics).
|
||||
CREATE TABLE IF NOT EXISTS feedback (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
category TEXT NOT NULL DEFAULT 'other',
|
||||
message TEXT NOT NULL,
|
||||
contact_email TEXT,
|
||||
user_id INTEGER REFERENCES users(id) ON DELETE SET NULL,
|
||||
visitor_hash TEXT NOT NULL DEFAULT '',
|
||||
day TEXT NOT NULL,
|
||||
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_feedback_created ON feedback(created_at);
|
||||
"""
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user