feat: analytics abstraction with debug backend and game event wiring
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
/// Where events land. Phase 4 ships the debug logger; the Firebase backend
|
||||
/// plugs in here after the owner runs flutterfire configure.
|
||||
abstract class AnalyticsBackend {
|
||||
void logEvent(String name, Map<String, Object> params);
|
||||
}
|
||||
|
||||
class DebugAnalyticsBackend implements AnalyticsBackend {
|
||||
@override
|
||||
void logEvent(String name, Map<String, Object> params) {
|
||||
debugPrint('[analytics] $name $params');
|
||||
}
|
||||
}
|
||||
|
||||
/// Typed event surface. Booleans are sent as 0/1 ints so every backend
|
||||
/// (GA4 included) aggregates them the same way.
|
||||
class AnalyticsService {
|
||||
AnalyticsService(this._backend);
|
||||
|
||||
final AnalyticsBackend _backend;
|
||||
|
||||
void stageStart({required String seasonId, required String stageId}) {
|
||||
_backend.logEvent('stage_start', {
|
||||
'season_id': seasonId,
|
||||
'stage_id': stageId,
|
||||
});
|
||||
}
|
||||
|
||||
void stageEnd({
|
||||
required String seasonId,
|
||||
required String stageId,
|
||||
required bool won,
|
||||
required int stars,
|
||||
required int score,
|
||||
required int movesUsed,
|
||||
}) {
|
||||
_backend.logEvent('stage_end', {
|
||||
'season_id': seasonId,
|
||||
'stage_id': stageId,
|
||||
'won': won ? 1 : 0,
|
||||
'stars': stars,
|
||||
'score': score,
|
||||
'moves_used': movesUsed,
|
||||
});
|
||||
}
|
||||
|
||||
void endlessStart() => _backend.logEvent('endless_start', const {});
|
||||
|
||||
void endlessEnd({required int score, required bool isNewBest}) {
|
||||
_backend.logEvent('endless_end', {
|
||||
'score': score,
|
||||
'new_best': isNewBest ? 1 : 0,
|
||||
});
|
||||
}
|
||||
|
||||
void rescueUsed({required String type}) {
|
||||
_backend.logEvent('rescue_used', {'type': type});
|
||||
}
|
||||
|
||||
void tutorialFinished({required bool skipped}) {
|
||||
_backend.logEvent('tutorial_finished', {'skipped': skipped ? 1 : 0});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user