Files
social-app/.trellis/spec/frontend/hook-guidelines.md
T

2.6 KiB

Hook Guidelines (Bloc/Cubit State Flows)

This repository is Flutter-based. This file defines state-flow conventions using Bloc/Cubit.


Practical Conventions

  1. Treat AuthBloc as the global auth source of truth; auth invalidation should flow through its event chain.
  2. Keep Cubit/Bloc states immutable and updated via copyWith.
  3. Catch-and-handle branches should log errors with module-scoped logger names.
  4. For async flow handoff (auth/session switch, SSE stream lifecycle), ensure race ordering is explicit (queues/epoch tokens/cancel semantics).

Real File Path Examples

  • Auth state source of truth and transitions:
    • apps/lib/features/auth/presentation/bloc/auth_bloc.dart
    • apps/lib/features/auth/presentation/bloc/auth_event.dart
    • apps/lib/features/auth/presentation/bloc/auth_state.dart
  • Feature-local form/interaction state:
    • apps/lib/features/auth/presentation/cubits/login_cubit.dart
    • apps/lib/features/settings/presentation/cubits/automation_jobs_cubit.dart
  • Multi-step async orchestration with explicit stream/session control:
    • apps/lib/features/chat/presentation/bloc/chat_bloc.dart
    • apps/lib/core/chat/ag_ui_service.dart
    • apps/lib/app/app.dart

State-Flow Checklist

Before adding/changing state logic:

  1. Is state ownership clear (global vs feature-local)?
  2. Are transitions serialized when order matters?
  3. Are recoverable failures surfaced to UI state and logged?
  4. Are side effects (cache reset, prewarm, SSE cancel/restart) bound to lifecycle events, not random UI callbacks?

Anti-patterns (with evidence)

  • Feature-level auth reset/navigation bypassing global auth flow.
    • Correct path: ApiClient auth-failure callback -> AuthSessionInvalidated event (apps/lib/app/di/injection.dart, apps/lib/features/auth/presentation/bloc/auth_bloc.dart).
  • Silent exception handling in async orchestration.
    • Existing weak branches to avoid copying:
      • apps/lib/app/di/injection.dart refresh callback catches and returns false without structured logging.
      • apps/lib/core/chat/ag_ui_service.dart ignores malformed SSE payload parsing errors by design.
  • Emitting mutable/partially-updated state objects.
    • Current state classes use immutable fields + copyWith (LoginState, ChatState, AutomationJobsState).

Uncertainties / Gaps

  • The codebase uses both Bloc and Cubit; exact selection criteria (when to pick Bloc vs Cubit) are not formally codified beyond existing patterns.
  • Some cancellation/retry branches return error strings directly (e.g., chat flow) and may need future standardization if UX/error taxonomy requirements tighten.