feat: WebSocket temps réel + Finance Workflow + corrections

- Task #6: WebSocket /ws/dashboard + Kafka events (5 topics)
  * Backend: KafkaEventProducer, KafkaEventConsumer
  * Mobile: WebSocketService (reconnection, heartbeat, typed events)
  * DashboardBloc: Auto-refresh depuis WebSocket events

- Finance Workflow: approbations + budgets (backend + mobile)
  * Backend: entities, services, resources, migrations Flyway V6
  * Mobile: features finance_workflow complète avec BLoC

- Corrections DI: interfaces IRepository partout
  * IProfileRepository, IOrganizationRepository, IMembreRepository
  * GetIt configuré avec @injectable

- Spec-Kit: constitution + templates mis à jour
  * .specify/memory/constitution.md enrichie
  * Templates agent, plan, spec, tasks, checklist

- Nettoyage: fichiers temporaires supprimés

Signed-off-by: lions dev Team
This commit is contained in:
dahoud
2026-03-15 02:12:17 +00:00
parent bbc409de9d
commit e8ad874015
635 changed files with 58160 additions and 20674 deletions

View File

@@ -3,15 +3,40 @@ library membres_bloc;
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:dio/dio.dart';
import 'package:injectable/injectable.dart';
import 'membres_event.dart';
import 'membres_state.dart';
import '../data/repositories/membre_repository_impl.dart';
import '../domain/usecases/get_members.dart';
import '../domain/usecases/get_member_by_id.dart';
import '../domain/usecases/create_member.dart' as uc;
import '../domain/usecases/update_member.dart' as uc;
import '../domain/usecases/delete_member.dart' as uc;
import '../domain/usecases/search_members.dart';
import '../domain/usecases/get_member_stats.dart';
import '../domain/repositories/membre_repository.dart';
/// BLoC pour la gestion des membres
/// BLoC pour la gestion des membres (Clean Architecture)
@injectable
class MembresBloc extends Bloc<MembresEvent, MembresState> {
final MembreRepository _repository;
final GetMembers _getMembers;
final GetMemberById _getMemberById;
final uc.CreateMember _createMember;
final uc.UpdateMember _updateMember;
final uc.DeleteMember _deleteMember;
final SearchMembers _searchMembers;
final GetMemberStats _getMemberStats;
final IMembreRepository _repository; // Pour méthodes non-couvertes par use cases
MembresBloc(this._repository) : super(const MembresInitial()) {
MembresBloc(
this._getMembers,
this._getMemberById,
this._createMember,
this._updateMember,
this._deleteMember,
this._searchMembers,
this._getMemberStats,
this._repository,
) : super(const MembresInitial()) {
on<LoadMembres>(_onLoadMembres);
on<LoadMembreById>(_onLoadMembreById);
on<CreateMembre>(_onCreateMembre);
@@ -39,7 +64,7 @@ class MembresBloc extends Bloc<MembresEvent, MembresState> {
emit(const MembresLoading());
}
final result = await _repository.getMembres(
final result = await _getMembers(
page: event.page,
size: event.size,
recherche: event.recherche,
@@ -74,7 +99,7 @@ class MembresBloc extends Bloc<MembresEvent, MembresState> {
try {
emit(const MembresLoading());
final membre = await _repository.getMembreById(event.id);
final membre = await _getMemberById(event.id);
if (membre != null) {
emit(MembreDetailLoaded(membre));
@@ -106,7 +131,7 @@ class MembresBloc extends Bloc<MembresEvent, MembresState> {
try {
emit(const MembresLoading());
final membre = await _repository.createMembre(event.membre);
final membre = await _createMember(event.membre);
emit(MembreCreated(membre));
} on DioException catch (e) {
@@ -141,7 +166,7 @@ class MembresBloc extends Bloc<MembresEvent, MembresState> {
try {
emit(const MembresLoading());
final membre = await _repository.updateMembre(event.id, event.membre);
final membre = await _updateMember(event.id, event.membre);
emit(MembreUpdated(membre));
} on DioException catch (e) {
@@ -175,7 +200,7 @@ class MembresBloc extends Bloc<MembresEvent, MembresState> {
try {
emit(const MembresLoading());
await _repository.deleteMembre(event.id);
await _deleteMember(event.id);
emit(MembreDeleted(event.id));
} on DioException catch (e) {
@@ -250,7 +275,7 @@ class MembresBloc extends Bloc<MembresEvent, MembresState> {
try {
emit(const MembresLoading());
final result = await _repository.searchMembres(
final result = await _searchMembers(
criteria: event.criteria,
page: event.page,
size: event.size,
@@ -353,7 +378,7 @@ class MembresBloc extends Bloc<MembresEvent, MembresState> {
try {
emit(const MembresLoading());
final stats = await _repository.getMembresStats();
final stats = await _getMemberStats();
emit(MembresStatsLoaded(stats));
} on DioException catch (e) {