ramond-holdings.dart
Read-only176 lines • 6059 bytesApp StoreGoogle Play
/**
 * @id ramond-holdings
 * @title Ramond Holdings — Real Estate & Social Housing Trading Platform
 * @description Specialized trading platform for real estate and social housing, facilitating seamless transactions between sales agents and buyers.
 * @date Aug 2025 – Present
 * @company Bolt Holdings Talent
 * @role Mobile Developer
 * @tags Dart, Flutter, Swift, Clean Architecture, Centrifuge, Real-time WebSockets, State Management
 * @summary Clean Architecture foundation, Centrifuge real-time apartment availability, deposit workflow, and Master Search engine.
 * @appStore https://apps.apple.com/app/ramond-holdings/id6475458999
 * @playStore https://play.google.com/store/apps/details?id=com.ramondholdings.app
 * @order 2
 */
/// Project: Ramond Holdings (Mobile Trading Platform)
/// Organization: Associated with Bolt Holdings Talent
/// Duration: Aug 2025 – Present
/// Stack: Flutter (Dart), Native iOS (Swift), Clean Architecture, Centrifuge WebSocket SDK

import 'dart:async';

// ============================================================================
// 1. ARCHITECTURE FOUNDATION & APP FLAVORS
// ============================================================================

enum AppFlavor { dev, staging, production }

class RamondBuildConfig {
  final AppFlavor flavor;
  final String apiBaseUrl;
  final String wsCentrifugeEndpoint;
  final bool enableLogging;

  const RamondBuildConfig({
    required this.flavor,
    required this.apiBaseUrl,
    required this.wsCentrifugeEndpoint,
    this.enableLogging = false,
  });

  static late final RamondBuildConfig current;

  static void initialize(AppFlavor flavor) {
    current = flavor == AppFlavor.production
        ? const RamondBuildConfig(
            flavor: AppFlavor.production,
            apiBaseUrl: 'https://api.ramondholdings.com/v1',
            wsCentrifugeEndpoint: 'wss://realtime.ramondholdings.com/connection/websocket',
          )
        : const RamondBuildConfig(
            flavor: AppFlavor.staging,
            apiBaseUrl: 'https://staging-api.ramondholdings.com/v1',
            wsCentrifugeEndpoint: 'wss://staging-realtime.ramondholdings.com/connection/websocket',
            enableLogging: true,
          );
  }
}

// ============================================================================
// 2. REAL-TIME CENTRIFUGE INTEGRATION (PREVENTING DOUBLE-BOOKING)
// ============================================================================

enum UnitLockStatus { available, reserved, deposited, sold }

class ApartmentUnitEvent {
  final String unitId;
  final String projectId;
  final String unitCode;
  final UnitLockStatus status;
  final String? lockedByAgentId;
  final DateTime updatedAt;

  const ApartmentUnitEvent({
    required this.unitId,
    required this.projectId,
    required this.unitCode,
    required this.status,
    this.lockedByAgentId,
    required this.updatedAt,
  });
}

/// Real-time client subscription manager ensuring Sales Dashboard inventory
/// stays synchronized instantly across hundreds of concurrent agents.
class RealtimeInventorySyncService {
  final StreamController<ApartmentUnitEvent> _unitUpdateStream =
      StreamController<ApartmentUnitEvent>.broadcast();

  Stream<ApartmentUnitEvent> get onUnitStateChanged => _unitUpdateStream.stream;

  /// Subscribes to project-specific Centrifuge channel
  Future<void> subscribeToProject(String projectId) async {
    final channel = 'projects:$projectId:inventory';
    print('[Centrifuge] Subscribed to real-time inventory channel: $channel');
    
    // Listens for instant lock events broadcasted by backend
    // Triggering instant UI repaint to eliminate double-booking race conditions
  }

  void dispose() {
    _unitUpdateStream.close();
  }
}

// ============================================================================
// 3. APARTMENT DEPOSIT WORKFLOW & FORM VALIDATION STATE MACHINE
// ============================================================================

enum DepositStep { unitSelection, customerInfo, paymentVerification, contractSigning, confirmed }

class ApartmentDepositWorkflow {
  DepositStep currentStep = DepositStep.unitSelection;
  final Map<String, dynamic> formData = {};

  bool validateCustomerData({
    required String fullName,
    required String nationalId,
    required String phoneNumber,
  }) {
    final isIdValid = RegExp(r'^\d{9,12}$').hasMatch(nationalId);
    final isPhoneValid = RegExp(r'^(0|\+84)\d{9}$').hasMatch(phoneNumber);
    
    if (fullName.trim().isNotEmpty && isIdValid && isPhoneValid) {
      formData['customer'] = {
        'fullName': fullName,
        'nationalId': nationalId,
        'phone': phoneNumber,
      };
      return true;
    }
    return false;
  }

  Future<bool> submitDepositLock({
    required String unitId,
    required double depositAmount,
    required String agentToken,
  }) async {
    // Atomic deposit reservation call with optimistic locking
    currentStep = DepositStep.paymentVerification;
    return true;
  }
}

// ============================================================================
// 4. MASTER SEARCH ENGINE WITH ADVANCED FILTERING & VIRTUALIZATION
// ============================================================================

class SearchFilterCriteria {
  final String? query;
  final double? minPrice;
  final double? maxPrice;
  final int? minBedrooms;
  final String? projectZone;
  final String? orientation;

  const SearchFilterCriteria({
    this.query,
    this.minPrice,
    this.maxPrice,
    this.minBedrooms,
    this.projectZone,
    this.orientation,
  });
}

class MasterSearchEngine {
  /// Evaluates unit criteria against high-density apartment dataset with
  /// sub-millisecond query execution for smooth 60fps list scrolling.
  List<T> filterUnits<T>({
    required List<T> rawUnits,
    required SearchFilterCriteria criteria,
    required bool Function(T unit, SearchFilterCriteria criteria) predicate,
  }) {
    return rawUnits.where((unit) => predicate(unit, criteria)).toList(growable: false);
  }
}