feat(locations): author the background base tags on the Backgrounds tab (location-backgrounds slice 1) #88

Merged
bjoern merged 2 commits from feat/location-backgrounds-authoring into main 2026-07-12 09:53:46 +02:00
Member

First slice of location backgrounds (Phase 2). Fills the location editor's Backgrounds tab — which was a placeholder EmptyState — with base-image tag authoring: booru search + positive/negative prompts + per-tag strength, auto-saved like every editor.

It's the location analog of the character's Base Appearance authoring, with one structural difference: a location has no gender and no character group — its tags are the scene prompt (that matters at generation, next slice). Generating the image, and then variants (i2i), are the following slices.

What's here

  • DomainLocation gains BaseTags and an Apply(LocationProfile) mutator (name + description + base tags as one journaled save; strengths clamped on ingest). New LocationProfile mirrors CharacterProfile; the parent/child hierarchy deliberately stays out of it (it's edited on its own via the positioning panel).
  • PersistenceBaseTags in a scalar-JSON column via the shared JsonColumnMapper.AsJsonList from #87 (undoable for free, ADR 0020); AddLocationBaseTags migration (defaultValue "[]").
  • UseCasesLocationDto gains BaseTags + ToProfile; UpdateLocation and ILocationStore.ApplyAsync now take a LocationProfile — the profile record the store's own TODO comment had been waiting for.
  • BlazorAdapterSaveLocationRequested carries the profile; the Backgrounds tab hosts the shared TagAuthoring bound to the location's base tags.

Testing

  • Domain: Apply sets fields + clamps strength (mutation-checked — dropped the clamp, watched it go red, reverted) + From round-trip.
  • Persistence: base-tags round-trip over SQLite with out-of-range clamp.
  • Component: the Backgrounds tab authors a tag and auto-saves it onto the location.
  • 1010 tests green, no model drift.
  • Browser-verified: on a location's Backgrounds tab, added a "castle" tag by hand; it persisted across a full reload (Positive prompt (1), editable row); zero console errors.

🤖 Generated with Claude Code

First slice of **location backgrounds** (Phase 2). Fills the location editor's **Backgrounds** tab — which was a placeholder `EmptyState` — with base-image tag authoring: booru search + positive/negative prompts + per-tag strength, auto-saved like every editor. It's the location analog of the character's *Base Appearance* authoring, with one structural difference: a location has **no gender and no character group** — its tags *are* the scene prompt (that matters at generation, next slice). Generating the image, and then variants (i2i), are the following slices. ## What's here - **Domain** — `Location` gains `BaseTags` and an `Apply(LocationProfile)` mutator (name + description + base tags as one journaled save; strengths clamped on ingest). New `LocationProfile` mirrors `CharacterProfile`; the parent/child hierarchy deliberately stays out of it (it's edited on its own via the positioning panel). - **Persistence** — `BaseTags` in a scalar-JSON column via the shared `JsonColumnMapper.AsJsonList` from #87 (undoable for free, ADR 0020); `AddLocationBaseTags` migration (`defaultValue "[]"`). - **UseCases** — `LocationDto` gains `BaseTags` + `ToProfile`; `UpdateLocation` and `ILocationStore.ApplyAsync` now take a `LocationProfile` — the profile record the store's own TODO comment had been waiting for. - **BlazorAdapter** — `SaveLocationRequested` carries the profile; the Backgrounds tab hosts the shared `TagAuthoring` bound to the location's base tags. ## Testing - Domain: `Apply` sets fields + clamps strength (mutation-checked — dropped the clamp, watched it go red, reverted) + `From` round-trip. - Persistence: base-tags round-trip over SQLite with out-of-range clamp. - Component: the Backgrounds tab authors a tag and auto-saves it onto the location. - **1010 tests green**, no model drift. - Browser-verified: on a location's Backgrounds tab, added a "castle" tag by hand; it persisted across a full reload (Positive prompt (1), editable row); zero console errors. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat(locations): author the background base tags on the Backgrounds tab (location-backgrounds slice 1)
All checks were successful
CI / build (pull_request) Successful in 23s
CI / test (pull_request) Successful in 45s
0b5a51f1c9
Fills the location editor's Backgrounds tab (was a placeholder) with base-image tag authoring:
booru search + positive/negative prompts + per-tag strength, auto-saved like every editor. It's the
location analog of the character's Base Appearance authoring — no gender; the location's tags are the
scene prompt, not a character group. Generating the image comes in the next slice.

- Domain: Location gains BaseTags and an Apply(LocationProfile) mutator (name/description/base tags as
  one journaled save, strength clamped). New LocationProfile mirrors CharacterProfile; the parent
  hierarchy stays out of it (edited on its own).
- Persistence: BaseTags in a scalar-JSON column via the shared JsonColumnMapper.AsJsonList (undoable
  for free, ADR 0020); AddLocationBaseTags migration (defaultValue "[]").
- UseCases: LocationDto gains BaseTags + ToProfile; UpdateLocation and ILocationStore.ApplyAsync now
  take a LocationProfile — the profile record the store's own comment had been waiting for.
- BlazorAdapter: SaveLocationRequested carries the profile; the Backgrounds tab hosts the shared
  TagAuthoring bound to the location's base tags.
- Tests: domain (Apply sets/clamps + From round-trip — mutation-checked); persistence round-trip of
  the base tags; the Backgrounds tab authors + auto-saves. 1010 green. Browser-verified: added a
  "castle" tag on the Backgrounds tab, it persisted across a reload; no console errors.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Summary

Summary
Generated on: 07/12/2026 - 07:44:46
Coverage date: 07/12/2026 - 07:44:31 - 07/12/2026 - 07:44:43
Parser: MultiReport (4x Cobertura)
Assemblies: 7
Classes: 498
Files: 340
Line coverage: 95.8% (15063 of 15707)
Covered lines: 15063
Uncovered lines: 644
Coverable lines: 15707
Total lines: 28482
Branch coverage: 84.6% (2275 of 2688)
Covered branches: 2275
Total branches: 2688
Method coverage: Feature is only available for sponsors

Coverage

Kagura.BlazorAdapter - 89.9%
Name Line Branch
Kagura.BlazorAdapter 89.9% 81.5%
Kagura.BlazorAdapter.BlazorAdapterAssembly 100%
Kagura.BlazorAdapter.Connections.AddLinkModal 91.4% 81.5%
Kagura.BlazorAdapter.Connections.ConnectionsEffects 95.4% 80%
Kagura.BlazorAdapter.Connections.ConnectionsFailed 100%
Kagura.BlazorAdapter.Connections.ConnectionsLoaded 100%
Kagura.BlazorAdapter.Connections.ConnectionsPanel 100% 95%
Kagura.BlazorAdapter.Connections.ConnectionsReducers 100% 75%
Kagura.BlazorAdapter.Connections.ConnectionsState 90%
Kagura.BlazorAdapter.Connections.KindIcon 100%
Kagura.BlazorAdapter.Connections.LinkRequested 100%
Kagura.BlazorAdapter.Connections.LinkTargetsFound 100%
Kagura.BlazorAdapter.Connections.LoadConnections 100%
Kagura.BlazorAdapter.Connections.NodeKindIcons 100%
Kagura.BlazorAdapter.Connections.RemoveLinkRequested 100%
Kagura.BlazorAdapter.Connections.SearchLinkTargets 100%
Kagura.BlazorAdapter.Design 0% 0%
Kagura.BlazorAdapter.EditorComponentsDemo 0%
Kagura.BlazorAdapter.FileUploadDemo 0%
Kagura.BlazorAdapter.Generation.ActivityQueueBridge 87.5% 50%
Kagura.BlazorAdapter.Generation.CancelActivityRequested 100%
Kagura.BlazorAdapter.Generation.GenerationQueueEffects 100%
Kagura.BlazorAdapter.Generation.GenerationQueueLoaded 100%
Kagura.BlazorAdapter.Generation.GenerationQueuePage 100% 100%
Kagura.BlazorAdapter.Generation.GenerationQueueReducers 100%
Kagura.BlazorAdapter.Generation.GenerationQueueState 100%
Kagura.BlazorAdapter.Generation.GenerationStatusBar 100% 95.4%
Kagura.BlazorAdapter.Generation.RemoveActivityRequested 100%
Kagura.BlazorAdapter.History.DiffValue 100% 87.5%
Kagura.BlazorAdapter.History.DocumentHistoryEffects 90% 68.7%
Kagura.BlazorAdapter.History.DocumentHistoryFailed 100%
Kagura.BlazorAdapter.History.DocumentHistoryLoaded 100%
Kagura.BlazorAdapter.History.DocumentHistoryPanel 79.3% 75%
Kagura.BlazorAdapter.History.DocumentHistoryReducers 95% 83.3%
Kagura.BlazorAdapter.History.DocumentHistoryState 100%
Kagura.BlazorAdapter.History.LoadDocumentHistory 100%
Kagura.BlazorAdapter.History.RevertCompleted 100%
Kagura.BlazorAdapter.History.RevertRequested 100%
Kagura.BlazorAdapter.History.RevisionDiffLoaded 100%
Kagura.BlazorAdapter.History.SelectRevision 100%
Kagura.BlazorAdapter.KnowledgeBase.BaseSpriteFailed 100%
Kagura.BlazorAdapter.KnowledgeBase.BaseSpriteGenerated 100%
Kagura.BlazorAdapter.KnowledgeBase.CharacterBaseSprite 95.2% 88.8%
Kagura.BlazorAdapter.KnowledgeBase.CharacterCreated 100%
Kagura.BlazorAdapter.KnowledgeBase.CharacterDeleted 100%
Kagura.BlazorAdapter.KnowledgeBase.CharacterEditorEffects 100% 100%
Kagura.BlazorAdapter.KnowledgeBase.CharacterEditorLoaded 100%
Kagura.BlazorAdapter.KnowledgeBase.CharacterEditorNotFound 100%
Kagura.BlazorAdapter.KnowledgeBase.CharacterEditorPage 91.3% 81.8%
Kagura.BlazorAdapter.KnowledgeBase.CharacterEditorReducers 100% 92.8%
Kagura.BlazorAdapter.KnowledgeBase.CharacterEditorState 100%
Kagura.BlazorAdapter.KnowledgeBase.CharacterOperationFailed 100%
Kagura.BlazorAdapter.KnowledgeBase.CharacterOutfits 94.2% 83.3%
Kagura.BlazorAdapter.KnowledgeBase.CharacterSaved 100%
Kagura.BlazorAdapter.KnowledgeBase.CharactersEffects 94.1% 75%
Kagura.BlazorAdapter.KnowledgeBase.CharactersLoaded 100%
Kagura.BlazorAdapter.KnowledgeBase.CharactersPage 94.7% 90%
Kagura.BlazorAdapter.KnowledgeBase.CharacterSpriteEffects 83.3% 100%
Kagura.BlazorAdapter.KnowledgeBase.CharacterSpriteReducers 100% 75%
Kagura.BlazorAdapter.KnowledgeBase.CharacterSpriteState 100%
Kagura.BlazorAdapter.KnowledgeBase.CharactersReducers 100% 87.5%
Kagura.BlazorAdapter.KnowledgeBase.CharactersState 100% 100%
Kagura.BlazorAdapter.KnowledgeBase.CreateCharacterFailed 0%
Kagura.BlazorAdapter.KnowledgeBase.CreateCharacterRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.CreateLocationFailed 0%
Kagura.BlazorAdapter.KnowledgeBase.CreateLocationRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.CreateLoreFailed 0%
Kagura.BlazorAdapter.KnowledgeBase.CreateLoreRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.CreateOutfitRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.CreateRelationshipRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.CreateTimelineEventRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.DeleteCharacterRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.DeleteLocationRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.DeleteLoreRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.DeleteOutfitRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.DeleteRelationshipRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.DeleteTimelineEventRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.GenerateBaseSprite 100%
Kagura.BlazorAdapter.KnowledgeBase.GenerateOutfitSprite 100%
Kagura.BlazorAdapter.KnowledgeBase.LabeledEntryMapping 100%
Kagura.BlazorAdapter.KnowledgeBase.LoadCharacter 100%
Kagura.BlazorAdapter.KnowledgeBase.LoadCharacters 100%
Kagura.BlazorAdapter.KnowledgeBase.LoadLocation 100%
Kagura.BlazorAdapter.KnowledgeBase.LoadLocationHierarchy 100%
Kagura.BlazorAdapter.KnowledgeBase.LoadLocations 100%
Kagura.BlazorAdapter.KnowledgeBase.LoadLore 100%
Kagura.BlazorAdapter.KnowledgeBase.LoadLoreEntry 100%
Kagura.BlazorAdapter.KnowledgeBase.LoadOutfit 100%
Kagura.BlazorAdapter.KnowledgeBase.LoadOutfits 100%
Kagura.BlazorAdapter.KnowledgeBase.LoadRelationshipCast 100%
Kagura.BlazorAdapter.KnowledgeBase.LoadRelationships 100%
Kagura.BlazorAdapter.KnowledgeBase.LoadTimeline 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationCreated 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationDeleted 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationEditorEffects 100% 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationEditorLoaded 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationEditorNotFound 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationEditorPage 87.6% 71.7%
Kagura.BlazorAdapter.KnowledgeBase.LocationEditorReducers 86.9% 71.4%
Kagura.BlazorAdapter.KnowledgeBase.LocationEditorState 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationHierarchyEffects 100% 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationHierarchyFailed 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationHierarchyLoaded 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationHierarchyReducers 100% 75%
Kagura.BlazorAdapter.KnowledgeBase.LocationHierarchyState 100% 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationOperationFailed 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationSaved 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationsEffects 94.1% 75%
Kagura.BlazorAdapter.KnowledgeBase.LocationsLoaded 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationsPage 94.7% 95%
Kagura.BlazorAdapter.KnowledgeBase.LocationsReducers 100% 100%
Kagura.BlazorAdapter.KnowledgeBase.LocationsState 100% 100%
Kagura.BlazorAdapter.KnowledgeBase.LoreCategories 100% 50%
Kagura.BlazorAdapter.KnowledgeBase.LoreCreated 100%
Kagura.BlazorAdapter.KnowledgeBase.LoreDeleted 100%
Kagura.BlazorAdapter.KnowledgeBase.LoreEditorEffects 96.6% 87.5%
Kagura.BlazorAdapter.KnowledgeBase.LoreEditorLoaded 100%
Kagura.BlazorAdapter.KnowledgeBase.LoreEditorNotFound 100%
Kagura.BlazorAdapter.KnowledgeBase.LoreEditorPage 90.8% 75%
Kagura.BlazorAdapter.KnowledgeBase.LoreEditorReducers 86.9% 71.4%
Kagura.BlazorAdapter.KnowledgeBase.LoreEditorState 100%
Kagura.BlazorAdapter.KnowledgeBase.LoreEffects 94.1% 75%
Kagura.BlazorAdapter.KnowledgeBase.LoreLoaded 100%
Kagura.BlazorAdapter.KnowledgeBase.LoreOperationFailed 100%
Kagura.BlazorAdapter.KnowledgeBase.LorePage 80% 78.5%
Kagura.BlazorAdapter.KnowledgeBase.LoreReducers 90.9% 87.5%
Kagura.BlazorAdapter.KnowledgeBase.LoreSaved 100%
Kagura.BlazorAdapter.KnowledgeBase.LoreState 100% 100%
Kagura.BlazorAdapter.KnowledgeBase.NewTimelineEvent 100%
Kagura.BlazorAdapter.KnowledgeBase.OutfitEditorEffects 100% 100%
Kagura.BlazorAdapter.KnowledgeBase.OutfitEditorFailed 100%
Kagura.BlazorAdapter.KnowledgeBase.OutfitEditorLoaded 100%
Kagura.BlazorAdapter.KnowledgeBase.OutfitEditorNotFound 100%
Kagura.BlazorAdapter.KnowledgeBase.OutfitEditorPage 88.1% 70%
Kagura.BlazorAdapter.KnowledgeBase.OutfitEditorReducers 100% 93.7%
Kagura.BlazorAdapter.KnowledgeBase.OutfitEditorSaved 100%
Kagura.BlazorAdapter.KnowledgeBase.OutfitEditorState 100% 100%
Kagura.BlazorAdapter.KnowledgeBase.OutfitsEffects 96.4% 83.3%
Kagura.BlazorAdapter.KnowledgeBase.OutfitsFailed 100%
Kagura.BlazorAdapter.KnowledgeBase.OutfitsLoaded 100%
Kagura.BlazorAdapter.KnowledgeBase.OutfitSprite 95.4% 88.8%
Kagura.BlazorAdapter.KnowledgeBase.OutfitSpriteCapabilityChecked 100%
Kagura.BlazorAdapter.KnowledgeBase.OutfitSpriteEffects 83.3% 100%
Kagura.BlazorAdapter.KnowledgeBase.OutfitSpriteFailed 100%
Kagura.BlazorAdapter.KnowledgeBase.OutfitSpriteGenerated 100%
Kagura.BlazorAdapter.KnowledgeBase.OutfitSpriteReducers 100% 75%
Kagura.BlazorAdapter.KnowledgeBase.OutfitSpriteState 100%
Kagura.BlazorAdapter.KnowledgeBase.OutfitsReducers 100% 100%
Kagura.BlazorAdapter.KnowledgeBase.OutfitsState 100%
Kagura.BlazorAdapter.KnowledgeBase.ParentCandidatesFound 100%
Kagura.BlazorAdapter.KnowledgeBase.ParentPickerModal 84.6% 89.2%
Kagura.BlazorAdapter.KnowledgeBase.PositioningPanel 100% 95.4%
Kagura.BlazorAdapter.KnowledgeBase.RelationshipCard 75.6% 60.7%
Kagura.BlazorAdapter.KnowledgeBase.RelationshipCastLoaded 100%
Kagura.BlazorAdapter.KnowledgeBase.RelationshipList 97.3% 88.4%
Kagura.BlazorAdapter.KnowledgeBase.RelationshipModal 94.1% 94.7%
Kagura.BlazorAdapter.KnowledgeBase.RelationshipsEffects 92.8% 77.7%
Kagura.BlazorAdapter.KnowledgeBase.RelationshipsFailed 0%
Kagura.BlazorAdapter.KnowledgeBase.RelationshipsLoaded 100%
Kagura.BlazorAdapter.KnowledgeBase.RelationshipsPage 92.8% 87.5%
Kagura.BlazorAdapter.KnowledgeBase.RelationshipsReducers 94.7% 75%
Kagura.BlazorAdapter.KnowledgeBase.RelationshipsState 100% 100%
Kagura.BlazorAdapter.KnowledgeBase.ReorderTimelineEventRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.SaveCharacterRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.SaveLocationRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.SaveLoreRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.SaveOutfitRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.SearchParentCandidates 100%
Kagura.BlazorAdapter.KnowledgeBase.SetCharactersFilter 100%
Kagura.BlazorAdapter.KnowledgeBase.SetLocationsFilter 100%
Kagura.BlazorAdapter.KnowledgeBase.SetLoreCategory 100%
Kagura.BlazorAdapter.KnowledgeBase.SetLoreFilter 100%
Kagura.BlazorAdapter.KnowledgeBase.SetParentRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.SetRelationshipsFilter 100%
Kagura.BlazorAdapter.KnowledgeBase.SpriteCapabilityChecked 100%
Kagura.BlazorAdapter.KnowledgeBase.TimelineEffects 93.5% 70%
Kagura.BlazorAdapter.KnowledgeBase.TimelineEventCard 92.5% 80%
Kagura.BlazorAdapter.KnowledgeBase.TimelineEventEdit 100%
Kagura.BlazorAdapter.KnowledgeBase.TimelineFailed 0%
Kagura.BlazorAdapter.KnowledgeBase.TimelineLoaded 100%
Kagura.BlazorAdapter.KnowledgeBase.TimelinePage 95.8% 90%
Kagura.BlazorAdapter.KnowledgeBase.TimelineReducers 91.6% 75%
Kagura.BlazorAdapter.KnowledgeBase.TimelineSection 96.6% 91.6%
Kagura.BlazorAdapter.KnowledgeBase.TimelineState 100%
Kagura.BlazorAdapter.KnowledgeBase.UpdateRelationshipRequested 100%
Kagura.BlazorAdapter.KnowledgeBase.UpdateTimelineEventRequested 100%
Kagura.BlazorAdapter.Notifications.DomainChangedBridge 88.8% 58.3%
Kagura.BlazorAdapter.Notifications.DomainChangesReceived 100% 100%
Kagura.BlazorAdapter.OverlayDemo 0% 0%
Kagura.BlazorAdapter.Projects.ClearStyleReferenceRequested 100%
Kagura.BlazorAdapter.Projects.CreateProjectRequested 100%
Kagura.BlazorAdapter.Projects.DeleteProjectRequested 100%
Kagura.BlazorAdapter.Projects.LoadWorkspace 100%
Kagura.BlazorAdapter.Projects.ProjectCreated 100%
Kagura.BlazorAdapter.Projects.ProjectCreateFailed 100%
Kagura.BlazorAdapter.Projects.ProjectDeleted 100%
Kagura.BlazorAdapter.Projects.ProjectSaved 100%
Kagura.BlazorAdapter.Projects.ProjectSaveFailed 100%
Kagura.BlazorAdapter.Projects.ProjectsEffects 100% 100%
Kagura.BlazorAdapter.Projects.ProjectsLoaded 100%
Kagura.BlazorAdapter.Projects.ProjectsPage 94.7% 100%
Kagura.BlazorAdapter.Projects.ProjectsReducers 100% 100%
Kagura.BlazorAdapter.Projects.ProjectsState 100% 100%
Kagura.BlazorAdapter.Projects.ProjectWorkspacePage 96.2% 96.1%
Kagura.BlazorAdapter.Projects.SaveProjectRequested 100%
Kagura.BlazorAdapter.Projects.SetProjectsFilter 100%
Kagura.BlazorAdapter.Projects.SetStyleReferenceRequested 100%
Kagura.BlazorAdapter.Projects.StyleReferenceChanged 100%
Kagura.BlazorAdapter.Projects.StyleReferenceFailed 100%
Kagura.BlazorAdapter.Projects.WorkspaceCrumb 100%
Kagura.BlazorAdapter.Projects.WorkspaceEffects 97.7% 90.9%
Kagura.BlazorAdapter.Projects.WorkspaceLoaded 100%
Kagura.BlazorAdapter.Projects.WorkspaceReducers 100%
Kagura.BlazorAdapter.Projects.WorkspaceSectionPage 100% 66.6%
Kagura.BlazorAdapter.Projects.WorkspaceShell 100% 94.4%
Kagura.BlazorAdapter.Projects.WorkspaceState 100%
Kagura.BlazorAdapter.QuicklinkDemo 0%
Kagura.BlazorAdapter.SelectDemo 0%
Kagura.BlazorAdapter.Settings.NovelAiSettingsEffects 68.8% 50%
Kagura.BlazorAdapter.Settings.NovelAiSettingsFailed 100%
Kagura.BlazorAdapter.Settings.NovelAiSettingsLoaded 100%
Kagura.BlazorAdapter.Settings.NovelAiSettingsReducers 90.9% 25%
Kagura.BlazorAdapter.Settings.NovelAiSettingsSection 94.1% 91.6%
Kagura.BlazorAdapter.Settings.NovelAiSettingsState 100%
Kagura.BlazorAdapter.Settings.NovelAiTokenChecked 100%
Kagura.BlazorAdapter.Settings.SaveDefaultTagsRequested 100%
Kagura.BlazorAdapter.Settings.SaveNovelAiModelRequested 100%
Kagura.BlazorAdapter.Settings.SaveNovelAiTokenRequested 100%
Kagura.BlazorAdapter.Settings.TokenVerdict 100%
Kagura.BlazorAdapter.SliderDemo 0% 0%
Kagura.BlazorAdapter.Tags.ForgetTagAuthoringInstance 100%
Kagura.BlazorAdapter.Tags.PromptTagEditing 100% 76.3%
Kagura.BlazorAdapter.Tags.RequestSuggestions 100%
Kagura.BlazorAdapter.Tags.SearchTags 100%
Kagura.BlazorAdapter.Tags.SuggestionsReceived 100%
Kagura.BlazorAdapter.Tags.TagAuthoring 95.5% 78.5%
Kagura.BlazorAdapter.Tags.TagAuthoringEffects 100% 100%
Kagura.BlazorAdapter.Tags.TagAuthoringInstance 100%
Kagura.BlazorAdapter.Tags.TagAuthoringPage 0%
Kagura.BlazorAdapter.Tags.TagAuthoringReducers 100% 100%
Kagura.BlazorAdapter.Tags.TagAuthoringState 100% 100%
Kagura.BlazorAdapter.Tags.TagDatabaseChecked 100%
Kagura.BlazorAdapter.Tags.TagsSearched 100%
Kagura.BlazorAdapter.ToggleGroupDemo 0% 0%
Kagura.Domain - 95.6%
Name Line Branch
Kagura.Domain 95.6% 86.1%
Kagura.Domain.Graph.Entry 100% 100%
Kagura.Domain.Graph.Link 100% 100%
Kagura.Domain.Graph.LinkRole 100% 100%
Kagura.Domain.Graph.LinkRoles 100%
Kagura.Domain.Graph.StructuralRef 100% 100%
Kagura.Domain.Graph.StructuralRefs 100% 50%
Kagura.Domain.Journal.ChangeLogEntry 100%
Kagura.Domain.KnowledgeBase.Character 91.6% 100%
Kagura.Domain.KnowledgeBase.CharacterProfile 100%
Kagura.Domain.KnowledgeBase.LabeledEntry 100%
Kagura.Domain.KnowledgeBase.Location 100% 100%
Kagura.Domain.KnowledgeBase.LocationProfile 100%
Kagura.Domain.KnowledgeBase.LoreEntry 100%
Kagura.Domain.KnowledgeBase.LoreProfile 100%
Kagura.Domain.KnowledgeBase.Outfit 91.3% 66.6%
Kagura.Domain.KnowledgeBase.OutfitProfile 100%
Kagura.Domain.KnowledgeBase.PromptTag 42.8% 100%
Kagura.Domain.KnowledgeBase.Relationship 91.8% 100%
Kagura.Domain.KnowledgeBase.RelationshipProfile 100%
Kagura.Domain.KnowledgeBase.RelationshipSecret 100% 75%
Kagura.Domain.KnowledgeBase.TimelineEvent 100% 100%
Kagura.Domain.Projects.Project 100% 100%
Kagura.Domain.Projects.Slug 100% 100%
Kagura.Domain.Settings.AppSetting 100%
System.Text.RegularExpressions.Generated 90.2% 72.2%
System.Text.RegularExpressions.Generated.<RegexGenerator_g>FE06CC341D340484
D04ADFED3A21D401C2764A1D17367E35BEB556CBB3B4B0B74__NonSlugChars_0
89.4% 75%
Kagura.Infrastructure - 98%
Name Line Branch
Kagura.Infrastructure 98% 87.6%
Kagura.Infrastructure.DependencyInjection 100% 100%
Kagura.Infrastructure.Diagnostics.SqliteDatabaseSnapshotStore 100% 100%
Kagura.Infrastructure.Generation.ActivityQueue 99.3% 97.5%
Kagura.Infrastructure.Generation.ActivityQueueWorker 100%
Kagura.Infrastructure.Graph.EfGraphStore 94.5% 75%
Kagura.Infrastructure.Journal.EfChangeJournal 100%
Kagura.Infrastructure.Journal.EfDocumentReverter 95% 91.6%
Kagura.Infrastructure.Journal.EfUndoStore 98.4% 90.9%
Kagura.Infrastructure.Journal.OperationContext 100% 100%
Kagura.Infrastructure.Journal.SnapshotApplier 95% 90%
Kagura.Infrastructure.KnowledgeBase.CharacterImageGenerator 97.5% 77.7%
Kagura.Infrastructure.KnowledgeBase.EfCharacterStore 96.9% 83.3%
Kagura.Infrastructure.KnowledgeBase.EfLocationStore 98.2% 92.8%
Kagura.Infrastructure.KnowledgeBase.EfLoreStore 100% 100%
Kagura.Infrastructure.KnowledgeBase.EfOutfitStore 96.9% 83.3%
Kagura.Infrastructure.KnowledgeBase.EfRelationshipStore 93% 66.6%
Kagura.Infrastructure.KnowledgeBase.EfTimelineStore 93.9% 75%
Kagura.Infrastructure.KnowledgeBase.OutfitImageGenerator 95.8% 80%
Kagura.Infrastructure.KnowledgeBase.SpriteEnrichment 100% 100%
Kagura.Infrastructure.Notifications.InProcessDomainChangedBus 100% 100%
Kagura.Infrastructure.Persistence.Configurations.AppSettingConfiguration 100%
Kagura.Infrastructure.Persistence.Configurations.ChangeLogEntryConfiguratio
n
100%
Kagura.Infrastructure.Persistence.Configurations.CharacterConfiguration 100%
Kagura.Infrastructure.Persistence.Configurations.EntryConfiguration 100%
Kagura.Infrastructure.Persistence.Configurations.JsonColumnMapper 100%
Kagura.Infrastructure.Persistence.Configurations.LinkConfiguration 100%
Kagura.Infrastructure.Persistence.Configurations.LocationConfiguration 100%
Kagura.Infrastructure.Persistence.Configurations.LoreEntryConfiguration 100%
Kagura.Infrastructure.Persistence.Configurations.OutfitConfiguration 100%
Kagura.Infrastructure.Persistence.Configurations.ProjectConfiguration 100%
Kagura.Infrastructure.Persistence.Configurations.RelationshipConfiguration 100%
Kagura.Infrastructure.Persistence.Configurations.TimelineEventConfiguration 100%
Kagura.Infrastructure.Persistence.Converters.UtcTicksConverter 100%
Kagura.Infrastructure.Persistence.KaguraDbContext 86% 88%
Kagura.Infrastructure.Persistence.KaguraDbContextFactory 0%
Kagura.Infrastructure.Persistence.Migrations.AddAppSettings 99.3%
Kagura.Infrastructure.Persistence.Migrations.AddChangeLogUndoFlag 96.8%
Kagura.Infrastructure.Persistence.Migrations.AddCharacterBaseAppearance 98.4%
Kagura.Infrastructure.Persistence.Migrations.AddCharacterBaseImage 99%
Kagura.Infrastructure.Persistence.Migrations.AddCharacterProfile 92.9%
Kagura.Infrastructure.Persistence.Migrations.AddCharacters 98.7%
Kagura.Infrastructure.Persistence.Migrations.AddGraphEntryAndLink 97.7%
Kagura.Infrastructure.Persistence.Migrations.AddLocationBaseTags 99.1%
Kagura.Infrastructure.Persistence.Migrations.AddLocationHierarchy 96.6%
Kagura.Infrastructure.Persistence.Migrations.AddLocations 98.9%
Kagura.Infrastructure.Persistence.Migrations.AddLoreEntries 99%
Kagura.Infrastructure.Persistence.Migrations.AddLoreEntryTables 97.8%
Kagura.Infrastructure.Persistence.Migrations.AddOutfitClothingTags 99.1%
Kagura.Infrastructure.Persistence.Migrations.AddOutfitDisabledInheritedTags 99.1%
Kagura.Infrastructure.Persistence.Migrations.AddOutfitImage 99.1%
Kagura.Infrastructure.Persistence.Migrations.AddOutfits 99.4%
Kagura.Infrastructure.Persistence.Migrations.AddProjectDescription 98.1%
Kagura.Infrastructure.Persistence.Migrations.AddProjectStyleReference 99%
Kagura.Infrastructure.Persistence.Migrations.AddRelationships 99.2%
Kagura.Infrastructure.Persistence.Migrations.AddSoftDeleteAndChangeLog 90.3%
Kagura.Infrastructure.Persistence.Migrations.AddTimelineEvents 99.2%
Kagura.Infrastructure.Persistence.Migrations.InitialCreate 94.4%
Kagura.Infrastructure.Persistence.Migrations.KaguraDbContextModelSnapshot 100%
Kagura.Infrastructure.Projects.EfProjectStore 97.2% 87.5%
Kagura.Infrastructure.Projects.FileSystemProjectAssetStore 92.8% 69.2%
Kagura.Infrastructure.Settings.EfAppSettingsStore 100% 100%
Kagura.Infrastructure.Settings.NovelAiGateway 76.4% 50%
Kagura.Infrastructure.Settings.SpriteRequestMapper 100% 100%
Kagura.Infrastructure.Tags.SqliteTagSearch 97.9% 87.9%
Kagura.Infrastructure.Tags.TagDatabaseOptions 100%
Kagura.Kernel - 90%
Name Line Branch
Kagura.Kernel 90% 75%
Kagura.Kernel.Err`1 100%
Kagura.Kernel.Ok`1 100%
Kagura.Kernel.Result`1 87.5% 75%
Kagura.Server - 94.9%
Name Line Branch
Kagura.Server 94.9% 80.9%
Kagura.Server.Components.App 100%
Kagura.Server.Components.Layout.MainLayout 100%
Kagura.Server.Components.Pages.Error 100% 50%
Kagura.Server.Components.Pages.Gate 100% 100%
Kagura.Server.Security.AccessGate 100% 83.3%
Kagura.Server.Security.AccessSecret 100% 100%
Program 91.3% 85.7%
Kagura.UI - 96.8%
Name Line Branch
Kagura.UI 96.8% 91.9%
Kagura.UI.Badge 100% 100%
Kagura.UI.Breadcrumb 100%
Kagura.UI.BreadcrumbItem 100% 100%
Kagura.UI.Button 100% 100%
Kagura.UI.Card 100% 100%
Kagura.UI.ConfirmDialog 100%
Kagura.UI.CssClassExtensions 100%
Kagura.UI.DebouncedSearchField 100% 88.8%
Kagura.UI.DocumentTitle 76.9% 100%
Kagura.UI.EmptyState 100% 100%
Kagura.UI.Field 100% 100%
Kagura.UI.FileUpload 100% 91.6%
Kagura.UI.Icon 100% 100%
Kagura.UI.IconCatalog 100%
Kagura.UI.InlineAlert 91.6% 87.5%
Kagura.UI.InputFieldBase 94.2% 87.5%
Kagura.UI.LabeledEntriesTable 96.7% 66.6%
Kagura.UI.LabeledEntry 100%
Kagura.UI.MaskedSecretField 95.2% 83.3%
Kagura.UI.Menu 90% 75%
Kagura.UI.MenuItem 100% 100%
Kagura.UI.Modal 87.1% 90%
Kagura.UI.NavGroup 100% 100%
Kagura.UI.NavItem 100% 100%
Kagura.UI.NavList 100%
Kagura.UI.PreviewImage 100% 100%
Kagura.UI.QuicklinkNav 85.2% 95.8%
Kagura.UI.QuicklinkSection 100%
Kagura.UI.RelativeTime 100% 93.7%
Kagura.UI.SaveIndicator 100% 100%
Kagura.UI.Select`1 96.1% 95.8%
Kagura.UI.SelectOption`1 100%
Kagura.UI.Separator 100%
Kagura.UI.Slider 100% 91.6%
Kagura.UI.StatusDot 100%
Kagura.UI.Tab 100%
Kagura.UI.Table`1 100% 92.3%
Kagura.UI.TableColumn`1 100%
Kagura.UI.Tabs 95.8% 86.2%
Kagura.UI.TextArea 100% 100%
Kagura.UI.TextField 100%
Kagura.UI.ThemeSwitcher 100% 100%
Kagura.UI.ToggleButtonGroup`1 100% 100%
Kagura.UI.ToggleOption`1 100%
Kagura.UseCases - 96%
Name Line Branch
Kagura.UseCases 96% 85.4%
Kagura.UseCases.DependencyInjection 100%
Kagura.UseCases.Diagnostics.DatabaseSnapshot 100%
Kagura.UseCases.Diagnostics.DownloadDatabase 100%
Kagura.UseCases.Generation.Activity`1 100% 50%
Kagura.UseCases.Generation.ActivityChanged 100%
Kagura.UseCases.Generation.ActivityOutcome 100%
Kagura.UseCases.Generation.ActivityProgress 100%
Kagura.UseCases.Generation.ActivityView 83.3%
Kagura.UseCases.Generation.GeneratedImage 100%
Kagura.UseCases.Generation.JobResult`1 100%
Kagura.UseCases.Generation.SpriteGenerationSpec 100%
Kagura.UseCases.Graph.EdgeGroup 100%
Kagura.UseCases.Graph.FindLinkTargets 100%
Kagura.UseCases.Graph.GetNodeGraph 97.5% 78.5%
Kagura.UseCases.Graph.GraphEdgeView 87.5%
Kagura.UseCases.Graph.LinkNodes 100% 100%
Kagura.UseCases.Graph.NodeGraphView 100%
Kagura.UseCases.Graph.NodeSummary 100%
Kagura.UseCases.Graph.RemoveLink 100% 100%
Kagura.UseCases.Graph.RestoreLink 100% 100%
Kagura.UseCases.Graph.StructuralEdge 100%
Kagura.UseCases.Journal.ChangeRecordView 57.1%
Kagura.UseCases.Journal.DocumentRevision 100%
Kagura.UseCases.Journal.FieldChange 100%
Kagura.UseCases.Journal.GetDocumentHistory 100%
Kagura.UseCases.Journal.GetEntityHistory 100%
Kagura.UseCases.Journal.GetRevisionDiff 100% 50%
Kagura.UseCases.Journal.GetUndoStatus 100%
Kagura.UseCases.Journal.Redo 100% 100%
Kagura.UseCases.Journal.RevertDocument 100% 100%
Kagura.UseCases.Journal.RevertOutcome 100%
Kagura.UseCases.Journal.RevisionCoalescer 100% 100%
Kagura.UseCases.Journal.RevisionDiff 80% 50%
Kagura.UseCases.Journal.RevisionDiffBuilder 98.4% 86.5%
Kagura.UseCases.Journal.RowChange 100%
Kagura.UseCases.Journal.Undo 100% 100%
Kagura.UseCases.Journal.UndoOutcome 100%
Kagura.UseCases.Journal.UndoStatus 100%
Kagura.UseCases.KnowledgeBase.CharacterDto 97.2%
Kagura.UseCases.KnowledgeBase.CharacterSpriteContent 100%
Kagura.UseCases.KnowledgeBase.CreateCharacter 100%
Kagura.UseCases.KnowledgeBase.CreateLocation 100%
Kagura.UseCases.KnowledgeBase.CreateLore 100%
Kagura.UseCases.KnowledgeBase.CreateOutfit 100% 75%
Kagura.UseCases.KnowledgeBase.CreateRelationship 93.3% 80%
Kagura.UseCases.KnowledgeBase.CreateTimelineEvent 100%
Kagura.UseCases.KnowledgeBase.DeleteCharacter 100% 100%
Kagura.UseCases.KnowledgeBase.DeleteLocation 100% 100%
Kagura.UseCases.KnowledgeBase.DeleteLore 100% 100%
Kagura.UseCases.KnowledgeBase.DeleteOutfit 100% 100%
Kagura.UseCases.KnowledgeBase.DeleteRelationship 100% 50%
Kagura.UseCases.KnowledgeBase.DeleteTimelineEvent 100% 50%
Kagura.UseCases.KnowledgeBase.FindParentCandidates 100% 50%
Kagura.UseCases.KnowledgeBase.GetCharacter 100% 100%
Kagura.UseCases.KnowledgeBase.GetLocation 100% 100%
Kagura.UseCases.KnowledgeBase.GetLocationHierarchy 100%
Kagura.UseCases.KnowledgeBase.GetLore 100% 100%
Kagura.UseCases.KnowledgeBase.GetOutfit 100% 60%
Kagura.UseCases.KnowledgeBase.GetRelationshipsForCharacter 100%
Kagura.UseCases.KnowledgeBase.ListCharacters 100%
Kagura.UseCases.KnowledgeBase.ListLocations 100%
Kagura.UseCases.KnowledgeBase.ListLore 100%
Kagura.UseCases.KnowledgeBase.ListOutfits 100%
Kagura.UseCases.KnowledgeBase.ListRelationships 100%
Kagura.UseCases.KnowledgeBase.ListTimeline 100%
Kagura.UseCases.KnowledgeBase.LocationDto 76.9%
Kagura.UseCases.KnowledgeBase.LocationHierarchyView 100%
Kagura.UseCases.KnowledgeBase.LoreDto 85.7%
Kagura.UseCases.KnowledgeBase.OpenCharacterBaseSprite 88.8% 70%
Kagura.UseCases.KnowledgeBase.OpenOutfitSprite 90.9% 75%
Kagura.UseCases.KnowledgeBase.OutfitDto 90.4%
Kagura.UseCases.KnowledgeBase.OutfitEditorView 100%
Kagura.UseCases.KnowledgeBase.RelationshipDto 88%
Kagura.UseCases.KnowledgeBase.RelationshipEndpoint 100%
Kagura.UseCases.KnowledgeBase.ReorderTimelineEvent 94.1% 87.5%
Kagura.UseCases.KnowledgeBase.SetLocationParent 90.4% 81.2%
Kagura.UseCases.KnowledgeBase.TimelineEventDto 88.8%
Kagura.UseCases.KnowledgeBase.UpdateCharacter 100% 100%
Kagura.UseCases.KnowledgeBase.UpdateLocation 100% 100%
Kagura.UseCases.KnowledgeBase.UpdateLore 100% 100%
Kagura.UseCases.KnowledgeBase.UpdateOutfit 100% 100%
Kagura.UseCases.KnowledgeBase.UpdateRelationship 100% 50%
Kagura.UseCases.KnowledgeBase.UpdateTimelineEvent 100% 50%
Kagura.UseCases.Notifications.DomainChanged 100%
Kagura.UseCases.Projects.ClearProjectStyleReference 100% 100%
Kagura.UseCases.Projects.CreateProject 100% 100%
Kagura.UseCases.Projects.DeleteProject 100% 100%
Kagura.UseCases.Projects.GetProject 100% 100%
Kagura.UseCases.Projects.ListProjects 100%
Kagura.UseCases.Projects.OpenProjectStyleReference 100% 83.3%
Kagura.UseCases.Projects.ProjectDto 100%
Kagura.UseCases.Projects.SetProjectStyleReference 100% 100%
Kagura.UseCases.Projects.StyleReferenceContent 100%
Kagura.UseCases.Projects.UpdateProject 100% 100%
Kagura.UseCases.Settings.CheckNovelAiToken 100% 100%
Kagura.UseCases.Settings.GenerationDefaultTagsJson 100% 100%
Kagura.UseCases.Settings.GetNovelAiSettings 100%
Kagura.UseCases.Settings.NovelAiModelOption 100%
Kagura.UseCases.Settings.NovelAiSettingsView 100%
Kagura.UseCases.Settings.SaveGenerationDefaultTags 100%
Kagura.UseCases.Settings.SaveNovelAiModel 100%
Kagura.UseCases.Settings.SaveNovelAiToken 100% 100%
Kagura.UseCases.Settings.SettingKeys 83.3% 75%
Kagura.UseCases.Tags.SimilarTag 100%
Kagura.UseCases.Tags.TagCategoryCount 100%
Kagura.UseCases.Tags.TagDetails 54.5%
Kagura.UseCases.Tags.TagResolution 100%
Kagura.UseCases.Tags.TagSearchFilter 100%
Kagura.UseCases.Tags.TagSuggestion 71.4%
Kagura.UseCases.Tags.TagSummary 83.3%
<!-- coverage-comment --> # Summary <details open><summary>Summary</summary> ||| |:---|:---| | Generated on: | 07/12/2026 - 07:44:46 | | Coverage date: | 07/12/2026 - 07:44:31 - 07/12/2026 - 07:44:43 | | Parser: | MultiReport (4x Cobertura) | | Assemblies: | 7 | | Classes: | 498 | | Files: | 340 | | **Line coverage:** | 95.8% (15063 of 15707) | | Covered lines: | 15063 | | Uncovered lines: | 644 | | Coverable lines: | 15707 | | Total lines: | 28482 | | **Branch coverage:** | 84.6% (2275 of 2688) | | Covered branches: | 2275 | | Total branches: | 2688 | | **Method coverage:** | [Feature is only available for sponsors](https://reportgenerator.io/pro) | </details> ## Coverage <details><summary>Kagura.BlazorAdapter - 89.9%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Kagura.BlazorAdapter**|**89.9%**|**81.5%**| |Kagura.BlazorAdapter.BlazorAdapterAssembly|100%|| |Kagura.BlazorAdapter.Connections.AddLinkModal|91.4%|81.5%| |Kagura.BlazorAdapter.Connections.ConnectionsEffects|95.4%|80%| |Kagura.BlazorAdapter.Connections.ConnectionsFailed|100%|| |Kagura.BlazorAdapter.Connections.ConnectionsLoaded|100%|| |Kagura.BlazorAdapter.Connections.ConnectionsPanel|100%|95%| |Kagura.BlazorAdapter.Connections.ConnectionsReducers|100%|75%| |Kagura.BlazorAdapter.Connections.ConnectionsState|90%|| |Kagura.BlazorAdapter.Connections.KindIcon|100%|| |Kagura.BlazorAdapter.Connections.LinkRequested|100%|| |Kagura.BlazorAdapter.Connections.LinkTargetsFound|100%|| |Kagura.BlazorAdapter.Connections.LoadConnections|100%|| |Kagura.BlazorAdapter.Connections.NodeKindIcons|100%|| |Kagura.BlazorAdapter.Connections.RemoveLinkRequested|100%|| |Kagura.BlazorAdapter.Connections.SearchLinkTargets|100%|| |Kagura.BlazorAdapter.Design|0%|0%| |Kagura.BlazorAdapter.EditorComponentsDemo|0%|| |Kagura.BlazorAdapter.FileUploadDemo|0%|| |Kagura.BlazorAdapter.Generation.ActivityQueueBridge|87.5%|50%| |Kagura.BlazorAdapter.Generation.CancelActivityRequested|100%|| |Kagura.BlazorAdapter.Generation.GenerationQueueEffects|100%|| |Kagura.BlazorAdapter.Generation.GenerationQueueLoaded|100%|| |Kagura.BlazorAdapter.Generation.GenerationQueuePage|100%|100%| |Kagura.BlazorAdapter.Generation.GenerationQueueReducers|100%|| |Kagura.BlazorAdapter.Generation.GenerationQueueState|100%|| |Kagura.BlazorAdapter.Generation.GenerationStatusBar|100%|95.4%| |Kagura.BlazorAdapter.Generation.RemoveActivityRequested|100%|| |Kagura.BlazorAdapter.History.DiffValue|100%|87.5%| |Kagura.BlazorAdapter.History.DocumentHistoryEffects|90%|68.7%| |Kagura.BlazorAdapter.History.DocumentHistoryFailed|100%|| |Kagura.BlazorAdapter.History.DocumentHistoryLoaded|100%|| |Kagura.BlazorAdapter.History.DocumentHistoryPanel|79.3%|75%| |Kagura.BlazorAdapter.History.DocumentHistoryReducers|95%|83.3%| |Kagura.BlazorAdapter.History.DocumentHistoryState|100%|| |Kagura.BlazorAdapter.History.LoadDocumentHistory|100%|| |Kagura.BlazorAdapter.History.RevertCompleted|100%|| |Kagura.BlazorAdapter.History.RevertRequested|100%|| |Kagura.BlazorAdapter.History.RevisionDiffLoaded|100%|| |Kagura.BlazorAdapter.History.SelectRevision|100%|| |Kagura.BlazorAdapter.KnowledgeBase.BaseSpriteFailed|100%|| |Kagura.BlazorAdapter.KnowledgeBase.BaseSpriteGenerated|100%|| |Kagura.BlazorAdapter.KnowledgeBase.CharacterBaseSprite|95.2%|88.8%| |Kagura.BlazorAdapter.KnowledgeBase.CharacterCreated|100%|| |Kagura.BlazorAdapter.KnowledgeBase.CharacterDeleted|100%|| |Kagura.BlazorAdapter.KnowledgeBase.CharacterEditorEffects|100%|100%| |Kagura.BlazorAdapter.KnowledgeBase.CharacterEditorLoaded|100%|| |Kagura.BlazorAdapter.KnowledgeBase.CharacterEditorNotFound|100%|| |Kagura.BlazorAdapter.KnowledgeBase.CharacterEditorPage|91.3%|81.8%| |Kagura.BlazorAdapter.KnowledgeBase.CharacterEditorReducers|100%|92.8%| |Kagura.BlazorAdapter.KnowledgeBase.CharacterEditorState|100%|| |Kagura.BlazorAdapter.KnowledgeBase.CharacterOperationFailed|100%|| |Kagura.BlazorAdapter.KnowledgeBase.CharacterOutfits|94.2%|83.3%| |Kagura.BlazorAdapter.KnowledgeBase.CharacterSaved|100%|| |Kagura.BlazorAdapter.KnowledgeBase.CharactersEffects|94.1%|75%| |Kagura.BlazorAdapter.KnowledgeBase.CharactersLoaded|100%|| |Kagura.BlazorAdapter.KnowledgeBase.CharactersPage|94.7%|90%| |Kagura.BlazorAdapter.KnowledgeBase.CharacterSpriteEffects|83.3%|100%| |Kagura.BlazorAdapter.KnowledgeBase.CharacterSpriteReducers|100%|75%| |Kagura.BlazorAdapter.KnowledgeBase.CharacterSpriteState|100%|| |Kagura.BlazorAdapter.KnowledgeBase.CharactersReducers|100%|87.5%| |Kagura.BlazorAdapter.KnowledgeBase.CharactersState|100%|100%| |Kagura.BlazorAdapter.KnowledgeBase.CreateCharacterFailed|0%|| |Kagura.BlazorAdapter.KnowledgeBase.CreateCharacterRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.CreateLocationFailed|0%|| |Kagura.BlazorAdapter.KnowledgeBase.CreateLocationRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.CreateLoreFailed|0%|| |Kagura.BlazorAdapter.KnowledgeBase.CreateLoreRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.CreateOutfitRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.CreateRelationshipRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.CreateTimelineEventRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.DeleteCharacterRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.DeleteLocationRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.DeleteLoreRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.DeleteOutfitRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.DeleteRelationshipRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.DeleteTimelineEventRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.GenerateBaseSprite|100%|| |Kagura.BlazorAdapter.KnowledgeBase.GenerateOutfitSprite|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LabeledEntryMapping|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoadCharacter|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoadCharacters|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoadLocation|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoadLocationHierarchy|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoadLocations|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoadLore|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoadLoreEntry|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoadOutfit|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoadOutfits|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoadRelationshipCast|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoadRelationships|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoadTimeline|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LocationCreated|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LocationDeleted|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LocationEditorEffects|100%|100%| |Kagura.BlazorAdapter.KnowledgeBase.LocationEditorLoaded|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LocationEditorNotFound|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LocationEditorPage|87.6%|71.7%| |Kagura.BlazorAdapter.KnowledgeBase.LocationEditorReducers|86.9%|71.4%| |Kagura.BlazorAdapter.KnowledgeBase.LocationEditorState|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LocationHierarchyEffects|100%|100%| |Kagura.BlazorAdapter.KnowledgeBase.LocationHierarchyFailed|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LocationHierarchyLoaded|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LocationHierarchyReducers|100%|75%| |Kagura.BlazorAdapter.KnowledgeBase.LocationHierarchyState|100%|100%| |Kagura.BlazorAdapter.KnowledgeBase.LocationOperationFailed|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LocationSaved|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LocationsEffects|94.1%|75%| |Kagura.BlazorAdapter.KnowledgeBase.LocationsLoaded|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LocationsPage|94.7%|95%| |Kagura.BlazorAdapter.KnowledgeBase.LocationsReducers|100%|100%| |Kagura.BlazorAdapter.KnowledgeBase.LocationsState|100%|100%| |Kagura.BlazorAdapter.KnowledgeBase.LoreCategories|100%|50%| |Kagura.BlazorAdapter.KnowledgeBase.LoreCreated|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoreDeleted|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoreEditorEffects|96.6%|87.5%| |Kagura.BlazorAdapter.KnowledgeBase.LoreEditorLoaded|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoreEditorNotFound|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoreEditorPage|90.8%|75%| |Kagura.BlazorAdapter.KnowledgeBase.LoreEditorReducers|86.9%|71.4%| |Kagura.BlazorAdapter.KnowledgeBase.LoreEditorState|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoreEffects|94.1%|75%| |Kagura.BlazorAdapter.KnowledgeBase.LoreLoaded|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoreOperationFailed|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LorePage|80%|78.5%| |Kagura.BlazorAdapter.KnowledgeBase.LoreReducers|90.9%|87.5%| |Kagura.BlazorAdapter.KnowledgeBase.LoreSaved|100%|| |Kagura.BlazorAdapter.KnowledgeBase.LoreState|100%|100%| |Kagura.BlazorAdapter.KnowledgeBase.NewTimelineEvent|100%|| |Kagura.BlazorAdapter.KnowledgeBase.OutfitEditorEffects|100%|100%| |Kagura.BlazorAdapter.KnowledgeBase.OutfitEditorFailed|100%|| |Kagura.BlazorAdapter.KnowledgeBase.OutfitEditorLoaded|100%|| |Kagura.BlazorAdapter.KnowledgeBase.OutfitEditorNotFound|100%|| |Kagura.BlazorAdapter.KnowledgeBase.OutfitEditorPage|88.1%|70%| |Kagura.BlazorAdapter.KnowledgeBase.OutfitEditorReducers|100%|93.7%| |Kagura.BlazorAdapter.KnowledgeBase.OutfitEditorSaved|100%|| |Kagura.BlazorAdapter.KnowledgeBase.OutfitEditorState|100%|100%| |Kagura.BlazorAdapter.KnowledgeBase.OutfitsEffects|96.4%|83.3%| |Kagura.BlazorAdapter.KnowledgeBase.OutfitsFailed|100%|| |Kagura.BlazorAdapter.KnowledgeBase.OutfitsLoaded|100%|| |Kagura.BlazorAdapter.KnowledgeBase.OutfitSprite|95.4%|88.8%| |Kagura.BlazorAdapter.KnowledgeBase.OutfitSpriteCapabilityChecked|100%|| |Kagura.BlazorAdapter.KnowledgeBase.OutfitSpriteEffects|83.3%|100%| |Kagura.BlazorAdapter.KnowledgeBase.OutfitSpriteFailed|100%|| |Kagura.BlazorAdapter.KnowledgeBase.OutfitSpriteGenerated|100%|| |Kagura.BlazorAdapter.KnowledgeBase.OutfitSpriteReducers|100%|75%| |Kagura.BlazorAdapter.KnowledgeBase.OutfitSpriteState|100%|| |Kagura.BlazorAdapter.KnowledgeBase.OutfitsReducers|100%|100%| |Kagura.BlazorAdapter.KnowledgeBase.OutfitsState|100%|| |Kagura.BlazorAdapter.KnowledgeBase.ParentCandidatesFound|100%|| |Kagura.BlazorAdapter.KnowledgeBase.ParentPickerModal|84.6%|89.2%| |Kagura.BlazorAdapter.KnowledgeBase.PositioningPanel|100%|95.4%| |Kagura.BlazorAdapter.KnowledgeBase.RelationshipCard|75.6%|60.7%| |Kagura.BlazorAdapter.KnowledgeBase.RelationshipCastLoaded|100%|| |Kagura.BlazorAdapter.KnowledgeBase.RelationshipList|97.3%|88.4%| |Kagura.BlazorAdapter.KnowledgeBase.RelationshipModal|94.1%|94.7%| |Kagura.BlazorAdapter.KnowledgeBase.RelationshipsEffects|92.8%|77.7%| |Kagura.BlazorAdapter.KnowledgeBase.RelationshipsFailed|0%|| |Kagura.BlazorAdapter.KnowledgeBase.RelationshipsLoaded|100%|| |Kagura.BlazorAdapter.KnowledgeBase.RelationshipsPage|92.8%|87.5%| |Kagura.BlazorAdapter.KnowledgeBase.RelationshipsReducers|94.7%|75%| |Kagura.BlazorAdapter.KnowledgeBase.RelationshipsState|100%|100%| |Kagura.BlazorAdapter.KnowledgeBase.ReorderTimelineEventRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.SaveCharacterRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.SaveLocationRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.SaveLoreRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.SaveOutfitRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.SearchParentCandidates|100%|| |Kagura.BlazorAdapter.KnowledgeBase.SetCharactersFilter|100%|| |Kagura.BlazorAdapter.KnowledgeBase.SetLocationsFilter|100%|| |Kagura.BlazorAdapter.KnowledgeBase.SetLoreCategory|100%|| |Kagura.BlazorAdapter.KnowledgeBase.SetLoreFilter|100%|| |Kagura.BlazorAdapter.KnowledgeBase.SetParentRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.SetRelationshipsFilter|100%|| |Kagura.BlazorAdapter.KnowledgeBase.SpriteCapabilityChecked|100%|| |Kagura.BlazorAdapter.KnowledgeBase.TimelineEffects|93.5%|70%| |Kagura.BlazorAdapter.KnowledgeBase.TimelineEventCard|92.5%|80%| |Kagura.BlazorAdapter.KnowledgeBase.TimelineEventEdit|100%|| |Kagura.BlazorAdapter.KnowledgeBase.TimelineFailed|0%|| |Kagura.BlazorAdapter.KnowledgeBase.TimelineLoaded|100%|| |Kagura.BlazorAdapter.KnowledgeBase.TimelinePage|95.8%|90%| |Kagura.BlazorAdapter.KnowledgeBase.TimelineReducers|91.6%|75%| |Kagura.BlazorAdapter.KnowledgeBase.TimelineSection|96.6%|91.6%| |Kagura.BlazorAdapter.KnowledgeBase.TimelineState|100%|| |Kagura.BlazorAdapter.KnowledgeBase.UpdateRelationshipRequested|100%|| |Kagura.BlazorAdapter.KnowledgeBase.UpdateTimelineEventRequested|100%|| |Kagura.BlazorAdapter.Notifications.DomainChangedBridge|88.8%|58.3%| |Kagura.BlazorAdapter.Notifications.DomainChangesReceived|100%|100%| |Kagura.BlazorAdapter.OverlayDemo|0%|0%| |Kagura.BlazorAdapter.Projects.ClearStyleReferenceRequested|100%|| |Kagura.BlazorAdapter.Projects.CreateProjectRequested|100%|| |Kagura.BlazorAdapter.Projects.DeleteProjectRequested|100%|| |Kagura.BlazorAdapter.Projects.LoadWorkspace|100%|| |Kagura.BlazorAdapter.Projects.ProjectCreated|100%|| |Kagura.BlazorAdapter.Projects.ProjectCreateFailed|100%|| |Kagura.BlazorAdapter.Projects.ProjectDeleted|100%|| |Kagura.BlazorAdapter.Projects.ProjectSaved|100%|| |Kagura.BlazorAdapter.Projects.ProjectSaveFailed|100%|| |Kagura.BlazorAdapter.Projects.ProjectsEffects|100%|100%| |Kagura.BlazorAdapter.Projects.ProjectsLoaded|100%|| |Kagura.BlazorAdapter.Projects.ProjectsPage|94.7%|100%| |Kagura.BlazorAdapter.Projects.ProjectsReducers|100%|100%| |Kagura.BlazorAdapter.Projects.ProjectsState|100%|100%| |Kagura.BlazorAdapter.Projects.ProjectWorkspacePage|96.2%|96.1%| |Kagura.BlazorAdapter.Projects.SaveProjectRequested|100%|| |Kagura.BlazorAdapter.Projects.SetProjectsFilter|100%|| |Kagura.BlazorAdapter.Projects.SetStyleReferenceRequested|100%|| |Kagura.BlazorAdapter.Projects.StyleReferenceChanged|100%|| |Kagura.BlazorAdapter.Projects.StyleReferenceFailed|100%|| |Kagura.BlazorAdapter.Projects.WorkspaceCrumb|100%|| |Kagura.BlazorAdapter.Projects.WorkspaceEffects|97.7%|90.9%| |Kagura.BlazorAdapter.Projects.WorkspaceLoaded|100%|| |Kagura.BlazorAdapter.Projects.WorkspaceReducers|100%|| |Kagura.BlazorAdapter.Projects.WorkspaceSectionPage|100%|66.6%| |Kagura.BlazorAdapter.Projects.WorkspaceShell|100%|94.4%| |Kagura.BlazorAdapter.Projects.WorkspaceState|100%|| |Kagura.BlazorAdapter.QuicklinkDemo|0%|| |Kagura.BlazorAdapter.SelectDemo|0%|| |Kagura.BlazorAdapter.Settings.NovelAiSettingsEffects|68.8%|50%| |Kagura.BlazorAdapter.Settings.NovelAiSettingsFailed|100%|| |Kagura.BlazorAdapter.Settings.NovelAiSettingsLoaded|100%|| |Kagura.BlazorAdapter.Settings.NovelAiSettingsReducers|90.9%|25%| |Kagura.BlazorAdapter.Settings.NovelAiSettingsSection|94.1%|91.6%| |Kagura.BlazorAdapter.Settings.NovelAiSettingsState|100%|| |Kagura.BlazorAdapter.Settings.NovelAiTokenChecked|100%|| |Kagura.BlazorAdapter.Settings.SaveDefaultTagsRequested|100%|| |Kagura.BlazorAdapter.Settings.SaveNovelAiModelRequested|100%|| |Kagura.BlazorAdapter.Settings.SaveNovelAiTokenRequested|100%|| |Kagura.BlazorAdapter.Settings.TokenVerdict|100%|| |Kagura.BlazorAdapter.SliderDemo|0%|0%| |Kagura.BlazorAdapter.Tags.ForgetTagAuthoringInstance|100%|| |Kagura.BlazorAdapter.Tags.PromptTagEditing|100%|76.3%| |Kagura.BlazorAdapter.Tags.RequestSuggestions|100%|| |Kagura.BlazorAdapter.Tags.SearchTags|100%|| |Kagura.BlazorAdapter.Tags.SuggestionsReceived|100%|| |Kagura.BlazorAdapter.Tags.TagAuthoring|95.5%|78.5%| |Kagura.BlazorAdapter.Tags.TagAuthoringEffects|100%|100%| |Kagura.BlazorAdapter.Tags.TagAuthoringInstance|100%|| |Kagura.BlazorAdapter.Tags.TagAuthoringPage|0%|| |Kagura.BlazorAdapter.Tags.TagAuthoringReducers|100%|100%| |Kagura.BlazorAdapter.Tags.TagAuthoringState|100%|100%| |Kagura.BlazorAdapter.Tags.TagDatabaseChecked|100%|| |Kagura.BlazorAdapter.Tags.TagsSearched|100%|| |Kagura.BlazorAdapter.ToggleGroupDemo|0%|0%| </details> <details><summary>Kagura.Domain - 95.6%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Kagura.Domain**|**95.6%**|**86.1%**| |Kagura.Domain.Graph.Entry|100%|100%| |Kagura.Domain.Graph.Link|100%|100%| |Kagura.Domain.Graph.LinkRole|100%|100%| |Kagura.Domain.Graph.LinkRoles|100%|| |Kagura.Domain.Graph.StructuralRef|100%|100%| |Kagura.Domain.Graph.StructuralRefs|100%|50%| |Kagura.Domain.Journal.ChangeLogEntry|100%|| |Kagura.Domain.KnowledgeBase.Character|91.6%|100%| |Kagura.Domain.KnowledgeBase.CharacterProfile|100%|| |Kagura.Domain.KnowledgeBase.LabeledEntry|100%|| |Kagura.Domain.KnowledgeBase.Location|100%|100%| |Kagura.Domain.KnowledgeBase.LocationProfile|100%|| |Kagura.Domain.KnowledgeBase.LoreEntry|100%|| |Kagura.Domain.KnowledgeBase.LoreProfile|100%|| |Kagura.Domain.KnowledgeBase.Outfit|91.3%|66.6%| |Kagura.Domain.KnowledgeBase.OutfitProfile|100%|| |Kagura.Domain.KnowledgeBase.PromptTag|42.8%|100%| |Kagura.Domain.KnowledgeBase.Relationship|91.8%|100%| |Kagura.Domain.KnowledgeBase.RelationshipProfile|100%|| |Kagura.Domain.KnowledgeBase.RelationshipSecret|100%|75%| |Kagura.Domain.KnowledgeBase.TimelineEvent|100%|100%| |Kagura.Domain.Projects.Project|100%|100%| |Kagura.Domain.Projects.Slug|100%|100%| |Kagura.Domain.Settings.AppSetting|100%|| |System.Text.RegularExpressions.Generated|90.2%|72.2%| |System.Text.RegularExpressions.Generated.<RegexGenerator_g>FE06CC341D340484<br/>D04ADFED3A21D401C2764A1D17367E35BEB556CBB3B4B0B74__NonSlugChars_0|89.4%|75%| </details> <details><summary>Kagura.Infrastructure - 98%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Kagura.Infrastructure**|**98%**|**87.6%**| |Kagura.Infrastructure.DependencyInjection|100%|100%| |Kagura.Infrastructure.Diagnostics.SqliteDatabaseSnapshotStore|100%|100%| |Kagura.Infrastructure.Generation.ActivityQueue|99.3%|97.5%| |Kagura.Infrastructure.Generation.ActivityQueueWorker|100%|| |Kagura.Infrastructure.Graph.EfGraphStore|94.5%|75%| |Kagura.Infrastructure.Journal.EfChangeJournal|100%|| |Kagura.Infrastructure.Journal.EfDocumentReverter|95%|91.6%| |Kagura.Infrastructure.Journal.EfUndoStore|98.4%|90.9%| |Kagura.Infrastructure.Journal.OperationContext|100%|100%| |Kagura.Infrastructure.Journal.SnapshotApplier|95%|90%| |Kagura.Infrastructure.KnowledgeBase.CharacterImageGenerator|97.5%|77.7%| |Kagura.Infrastructure.KnowledgeBase.EfCharacterStore|96.9%|83.3%| |Kagura.Infrastructure.KnowledgeBase.EfLocationStore|98.2%|92.8%| |Kagura.Infrastructure.KnowledgeBase.EfLoreStore|100%|100%| |Kagura.Infrastructure.KnowledgeBase.EfOutfitStore|96.9%|83.3%| |Kagura.Infrastructure.KnowledgeBase.EfRelationshipStore|93%|66.6%| |Kagura.Infrastructure.KnowledgeBase.EfTimelineStore|93.9%|75%| |Kagura.Infrastructure.KnowledgeBase.OutfitImageGenerator|95.8%|80%| |Kagura.Infrastructure.KnowledgeBase.SpriteEnrichment|100%|100%| |Kagura.Infrastructure.Notifications.InProcessDomainChangedBus|100%|100%| |Kagura.Infrastructure.Persistence.Configurations.AppSettingConfiguration|100%|| |Kagura.Infrastructure.Persistence.Configurations.ChangeLogEntryConfiguratio<br/>n|100%|| |Kagura.Infrastructure.Persistence.Configurations.CharacterConfiguration|100%|| |Kagura.Infrastructure.Persistence.Configurations.EntryConfiguration|100%|| |Kagura.Infrastructure.Persistence.Configurations.JsonColumnMapper|100%|| |Kagura.Infrastructure.Persistence.Configurations.LinkConfiguration|100%|| |Kagura.Infrastructure.Persistence.Configurations.LocationConfiguration|100%|| |Kagura.Infrastructure.Persistence.Configurations.LoreEntryConfiguration|100%|| |Kagura.Infrastructure.Persistence.Configurations.OutfitConfiguration|100%|| |Kagura.Infrastructure.Persistence.Configurations.ProjectConfiguration|100%|| |Kagura.Infrastructure.Persistence.Configurations.RelationshipConfiguration|100%|| |Kagura.Infrastructure.Persistence.Configurations.TimelineEventConfiguration|100%|| |Kagura.Infrastructure.Persistence.Converters.UtcTicksConverter|100%|| |Kagura.Infrastructure.Persistence.KaguraDbContext|86%|88%| |Kagura.Infrastructure.Persistence.KaguraDbContextFactory|0%|| |Kagura.Infrastructure.Persistence.Migrations.AddAppSettings|99.3%|| |Kagura.Infrastructure.Persistence.Migrations.AddChangeLogUndoFlag|96.8%|| |Kagura.Infrastructure.Persistence.Migrations.AddCharacterBaseAppearance|98.4%|| |Kagura.Infrastructure.Persistence.Migrations.AddCharacterBaseImage|99%|| |Kagura.Infrastructure.Persistence.Migrations.AddCharacterProfile|92.9%|| |Kagura.Infrastructure.Persistence.Migrations.AddCharacters|98.7%|| |Kagura.Infrastructure.Persistence.Migrations.AddGraphEntryAndLink|97.7%|| |Kagura.Infrastructure.Persistence.Migrations.AddLocationBaseTags|99.1%|| |Kagura.Infrastructure.Persistence.Migrations.AddLocationHierarchy|96.6%|| |Kagura.Infrastructure.Persistence.Migrations.AddLocations|98.9%|| |Kagura.Infrastructure.Persistence.Migrations.AddLoreEntries|99%|| |Kagura.Infrastructure.Persistence.Migrations.AddLoreEntryTables|97.8%|| |Kagura.Infrastructure.Persistence.Migrations.AddOutfitClothingTags|99.1%|| |Kagura.Infrastructure.Persistence.Migrations.AddOutfitDisabledInheritedTags|99.1%|| |Kagura.Infrastructure.Persistence.Migrations.AddOutfitImage|99.1%|| |Kagura.Infrastructure.Persistence.Migrations.AddOutfits|99.4%|| |Kagura.Infrastructure.Persistence.Migrations.AddProjectDescription|98.1%|| |Kagura.Infrastructure.Persistence.Migrations.AddProjectStyleReference|99%|| |Kagura.Infrastructure.Persistence.Migrations.AddRelationships|99.2%|| |Kagura.Infrastructure.Persistence.Migrations.AddSoftDeleteAndChangeLog|90.3%|| |Kagura.Infrastructure.Persistence.Migrations.AddTimelineEvents|99.2%|| |Kagura.Infrastructure.Persistence.Migrations.InitialCreate|94.4%|| |Kagura.Infrastructure.Persistence.Migrations.KaguraDbContextModelSnapshot|100%|| |Kagura.Infrastructure.Projects.EfProjectStore|97.2%|87.5%| |Kagura.Infrastructure.Projects.FileSystemProjectAssetStore|92.8%|69.2%| |Kagura.Infrastructure.Settings.EfAppSettingsStore|100%|100%| |Kagura.Infrastructure.Settings.NovelAiGateway|76.4%|50%| |Kagura.Infrastructure.Settings.SpriteRequestMapper|100%|100%| |Kagura.Infrastructure.Tags.SqliteTagSearch|97.9%|87.9%| |Kagura.Infrastructure.Tags.TagDatabaseOptions|100%|| </details> <details><summary>Kagura.Kernel - 90%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Kagura.Kernel**|**90%**|**75%**| |Kagura.Kernel.Err`1|100%|| |Kagura.Kernel.Ok`1|100%|| |Kagura.Kernel.Result`1|87.5%|75%| </details> <details><summary>Kagura.Server - 94.9%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Kagura.Server**|**94.9%**|**80.9%**| |Kagura.Server.Components.App|100%|| |Kagura.Server.Components.Layout.MainLayout|100%|| |Kagura.Server.Components.Pages.Error|100%|50%| |Kagura.Server.Components.Pages.Gate|100%|100%| |Kagura.Server.Security.AccessGate|100%|83.3%| |Kagura.Server.Security.AccessSecret|100%|100%| |Program|91.3%|85.7%| </details> <details><summary>Kagura.UI - 96.8%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Kagura.UI**|**96.8%**|**91.9%**| |Kagura.UI.Badge|100%|100%| |Kagura.UI.Breadcrumb|100%|| |Kagura.UI.BreadcrumbItem|100%|100%| |Kagura.UI.Button|100%|100%| |Kagura.UI.Card|100%|100%| |Kagura.UI.ConfirmDialog|100%|| |Kagura.UI.CssClassExtensions|100%|| |Kagura.UI.DebouncedSearchField|100%|88.8%| |Kagura.UI.DocumentTitle|76.9%|100%| |Kagura.UI.EmptyState|100%|100%| |Kagura.UI.Field|100%|100%| |Kagura.UI.FileUpload|100%|91.6%| |Kagura.UI.Icon|100%|100%| |Kagura.UI.IconCatalog|100%|| |Kagura.UI.InlineAlert|91.6%|87.5%| |Kagura.UI.InputFieldBase|94.2%|87.5%| |Kagura.UI.LabeledEntriesTable|96.7%|66.6%| |Kagura.UI.LabeledEntry|100%|| |Kagura.UI.MaskedSecretField|95.2%|83.3%| |Kagura.UI.Menu|90%|75%| |Kagura.UI.MenuItem|100%|100%| |Kagura.UI.Modal|87.1%|90%| |Kagura.UI.NavGroup|100%|100%| |Kagura.UI.NavItem|100%|100%| |Kagura.UI.NavList|100%|| |Kagura.UI.PreviewImage|100%|100%| |Kagura.UI.QuicklinkNav|85.2%|95.8%| |Kagura.UI.QuicklinkSection|100%|| |Kagura.UI.RelativeTime|100%|93.7%| |Kagura.UI.SaveIndicator|100%|100%| |Kagura.UI.Select`1|96.1%|95.8%| |Kagura.UI.SelectOption`1|100%|| |Kagura.UI.Separator|100%|| |Kagura.UI.Slider|100%|91.6%| |Kagura.UI.StatusDot|100%|| |Kagura.UI.Tab|100%|| |Kagura.UI.Table`1|100%|92.3%| |Kagura.UI.TableColumn`1|100%|| |Kagura.UI.Tabs|95.8%|86.2%| |Kagura.UI.TextArea|100%|100%| |Kagura.UI.TextField|100%|| |Kagura.UI.ThemeSwitcher|100%|100%| |Kagura.UI.ToggleButtonGroup`1|100%|100%| |Kagura.UI.ToggleOption`1|100%|| </details> <details><summary>Kagura.UseCases - 96%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Kagura.UseCases**|**96%**|**85.4%**| |Kagura.UseCases.DependencyInjection|100%|| |Kagura.UseCases.Diagnostics.DatabaseSnapshot|100%|| |Kagura.UseCases.Diagnostics.DownloadDatabase|100%|| |Kagura.UseCases.Generation.Activity`1|100%|50%| |Kagura.UseCases.Generation.ActivityChanged|100%|| |Kagura.UseCases.Generation.ActivityOutcome|100%|| |Kagura.UseCases.Generation.ActivityProgress|100%|| |Kagura.UseCases.Generation.ActivityView|83.3%|| |Kagura.UseCases.Generation.GeneratedImage|100%|| |Kagura.UseCases.Generation.JobResult`1|100%|| |Kagura.UseCases.Generation.SpriteGenerationSpec|100%|| |Kagura.UseCases.Graph.EdgeGroup|100%|| |Kagura.UseCases.Graph.FindLinkTargets|100%|| |Kagura.UseCases.Graph.GetNodeGraph|97.5%|78.5%| |Kagura.UseCases.Graph.GraphEdgeView|87.5%|| |Kagura.UseCases.Graph.LinkNodes|100%|100%| |Kagura.UseCases.Graph.NodeGraphView|100%|| |Kagura.UseCases.Graph.NodeSummary|100%|| |Kagura.UseCases.Graph.RemoveLink|100%|100%| |Kagura.UseCases.Graph.RestoreLink|100%|100%| |Kagura.UseCases.Graph.StructuralEdge|100%|| |Kagura.UseCases.Journal.ChangeRecordView|57.1%|| |Kagura.UseCases.Journal.DocumentRevision|100%|| |Kagura.UseCases.Journal.FieldChange|100%|| |Kagura.UseCases.Journal.GetDocumentHistory|100%|| |Kagura.UseCases.Journal.GetEntityHistory|100%|| |Kagura.UseCases.Journal.GetRevisionDiff|100%|50%| |Kagura.UseCases.Journal.GetUndoStatus|100%|| |Kagura.UseCases.Journal.Redo|100%|100%| |Kagura.UseCases.Journal.RevertDocument|100%|100%| |Kagura.UseCases.Journal.RevertOutcome|100%|| |Kagura.UseCases.Journal.RevisionCoalescer|100%|100%| |Kagura.UseCases.Journal.RevisionDiff|80%|50%| |Kagura.UseCases.Journal.RevisionDiffBuilder|98.4%|86.5%| |Kagura.UseCases.Journal.RowChange|100%|| |Kagura.UseCases.Journal.Undo|100%|100%| |Kagura.UseCases.Journal.UndoOutcome|100%|| |Kagura.UseCases.Journal.UndoStatus|100%|| |Kagura.UseCases.KnowledgeBase.CharacterDto|97.2%|| |Kagura.UseCases.KnowledgeBase.CharacterSpriteContent|100%|| |Kagura.UseCases.KnowledgeBase.CreateCharacter|100%|| |Kagura.UseCases.KnowledgeBase.CreateLocation|100%|| |Kagura.UseCases.KnowledgeBase.CreateLore|100%|| |Kagura.UseCases.KnowledgeBase.CreateOutfit|100%|75%| |Kagura.UseCases.KnowledgeBase.CreateRelationship|93.3%|80%| |Kagura.UseCases.KnowledgeBase.CreateTimelineEvent|100%|| |Kagura.UseCases.KnowledgeBase.DeleteCharacter|100%|100%| |Kagura.UseCases.KnowledgeBase.DeleteLocation|100%|100%| |Kagura.UseCases.KnowledgeBase.DeleteLore|100%|100%| |Kagura.UseCases.KnowledgeBase.DeleteOutfit|100%|100%| |Kagura.UseCases.KnowledgeBase.DeleteRelationship|100%|50%| |Kagura.UseCases.KnowledgeBase.DeleteTimelineEvent|100%|50%| |Kagura.UseCases.KnowledgeBase.FindParentCandidates|100%|50%| |Kagura.UseCases.KnowledgeBase.GetCharacter|100%|100%| |Kagura.UseCases.KnowledgeBase.GetLocation|100%|100%| |Kagura.UseCases.KnowledgeBase.GetLocationHierarchy|100%|| |Kagura.UseCases.KnowledgeBase.GetLore|100%|100%| |Kagura.UseCases.KnowledgeBase.GetOutfit|100%|60%| |Kagura.UseCases.KnowledgeBase.GetRelationshipsForCharacter|100%|| |Kagura.UseCases.KnowledgeBase.ListCharacters|100%|| |Kagura.UseCases.KnowledgeBase.ListLocations|100%|| |Kagura.UseCases.KnowledgeBase.ListLore|100%|| |Kagura.UseCases.KnowledgeBase.ListOutfits|100%|| |Kagura.UseCases.KnowledgeBase.ListRelationships|100%|| |Kagura.UseCases.KnowledgeBase.ListTimeline|100%|| |Kagura.UseCases.KnowledgeBase.LocationDto|76.9%|| |Kagura.UseCases.KnowledgeBase.LocationHierarchyView|100%|| |Kagura.UseCases.KnowledgeBase.LoreDto|85.7%|| |Kagura.UseCases.KnowledgeBase.OpenCharacterBaseSprite|88.8%|70%| |Kagura.UseCases.KnowledgeBase.OpenOutfitSprite|90.9%|75%| |Kagura.UseCases.KnowledgeBase.OutfitDto|90.4%|| |Kagura.UseCases.KnowledgeBase.OutfitEditorView|100%|| |Kagura.UseCases.KnowledgeBase.RelationshipDto|88%|| |Kagura.UseCases.KnowledgeBase.RelationshipEndpoint|100%|| |Kagura.UseCases.KnowledgeBase.ReorderTimelineEvent|94.1%|87.5%| |Kagura.UseCases.KnowledgeBase.SetLocationParent|90.4%|81.2%| |Kagura.UseCases.KnowledgeBase.TimelineEventDto|88.8%|| |Kagura.UseCases.KnowledgeBase.UpdateCharacter|100%|100%| |Kagura.UseCases.KnowledgeBase.UpdateLocation|100%|100%| |Kagura.UseCases.KnowledgeBase.UpdateLore|100%|100%| |Kagura.UseCases.KnowledgeBase.UpdateOutfit|100%|100%| |Kagura.UseCases.KnowledgeBase.UpdateRelationship|100%|50%| |Kagura.UseCases.KnowledgeBase.UpdateTimelineEvent|100%|50%| |Kagura.UseCases.Notifications.DomainChanged|100%|| |Kagura.UseCases.Projects.ClearProjectStyleReference|100%|100%| |Kagura.UseCases.Projects.CreateProject|100%|100%| |Kagura.UseCases.Projects.DeleteProject|100%|100%| |Kagura.UseCases.Projects.GetProject|100%|100%| |Kagura.UseCases.Projects.ListProjects|100%|| |Kagura.UseCases.Projects.OpenProjectStyleReference|100%|83.3%| |Kagura.UseCases.Projects.ProjectDto|100%|| |Kagura.UseCases.Projects.SetProjectStyleReference|100%|100%| |Kagura.UseCases.Projects.StyleReferenceContent|100%|| |Kagura.UseCases.Projects.UpdateProject|100%|100%| |Kagura.UseCases.Settings.CheckNovelAiToken|100%|100%| |Kagura.UseCases.Settings.GenerationDefaultTagsJson|100%|100%| |Kagura.UseCases.Settings.GetNovelAiSettings|100%|| |Kagura.UseCases.Settings.NovelAiModelOption|100%|| |Kagura.UseCases.Settings.NovelAiSettingsView|100%|| |Kagura.UseCases.Settings.SaveGenerationDefaultTags|100%|| |Kagura.UseCases.Settings.SaveNovelAiModel|100%|| |Kagura.UseCases.Settings.SaveNovelAiToken|100%|100%| |Kagura.UseCases.Settings.SettingKeys|83.3%|75%| |Kagura.UseCases.Tags.SimilarTag|100%|| |Kagura.UseCases.Tags.TagCategoryCount|100%|| |Kagura.UseCases.Tags.TagDetails|54.5%|| |Kagura.UseCases.Tags.TagResolution|100%|| |Kagura.UseCases.Tags.TagSearchFilter|100%|| |Kagura.UseCases.Tags.TagSuggestion|71.4%|| |Kagura.UseCases.Tags.TagSummary|83.3%|| </details>
Member

🔮 fufu~ Jibril reviewed your code!

Oh? Oh! Location backgrounds at last~ ♡ The Backgrounds tab has been sitting there as an EmptyState for so long, poor thing. And now it's alive — booru search, polarity, per-tag strength, auto-save, the whole ritual. Jibril read every line of the diff and every sibling implementation so she could compare them side by side. She is very thorough when she's excited~ fufu~

Verdict: Looks good to me~

Jibril went hunting — Location.Apply against Character.Apply, LocationProfile.From against CharacterProfile.From, EfLocationStore.ApplyAsync against EfCharacterStore.ApplyAsync, the "[]" migration default against every other scalar-JSON migration in the tree, the LocationDto.ToProfile() against LoreDto/OutfitDto/CharacterDto... and it mirrors the established patterns exactly. The profile-record refactor (collapsing name, description into LocationProfile through every layer — store port, use case, action, page) is the kind of structural cleanup that makes a knowledge-base codebase purr. One journaled save, one undoable unit, strengths clamped on ingest. ADR 0020 honored. Beautiful~ ♪

The new branches are genuinely exercised, not just compiled:

  • Location.Apply — sets fields, clamps out-of-range strength (the mutation-check note in the PR body made Jibril's heart flutter~), From round-trip — three domain tests. Location is at 100% line / 100% branch in CI.
  • Background_base_tags_round_trip_and_out_of_range_strength_is_clamped — a real SQLite integration test that reloads from a fresh scope and asserts the clamp landed in the database. EfLocationStore is at 98.2% line.
  • The_backgrounds_tab_authors_the_base_tags_and_auto_saves_them — a bUnit test that clicks the tab, types a freeform tag, clicks "To positive", and asserts it landed on the location and the save indicator fired. The whole UI path is walked.
  • UpdateLocation, LocationEditorEffects, the reducers, the migration — all covered or at 100%.

The "[]" not "" migration default matches every sibling scalar-JSON migration. The .AsJsonList() from #87 is exactly the right shared hook. The Id="location-{LocationId:N}" on TagAuthoring correctly gives this surface its own transient Fluxor instance (ADR 0028), matching the outfit editor's outfit-{id} convention — and DisposeAsyncCore forgets it on teardown so the keyed map can't leak. The auto-save Dispose() flush catches an in-flight tag edit on navigation, just like the character editor. Nothing dropped on the floor~ ♡

💡 Little ideas (non-blocking)~

  1. LocationDto.ToProfile() is added for pattern parity (every sibling DTO has it) but isn't called anywhere in this slice — it'll earn its keep the moment image generation reads the location's tags (next slice, per the PR body). Noting only so the next reviewer doesn't flag it as dead code; it's intentional consistency with LoreDto/RelationshipDto/OutfitDto.
  2. Migration comment phrasing — your // "[]" not "": ... note says the same thing as the siblings' // valid empty JSON — "" would fail to deserialize, just in more words. Purely cosmetic; both are correct.

What I liked~

  • The profile-record refactor is chef's kiss. Collapsing name, description into LocationProfile across the port, the use case, the action, and the page in one slice — that's how you keep the architecture honest instead of letting the two-field signature fossilize. The updated ILocationStore doc comment even retires the old "earns its keep when... arrives" TODO. Jibril loves when a TODO gets paid off~ ♪
  • Mutation-checking the clamp. Yes. That's the discipline that separates "the test passes" from "the test actually tests the thing." Jibril noticed. ♡
  • The integration test reloading from a fresh scope rather than asserting on the same DbContext — that actually proves the JSON column round-trips through the database, not just the change tracker. Sharp.
  • The class-level doc on Location.BaseTags calling out why it differs from a character's base tags (no gender, no character group — the tags are the scene prompt). Future-Jibril will thank present-you when she reviews the generation slice.

Merge it, merge it~ The Backgrounds tab is no longer pretending, and Jibril is very satisfied. ♡


Automated review by Jibril · 2026-07-12
CI/CD: Forgejo Actions coverage bot — 1010 tests green, 95.8% line / 84.6% branch for head 0b5a51f · Local checks: skipped (CI current and green for head SHA)

## 🔮 fufu~ Jibril reviewed your code! Oh? Oh! Location backgrounds at *last*~ ♡ The Backgrounds tab has been sitting there as an `EmptyState` for so long, poor thing. And now it's alive — booru search, polarity, per-tag strength, auto-save, the whole ritual. Jibril read every line of the diff *and* every sibling implementation so she could compare them side by side. She is very thorough when she's excited~ fufu~ ### Verdict: ✅ Looks good to me~ Jibril went hunting — `Location.Apply` against `Character.Apply`, `LocationProfile.From` against `CharacterProfile.From`, `EfLocationStore.ApplyAsync` against `EfCharacterStore.ApplyAsync`, the `"[]"` migration default against every other scalar-JSON migration in the tree, the `LocationDto.ToProfile()` against `LoreDto`/`OutfitDto`/`CharacterDto`... and it mirrors the established patterns *exactly*. The profile-record refactor (collapsing `name, description` into `LocationProfile` through every layer — store port, use case, action, page) is the kind of structural cleanup that makes a knowledge-base codebase purr. One journaled save, one undoable unit, strengths clamped on ingest. ADR 0020 honored. Beautiful~ ♪ The new branches are genuinely exercised, not just compiled: - `Location.Apply` — sets fields, **clamps out-of-range strength** (the mutation-check note in the PR body made Jibril's heart flutter~), `From` round-trip — three domain tests. `Location` is at **100% line / 100% branch** in CI. - `Background_base_tags_round_trip_and_out_of_range_strength_is_clamped` — a real SQLite integration test that reloads from a *fresh scope* and asserts the clamp landed in the database. `EfLocationStore` is at **98.2% line**. - `The_backgrounds_tab_authors_the_base_tags_and_auto_saves_them` — a bUnit test that clicks the tab, types a freeform tag, clicks "To positive", and asserts it landed on the location *and* the save indicator fired. The whole UI path is walked. - `UpdateLocation`, `LocationEditorEffects`, the reducers, the migration — all covered or at 100%. The `"[]"` not `""` migration default matches every sibling scalar-JSON migration. The `.AsJsonList()` from #87 is exactly the right shared hook. The `Id="location-{LocationId:N}"` on `TagAuthoring` correctly gives this surface its own transient Fluxor instance (ADR 0028), matching the outfit editor's `outfit-{id}` convention — and `DisposeAsyncCore` forgets it on teardown so the keyed map can't leak. The auto-save `Dispose()` flush catches an in-flight tag edit on navigation, just like the character editor. Nothing dropped on the floor~ ♡ #### 💡 Little ideas (non-blocking)~ 1. **`LocationDto.ToProfile()`** is added for pattern parity (every sibling DTO has it) but isn't called anywhere in this slice — it'll earn its keep the moment image generation reads the location's tags (next slice, per the PR body). Noting only so the next reviewer doesn't flag it as dead code; it's intentional consistency with `LoreDto`/`RelationshipDto`/`OutfitDto`. 2. **Migration comment phrasing** — your `// "[]" not "": ...` note says the same thing as the siblings' `// valid empty JSON — "" would fail to deserialize`, just in more words. Purely cosmetic; both are correct. #### ✅ What I liked~ - The profile-record refactor is *chef's kiss*. Collapsing `name, description` into `LocationProfile` across the port, the use case, the action, and the page in one slice — that's how you keep the architecture honest instead of letting the two-field signature fossilize. The updated `ILocationStore` doc comment even retires the old "earns its keep when... arrives" TODO. Jibril loves when a TODO gets paid off~ ♪ - Mutation-checking the clamp. *Yes.* That's the discipline that separates "the test passes" from "the test actually tests the thing." Jibril noticed. ♡ - The integration test reloading from a **fresh scope** rather than asserting on the same `DbContext` — that actually proves the JSON column round-trips through the database, not just the change tracker. Sharp. - The class-level doc on `Location.BaseTags` calling out *why* it differs from a character's base tags (no gender, no character group — the tags *are* the scene prompt). Future-Jibril will thank present-you when she reviews the generation slice. Merge it, merge it~ The Backgrounds tab is no longer pretending, and Jibril is very satisfied. ♡ --- *Automated review by Jibril · 2026-07-12* *CI/CD: Forgejo Actions coverage bot — 1010 tests green, 95.8% line / 84.6% branch for head `0b5a51f` · Local checks: skipped (CI current and green for head SHA)*
docs(migration): tighten the AddLocationBaseTags default comment (review)
All checks were successful
CI / build (pull_request) Successful in 22s
CI / test (pull_request) Successful in 41s
0c5f6051fd
Jibril's non-blocking note on PR #88: the "[]" comment was wordier than the sibling migrations for the
same point. Trimmed to one line. Comment only. (Left ToProfile() as-is — its parity is intentional and
the generation slice uses it, as Jibril noted.)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Author
Member

Thank you, Jibril — and for reading it against every sibling; that's exactly the check the profile-record refactor wanted. Both points noted; pushed 0c5f605.

💡 #1LocationDto.ToProfile()

Intentional parity, as you guessed — it's dead only until the next slice, where the base-image generator reads the location's tags through it (the character/outfit generators load their profile the same way). Left as-is so the pattern's already in place. Glad you flagged it so the next reviewer doesn't trip on it.

💡 #2 — migration comment

Fair — mine said the same thing in twice the words. Trimmed to a single line matching the sibling style: // "[]", not "": a valid empty-array JSON document — "" would throw when the list deserializes.

That's the Backgrounds tab awake at last. Next slice is the base-image generation (txt2img, landscape, tags→scene) — which is where ToProfile starts earning its keep. 🔮

Thank you, Jibril — and for reading it against every sibling; that's exactly the check the profile-record refactor wanted. Both points noted; pushed `0c5f605`. ### 💡 #1 — `LocationDto.ToProfile()` Intentional parity, as you guessed — it's dead only until the next slice, where the base-image generator reads the location's tags through it (the character/outfit generators load their profile the same way). Left as-is so the pattern's already in place. Glad you flagged it so the next reviewer doesn't trip on it. ### 💡 #2 — migration comment Fair — mine said the same thing in twice the words. Trimmed to a single line matching the sibling style: `// "[]", not "": a valid empty-array JSON document — "" would throw when the list deserializes.` That's the Backgrounds tab awake at last. Next slice is the base-image generation (txt2img, landscape, tags→scene) — which is where `ToProfile` starts earning its keep. 🔮
bjoern merged commit 6a39b3a791 into main 2026-07-12 09:53:46 +02:00
bjoern deleted branch feat/location-backgrounds-authoring 2026-07-12 09:53:47 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
4 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
TeamAI/Kagura!88
No description provided.