*_screen.dart · מחולק לפי דומייןsplash_screen
onboarding_screen
age_gate_screen
login_screen
otp_screen
totp_challenge_screen
registration_wizard_screen
profile_setup_screen
unauthorized_screen
matches_screen
match_detail_screen
match_detail_error_screen
match_analysis_screen
room_selection_screen
chat_rooms_screen
sports_selection_screen
broadcast_schedule_screen
chat_screen
chat_media_screen
friend_list_screen
friend_requests_screen
user_discovery_screen
search_screen
notifications_screen
voice_rooms_list_screen
voice_room_screen
voice_call_screen
video_call_screen
incoming_call_screen
call_history_screen
watch_parties_list_screen
watch_party_detail_screen
create_watch_party_screen
pending_invites_screen
prediction_screen
prediction_detail_screen
prediction_history_screen
prediction_leaderboard_screen
leaderboard_screen
battle_pass_screen
missions_screen
badges_screen
achievements_screen
loyalty_screen
referral_screen
feed_screen
personalized_feed_screen
news_feed_screen
news_detail_screen
highlights_screen
create_post_screen
content_creator_screen
teams_browser_screen
my_teams_screen
choose_team_screen
leagues_browser_screen
league_standings_screen
stadium_tour_screen
favorites_screen
sports_selection_screen
profile_screen
edit_profile_screen
stats_overlay_screen
analytics_dashboard_screen
settings_screen
language_screen
notification_settings_screen
privacy_screen
privacy_center_screen
change_password_screen
two_factor_screen
recovery_email_screen
delete_account_screen
device_list_screen
active_sessions_screen
export_data_screen
gdpr_consent_screen
audit_log_screen
data_collection_details_screen
about_screen
terms_screen
safety_center_screen
safety_onboarding_screen
report_illegal_content_screen
my_reports_screen
moderation_review_screen
appeal_submission_screen
admin_audit_logs_screen
admin_moderation_screen
support_inbox_screen
premium_screen
currency_shop_screen
ticketing_merch_screen
my_tickets_screen
ticket_conversation_screen
cost_dashboard_screen
help_center_screen
contact_us_screen
contact_support_screen
support_inbox_screen
archive_screen
ar_experiences_screen
ai_creator_screen
experiments_screen
wearable_setup_screen
widgets_wearables_screen
| ספורט | ליגות / תחרויות מרכזיות | סוג נתונים |
|---|---|---|
| ⚽ כדורגל | Premier League · LaLiga · Serie A · Bundesliga · Champions League · ליגת העל | GoalServe Live |
| 🏀 כדורסל | NBA · Euroleague · ליגה לאומית | נתונים |
| 🎾 טניס | Grand Slams · ATP · WTA | נתונים |
| ⚾ בייסבול | MLB | נתונים |
| 🏈 פוטבול אמריקאי | NFL · NCAA | נתונים |
| 🏒 הוקי | NHL | נתונים |
| ⛳ גולף | PGA Tour · Masters | נתונים |
| 🏏 קריקט | IPL · ICC World Cup · The Ashes | נתונים |
| 🏉 רוגבי | Six Nations · Rugby World Cup | תוכן |
| 🏐 כדורעף | FIVB World Championship · Olympic | תוכן |
| 🥊 איגרוף | WBC · WBA · IBF | תוכן |
| 🥋 MMA | UFC · Bellator · ONE Championship | תוכן |
| 🏎️ מוטורספורט | Formula 1 · MotoGP · NASCAR | תוכן |
| 🚴 רכיבה | Tour de France · Giro d'Italia | תוכן |
| 🏊 שחייה | Olympic Games · World Championships | תוכן |
| 🎮 אספורט | League of Legends · CS2 · Valorant | תוכן |
Flutter 3.41 / Dart 3.11Riverpod 3.2 (@riverpod codegen)go_router 15.1 (typed routes)Drift 2.22 + SQLCipher (E2E encrypt)freezed + json_serializableDart 3 sealed Failure hierarchyvery_good_analysis v10.2.0Supabase (PostgreSQL)33 TypeScript serverlessSupabase Realtime WebSocket89+ טבלאות + RLS policies224 SQL migrationspgTAP — 1,810 assertions / 152 filesStockholm (active) + FrankfurtAgora RTC Engine v6.5.0Firebase Cloud Messaging (FCM)GoalServe API (כדורגל)80+ routes + universal linksShorebird (Dart-only patches)Anthropic Claude→ OpenAI → fallback providerAI classifierPhotoDNA stub + CSAM checksEU AI Act — risk classifiedFirebase AnalyticsFirebase CrashlyticsSentry (org: sportchat-i0)59 GitHub Actions workflows4,110+ (flutter_test + pgTAP)Supabase Auth + Firebase Authlocal_auth (face / fingerprint)TOTP challengeSQLCipher + Agora E2E callsGDPR · DSA · EU AI Actshared/ או core/ בלבד. הפרה = CI נכשל.
| מספר | החלטה | סיבה עיקרית | אלטרנטיבות שנדחו |
|---|---|---|---|
| 001 | Riverpod 3.2 + @riverpod codegen — State Management | Compile-time safe DI, AutoDispose, Stream support ל-Realtime — אין ProviderNotFoundException בprod | BLoC 9, GetX 5, Provider 6 |
| 002 | Drift 2.22 + SQLCipher — Local DB | Typed queries + migrations + E2E encryption — המפתח ב-flutter_secure_storage בלבד | Hive, Sembast, plain SQLite |
| 003 | Supabase — Backend | PostgreSQL + RLS + Realtime + Auth + Storage + Edge Functions — self-hostable, open-source, EU data residency | Firestore, AWS Amplify, custom stack |
| 004 | Agora RTC Engine 6.5 — קריאות קול/וידאו | E2E encrypted, 10k+ CCU, SDK maturity, Agora token generation ב-Edge Function | Zego (stubbed), LiveKit, Daily.co |
| 005 | go_router 15.1 + go_router_builder — Navigation | Type-safe deep links (80+ routes), Shell routes, codegen — אין String paths, אין navigation bugs | AutoRoute, Navigator 2.0 raw |
| 006 | Dart 3 Sealed Failure Hierarchy — Result Pattern | Typed domain errors בלי fpdart dependency, exhaustive switch compile-time safety, 9 sealed failure files | plain try/catch, fpdart Either, AsyncValue.guard-only |
| 007 | Shorebird 2.0.5 — OTA Updates | Dart-only patches בלי App Store review — CI מחסום על native-code changes | CodeMagic OTA, Firebase App Distribution |
| 008 | Stockholm + Frankfurt — 2-Region Supabase | EU data residency (GDPR), failover — Stockholm active, Frankfurt dormant (client plumbing pending) | US-East only, GCP multi-region |
| 009 | Stadium Noir — Design System | Token-based single source (dark_colors.dart), RTL-first, dark broadcast aesthetic עקבי |
Material3 defaults, Cupertino |
| 010 | very_good_analysis 10.2.0 — Lint | strict-casts + strict-inference + strict-raw-types — dynamic=0, print()=0, hardcoded colors=0 | flutter_lints, pedantic |
database/Drift + SQLCipher encryptednetwork/Dio 5.7 + certificate pinssecurity/biometric + TOTP + device revokeobservability/Sentry + SLOs encodedservices/Agora + 8 feature flagsrealtime/Supabase channel multiplexinganalytics/Firebase Analytics eventslogging/Structured logger (no print)error/Failure sealed class hierarchydi/DI container (no GetIt)providers/Core Riverpod providersconstants/API constants + endpointstypes/Domain primitives (RoomId, etc)storage/Secure storage + media cacheextensions/Dart + Flutter extensionsutils/Pure utility functionsinit/App bootstrap + initializationservices/sync/Offline-first sync layerlib/app/theme/dark_colors.dartbackground#050507Primary background — DarkColors.background
surface#0E0E14Cards, sheets — DarkColors.surface
surfaceVariant#1A1A22Variant surface — DarkColors.surfaceVariant
primary#C8FF00⚡ Electric Lime — brand accent
primaryDark#A0CC00Electric Lime dark — pressed/focus
secondary#3D8EFFBrand Blue — secondary accent + info
tertiary / success#28FB94Live green — success + live indicator
warning#FFAC00Amber — alerts, yellow cards
error#FF4757Red — errors, red cards, destructive
textPrimary#F9FAFAPrimary text — DarkColors.textPrimary
textSecondary#9EA2A4Supporting text
borderrgba(249,250,250,0.08)Borders — translucent on dark bg
textOnPrimary#080E12Text on Electric Lime buttons
2 · 4 · 8px12 · 16 · 20px24 · 32 · 40px12px (radiusMd)20px (radiusXl)999px (circle)17px / 5px (asymmetric)@riverpod
class ChatController extends _$ChatController {
@override
Future<ChatState> build(String chatId) async {
// cleanup registered in build() — not dispose()
ref.onDispose(() => _subscription?.cancel());
final repo = ref.watch(chatRepositoryProvider);
return repo.getChatState(chatId);
}
Future<void> sendMessage(String content) async {
state = const AsyncLoading();
state = await AsyncValue.guard(
() => _send(content),
);
}
}
// lib/core/error/failure_base.dart
abstract class Failure {
const Failure(this.message);
final String message;
}
// Sealed sub-hierarchies — exhaustive switch
sealed class DomainFailure extends Failure { ... }
final class DomainNotFoundFailure extends DomainFailure { ... }
final class DomainPermissionFailure extends DomainFailure { ... }
final class DomainInputFailure extends DomainFailure { ... }
sealed class StorageFailure extends Failure { ... }
sealed class NetworkFailure extends Failure { ... } // network_failures.dart
sealed class AuthFailure extends Failure { ... } // auth_failures.dart
sealed class ChatFailure extends Failure { ... } // chat_failures.dart
sealed class CallFailure extends Failure { ... } // call_failures.dart
// UI — Dart 3 exhaustive switch (compile-time safe)
switch (failure) {
DomainNotFoundFailure() => showNotFound(),
DomainPermissionFailure() => showAccessDenied(),
NetworkFailure() => showRetry(),
AuthFailure() => navigateToLogin(),
_ => showGenericError(),
};
// 80+ type-safe deep-link routes
// 12 route group files (part files)
// typed_routes_auth / chat / calls / settings...
// Navigation — אין String paths, אין typos
const SplashRoute().go(context);
MatchDetailRoute(matchId: '123').push(context);
ChatRoute(
roomId: RoomId('abc'),
$extra: chatArgs,
).go(context);
// Deep links — Universal Links + App Links
// sportchat://match/123/analysis
// sportchat://voice-room/789
// sportchat://profile/{userId}
// sportchat://predictions/{matchId}
@freezed
class Match with _$Match {
const factory Match({
required String id,
required String homeTeam,
required String awayTeam,
required DateTime kickoff,
@Default(MatchStatus.upcoming)
MatchStatus status,
// computed field — excluded from JSON
@JsonKey(includeFromJson: false)
String? computedLabel,
}) = _Match;
factory Match.fromJson(Map<String, dynamic> json)
=> _$MatchFromJson(json);
}
dynamic type — strict-casts + strict-inference + strict-raw-types מאכפיםprint() / debugPrint() — structured logger בלבד (core/logging/)EdgeInsets.only(left/right) — EdgeInsetsDirectional בלבד (RTL-first hard limit)dispose() לcontrollers, streams, Supabase channels, Agora engine.env או secrets — --dart-define-from-file בלבד + gitleaks pre-commitlib/app/theme/dark_colors.dart (StadiumColors)release() לפני ש-leaveChannel() מסתיים — mic/camera leakbuild_runner build --delete-conflicting-outputs אחרי כל שינוי ב-@freezed/@riverpodflutter analyze עד 0 issues לפני merge — נוכחי: 0 issues ✅