Skip to content

feat(openworlds): expose companion camp beat history - #198

Merged
100yenadmin merged 1 commit into
mainfrom
viewer/companion-camp-surface
May 26, 2026
Merged

feat(openworlds): expose companion camp beat history#198
100yenadmin merged 1 commit into
mainfrom
viewer/companion-camp-surface

Conversation

@100yenadmin

@100yenadmin 100yenadmin commented May 26, 2026

Copy link
Copy Markdown
Member

Summary

Adds the missing camp-beat visibility slice to the existing OpenWorlds relations surface. The repo already had factions, met NPCs, companion dossiers, and CompanionQuestArc projection wired; this PR makes the engine-owned camp_beats history visible so issue #118 can be reviewed against a concrete UI/read-model path.

What Changed

  • Adds campBeats to /relations-surface as a read-only projection:
    • history count and configured solo/pair cooldown days;
    • recent records with participant names, tags, resolved state, note, and computed ready day/remaining cooldown;
    • no raw snapshot writes and no scheduler mutation.
  • Adds a compact Camp section to the OpenWorlds companion detail pane.
  • Extends the read-model fixture/test to cover camp beat history and cooldown projection.

Architecture

The viewer remains a downstream projection layer. It reads the persisted Campaign.camp_beats snapshot shape and derives browser-safe display metadata. It does not call camp_scene, does not schedule candidates, and does not record beats. The only write path for camp history remains the existing engine record_camp_beat tool/API.

This keeps the state-authority boundary intact:

  • engine owns Campaign.camp_beats and all mutations;
  • viewer/OpenWorlds displays the state;
  • browser actions, if added later, must go through existing player-intent or engine-owned record paths.

OSS Research Tie-In

This follows the roadmap-squeeze recommendation to build companion/camp UX natively rather than importing external VTT or generator code. External repos are useful as UX references here, but ClawDnD already has a domain-specific camp scheduler and companion model, so the fastest safe lift is exposing those existing engine facts.

Validation

Run from /Volumes/LEXAR/repos/ClawDnD-companion-camp:

python3 -m unittest viewer.tests.test_readmodel_surfaces -q
python3 -m unittest viewer.tests.test_openworlds_static -q
python3 -m py_compile viewer/server.py
python3 scripts/license_check.py
git diff --check

All listed checks passed locally before opening this draft PR.

Rollback

Revert this PR to remove only the campBeats projection and OpenWorlds companion camp section. Existing relations/faction/NPC/arc surfaces are otherwise unchanged.

Refs #118, #58.

Summary by CodeRabbit

New Features

  • Added camp beat ledger display in NPC details showing recent camp activities with cooldown status indicators
  • Displays up to three recent entries with summary counts and configured cooldown periods
  • Backend API now surfaces camp beat history and cooldown data for player consumption

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 26, 2026

Copy link
Copy Markdown

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 30fb8b99-7352-447d-984a-605aa718ca8b

📥 Commits

Reviewing files that changed from the base of the PR and between 0eb87c5 and 281a9ed.

📒 Files selected for processing (3)
  • viewer/openworlds/screen-relations.jsx
  • viewer/server.py
  • viewer/tests/test_readmodel_surfaces.py

Cache: Disabled due to Reviews > Disable Cache setting


📝 Walkthrough

Walkthrough

The PR projects camp beat history and cooldown metadata from snapshot state into the relations surface, adds tests for that projection, and wires the payload to the frontend where NPCDetail renders a new CampBeatLedger showing recent beats and cooldown readiness for the selected NPC.

Changes

Camp Beat History Integration

Layer / File(s) Summary
Camp beats normalization and cooldown computation
viewer/server.py
_relations_camp_beats(snapshot) reads camp beat records, normalizes them into player-facing entries (participants, kind, tags, resolved, note), computes cooldown/ready-day timing based on solo vs pair configuration, sorts by descending day/id, and caps results to eight entries.
Relations surface wiring and test validation
viewer/server.py, viewer/tests/test_readmodel_surfaces.py
build_relations_surface() attaches the campBeats projection into the response payload. Test fixture is extended with camp beats model data and assertions verify correct projection of record counts, cooldown fields, participant identity, ready-day timing, and note text.
Frontend camp beats display
viewer/openworlds/screen-relations.jsx
ScreenRelations extracts campBeats from the relations surface payload and wires it into NPCDetail. NPCDetail component signature is updated to accept campBeats and renders a new CampBeatLedger component in the companion dossier. CampBeatLedger filters recent beats by NPC id, displays up to three entries with cooldown status, shows summary counts, and renders a fallback when no beats exist.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

Possibly related PRs

  • 100yenadmin/ClawDnD#161: Introduced the /relations-surface pipeline and earlier build_relations_surface/frontend wiring that this PR extends with campBeats.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Comment @coderabbitai help to get the list of available commands and usage tips.

@100yenadmin
100yenadmin force-pushed the viewer/companion-camp-surface branch from caac76f to 281a9ed Compare May 26, 2026 18:50
@100yenadmin
100yenadmin marked this pull request as ready for review May 26, 2026 18:50
@100yenadmin
100yenadmin merged commit 10b0541 into main May 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant