Phase 2 refinements: Firebase config, dev environment fixes, phase 3 requirement draft

- Integrated Firebase SDK in both Flutter apps (google-services, firebase_options)
- Fixed auth flow, API client, and pairing/status blocs for dev environment
- Added full Flutter project scaffolds (android, ios, web, etc.)
- Added phase 3 chat engine requirement document
- Added bugreport zip pattern to gitignore

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-07 19:16:34 +08:00
parent d668112edd
commit 844d7234e6
229 changed files with 10439 additions and 102 deletions

View File

@@ -91,11 +91,10 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
final prefs = await SharedPreferences.getInstance();
final customerId = prefs.getString('anonymous_customer_id');
final displayName = prefs.getString('anonymous_display_name');
final currentUser = _auth.currentUser;
if (_auth.currentUser != null) {
await _verifyAndEmit(emit);
} else if (customerId != null && displayName != null) {
// Check anonymity config
if (currentUser != null && currentUser.isAnonymous && customerId != null && displayName != null) {
// Anonymous Firebase user — restore anonymous state
try {
final config = await apiClient.get('/api/shared/config/anonymity');
final anonymityEnabled = config['data']['anonymity_enabled'] as bool;
@@ -107,6 +106,9 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
} catch (_) {
emit(AuthAnonymous(customerId: customerId, displayName: displayName));
}
} else if (currentUser != null && !currentUser.isAnonymous) {
// Fully registered Firebase user
await _verifyAndEmit(emit);
} else {
emit(AuthInitial());
}
@@ -115,6 +117,10 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
Future<void> _onAnonymousLogin(AnonymousLoginRequested event, Emitter<AuthState> emit) async {
emit(AuthLoading());
try {
// Sign in anonymously with Firebase to get a real JWT
await _auth.signInAnonymously();
// Create/get customer record on backend linked to this Firebase UID
final response = await apiClient.post(
'/api/shared/customer/anonymous',
data: {'display_name': event.displayName},