From e0513100765c5097924ae015cf4cc11d5bfaf7f9 Mon Sep 17 00:00:00 2001 From: Codex Date: Tue, 28 Jul 2026 13:17:49 +0800 Subject: [PATCH] fix(engine): hide NPC-only promises from PlayerView --- crates/nana-engine/src/projection.rs | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/crates/nana-engine/src/projection.rs b/crates/nana-engine/src/projection.rs index 2311425..edce0a9 100644 --- a/crates/nana-engine/src/projection.rs +++ b/crates/nana-engine/src/projection.rs @@ -74,7 +74,11 @@ pub fn project_player_view( let promises = state .promises .iter() - .filter(|promise| is_visible_promise_status(promise.status)) + .filter(|promise| { + is_visible_promise_status(promise.status) + && (promise.promiser == context.player_id + || promise.promisee == context.player_id) + }) .map(|promise| PlayerPromiseView { id: promise.id.clone(), content: promise.content.clone(), @@ -406,7 +410,8 @@ mod tests { } #[test] - fn promises_hide_proposals_and_include_accepted_and_terminal_states() { + fn promises_only_show_player_involved_accepted_and_terminal_states() { + const NPC_PROMISE_CANARY: &str = "NPC_ONLY_ACCEPTED_PROMISE_CANARY"; let statuses = [ PromiseStatus::Proposed, PromiseStatus::Accepted, @@ -421,11 +426,23 @@ mod tests { .enumerate() .map(|(index, status)| promise(&format!("promise_{index}"), status)) .collect(); + original.promises.push(Promise { + id: "npc_only".to_owned(), + promiser: "nana".to_owned(), + promisee: "sister".to_owned(), + content: NPC_PROMISE_CANARY.to_owned(), + status: PromiseStatus::Accepted, + weight: PromiseWeight::Major, + created_at: "node_001".to_owned(), + accepted_at: Some("node_002".to_owned()), + resolved_at: None, + }); let view = project_player_view(&original, &context(&[], &[], &[], &[])); assert_eq!(view.promises.len(), 5); + assert!(!format!("{view:?}").contains(NPC_PROMISE_CANARY)); assert!( view.promises .iter()