manager-service/ManagerService/Data/ApplicationInstance.cs
Thomas Fransolet ea237d2913 Sauvegarde des champs du guide et unicité des canaux par instance
Updateinstance recopiait les champs un par un et n'avait jamais été étendu
aux champs du guide : GuideName, GuidePersonaPrompt, GuideVoiceId,
IsVisitorQuestionCollectionEnabled et GuideFallbackMessages étaient reçus
puis ignorés, donc l'écran Guide IA ne sauvegardait rien. Reprend les mêmes
gardes que Instance.FromDTO.

Rien n'empêchait deux ApplicationInstance du même AppType sur une instance,
alors que manager-app et AiController résolvent tous deux le canal par un
FirstOrDefault sur (InstanceId, AppType) : un doublon rendait le canal
ambigu, l'assistant pouvant s'afficher activé pendant que l'API répondait
Forbid. Ajoute l'index unique et le contrôle en amont dans Create (409).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-14 15:30:47 +02:00

116 lines
3.8 KiB
C#

using Manager.DTOs;
using ManagerService.Data.SubSection;
using ManagerService.DTOs;
using ManagerService.Services;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using Microsoft.EntityFrameworkCore;
namespace ManagerService.Data
{
/// <summary>
/// Defines the link between an application instance and a configuration,
/// allowing apps to use one or multiple configurations.
/// </summary>
[Index(nameof(InstanceId))]
[Index(nameof(InstanceId), nameof(AppType), IsUnique = true)]
public class ApplicationInstance : IAuditableEntity
{
[Key]
public string Id { get; set; }
[Required]
public string InstanceId { get; set; }
public DateTime DateCreation { get; set; }
public DateTime DateUpdate { get; set; }
[Required]
public AppType AppType { get; set; }
public List<AppConfigurationLink> Configurations { get; set; }
public string MainImageId { get; set; } // Specific Mobile et web(?)
public string MainImageUrl { get; set; } // Specific Mobile et web(?)
public string LoaderImageId { get; set; } // Specific Mobile et web
public string LoaderImageUrl { get; set; } // Specific Mobile et web
public string PrimaryColor { get; set; } // Specific Mobile et web
public string SecondaryColor { get; set; } // Specific Mobile et web
public List<string> Languages { get; set; } // All app must support languages, if not, client's problem
public string? SectionEventId { get; set; } // Specific Mobile et web(?)
[ForeignKey("SectionEventId")]
public SectionEvent? SectionEvent { get; set; } // => To Display in large a event with countdown (in mobile app).
public bool IsAssistant { get; set; } = false;
public ApplicationInstanceDTO ToDTO(MyInfoMateDbContext myInfoMateDbContext)
{
SectionEventDTO sectionEventDTO = null;
if (SectionEventId != null)
{
SectionEvent = myInfoMateDbContext.Sections.OfType<SectionEvent>().FirstOrDefault(s => s.Id == SectionEventId);
sectionEventDTO = SectionEvent != null ? SectionFactory.ToDTO(SectionEvent) as SectionEventDTO : null;
}
return new ApplicationInstanceDTO()
{
id = Id,
instanceId = InstanceId,
appType = AppType,
configurations = Configurations,
mainImageId = MainImageId,
mainImageUrl = MainImageUrl,
loaderImageId = LoaderImageId,
loaderImageUrl = LoaderImageUrl,
primaryColor = PrimaryColor,
secondaryColor = SecondaryColor,
languages = Languages,
sectionEventId = SectionEventId,
sectionEventDTO = sectionEventDTO,
isAssistant = IsAssistant
};
}
public ApplicationInstance FromDTO(ApplicationInstanceDTO dto)
{
InstanceId = dto.instanceId;
AppType = dto.appType;
MainImageId = dto.mainImageId;
MainImageUrl = dto.mainImageUrl;
LoaderImageId = dto.loaderImageId;
LoaderImageUrl = dto.loaderImageUrl;
PrimaryColor = dto.primaryColor;
SecondaryColor = dto.secondaryColor;
Languages = dto.languages;
Configurations = dto.configurations;
SectionEventId = dto.sectionEventId;
IsAssistant = dto.isAssistant;
return this;
}
}
public enum AppType
{
Mobile,
Tablet,
Web,
VR,
Voice // Lunettes Ray-Ban Meta / interface vocale — pas de navigation UI
}
}