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

@@ -112,12 +112,12 @@ class UFCard extends StatelessWidget {
switch (style) {
case UFCardStyle.elevated:
return BoxDecoration(
color: color ?? ColorTokens.surface,
color: color ?? AppColors.lightSurface,
borderRadius: BorderRadius.circular(radius),
boxShadow: elevation != null
? [
BoxShadow(
color: ColorTokens.shadow,
color: AppColors.darkBorder.withOpacity(0.1),
blurRadius: elevation!,
offset: const Offset(0, 2),
),
@@ -127,17 +127,17 @@ class UFCard extends StatelessWidget {
case UFCardStyle.outlined:
return BoxDecoration(
color: color ?? ColorTokens.surface,
color: color ?? AppColors.lightSurface,
borderRadius: BorderRadius.circular(radius),
border: Border.all(
color: borderColor ?? ColorTokens.outline,
color: borderColor ?? AppColors.lightBorder,
width: borderWidth ?? 1.0,
),
);
case UFCardStyle.filled:
return BoxDecoration(
color: color ?? ColorTokens.surfaceContainer,
color: color ?? AppColors.lightSurface,
borderRadius: BorderRadius.circular(radius),
);
}

View File

@@ -4,10 +4,7 @@
library uf_info_card;
import 'package:flutter/material.dart';
import '../../tokens/color_tokens.dart';
import '../../tokens/spacing_tokens.dart';
import '../../tokens/typography_tokens.dart';
import '../../tokens/shadow_tokens.dart';
import '../../unionflow_design_system.dart';
/// Card d'information générique
///
@@ -52,13 +49,13 @@ class UFInfoCard extends StatelessWidget {
@override
Widget build(BuildContext context) {
final effectiveIconColor = iconColor ?? ColorTokens.primary;
final effectiveIconColor = iconColor ?? AppColors.primaryGreen;
final effectivePadding = padding ?? const EdgeInsets.all(SpacingTokens.xl);
return Container(
padding: effectivePadding,
decoration: BoxDecoration(
color: ColorTokens.surface,
color: Colors.white,
borderRadius: BorderRadius.circular(SpacingTokens.radiusLg),
boxShadow: ShadowTokens.sm,
),
@@ -73,8 +70,8 @@ class UFInfoCard extends StatelessWidget {
Expanded(
child: Text(
title,
style: TypographyTokens.titleMedium.copyWith(
color: ColorTokens.onSurface,
style: AppTypography.headerSmall.copyWith(
color: AppColors.textPrimaryLight,
),
),
),

View File

@@ -5,8 +5,7 @@ library uf_metric_card;
import 'package:flutter/material.dart';
import '../../tokens/spacing_tokens.dart';
import '../../tokens/typography_tokens.dart';
import '../../unionflow_design_system.dart';
/// Card de métrique système
///
@@ -54,7 +53,7 @@ class UFMetricCard extends StatelessWidget {
const SizedBox(height: SpacingTokens.sm),
Text(
value,
style: TypographyTokens.labelSmall.copyWith(
style: AppTypography.badgeText.copyWith(
fontWeight: FontWeight.bold,
color: Colors.white,
),
@@ -62,7 +61,7 @@ class UFMetricCard extends StatelessWidget {
),
Text(
label,
style: TypographyTokens.labelSmall.copyWith(
style: AppTypography.badgeText.copyWith(
fontSize: 9,
color: Colors.white.withOpacity(0.8),
),

View File

@@ -5,9 +5,7 @@
library uf_stat_card;
import 'package:flutter/material.dart';
import '../../tokens/color_tokens.dart';
import '../../tokens/spacing_tokens.dart';
import '../../tokens/typography_tokens.dart';
import '../../unionflow_design_system.dart';
/// Card de statistiques UnionFlow
///
@@ -57,13 +55,13 @@ class UFStatCard extends StatelessWidget {
@override
Widget build(BuildContext context) {
final effectiveIconColor = iconColor ?? ColorTokens.primary;
final effectiveIconColor = iconColor ?? AppColors.primaryGreen;
final effectiveIconBgColor = iconBackgroundColor ??
effectiveIconColor.withOpacity(0.1);
return Card(
elevation: SpacingTokens.elevationSm,
shadowColor: ColorTokens.shadow,
shadowColor: AppColors.darkBorder.withOpacity(0.1),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(SpacingTokens.radiusLg),
),
@@ -98,7 +96,7 @@ class UFStatCard extends StatelessWidget {
const Icon(
Icons.arrow_forward_ios,
size: 16,
color: ColorTokens.onSurfaceVariant,
color: AppColors.textSecondaryLight,
),
],
),
@@ -108,8 +106,8 @@ class UFStatCard extends StatelessWidget {
// Titre
Text(
title,
style: TypographyTokens.labelLarge.copyWith(
color: ColorTokens.onSurfaceVariant,
style: AppTypography.badgeText.copyWith(
color: AppColors.textSecondaryLight,
),
),
@@ -118,8 +116,8 @@ class UFStatCard extends StatelessWidget {
// Valeur
Text(
value,
style: TypographyTokens.cardValue.copyWith(
color: ColorTokens.onSurface,
style: AppTypography.headerSmall.copyWith(
color: AppColors.textPrimaryLight,
),
),
@@ -128,8 +126,8 @@ class UFStatCard extends StatelessWidget {
const SizedBox(height: SpacingTokens.sm),
Text(
subtitle!,
style: TypographyTokens.bodySmall.copyWith(
color: ColorTokens.onSurfaceVariant,
style: AppTypography.subtitleSmall.copyWith(
color: AppColors.textSecondaryLight,
),
),
],