feat(unionflow): ajout Spec-Kit, constitution, mission mutuelles

- Config Spec-Kit pour Spec-Driven Development
- CONSTITUTION.md + .specify/memory/constitution.md
- Commandes Cursor /speckit.*, règles projet
- Mission: associations + mutuelles d'épargne et de financement
- .gitignore: versionner config spec-kit unionflow

Made-with: Cursor
This commit is contained in:
dahoud
2026-02-27 14:41:07 +00:00
parent 144b68f8e7
commit b1957c1c81
631 changed files with 104070 additions and 0 deletions

View File

@@ -0,0 +1,89 @@
library admin_users_bloc;
import 'package:flutter_bloc/flutter_bloc.dart';
import '../data/models/admin_user_model.dart';
import '../data/repositories/admin_user_repository.dart';
import 'admin_users_event.dart';
import 'admin_users_state.dart';
class AdminUsersBloc extends Bloc<AdminUsersEvent, AdminUsersState> {
final AdminUserRepository _repository;
AdminUsersBloc(this._repository) : super(AdminUsersInitial()) {
on<AdminUsersLoadRequested>(_onLoadRequested);
on<AdminUserDetailRequested>(_onDetailRequested);
on<AdminUserDetailWithRolesRequested>(_onDetailWithRolesRequested);
on<AdminUserRolesUpdateRequested>(_onRolesUpdateRequested);
on<AdminRolesLoadRequested>(_onRolesLoadRequested);
}
Future<void> _onLoadRequested(AdminUsersLoadRequested e, Emitter<AdminUsersState> emit) async {
emit(AdminUsersLoading());
try {
final result = await _repository.search(
page: e.page ?? 0,
size: e.size ?? 20,
search: e.search,
);
emit(AdminUsersLoaded(
users: result.users,
totalCount: result.totalCount,
currentPage: result.currentPage,
pageSize: result.pageSize,
totalPages: result.totalPages,
));
} catch (err) {
emit(AdminUsersError(err.toString()));
}
}
Future<void> _onDetailRequested(AdminUserDetailRequested e, Emitter<AdminUsersState> emit) async {
emit(AdminUsersLoading());
try {
final user = await _repository.getById(e.userId);
if (user == null) {
emit(AdminUsersError('Utilisateur non trouvé'));
return;
}
final roles = await _repository.getUserRoles(e.userId);
emit(AdminUserDetailLoaded(user: user, userRoles: roles));
} catch (err) {
emit(AdminUsersError(err.toString()));
}
}
Future<void> _onDetailWithRolesRequested(AdminUserDetailWithRolesRequested e, Emitter<AdminUsersState> emit) async {
emit(AdminUsersLoading());
try {
final user = await _repository.getById(e.userId);
if (user == null) {
emit(AdminUsersError('Utilisateur non trouvé'));
return;
}
final userRoles = await _repository.getUserRoles(e.userId);
final allRoles = await _repository.getRealmRoles();
emit(AdminUserDetailLoaded(user: user, userRoles: userRoles, allRoles: allRoles));
} catch (err) {
emit(AdminUsersError(err.toString()));
}
}
Future<void> _onRolesUpdateRequested(AdminUserRolesUpdateRequested e, Emitter<AdminUsersState> emit) async {
try {
await _repository.setUserRoles(e.userId, e.roleNames);
emit(AdminUserRolesUpdated());
add(AdminUserDetailWithRolesRequested(e.userId));
} catch (err) {
emit(AdminUsersError(err.toString()));
}
}
Future<void> _onRolesLoadRequested(AdminRolesLoadRequested e, Emitter<AdminUsersState> emit) async {
try {
final roles = await _repository.getRealmRoles();
emit(AdminRolesLoaded(roles));
} catch (err) {
emit(AdminUsersError(err.toString()));
}
}
}

View File

@@ -0,0 +1,29 @@
library admin_users_event;
abstract class AdminUsersEvent {}
class AdminUsersLoadRequested extends AdminUsersEvent {
final int page;
final int size;
final String? search;
AdminUsersLoadRequested({this.page = 0, this.size = 20, this.search});
}
class AdminUserDetailRequested extends AdminUsersEvent {
final String userId;
AdminUserDetailRequested(this.userId);
}
/// Charge détail utilisateur + liste complète des rôles (pour édition)
class AdminUserDetailWithRolesRequested extends AdminUsersEvent {
final String userId;
AdminUserDetailWithRolesRequested(this.userId);
}
class AdminUserRolesUpdateRequested extends AdminUsersEvent {
final String userId;
final List<String> roleNames;
AdminUserRolesUpdateRequested(this.userId, this.roleNames);
}
class AdminRolesLoadRequested extends AdminUsersEvent {}

View File

@@ -0,0 +1,47 @@
library admin_users_state;
import '../data/models/admin_user_model.dart';
abstract class AdminUsersState {}
class AdminUsersInitial extends AdminUsersState {}
class AdminUsersLoading extends AdminUsersState {}
class AdminUsersLoaded extends AdminUsersState {
final List<AdminUserModel> users;
final int totalCount;
final int currentPage;
final int pageSize;
final int totalPages;
AdminUsersLoaded({
required this.users,
required this.totalCount,
required this.currentPage,
required this.pageSize,
required this.totalPages,
});
}
class AdminUsersError extends AdminUsersState {
final String message;
AdminUsersError(this.message);
}
class AdminUserDetailLoaded extends AdminUsersState {
final AdminUserModel user;
final List<AdminRoleModel> userRoles;
final List<AdminRoleModel> allRoles;
AdminUserDetailLoaded({
required this.user,
required this.userRoles,
this.allRoles = const [],
});
}
class AdminRolesLoaded extends AdminUsersState {
final List<AdminRoleModel> roles;
AdminRolesLoaded(this.roles);
}
class AdminUserRolesUpdated extends AdminUsersState {}