Stats : lire voiceSessions, et l'aperçu cesse de polluer le rapport du client
_voiceSessions lisait appTypeDistribution['Voice'], qui ne se serait jamais rempli : le vocal est un mode d'interaction, pas une plateforme. Le serveur expose désormais « sessions ayant utilisé le vocal », qui est vrai. Et l'aperçu de conversation du Guide IA journalisait chaque essai comme une question de visiteur : le gestionnaire qui testait sa personnalité polluait son propre onglet « Ce que demandent vos visiteurs » et gonflait le bloc des questions sans réponse. isVisitorQuestion: false. manager_api_new étendu à la main (voiceSessions, renommage isVisitorQuestion). flutter analyze lib sans erreur, flutter build web vert. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
04e73a8832
commit
82cb4cff3e
@ -630,6 +630,10 @@ class _GuideIaScreenState extends State<GuideIaScreen> {
|
||||
instanceId: ctx.instanceId,
|
||||
appType: AppType.Web,
|
||||
language: _editingLanguage,
|
||||
// ⚠️ C'est le gestionnaire qui teste sa personnalité, pas un visiteur qui pose une
|
||||
// question : sans ce drapeau, chaque essai atterrissait dans son propre onglet
|
||||
// « Ce que demandent vos visiteurs » et gonflait le bloc des questions sans réponse.
|
||||
isVisitorQuestion: false,
|
||||
));
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
|
||||
@ -202,8 +202,14 @@ class _StatisticsScreenState extends State<StatisticsScreen> {
|
||||
double _contentsPerVisit(StatsSummaryDTO stats) =>
|
||||
stats.totalSessions == 0 ? 0 : _totalViews(stats) / stats.totalSessions;
|
||||
|
||||
int _voiceSessions(StatsSummaryDTO stats) =>
|
||||
stats.appTypeDistribution[AppType.Voice.name] ?? 0;
|
||||
/// ⚠️ Lisait `appTypeDistribution['Voice']`, qui ne se remplira jamais : **le vocal
|
||||
/// n'est pas une plateforme mais un mode d'interaction**. Un visiteur passe des
|
||||
/// lunettes à l'écran dans une même session, or la distribution ne compte qu'une
|
||||
/// entrée par session, tranchée sur l'événement le plus ancien — le chiffre aurait
|
||||
/// dépendu de l'ordre dans lequel le visiteur a touché ses appareils.
|
||||
///
|
||||
/// Le serveur expose désormais « sessions ayant utilisé le vocal », qui est vrai.
|
||||
int _voiceSessions(StatsSummaryDTO stats) => stats.voiceSessions ?? 0;
|
||||
|
||||
double _voiceShare(StatsSummaryDTO stats) => stats.totalSessions == 0
|
||||
? 0
|
||||
|
||||
@ -21,7 +21,7 @@ class AiChatRequest {
|
||||
this.conversationId,
|
||||
this.history = const [],
|
||||
this.isVoice = false,
|
||||
this.isAutoTriggered = false,
|
||||
this.isVisitorQuestion = true,
|
||||
});
|
||||
|
||||
String? message;
|
||||
@ -50,9 +50,11 @@ class AiChatRequest {
|
||||
/// true = interaction vocale (lunettes) — prompt audio-friendly, pas de navigation
|
||||
bool? isVoice;
|
||||
|
||||
/// true = tour déclenché par le système (mode proactif), pas demandé par le visiteur.
|
||||
/// Le backend compte les jetons mais ne journalise pas la question : elle n'en est pas une.
|
||||
bool? isAutoTriggered;
|
||||
/// false = ce tour n'est pas une question de visiteur (prompt du mode proactif, ou
|
||||
/// gestionnaire testant sa personnalité dans l'aperçu du Guide IA). Le backend compte
|
||||
/// les jetons mais ne journalise rien. Défaut à true : ne pas envoyer le champ revient
|
||||
/// à journaliser, ce qui est le bon comportement pour une app visiteur.
|
||||
bool? isVisitorQuestion;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
@ -117,7 +119,7 @@ class AiChatRequest {
|
||||
json[r'conversationId'] = null;
|
||||
}
|
||||
json[r'isVoice'] = this.isVoice ?? false;
|
||||
json[r'isAutoTriggered'] = this.isAutoTriggered ?? false;
|
||||
json[r'isVisitorQuestion'] = this.isVisitorQuestion ?? true;
|
||||
return json;
|
||||
}
|
||||
|
||||
|
||||
@ -15,6 +15,7 @@ class StatsSummaryDTO {
|
||||
this.visitsByDay = const [],
|
||||
this.languageDistribution = const {},
|
||||
this.appTypeDistribution = const {},
|
||||
this.voiceSessions,
|
||||
this.topPois = const [],
|
||||
this.topAgendaEvents = const [],
|
||||
this.quizStats = const [],
|
||||
@ -30,6 +31,12 @@ class StatsSummaryDTO {
|
||||
List<DayStatDTO> visitsByDay;
|
||||
Map<String, int> languageDistribution;
|
||||
Map<String, int> appTypeDistribution;
|
||||
|
||||
/// Sessions ayant utilisé le vocal au moins une fois. Volontairement **hors** de
|
||||
/// `appTypeDistribution` : le vocal est un mode d'interaction, pas une plateforme —
|
||||
/// une même session mêle la voix et le tactile.
|
||||
int? voiceSessions;
|
||||
|
||||
List<PoiStatDTO> topPois;
|
||||
List<AgendaEventStatDTO> topAgendaEvents;
|
||||
List<QuizStatDTO> quizStats;
|
||||
@ -52,6 +59,7 @@ class StatsSummaryDTO {
|
||||
appTypeDistribution: (json[r'appTypeDistribution'] is Map)
|
||||
? (json[r'appTypeDistribution'] as Map).cast<String, int>()
|
||||
: {},
|
||||
voiceSessions: (json[r'voiceSessions'] as num?)?.toInt(),
|
||||
topPois: PoiStatDTO.listFromJson(json[r'topPois']),
|
||||
topAgendaEvents: AgendaEventStatDTO.listFromJson(json[r'topAgendaEvents']),
|
||||
quizStats: QuizStatDTO.listFromJson(json[r'quizStats']),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user