feat(analytics): opt-in usage analytics with server ingest and settings toggle
- Server: POST /api/analytics endpoint with per-IP rate limit (5/min), batch validation (≤50 events, event_type regex, UUID dedup, clock check), INSERT OR IGNORE for idempotency, and migration 004_analytics.sql - Client (solitaire_data): AnalyticsClient with in-memory Mutex buffer, UUID session_id per launch, async flush via background task - Engine: AnalyticsPlugin records game_won, game_forfeit, game_start, achievement_unlocked; flushes immediately on game-end, every 60 s otherwise - Settings UI: Privacy section with ON/OFF toggle, hidden in local-only mode - Default: analytics_enabled = false (explicit opt-in required) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -243,6 +243,13 @@ pub struct Settings {
|
||||
/// `false` via `#[serde(default)]`.
|
||||
#[serde(default)]
|
||||
pub take_from_foundation: bool,
|
||||
/// When `true`, anonymous game-play events (game start, game won, etc.)
|
||||
/// are sent to the configured sync server for aggregate analytics. Opt-in;
|
||||
/// defaults to `false`. Only active when `sync_backend` is
|
||||
/// `SolitaireServer`. Older `settings.json` files deserialize cleanly to
|
||||
/// `false` via `#[serde(default)]`.
|
||||
#[serde(default)]
|
||||
pub analytics_enabled: bool,
|
||||
}
|
||||
|
||||
fn default_draw_mode() -> DrawMode {
|
||||
@@ -364,6 +371,7 @@ impl Default for Settings {
|
||||
last_difficulty: None,
|
||||
leaderboard_display_name: None,
|
||||
take_from_foundation: false,
|
||||
analytics_enabled: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user