Ajout de tableaux dans la partie templates / pages de lore : possibilité d'ajouter un tableau multiligne (par exemple pour faire des tableaux d'objets dans les boutiques) ; tableau type liste clé / valeur (pour des statistiques et ce genre de chose).
All checks were successful
All checks were successful
Ajout de la possibilité de lié un PNJ à une page de lore Ajout d'un graphe de liaison entre lore / PNJs Passage en v.0.12.3-beta
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
|
||||
<groupId>com.loremind</groupId>
|
||||
<artifactId>loremind-core</artifactId>
|
||||
<version>0.12.2-beta</version>
|
||||
<version>0.12.3-beta</version>
|
||||
<name>LoreMind Core</name>
|
||||
<description>Backend Core - Architecture Hexagonale</description>
|
||||
|
||||
|
||||
@@ -163,7 +163,7 @@ public class CampaignImportService {
|
||||
isBlank(p.description())
|
||||
? java.util.Map.of()
|
||||
: java.util.Map.of("Description", p.description().trim()),
|
||||
null, null, campaignId, null, null));
|
||||
null, null, campaignId, null, null, null));
|
||||
created++;
|
||||
}
|
||||
return created;
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
package com.loremind.application.campaigncontext;
|
||||
|
||||
import com.loremind.domain.campaigncontext.Campaign;
|
||||
import com.loremind.domain.campaigncontext.Npc;
|
||||
import com.loremind.domain.campaigncontext.ports.CampaignRepository;
|
||||
import com.loremind.domain.campaigncontext.ports.NpcRepository;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -16,9 +19,11 @@ import java.util.Optional;
|
||||
public class NpcService {
|
||||
|
||||
private final NpcRepository npcRepository;
|
||||
private final CampaignRepository campaignRepository;
|
||||
|
||||
public NpcService(NpcRepository npcRepository) {
|
||||
public NpcService(NpcRepository npcRepository, CampaignRepository campaignRepository) {
|
||||
this.npcRepository = npcRepository;
|
||||
this.campaignRepository = campaignRepository;
|
||||
}
|
||||
|
||||
public record NpcData(
|
||||
@@ -29,6 +34,7 @@ public class NpcService {
|
||||
Map<String, List<String>> imageValues,
|
||||
Map<String, Map<String, String>> keyValueValues,
|
||||
String campaignId,
|
||||
List<String> relatedPageIds,
|
||||
String folder,
|
||||
Integer order
|
||||
) {}
|
||||
@@ -45,6 +51,7 @@ public class NpcService {
|
||||
.imageValues(data.imageValues() != null ? new HashMap<>(data.imageValues()) : new HashMap<>())
|
||||
.keyValueValues(data.keyValueValues() != null ? new HashMap<>(data.keyValueValues()) : new HashMap<>())
|
||||
.campaignId(data.campaignId())
|
||||
.relatedPageIds(data.relatedPageIds() != null ? new ArrayList<>(data.relatedPageIds()) : new ArrayList<>())
|
||||
.folder(normalizeFolder(data.folder()))
|
||||
.order(order)
|
||||
.build();
|
||||
@@ -59,6 +66,21 @@ public class NpcService {
|
||||
return npcRepository.findByCampaignId(campaignId);
|
||||
}
|
||||
|
||||
/**
|
||||
* PNJ de TOUTES les campagnes liées au Lore donné (via {@code campaign.loreId}).
|
||||
* Sert au graphe du Lore : relier les PNJ aux pages qu'ils référencent.
|
||||
* Volume faible (usage mono-utilisateur) → filtrage en mémoire assumé.
|
||||
*/
|
||||
public List<Npc> getNpcsByLoreId(String loreId) {
|
||||
List<Npc> out = new ArrayList<>();
|
||||
for (Campaign campaign : campaignRepository.findAll()) {
|
||||
if (campaign.isLinkedToLore() && campaign.getLoreId().equals(loreId)) {
|
||||
out.addAll(npcRepository.findByCampaignId(campaign.getId()));
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
public Npc updateNpc(String id, NpcData data) {
|
||||
Npc existing = npcRepository.findById(id)
|
||||
.orElseThrow(() -> new IllegalArgumentException("Npc non trouvé avec l'ID: " + id));
|
||||
@@ -68,6 +90,7 @@ public class NpcService {
|
||||
existing.setValues(data.values() != null ? new HashMap<>(data.values()) : new HashMap<>());
|
||||
existing.setImageValues(data.imageValues() != null ? new HashMap<>(data.imageValues()) : new HashMap<>());
|
||||
existing.setKeyValueValues(data.keyValueValues() != null ? new HashMap<>(data.keyValueValues()) : new HashMap<>());
|
||||
existing.setRelatedPageIds(data.relatedPageIds() != null ? new ArrayList<>(data.relatedPageIds()) : new ArrayList<>());
|
||||
existing.setFolder(normalizeFolder(data.folder()));
|
||||
if (data.order() != null) {
|
||||
existing.setOrder(data.order());
|
||||
|
||||
@@ -76,6 +76,8 @@ public class PageService {
|
||||
existing.setNodeId(changes.getNodeId());
|
||||
existing.setValues(CollectionUtils.copyMap(changes.getValues()));
|
||||
existing.setImageValues(CollectionUtils.copyMap(changes.getImageValues()));
|
||||
existing.setKeyValueValues(CollectionUtils.copyMap(changes.getKeyValueValues()));
|
||||
existing.setTableValues(CollectionUtils.copyMap(changes.getTableValues()));
|
||||
existing.setNotes(changes.getNotes());
|
||||
existing.setTags(CollectionUtils.copyList(changes.getTags()));
|
||||
existing.setRelatedPageIds(CollectionUtils.copyList(changes.getRelatedPageIds()));
|
||||
|
||||
@@ -4,6 +4,7 @@ import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -46,6 +47,13 @@ public class Npc {
|
||||
/** Référence vers la Campaign parente (cross-aggregate via ID). */
|
||||
private String campaignId;
|
||||
|
||||
/**
|
||||
* IDs de Pages de Lore référencées par ce PNJ (sa ville, sa faction, sa
|
||||
* région…). Référence faible cross-context, même principe que sur
|
||||
* Arc/Chapter/Scene — alimente notamment le graphe du Lore.
|
||||
*/
|
||||
private List<String> relatedPageIds;
|
||||
|
||||
/** Dossier de classement (texte libre, ex. « Bard's Gate »). Nullable = non classé. */
|
||||
private String folder;
|
||||
|
||||
@@ -69,4 +77,9 @@ public class Npc {
|
||||
if (keyValueValues == null) keyValueValues = new HashMap<>();
|
||||
return keyValueValues;
|
||||
}
|
||||
|
||||
public List<String> getRelatedPageIds() {
|
||||
if (relatedPageIds == null) relatedPageIds = new ArrayList<>();
|
||||
return relatedPageIds;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,20 @@ public class Page {
|
||||
*/
|
||||
private Map<String, List<String>> imageValues;
|
||||
|
||||
/**
|
||||
* Valeurs des champs KEY_VALUE_LIST (tableau libelle → valeur, comme sur les
|
||||
* fiches de personnage) : fieldName → (label → valeur). Les labels sont
|
||||
* definis par le Template ; seules les valeurs vivent sur la page.
|
||||
*/
|
||||
private Map<String, Map<String, String>> keyValueValues;
|
||||
|
||||
/**
|
||||
* Valeurs des champs TABLE (colonnes figees au template, lignes libres) :
|
||||
* fieldName → liste ordonnee de lignes, chaque ligne = colonne → cellule.
|
||||
* Usage type : inventaire de boutique, table d'objets.
|
||||
*/
|
||||
private Map<String, List<Map<String, String>>> tableValues;
|
||||
|
||||
/** Notes privées du MJ (non exportées vers FoundryVTT). */
|
||||
private String notes;
|
||||
|
||||
|
||||
@@ -9,6 +9,11 @@ package com.loremind.domain.shared.template;
|
||||
* - KEY_VALUE_LIST : liste de paires {label, value} avec labels figes au template
|
||||
* (Map<String, Map<String, String>> : fieldName -> label -> value).
|
||||
* Usage : stat blocks, listes de competences, traits.
|
||||
* - TABLE : tableau a colonnes figees au template (TemplateField.labels =
|
||||
* noms de colonnes) et lignes LIBRES ajoutees au remplissage
|
||||
* (Map<String, List<Map<String, String>>> : fieldName -> lignes,
|
||||
* chaque ligne = colonne -> cellule).
|
||||
* Usage : inventaire de boutique, tables d'objets, listes de prix.
|
||||
* <p>
|
||||
* Extension future possible : RICH_TEXT, DATE, BOOLEAN, REFERENCE...
|
||||
*/
|
||||
@@ -16,5 +21,6 @@ public enum FieldType {
|
||||
TEXT,
|
||||
IMAGE,
|
||||
NUMBER,
|
||||
KEY_VALUE_LIST
|
||||
KEY_VALUE_LIST,
|
||||
TABLE
|
||||
}
|
||||
|
||||
@@ -30,8 +30,9 @@ public class TemplateField {
|
||||
/** Variante de rendu pour les champs IMAGE. Null = GALLERY. */
|
||||
private ImageLayout layout;
|
||||
/**
|
||||
* Labels predefinis pour les champs KEY_VALUE_LIST (ordre significatif).
|
||||
* Ex: ["FOR","DEX","CON","INT","SAG","CHA"] pour un champ "Caracteristiques".
|
||||
* Labels predefinis (ordre significatif), selon le type :
|
||||
* - KEY_VALUE_LIST : libelles des lignes. Ex: ["FOR","DEX","CON","INT","SAG","CHA"].
|
||||
* - TABLE : noms des COLONNES. Ex: ["Objet","Prix","Description"].
|
||||
* Null/vide pour les autres types.
|
||||
*/
|
||||
private List<String> labels;
|
||||
@@ -70,4 +71,9 @@ public class TemplateField {
|
||||
public static TemplateField keyValueList(String name, List<String> labels) {
|
||||
return new TemplateField(name, FieldType.KEY_VALUE_LIST, null, labels);
|
||||
}
|
||||
|
||||
/** Raccourci : construit un champ TABLE avec ses noms de colonnes. */
|
||||
public static TemplateField table(String name, List<String> columns) {
|
||||
return new TemplateField(name, FieldType.TABLE, null, columns);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.loremind.infrastructure.persistence.converter;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import jakarta.persistence.AttributeConverter;
|
||||
import jakarta.persistence.Converter;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Convertit une Map<String, List<Map<String, String>>> en JSON et inversement.
|
||||
* <p>
|
||||
* Utilise pour Page.tableValues : pour chaque champ TABLE du template, stocke
|
||||
* la liste ordonnee des LIGNES du tableau, chaque ligne etant une map
|
||||
* colonne -> cellule. Exemple :
|
||||
* {"Inventaire": [{"Objet":"Potion","Prix":"50 po"}, {"Objet":"Corde","Prix":"1 po"}]}
|
||||
* <p>
|
||||
* Adaptateur technique pur : le domaine ignore ce converter.
|
||||
*/
|
||||
@Converter
|
||||
public class StringRowListMapJsonConverter
|
||||
implements AttributeConverter<Map<String, List<Map<String, String>>>, String> {
|
||||
|
||||
private static final ObjectMapper MAPPER = new ObjectMapper();
|
||||
private static final TypeReference<Map<String, List<Map<String, String>>>> TYPE_REF =
|
||||
new TypeReference<>() {};
|
||||
|
||||
@Override
|
||||
public String convertToDatabaseColumn(Map<String, List<Map<String, String>>> attribute) {
|
||||
if (attribute == null || attribute.isEmpty()) return "{}";
|
||||
try {
|
||||
return MAPPER.writeValueAsString(attribute);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException(
|
||||
"Erreur serialisation Map<String, List<Map<String,String>>> -> JSON", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, List<Map<String, String>>> convertToEntityAttribute(String dbData) {
|
||||
if (dbData == null || dbData.isBlank()) return Collections.emptyMap();
|
||||
try {
|
||||
return MAPPER.readValue(dbData, TYPE_REF);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException(
|
||||
"Erreur deserialisation JSON -> Map<String, List<Map<String,String>>>", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -86,7 +86,7 @@ public class TemplateFieldListJsonConverter
|
||||
}
|
||||
}
|
||||
List<String> labels = null;
|
||||
if (type == FieldType.KEY_VALUE_LIST) {
|
||||
if (type == FieldType.KEY_VALUE_LIST || type == FieldType.TABLE) {
|
||||
JsonNode labelsNode = item.path("labels");
|
||||
if (labelsNode.isArray()) {
|
||||
labels = new ArrayList<>();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.loremind.infrastructure.persistence.entity;
|
||||
|
||||
import com.loremind.infrastructure.persistence.converter.StringListJsonConverter;
|
||||
import com.loremind.infrastructure.persistence.converter.StringListMapJsonConverter;
|
||||
import com.loremind.infrastructure.persistence.converter.StringMapJsonConverter;
|
||||
import com.loremind.infrastructure.persistence.converter.StringMapMapJsonConverter;
|
||||
@@ -54,6 +55,11 @@ public class NpcJpaEntity {
|
||||
@Column(name = "campaign_id", nullable = false)
|
||||
private Long campaignId;
|
||||
|
||||
/** IDs de Pages de Lore référencées (référence faible cross-context). JSON TEXT. */
|
||||
@Convert(converter = StringListJsonConverter.class)
|
||||
@Column(name = "related_page_ids", columnDefinition = "TEXT")
|
||||
private List<String> relatedPageIds;
|
||||
|
||||
@Column(name = "folder")
|
||||
private String folder;
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ package com.loremind.infrastructure.persistence.entity;
|
||||
import com.loremind.infrastructure.persistence.converter.StringListJsonConverter;
|
||||
import com.loremind.infrastructure.persistence.converter.StringListMapJsonConverter;
|
||||
import com.loremind.infrastructure.persistence.converter.StringMapJsonConverter;
|
||||
import com.loremind.infrastructure.persistence.converter.StringMapMapJsonConverter;
|
||||
import com.loremind.infrastructure.persistence.converter.StringRowListMapJsonConverter;
|
||||
import jakarta.persistence.*;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
@@ -52,6 +54,16 @@ public class PageJpaEntity {
|
||||
@Convert(converter = StringListMapJsonConverter.class)
|
||||
private Map<String, List<String>> imageValues;
|
||||
|
||||
/** Valeurs des champs KEY_VALUE_LIST : fieldName → (label → valeur). JSON TEXT. */
|
||||
@Column(name = "key_value_values", columnDefinition = "TEXT")
|
||||
@Convert(converter = StringMapMapJsonConverter.class)
|
||||
private Map<String, Map<String, String>> keyValueValues;
|
||||
|
||||
/** Valeurs des champs TABLE : fieldName → lignes (colonne → cellule). JSON TEXT. */
|
||||
@Column(name = "table_values", columnDefinition = "TEXT")
|
||||
@Convert(converter = StringRowListMapJsonConverter.class)
|
||||
private Map<String, List<Map<String, String>>> tableValues;
|
||||
|
||||
@Column(columnDefinition = "TEXT")
|
||||
private String notes;
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.loremind.infrastructure.persistence.entity.NpcJpaEntity;
|
||||
import com.loremind.infrastructure.persistence.jpa.NpcJpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@@ -59,6 +60,7 @@ public class PostgresNpcRepository implements NpcRepository {
|
||||
.imageValues(e.getImageValues() != null ? new HashMap<>(e.getImageValues()) : new HashMap<>())
|
||||
.keyValueValues(e.getKeyValueValues() != null ? new HashMap<>(e.getKeyValueValues()) : new HashMap<>())
|
||||
.campaignId(e.getCampaignId().toString())
|
||||
.relatedPageIds(e.getRelatedPageIds() != null ? new ArrayList<>(e.getRelatedPageIds()) : new ArrayList<>())
|
||||
.folder(e.getFolder())
|
||||
.order(e.getOrder())
|
||||
.createdAt(e.getCreatedAt())
|
||||
@@ -77,6 +79,7 @@ public class PostgresNpcRepository implements NpcRepository {
|
||||
.imageValues(n.getImageValues() != null ? new HashMap<>(n.getImageValues()) : new HashMap<>())
|
||||
.keyValueValues(n.getKeyValueValues() != null ? new HashMap<>(n.getKeyValueValues()) : new HashMap<>())
|
||||
.campaignId(Long.parseLong(n.getCampaignId()))
|
||||
.relatedPageIds(n.getRelatedPageIds() != null ? new ArrayList<>(n.getRelatedPageIds()) : new ArrayList<>())
|
||||
.folder(n.getFolder())
|
||||
.order(n.getOrder())
|
||||
.createdAt(n.getCreatedAt())
|
||||
|
||||
@@ -93,6 +93,8 @@ public class PostgresPageRepository implements PageRepository {
|
||||
.title(e.getTitle())
|
||||
.values(e.getValues() != null ? new HashMap<>(e.getValues()) : new HashMap<>())
|
||||
.imageValues(e.getImageValues() != null ? new HashMap<>(e.getImageValues()) : new HashMap<>())
|
||||
.keyValueValues(e.getKeyValueValues() != null ? new HashMap<>(e.getKeyValueValues()) : new HashMap<>())
|
||||
.tableValues(e.getTableValues() != null ? new HashMap<>(e.getTableValues()) : new HashMap<>())
|
||||
.notes(e.getNotes())
|
||||
.tags(e.getTags() != null ? new ArrayList<>(e.getTags()) : new ArrayList<>())
|
||||
.relatedPageIds(e.getRelatedPageIds() != null ? new ArrayList<>(e.getRelatedPageIds()) : new ArrayList<>())
|
||||
@@ -111,6 +113,8 @@ public class PostgresPageRepository implements PageRepository {
|
||||
.title(p.getTitle())
|
||||
.values(p.getValues() != null ? new HashMap<>(p.getValues()) : new HashMap<>())
|
||||
.imageValues(p.getImageValues() != null ? new HashMap<>(p.getImageValues()) : new HashMap<>())
|
||||
.keyValueValues(p.getKeyValueValues() != null ? new HashMap<>(p.getKeyValueValues()) : new HashMap<>())
|
||||
.tableValues(p.getTableValues() != null ? new HashMap<>(p.getTableValues()) : new HashMap<>())
|
||||
.notes(p.getNotes())
|
||||
.tags(p.getTags() != null ? new ArrayList<>(p.getTags()) : new ArrayList<>())
|
||||
.relatedPageIds(p.getRelatedPageIds() != null ? new ArrayList<>(p.getRelatedPageIds()) : new ArrayList<>())
|
||||
|
||||
@@ -43,6 +43,15 @@ public class NpcController {
|
||||
return ResponseEntity.ok(dtos);
|
||||
}
|
||||
|
||||
/** PNJ de toutes les campagnes liées au Lore donné — alimente le graphe du Lore. */
|
||||
@GetMapping("/lore/{loreId}")
|
||||
public ResponseEntity<List<NpcDTO>> getNpcsByLore(@PathVariable String loreId) {
|
||||
List<NpcDTO> dtos = npcService.getNpcsByLoreId(loreId).stream()
|
||||
.map(npcMapper::toDTO)
|
||||
.collect(Collectors.toList());
|
||||
return ResponseEntity.ok(dtos);
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
public ResponseEntity<NpcDTO> updateNpc(@PathVariable String id, @RequestBody NpcDTO dto) {
|
||||
Npc updated = npcService.updateNpc(id, toData(dto, dto.getOrder()));
|
||||
@@ -64,6 +73,7 @@ public class NpcController {
|
||||
dto.getImageValues(),
|
||||
dto.getKeyValueValues(),
|
||||
dto.getCampaignId(),
|
||||
dto.getRelatedPageIds(),
|
||||
dto.getFolder(),
|
||||
order
|
||||
);
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.loremind.infrastructure.web.dto.campaigncontext;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -20,6 +21,8 @@ public class NpcDTO {
|
||||
private Map<String, List<String>> imageValues = new HashMap<>();
|
||||
private Map<String, Map<String, String>> keyValueValues = new HashMap<>();
|
||||
private String campaignId;
|
||||
/** IDs de Pages de Lore référencées par ce PNJ (référence faible cross-context). */
|
||||
private List<String> relatedPageIds = new ArrayList<>();
|
||||
private String folder;
|
||||
private int order;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,10 @@ public class PageDTO {
|
||||
private Map<String, String> values;
|
||||
/** Pour chaque champ IMAGE du template, la liste ordonnee des IDs d'images. */
|
||||
private Map<String, List<String>> imageValues;
|
||||
/** Pour chaque champ KEY_VALUE_LIST du template : label → valeur. */
|
||||
private Map<String, Map<String, String>> keyValueValues;
|
||||
/** Pour chaque champ TABLE du template : lignes (colonne → cellule). */
|
||||
private Map<String, List<Map<String, String>>> tableValues;
|
||||
private String notes;
|
||||
private List<String> tags;
|
||||
private List<String> relatedPageIds;
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.loremind.domain.campaigncontext.Npc;
|
||||
import com.loremind.infrastructure.web.dto.campaigncontext.NpcDTO;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
@Component
|
||||
@@ -20,6 +21,7 @@ public class NpcMapper {
|
||||
dto.setImageValues(n.getImageValues() != null ? new HashMap<>(n.getImageValues()) : new HashMap<>());
|
||||
dto.setKeyValueValues(n.getKeyValueValues() != null ? new HashMap<>(n.getKeyValueValues()) : new HashMap<>());
|
||||
dto.setCampaignId(n.getCampaignId());
|
||||
dto.setRelatedPageIds(n.getRelatedPageIds() != null ? new ArrayList<>(n.getRelatedPageIds()) : new ArrayList<>());
|
||||
dto.setFolder(n.getFolder());
|
||||
dto.setOrder(n.getOrder());
|
||||
return dto;
|
||||
@@ -36,6 +38,7 @@ public class NpcMapper {
|
||||
.imageValues(dto.getImageValues() != null ? new HashMap<>(dto.getImageValues()) : new HashMap<>())
|
||||
.keyValueValues(dto.getKeyValueValues() != null ? new HashMap<>(dto.getKeyValueValues()) : new HashMap<>())
|
||||
.campaignId(dto.getCampaignId())
|
||||
.relatedPageIds(dto.getRelatedPageIds() != null ? new ArrayList<>(dto.getRelatedPageIds()) : new ArrayList<>())
|
||||
.folder(dto.getFolder())
|
||||
.order(dto.getOrder())
|
||||
.build();
|
||||
|
||||
@@ -23,6 +23,8 @@ public class PageMapper {
|
||||
dto.setTitle(page.getTitle());
|
||||
dto.setValues(CollectionUtils.copyMap(page.getValues()));
|
||||
dto.setImageValues(CollectionUtils.copyMap(page.getImageValues()));
|
||||
dto.setKeyValueValues(CollectionUtils.copyMap(page.getKeyValueValues()));
|
||||
dto.setTableValues(CollectionUtils.copyMap(page.getTableValues()));
|
||||
dto.setNotes(page.getNotes());
|
||||
dto.setTags(CollectionUtils.copyList(page.getTags()));
|
||||
dto.setRelatedPageIds(CollectionUtils.copyList(page.getRelatedPageIds()));
|
||||
@@ -41,6 +43,8 @@ public class PageMapper {
|
||||
.title(dto.getTitle())
|
||||
.values(CollectionUtils.copyMap(dto.getValues()))
|
||||
.imageValues(CollectionUtils.copyMap(dto.getImageValues()))
|
||||
.keyValueValues(CollectionUtils.copyMap(dto.getKeyValueValues()))
|
||||
.tableValues(CollectionUtils.copyMap(dto.getTableValues()))
|
||||
.notes(dto.getNotes())
|
||||
.tags(CollectionUtils.copyList(dto.getTags()))
|
||||
.relatedPageIds(CollectionUtils.copyList(dto.getRelatedPageIds()))
|
||||
|
||||
@@ -29,7 +29,8 @@ public class TemplateFieldMapper {
|
||||
layoutStr = layout.name();
|
||||
}
|
||||
List<String> labels = null;
|
||||
if (field.getType() == FieldType.KEY_VALUE_LIST && field.getLabels() != null) {
|
||||
if ((field.getType() == FieldType.KEY_VALUE_LIST || field.getType() == FieldType.TABLE)
|
||||
&& field.getLabels() != null) {
|
||||
labels = new ArrayList<>(field.getLabels());
|
||||
}
|
||||
return new TemplateFieldDTO(field.getName(), typeStr, layoutStr, labels);
|
||||
@@ -54,7 +55,7 @@ public class TemplateFieldMapper {
|
||||
}
|
||||
}
|
||||
List<String> labels = null;
|
||||
if (type == FieldType.KEY_VALUE_LIST && dto.getLabels() != null) {
|
||||
if ((type == FieldType.KEY_VALUE_LIST || type == FieldType.TABLE) && dto.getLabels() != null) {
|
||||
labels = new ArrayList<>(dto.getLabels());
|
||||
}
|
||||
return new TemplateField(dto.getName(), type, layout, labels);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.loremind.application.campaigncontext;
|
||||
|
||||
import com.loremind.domain.campaigncontext.Npc;
|
||||
import com.loremind.domain.campaigncontext.ports.CampaignRepository;
|
||||
import com.loremind.domain.campaigncontext.ports.NpcRepository;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -29,6 +30,9 @@ public class NpcServiceTest {
|
||||
@Mock
|
||||
private NpcRepository npcRepository;
|
||||
|
||||
@Mock
|
||||
private CampaignRepository campaignRepository;
|
||||
|
||||
@InjectMocks
|
||||
private NpcService npcService;
|
||||
|
||||
@@ -51,7 +55,7 @@ public class NpcServiceTest {
|
||||
|
||||
Npc result = npcService.createNpc(
|
||||
new NpcService.NpcData("Borin le forgeron", null, null,
|
||||
Map.of("Notes", "Borin"), null, null, "camp-1", null,5));
|
||||
Map.of("Notes", "Borin"), null, null, "camp-1", null, null, 5));
|
||||
|
||||
assertNotNull(result);
|
||||
ArgumentCaptor<Npc> captor = ArgumentCaptor.forClass(Npc.class);
|
||||
@@ -67,7 +71,7 @@ public class NpcServiceTest {
|
||||
when(npcRepository.findByCampaignId("camp-1")).thenReturn(List.of(a, b));
|
||||
when(npcRepository.save(any(Npc.class))).thenReturn(testNpc);
|
||||
|
||||
npcService.createNpc(new NpcService.NpcData("Nouveau", null, null, null, null, null, "camp-1", null,null));
|
||||
npcService.createNpc(new NpcService.NpcData("Nouveau", null, null, null, null, null, "camp-1", null, null, null));
|
||||
|
||||
ArgumentCaptor<Npc> captor = ArgumentCaptor.forClass(Npc.class);
|
||||
verify(npcRepository).save(captor.capture());
|
||||
@@ -79,7 +83,7 @@ public class NpcServiceTest {
|
||||
when(npcRepository.findByCampaignId("camp-1")).thenReturn(List.of());
|
||||
when(npcRepository.save(any(Npc.class))).thenReturn(testNpc);
|
||||
|
||||
npcService.createNpc(new NpcService.NpcData("Premier", null, null, null, null, null, "camp-1", null,null));
|
||||
npcService.createNpc(new NpcService.NpcData("Premier", null, null, null, null, null, "camp-1", null, null, null));
|
||||
|
||||
ArgumentCaptor<Npc> captor = ArgumentCaptor.forClass(Npc.class);
|
||||
verify(npcRepository).save(captor.capture());
|
||||
@@ -124,7 +128,7 @@ public class NpcServiceTest {
|
||||
|
||||
Npc result = npcService.updateNpc("npc-1",
|
||||
new NpcService.NpcData("Borin renommé", null, null,
|
||||
Map.of("Notes", "v2"), null, null, "camp-1", null,7));
|
||||
Map.of("Notes", "v2"), null, null, "camp-1", null, null, 7));
|
||||
|
||||
assertEquals("Borin renommé", result.getName());
|
||||
assertEquals("v2", result.getValues().get("Notes"));
|
||||
@@ -138,7 +142,7 @@ public class NpcServiceTest {
|
||||
|
||||
Npc result = npcService.updateNpc("npc-1",
|
||||
new NpcService.NpcData("Borin", null, null,
|
||||
Map.of("Notes", "txt"), null, null, "camp-1", null,null));
|
||||
Map.of("Notes", "txt"), null, null, "camp-1", null, null, null));
|
||||
|
||||
// testNpc avait order=1 → préservé
|
||||
assertEquals(1, result.getOrder());
|
||||
@@ -150,7 +154,7 @@ public class NpcServiceTest {
|
||||
|
||||
IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
|
||||
() -> npcService.updateNpc("missing",
|
||||
new NpcService.NpcData("x", null, null, null, null, null, "camp-1", null,null)));
|
||||
new NpcService.NpcData("x", null, null, null, null, null, "camp-1", null, null, null)));
|
||||
assertTrue(ex.getMessage().contains("missing"));
|
||||
verify(npcRepository, never()).save(any());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user