adventure: fix three review findings on the who page

- timelineLine named the viewer as their own rival on a lost duel: a
  rival_result arrives on the loser's page via the opponent column, so
  naming the opponent field pointed at themselves. Thread the page
  character's name through and name the other party.
- buildMapView drew a frontier room twice when two visited rooms both
  had a door to it (Nodes carried the id twice). Place each id once.
- proseGuard's board query ran before the IsGUIDSeen dedup, so a retried
  dispatch paid for it and threw it away. Check dedup first.
This commit is contained in:
prosolis
2026-07-17 10:31:15 -07:00
parent 8a5fea78ba
commit 9d9cfd9f9a
3 changed files with 32 additions and 13 deletions

View File

@@ -108,6 +108,15 @@ func (s *Server) handleAdventureIngest(w http.ResponseWriter, r *http.Request) {
http.Error(w, "unknown event_type", http.StatusBadRequest)
return
}
// Idempotent: a re-delivered fact (gogobee retry) is a no-op success. Checked
// before the prose-guard because the guard runs a board query (KnownCharacterNames);
// a retried dispatch we already have a story for should cost nothing.
if storage.IsGUIDSeen(f.GUID) {
w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte("duplicate"))
return
}
// Prefer gogobee's LLM prose when it is present and safe. Both fields must be
// supplied — a half-authored dispatch is not a voice, and mixing an LLM
// headline with a template lede reads as two writers. The guard is what makes
@@ -122,13 +131,6 @@ func (s *Server) handleAdventureIngest(w http.ResponseWriter, r *http.Request) {
}
}
// Idempotent: a re-delivered fact (gogobee retry) is a no-op success.
if storage.IsGUIDSeen(f.GUID) {
w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte("duplicate"))
return
}
// A fact with no occurred_at would otherwise be stored at the Unix epoch:
// dated 1970 on the permalink, pinned to the bottom of the section, and
// outside every digest window. Treat "missing" as "now".