Thomas Fransolet 7625487806 Lot B : geler le schéma, plus sécurité rapide et calculateur de stockage
LOT B — une seule migration EF (LotB_FreezeSchema) :
- SectionMap.MapResourceId → IconResourceId. L'écart (g) de la bascule tombe
  avec. Il fallait renommer aussi la propriété de navigation MapResource :
  la convention EF l'appariait au FK, la laisser aurait fabriqué un FK
  fantôme. Elle n'était utilisée nulle part ailleurs.
- SectionEvent.ParcoursIds supprimé (champ, DTO, SectionFactory, et une
  initialisation dans un montage de test).
- Instance.IsImageWatermark remplace le `instanceId == "633ee379…"` en dur
  de ResourceController.

EF a généré un RenameColumn, pas un drop+add : les icônes déjà configurées
survivent. L'avertissement de perte de données ne porte que sur le DropColumn
de ParcoursIds, ce qui est l'intention.

Non fait, et c'était une erreur de doc : « supprimer SectionEvent.IconResourceId ».
Ce champ n'existe pas — la ligne visée appartient à la classe imbriquée
MapAnnotation, partagée par SectionEvent, SectionAgenda et SectionMap, lue par
cinq contrôleurs et par GetReferencedResourceIds. La supprimer aurait cassé
les icônes d'annotation des trois types et la collecte offline.

SÉCURITÉ (lot A, même repo) :
- AuthenticationController.Authenticate : un bloc #if DEBUG écrasait l'email
  et le mot de passe reçus par un compte de test, donc toute compilation en
  Debug authentifiait n'importe quelle saisie. Retiré.
- EnableSensitiveDataLogging (qui écrit les valeurs des paramètres dans les
  logs) passe sous #if DEBUG, l'idiome déjà employé dans Startup.cs pour le
  CORS et Hangfire. Le Dockerfile publiant en -c Release, c'est un verrou réel.

LOT C1 :
- Calculateur StoragePath/SizeBytes extrait dans Helpers/ResourceStorage.cs,
  avec 13 tests fixant l'invariant des types URL. Il ferme le lien L5 : le
  backfill (C2) et l'écart (e) de la migration appelleront le même code.
- L'extraction a révélé la divergence qu'elle devait empêcher : des deux
  chemins de création de ResourceController, le chemin multipart écrivait
  SizeBytes mais laissait StoragePath nul.

dotnet build Debug et Release verts, dotnet test 143/143 (130 + 13).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 15:32:19 +02:00

790 lines
36 KiB
C#

