Storyline: per-chapter DM notes

Each chapter page gets a collapsible "Chapter notes" card at the top — a
free-text log the DM fills during play (the story the party tells after
the Crooked Goose, names given to NPCs, threads for next time). Saved
per chapter slug with a "saved <timestamp>" marker, same shape as the
Enemy/NPC game-notes field.

New: ChapterNote entity (slug-keyed, unique) + repository findOrCreate(),
ChapterNoteType form, chapter_note table migration (ENGINE = InnoDB
pinned). The storyline chapter route now also accepts POST to save.

Chapters stay hand-written Twig; only the mutable notes live in the DB.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Frank
2026-09-08 18:51:53 +02:00
co-authored by Claude Sonnet 5
parent 56f4641564
commit 5c821bd7ad
8 changed files with 257 additions and 2 deletions
+38
View File
@@ -0,0 +1,38 @@
<?php
namespace App\Tests\Entity;
use App\Entity\ChapterNote;
use PHPUnit\Framework\TestCase;
class ChapterNoteTest extends TestCase
{
public function testStartsEmptyForItsSlug(): void
{
$note = new ChapterNote('prologue-the-long-road');
self::assertSame('prologue-the-long-road', $note->getSlug());
self::assertNull($note->getId());
self::assertNull($note->getNotes());
self::assertNull($note->getUpdatedAt());
}
public function testTouchStampsUpdatedAt(): void
{
$note = new ChapterNote('overview');
$note->setNotes("The party told Maud the cottage was haunted.");
$note->touch();
self::assertNotNull($note->getUpdatedAt());
self::assertSame("The party told Maud the cottage was haunted.", $note->getNotes());
}
public function testNotesCanBeClearedBackToNull(): void
{
$note = (new ChapterNote('overview'))->setNotes('something');
$note->setNotes(null);
self::assertNull($note->getNotes());
}
}