Add father/mother links to NPCs, derived from the relationships text

- Npc gains self-referencing father/mother (nullable, ON DELETE SET NULL);
  editable as dropdowns on the per-NPC form
- app:npc:link-parents parses "son/daughter/child of X [and Y]" from the
  Relationships / Notes column, resolves the names within the same family,
  and works out which parent is father vs mother from husband/wife/widow(er)
  and son/daughter/sister/brother cues (plus a small name-gender table for
  the few the text can't disambiguate). --dry-run / --force. 92/180 linked,
  none ambiguous.
- migrations now pin ENGINE=InnoDB - the local WAMP MariaDB defaults to
  MyISAM, which silently drops foreign keys

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Frank
2026-09-06 15:21:03 +02:00
co-authored by Claude Sonnet 5
parent 3c622d7dd8
commit 5bf25d1802
7 changed files with 302 additions and 4 deletions
+15 -1
View File
@@ -7,6 +7,8 @@ use App\Enum\BloodCartInvolvement;
use App\Enum\MysteryImportance;
use App\Enum\Race;
use App\Enum\VillageStatus;
use App\Repository\NpcRepository;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\EnumType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
@@ -34,7 +36,19 @@ class NpcType extends AbstractType
'required' => false,
'label' => 'Relationships / Notes',
'attr' => ['rows' => 3],
])
]);
$parent = [
'class' => Npc::class,
'required' => false,
'placeholder' => '— unknown —',
'choice_label' => static fn (Npc $n) => sprintf('%s (%s)', $n->getName(), $n->getFamily()),
'query_builder' => static fn (NpcRepository $r) => $r->createQueryBuilder('n')
->orderBy('n.family', 'ASC')->addOrderBy('n.name', 'ASC'),
];
$builder
->add('father', EntityType::class, $parent)
->add('mother', EntityType::class, $parent)
->add('villageStatus', EnumType::class, $enum(VillageStatus::class))
->add('bloodCartInvolvement', EnumType::class, $enum(BloodCartInvolvement::class))
->add('mysteryImportance', EnumType::class, $enum(MysteryImportance::class))