using Manager.DTOs;
using ManagerService.Data;
using ManagerService.Data.SubSection;
using ManagerService.DTOs;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
namespace ManagerService.Services
{
public static class SectionFactory
{
/// <summary>
/// Sous-type concret vide, collections initialisées. Section étant abstraite,
/// c'est le seul point d'entrée pour créer une section dont on n'a que le type.
/// </summary>
public static Section CreateEmpty(SectionType type) => type switch
{
SectionType.Agenda => new SectionAgenda
{
AgendaResourceIds = new List<TranslationDTO>(),
EventAgendas = new List<EventAgenda>()
},
SectionType.Article => new SectionArticle
{
ArticleContents = new List<ContentDTO>(),
ArticleContent = new List<TranslationDTO>(),
ArticleAudioIds = new List<TranslationDTO>()
},
SectionType.Event => new SectionEvent
{
Programme = new List<SectionEvent.ProgrammeBlock>()
},
SectionType.Map => new SectionMap
{
MapMapType = MapTypeApp.hybrid,
MapTypeMapbox = MapTypeMapBox.standard,
MapMapProvider = MapProvider.Google,
MapZoom = 18,
MapPoints = new List<GeoPoint>(),
MapCategories = new List<CategorieDTO>()
},
SectionType.Menu => new SectionMenu { MenuSections = new List<Section>() },
SectionType.PDF => new SectionPdf { PDFOrderedTranslationAndResources = new List<OrderedTranslationAndResourceDTO>() },
SectionType.Game => new SectionGame
{
GameMessageDebut = new List<TranslationAndResourceDTO>(),
GameMessageFin = new List<TranslationAndResourceDTO>()
},
SectionType.Quiz => new SectionQuiz { QuizQuestions = new List<QuizQuestion>() },
SectionType.Slider => new SectionSlider { SliderContents = new List<ContentDTO>() },
SectionType.Video => new SectionVideo { VideoSource = "" },
SectionType.Weather => new SectionWeather(),
SectionType.Web => new SectionWeb { WebSource = "" },
SectionType.Parcours => new SectionParcours { GuidedPaths = new List<GuidedPath>() },
_ => throw new NotImplementedException($"Section type not handled: {type}")
};
public static Section Create(JsonElement jsonElement, SectionDTO dto)
{
AgendaDTO agendaDTO = new AgendaDTO();
ArticleDTO articleDTO = new ArticleDTO();
SectionEventDTO sectionEventDTO = new SectionEventDTO();
MapDTO mapDTO = new MapDTO();
MenuDTO menuDTO = new MenuDTO();
PdfDTO pdfDTO = new PdfDTO();
GameDTO puzzleDTO = new GameDTO();
QuizDTO quizDTO = new QuizDTO();
SliderDTO sliderDTO = new SliderDTO();
VideoDTO videoDTO = new VideoDTO();
WeatherDTO weatherDTO = new WeatherDTO();
WebDTO webDTO = new WebDTO();
ParcoursDTO parcoursDTO = new ParcoursDTO();
switch (dto.type)
{
case SectionType.Agenda:
agendaDTO = JsonConvert.DeserializeObject<AgendaDTO>(jsonElement.ToString());
break;
case SectionType.Article:
articleDTO = JsonConvert.DeserializeObject<ArticleDTO>(jsonElement.ToString());
break;
case SectionType.Event:
sectionEventDTO = JsonConvert.DeserializeObject<SectionEventDTO>(
jsonElement.ToString(),
new JsonSerializerSettings { Error = (_, args) => args.ErrorContext.Handled = true }
);
break;
case SectionType.Map:
mapDTO = JsonConvert.DeserializeObject<MapDTO>(jsonElement.ToString());
break;
case SectionType.Menu:
menuDTO = JsonConvert.DeserializeObject<MenuDTO>(jsonElement.ToString());
break;
case SectionType.PDF:
pdfDTO = JsonConvert.DeserializeObject<PdfDTO>(jsonElement.ToString());
break;
case SectionType.Game:
puzzleDTO = JsonConvert.DeserializeObject<GameDTO>(jsonElement.ToString());
break;
case SectionType.Quiz:
quizDTO = JsonConvert.DeserializeObject<QuizDTO>(jsonElement.ToString());
break;
case SectionType.Slider:
sliderDTO = JsonConvert.DeserializeObject<SliderDTO>(jsonElement.ToString());
break;
case SectionType.Video:
videoDTO = JsonConvert.DeserializeObject<VideoDTO>(jsonElement.ToString());
break;
case SectionType.Weather:
weatherDTO = JsonConvert.DeserializeObject<WeatherDTO>(jsonElement.ToString());
break;
case SectionType.Web:
webDTO = JsonConvert.DeserializeObject<WebDTO>(jsonElement.ToString());
break;
case SectionType.Parcours:
parcoursDTO = JsonConvert.DeserializeObject<ParcoursDTO>(jsonElement.ToString());
break;
}
return dto.type switch
{
SectionType.Agenda => new SectionAgenda
{
Id = dto.id,
DateCreation = dto.dateCreation.Value,
ConfigurationId = dto.configurationId,
InstanceId = dto.instanceId,
Label = dto.label,
Title = dto.title,
Description = dto.description,
Order = dto.order.Value,
ImageId = dto.imageId,
ImageSource = dto.imageSource,
IsSubSection = dto.isSubSection,
ParentId = dto.parentId,
IsBeacon = dto.isBeacon,
BeaconId = dto.beaconId,
Latitude = dto.latitude,
Longitude = dto.longitude,
MeterZoneGPS = dto.meterZoneGPS,
Type = dto.type,
IsOnlineAgenda = agendaDTO.isOnlineAgenda,
AgendaResourceIds = agendaDTO.resourceIds,
AgendaMapProvider = agendaDTO.agendaMapProvider,
//EventAgendas = // TODO specific
},
SectionType.Article => new SectionArticle
{
Id = dto.id,
DateCreation = dto.dateCreation.Value,
ConfigurationId = dto.configurationId,
InstanceId = dto.instanceId,
Label = dto.label,
Title = dto.title,
Description = dto.description,
Order = dto.order.Value,
ImageId = dto.imageId,
ImageSource = dto.imageSource,
IsSubSection = dto.isSubSection,
ParentId = dto.parentId,
IsBeacon = dto.isBeacon,
BeaconId = dto.beaconId,
Latitude = dto.latitude,
Longitude = dto.longitude,
MeterZoneGPS = dto.meterZoneGPS,
Type = dto.type,
ArticleContent = articleDTO.content,
ArticleIsContentTop = articleDTO.isContentTop,
ArticleAudioIds = articleDTO.audioIds,
ArticleIsReadAudioAuto = articleDTO.isReadAudioAuto,
ArticleContents = articleDTO.contents
},
SectionType.Event => new SectionEvent
{
Id = dto.id,
DateCreation = dto.dateCreation.Value,
ConfigurationId = dto.configurationId,
InstanceId = dto.instanceId,
Label = dto.label,
Title = dto.title,
Description = dto.description,
Order = dto.order.Value,
ImageId = dto.imageId,
ImageSource = dto.imageSource,
IsSubSection = dto.isSubSection,
ParentId = dto.parentId,
IsBeacon = dto.isBeacon,
BeaconId = dto.beaconId,
Latitude = dto.latitude,
Longitude = dto.longitude,
MeterZoneGPS = dto.meterZoneGPS,
Type = dto.type,
StartDate = sectionEventDTO.StartDate?.ToUniversalTime(),
EndDate = sectionEventDTO.EndDate?.ToUniversalTime(),
BaseSectionMapId = sectionEventDTO.BaseSectionMapId,
//Programmes = // TODO specific
},
SectionType.Map => new SectionMap
{
Id = dto.id,
DateCreation = dto.dateCreation.Value,
ConfigurationId = dto.configurationId,
InstanceId = dto.instanceId,
Label = dto.label,
Title = dto.title,
Description = dto.description,
Order = dto.order.Value,
ImageId = dto.imageId,
ImageSource = dto.imageSource,
IsSubSection = dto.isSubSection,
ParentId = dto.parentId,
IsBeacon = dto.isBeacon,
BeaconId = dto.beaconId,
Latitude = dto.latitude,
Longitude = dto.longitude,
MeterZoneGPS = dto.meterZoneGPS,
Type = dto.type,
MapZoom = mapDTO.zoom ?? 18,
MapMapType = mapDTO.mapType,
MapTypeMapbox = mapDTO.mapTypeMapbox,
MapMapProvider = mapDTO.mapProvider,
IconResourceId = mapDTO.iconResourceId,
MapCenterLatitude = mapDTO.centerLatitude,
MapCenterLongitude = mapDTO.centerLongitude,
MapCategories = mapDTO.categories,
IsListViewEnabled = mapDTO.isListViewEnabled
},
SectionType.Menu => new SectionMenu
{
Id = dto.id,
DateCreation = dto.dateCreation.Value,
ConfigurationId = dto.configurationId,
InstanceId = dto.instanceId,
Label = dto.label,
Title = dto.title,
Description = dto.description,
Order = dto.order.Value,
ImageId = dto.imageId,
ImageSource = dto.imageSource,
IsSubSection = dto.isSubSection,
ParentId = dto.parentId,
IsBeacon = dto.isBeacon,
BeaconId = dto.beaconId,
Latitude = dto.latitude,
Longitude = dto.longitude,
MeterZoneGPS = dto.meterZoneGPS,
Type = dto.type,
//Sections = ((MenuDTO)dto).sections, // TODO specific
},
SectionType.PDF => new SectionPdf
{
Id = dto.id,
DateCreation = dto.dateCreation.Value,
ConfigurationId = dto.configurationId,
InstanceId = dto.instanceId,
Label = dto.label,
Title = dto.title,
Description = dto.description,
Order = dto.order.Value,
ImageId = dto.imageId,
ImageSource = dto.imageSource,
IsSubSection = dto.isSubSection,
ParentId = dto.parentId,
IsBeacon = dto.isBeacon,
BeaconId = dto.beaconId,
Latitude = dto.latitude,
Longitude = dto.longitude,
MeterZoneGPS = dto.meterZoneGPS,
Type = dto.type,
PDFOrderedTranslationAndResources = pdfDTO.pdfs
},
SectionType.Game => new SectionGame
{
Id = dto.id,
DateCreation = dto.dateCreation.Value,
ConfigurationId = dto.configurationId,
InstanceId = dto.instanceId,
Label = dto.label,
Title = dto.title,
Description = dto.description,
Order = dto.order.Value,
ImageId = dto.imageId,
ImageSource = dto.imageSource,
IsSubSection = dto.isSubSection,
ParentId = dto.parentId,
IsBeacon = dto.isBeacon,
BeaconId = dto.beaconId,
Latitude = dto.latitude,
Longitude = dto.longitude,
MeterZoneGPS = dto.meterZoneGPS,
Type = dto.type,
GameMessageDebut = puzzleDTO.messageDebut,
GameMessageFin = puzzleDTO.messageFin,
GamePuzzleImageId = puzzleDTO.puzzleImageId,
GamePuzzleRows = puzzleDTO.rows,
GamePuzzleCols = puzzleDTO.cols,
GameType = puzzleDTO.gameType,
},
SectionType.Quiz => new SectionQuiz
{
Id = dto.id,
DateCreation = dto.dateCreation.Value,
ConfigurationId = dto.configurationId,
InstanceId = dto.instanceId,
Label = dto.label,
Title = dto.title,
Description = dto.description,
Order = dto.order.Value,
ImageId = dto.imageId,
ImageSource = dto.imageSource,
IsSubSection = dto.isSubSection,
ParentId = dto.parentId,
IsBeacon = dto.isBeacon,
BeaconId = dto.beaconId,
Latitude = dto.latitude,
Longitude = dto.longitude,
MeterZoneGPS = dto.meterZoneGPS,
Type = dto.type,
QuizBadLevel = quizDTO.bad_level,
QuizMediumLevel = quizDTO.medium_level,
QuizGoodLevel = quizDTO.good_level,
QuizGreatLevel = quizDTO.great_level,
//Questions = ((QuizDTO)dto).questions, // TODO specific
},
SectionType.Slider => new SectionSlider
{
Id = dto.id,
DateCreation = dto.dateCreation.Value,
ConfigurationId = dto.configurationId,
InstanceId = dto.instanceId,
Label = dto.label,
Title = dto.title,
Description = dto.description,
Order = dto.order.Value,
ImageId = dto.imageId,
ImageSource = dto.imageSource,
IsSubSection = dto.isSubSection,
ParentId = dto.parentId,
IsBeacon = dto.isBeacon,
BeaconId = dto.beaconId,
Latitude = dto.latitude,
Longitude = dto.longitude,
MeterZoneGPS = dto.meterZoneGPS,
Type = dto.type,
SliderContents = sliderDTO.contents, // TODO TEST
},
SectionType.Video => new SectionVideo
{
Id = dto.id,
DateCreation = dto.dateCreation.Value,
ConfigurationId = dto.configurationId,
InstanceId = dto.instanceId,
Label = dto.label,
Title = dto.title,
Description = dto.description,
Order = dto.order.Value,
ImageId = dto.imageId,
ImageSource = dto.imageSource,
IsSubSection = dto.isSubSection,
ParentId = dto.parentId,
IsBeacon = dto.isBeacon,
BeaconId = dto.beaconId,
Latitude = dto.latitude,
Longitude = dto.longitude,
MeterZoneGPS = dto.meterZoneGPS,
Type = dto.type,
VideoSource = videoDTO.source,
},
SectionType.Weather => new SectionWeather
{
Id = dto.id,
DateCreation = dto.dateCreation.Value,
ConfigurationId = dto.configurationId,
InstanceId = dto.instanceId,
Label = dto.label,
Title = dto.title,
Description = dto.description,
Order = dto.order.Value,
ImageId = dto.imageId,
ImageSource = dto.imageSource,
IsSubSection = dto.isSubSection,
ParentId = dto.parentId,
IsBeacon = dto.isBeacon,
BeaconId = dto.beaconId,
Latitude = dto.latitude,
Longitude = dto.longitude,
MeterZoneGPS = dto.meterZoneGPS,
Type = dto.type,
WeatherCity = weatherDTO.city,
WeatherUpdatedDate = weatherDTO.updatedDate,
WeatherResult = weatherDTO.result
},
SectionType.Web => new SectionWeb
{
Id = dto.id,
DateCreation = dto.dateCreation.Value,
ConfigurationId = dto.configurationId,
InstanceId = dto.instanceId,
Label = dto.label,
Title = dto.title,
Description = dto.description,
Order = dto.order.Value,
ImageId = dto.imageId,
ImageSource = dto.imageSource,
IsSubSection = dto.isSubSection,
ParentId = dto.parentId,
IsBeacon = dto.isBeacon,
BeaconId = dto.beaconId,
Latitude = dto.latitude,
Longitude = dto.longitude,
MeterZoneGPS = dto.meterZoneGPS,
Type = dto.type,
WebSource = webDTO.source,
},
SectionType.Parcours => new SectionParcours
{
Id = dto.id,
DateCreation = dto.dateCreation.Value,
ConfigurationId = dto.configurationId,
InstanceId = dto.instanceId,
Label = dto.label,
Title = dto.title,
Description = dto.description,
Order = dto.order.Value,
ImageId = dto.imageId,
ImageSource = dto.imageSource,
IsSubSection = dto.isSubSection,
ParentId = dto.parentId,
IsBeacon = dto.isBeacon,
BeaconId = dto.beaconId,
Latitude = dto.latitude,
Longitude = dto.longitude,
MeterZoneGPS = dto.meterZoneGPS,
Type = dto.type,
ShowMap = parcoursDTO.showMap,
BaseSectionMapId = parcoursDTO.baseSectionMapId,
},
_ => throw new NotImplementedException("Section type not handled")
};
}
public static object ToDTO(Section section)
{
// TODO retrieve specific elements ?
return section switch
{
SectionAgenda agenda => new AgendaDTO
{
id = agenda.Id,
dateCreation = agenda.DateCreation,
configurationId = agenda.ConfigurationId,
instanceId = agenda.InstanceId,
label = agenda.Label,
title = agenda.Title,
description = agenda.Description,
order = agenda.Order,
imageId = agenda.ImageId,
imageSource = agenda.ImageSource,
isActive = agenda.IsActive,
isSubSection = agenda.IsSubSection,
parentId = agenda.ParentId,
isBeacon = agenda.IsBeacon,
beaconId = agenda.BeaconId,
latitude = agenda.Latitude,
longitude = agenda.Longitude,
meterZoneGPS = agenda.MeterZoneGPS,
type = agenda.Type,
isOnlineAgenda = agenda.IsOnlineAgenda,
resourceIds = agenda.AgendaResourceIds,
agendaMapProvider = agenda.AgendaMapProvider,
// events => TODO specific
},
SectionArticle article => new ArticleDTO
{
id = article.Id,
dateCreation = article.DateCreation,
configurationId = article.ConfigurationId,
instanceId = article.InstanceId,
label = article.Label,
title = article.Title,
description = article.Description,
order = article.Order,
imageId = article.ImageId,
imageSource = article.ImageSource,
isActive = article.IsActive,
isSubSection = article.IsSubSection,
parentId = article.ParentId,
isBeacon = article.IsBeacon,
beaconId = article.BeaconId,
latitude = article.Latitude,
longitude = article.Longitude,
meterZoneGPS = article.MeterZoneGPS,
type = article.Type,
content = article.ArticleContent,
isContentTop = article.ArticleIsContentTop,
audioIds = article.ArticleAudioIds,
isReadAudioAuto = article.ArticleIsReadAudioAuto,
contents = article.ArticleContents
},
SectionEvent sectionEvent => new SectionEventDTO
{
id = sectionEvent.Id,
dateCreation = sectionEvent.DateCreation,
configurationId = sectionEvent.ConfigurationId,
instanceId = sectionEvent.InstanceId,
label = sectionEvent.Label,
title = sectionEvent.Title,
description = sectionEvent.Description,
order = sectionEvent.Order,
imageId = sectionEvent.ImageId,
imageSource = sectionEvent.ImageSource,
isActive = sectionEvent.IsActive,
isSubSection = sectionEvent.IsSubSection,
parentId = sectionEvent.ParentId,
isBeacon = sectionEvent.IsBeacon,
beaconId = sectionEvent.BeaconId,
latitude = sectionEvent.Latitude,
longitude = sectionEvent.Longitude,
meterZoneGPS = sectionEvent.MeterZoneGPS,
type = sectionEvent.Type,
StartDate = sectionEvent.StartDate?.Year > 1000 ? sectionEvent.StartDate : null,
EndDate = sectionEvent.EndDate?.Year > 1000 ? sectionEvent.EndDate : null,
BaseSectionMapId = sectionEvent.BaseSectionMapId,
GlobalMapAnnotations = sectionEvent.GlobalMapAnnotations?.Select(ma => ma.ToDTO()).ToList() ?? new(),
// Programme TODO specific
},
SectionMap map => new MapDTO
{
id = map.Id,
dateCreation = map.DateCreation,
configurationId = map.ConfigurationId,
instanceId = map.InstanceId,
label = map.Label,
title = map.Title,
description = map.Description,
order = map.Order,
imageId = map.ImageId,
imageSource = map.ImageSource,
isActive = map.IsActive,
isSubSection = map.IsSubSection,
parentId = map.ParentId,
isBeacon = map.IsBeacon,
beaconId = map.BeaconId,
latitude = map.Latitude,
longitude = map.Longitude,
meterZoneGPS = map.MeterZoneGPS,
type = map.Type,
zoom = map.MapZoom,
mapType = map.MapMapType,
mapTypeMapbox = map.MapTypeMapbox,
mapProvider = map.MapMapProvider,
iconResourceId = map.IconResourceId,
centerLatitude = map.MapCenterLatitude,
centerLongitude = map.MapCenterLongitude,
categories = map.MapCategories,
isListViewEnabled = map.IsListViewEnabled,
//points = null // map.MapPoints // TODO specific
},
SectionMenu menu => new MenuDTO
{
id = menu.Id,
dateCreation = menu.DateCreation,
configurationId = menu.ConfigurationId,
instanceId = menu.InstanceId,
label = menu.Label,
title = menu.Title,
description = menu.Description,
order = menu.Order,
imageId = menu.ImageId,
imageSource = menu.ImageSource,
isActive = menu.IsActive,
isSubSection = menu.IsSubSection,
parentId = menu.ParentId,
isBeacon = menu.IsBeacon,
beaconId = menu.BeaconId,
latitude = menu.Latitude,
longitude = menu.Longitude,
meterZoneGPS = menu.MeterZoneGPS,
type = menu.Type,
sections = null // menu.Sections, // TODO specific
},
SectionPdf pdf => new PdfDTO
{
id = pdf.Id,
dateCreation = pdf.DateCreation,
configurationId = pdf.ConfigurationId,
instanceId = pdf.InstanceId,
label = pdf.Label,
title = pdf.Title,
description = pdf.Description,
order = pdf.Order,
imageId = pdf.ImageId,
imageSource = pdf.ImageSource,
isActive = pdf.IsActive,
isSubSection = pdf.IsSubSection,
parentId = pdf.ParentId,
isBeacon = pdf.IsBeacon,
beaconId = pdf.BeaconId,
latitude = pdf.Latitude,
longitude = pdf.Longitude,
meterZoneGPS = pdf.MeterZoneGPS,
type = pdf.Type,
pdfs = pdf.PDFOrderedTranslationAndResources
},
SectionGame game => new GameDTO
{
id = game.Id,
dateCreation = game.DateCreation,
configurationId = game.ConfigurationId,
instanceId = game.InstanceId,
label = game.Label,
title = game.Title,
description = game.Description,
order = game.Order,
imageId = game.ImageId,
imageSource = game.ImageSource,
isActive = game.IsActive,
isSubSection = game.IsSubSection,
parentId = game.ParentId,
isBeacon = game.IsBeacon,
beaconId = game.BeaconId,
latitude = game.Latitude,
longitude = game.Longitude,
meterZoneGPS = game.MeterZoneGPS,
type = game.Type,
messageDebut = game.GameMessageDebut,
messageFin = game.GameMessageFin,
puzzleImage = game.GamePuzzleImage?.ToDTO(),
puzzleImageId = game.GamePuzzleImageId,
gameType = game.GameType,
rows = game.GamePuzzleRows,
cols = game.GamePuzzleCols
},
SectionQuiz quiz => new QuizDTO
{
id = quiz.Id,
dateCreation = quiz.DateCreation,
configurationId = quiz.ConfigurationId,
instanceId = quiz.InstanceId,
label = quiz.Label,
title = quiz.Title,
description = quiz.Description,
order = quiz.Order,
imageId = quiz.ImageId,
imageSource = quiz.ImageSource,
isActive = quiz.IsActive,
isSubSection = quiz.IsSubSection,
parentId = quiz.ParentId,
isBeacon = quiz.IsBeacon,
beaconId = quiz.BeaconId,
latitude = quiz.Latitude,
longitude = quiz.Longitude,
meterZoneGPS = quiz.MeterZoneGPS,
type = quiz.Type,
bad_level = quiz.QuizBadLevel,
medium_level = quiz.QuizMediumLevel,
good_level = quiz.QuizGoodLevel,
great_level = quiz.QuizGreatLevel,
questions = null // quiz.Questions, // TODO specific
},
SectionSlider slider => new SliderDTO
{
id = slider.Id,
dateCreation = slider.DateCreation,
configurationId = slider.ConfigurationId,
instanceId = slider.InstanceId,
label = slider.Label,
title = slider.Title,
description = slider.Description,
order = slider.Order,
imageId = slider.ImageId,
imageSource = slider.ImageSource,
isActive = slider.IsActive,
isSubSection = slider.IsSubSection,
parentId = slider.ParentId,
isBeacon = slider.IsBeacon,
beaconId = slider.BeaconId,
latitude = slider.Latitude,
longitude = slider.Longitude,
meterZoneGPS = slider.MeterZoneGPS,
type = slider.Type,
contents = slider.SliderContents
},
SectionVideo video => new VideoDTO
{
id = video.Id,
dateCreation = video.DateCreation,
configurationId = video.ConfigurationId,
instanceId = video.InstanceId,
label = video.Label,
title = video.Title,
description = video.Description,
order = video.Order,
imageId = video.ImageId,
imageSource = video.ImageSource,
isActive = video.IsActive,
isSubSection = video.IsSubSection,
parentId = video.ParentId,
isBeacon = video.IsBeacon,
beaconId = video.BeaconId,
latitude = video.Latitude,
longitude = video.Longitude,
meterZoneGPS = video.MeterZoneGPS,
type = video.Type,
source = video.VideoSource
},
SectionWeather weather => new WeatherDTO
{
id = weather.Id,
dateCreation = weather.DateCreation,
configurationId = weather.ConfigurationId,
instanceId = weather.InstanceId,
label = weather.Label,
title = weather.Title,
description = weather.Description,
order = weather.Order,
imageId = weather.ImageId,
imageSource = weather.ImageSource,
isActive = weather.IsActive,
isSubSection = weather.IsSubSection,
parentId = weather.ParentId,
isBeacon = weather.IsBeacon,
beaconId = weather.BeaconId,
latitude = weather.Latitude,
longitude = weather.Longitude,
meterZoneGPS = weather.MeterZoneGPS,
type = weather.Type,
city = weather.WeatherCity,
updatedDate = weather.WeatherUpdatedDate,
result = weather.WeatherResult
},
SectionWeb web => new WebDTO
{
id = web.Id,
dateCreation = web.DateCreation,
configurationId = web.ConfigurationId,
instanceId = web.InstanceId,
label = web.Label,
title = web.Title,
description = web.Description,
order = web.Order,
imageId = web.ImageId,
imageSource = web.ImageSource,
isActive = web.IsActive,
isSubSection = web.IsSubSection,
parentId = web.ParentId,
isBeacon = web.IsBeacon,
beaconId = web.BeaconId,
latitude = web.Latitude,
longitude = web.Longitude,
meterZoneGPS = web.MeterZoneGPS,
type = web.Type,
source = web.WebSource
},
SectionParcours parcours => new ParcoursDTO
{
id = parcours.Id,
dateCreation = parcours.DateCreation,
configurationId = parcours.ConfigurationId,
instanceId = parcours.InstanceId,
label = parcours.Label,
title = parcours.Title,
description = parcours.Description,
order = parcours.Order,
imageId = parcours.ImageId,
imageSource = parcours.ImageSource,
isActive = parcours.IsActive,
isSubSection = parcours.IsSubSection,
parentId = parcours.ParentId,
isBeacon = parcours.IsBeacon,
beaconId = parcours.BeaconId,
latitude = parcours.Latitude,
longitude = parcours.Longitude,
meterZoneGPS = parcours.MeterZoneGPS,
type = parcours.Type,
showMap = parcours.ShowMap,
baseSectionMapId = parcours.BaseSectionMapId,
// guidedPaths chargés spécifiquement dans GetFromConfigurationDetail
},
_ => throw new NotImplementedException("Section type not handled")
};
}
}
}