Import campagne : detection des PNJ et creatures notables (bout en bout)

Brain : la phase MAP recense les PNJ NOMMES et creatures uniques (pas les
monstres generiques) avec une courte fiche fidele au livre ; dedoublonnage
inter-morceaux (description la plus complete gardee) ; payload done + npc_count.

Core : CampaignImportProposal.npcs + NpcProposal ; a l apply, creation comme
Npc de la campagne (description -> values[Description], meme convention que
les cartes d action des ateliers) avec anti-doublon par nom.

Web : section de revue PNJ a cases a cocher (coches par defaut, grises si
deja presents), compteurs de progression et recapitulatif mis a jour.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-10 15:36:17 +02:00
parent 5061457f76
commit 092898e379
11 changed files with 272 additions and 40 deletions

View File

@@ -40,8 +40,16 @@ export interface ArcProposal {
existingId?: string | null;
}
/** PNJ/créature notable détecté dans le PDF (PNJ nommés, boss). */
export interface NpcProposal {
name: string;
description: string;
}
export interface CampaignImportProposal {
arcs: ArcProposal[];
/** PNJ cochés à la revue (créés comme Npc de la campagne à l'apply). */
npcs?: NpcProposal[];
}
/** Récapitulatif renvoyé après création effective des entités. */
@@ -49,6 +57,7 @@ export interface CampaignImportApplyResult {
arcsCreated: number;
chaptersCreated: number;
scenesCreated: number;
npcsCreated: number;
}
/**
@@ -67,6 +76,7 @@ export type CampaignImportStreamEvent =
arcCount: number;
chapterCount: number;
sceneCount: number;
npcCount: number;
}
| { type: 'done'; arcs: ArcProposal[] }
| { type: 'done'; arcs: ArcProposal[]; npcs: NpcProposal[] }
| { type: 'error'; message: string };

View File

@@ -72,7 +72,7 @@ export class CampaignImportService {
try {
const obj = JSON.parse(currentData);
if (name === 'done') {
subscriber.next({ type: 'done', arcs: obj.arcs ?? [] });
subscriber.next({ type: 'done', arcs: obj.arcs ?? [], npcs: obj.npcs ?? [] });
subscriber.complete();
} else {
subscriber.next({ type: 'progress', ...obj });