Add paginated channel subscription queries to the local message board (#56495)

## What changed

Add `LocalAgentMessageBoard::subscribed_channels` to list the caller's subscribed channel names on the current board in name order, using the existing `PageRequest` limits and cursors.

## Testing

Extend the local board test to verify that a read-only connection can retrieve two subscribed channels across successive one-item pages, with no cursor after the final page.

GitOrigin-RevId: 63f2e3e7caad9638e5e0f4f38aaf722a590c5d7f
This commit is contained in:
felixxia-oai
2026-10-23 15:00:06 +00:00
committed by copyberry
parent 2f1cc59790
commit 2839ed763b
2 changed files with 54 additions and 0 deletions
@@ -19,6 +19,7 @@ use crate::ChannelQuery;
use crate::ChannelSummary;
use crate::CreateChannelRequest;
use crate::Page;
use crate::PageRequest;
use crate::PostContent;
use crate::PostMetadata;
use crate::PostPreview;
@@ -80,6 +81,31 @@ impl LocalAgentMessageBoard {
.execute(&mut *tx).await.map_err(storage_error)?;
tx.commit().await.map_err(storage_error)
}
/// Lists the caller's channel subscriptions within the existing page budget.
pub async fn subscribed_channels(
&self,
caller: ThreadId,
page: PageRequest,
) -> Result<Page<String>> {
self.host.agent_path(caller).await?;
let window = Window::new(&page)?;
// Probe the existing subscriptions primary key for each channel.
let channels = sqlx::query_scalar::<_, String>(
"SELECT c.name FROM channels AS c WHERE c.board=? AND EXISTS (
SELECT 1 FROM subscriptions AS s
WHERE s.board=c.board AND s.target=json_object('Channel',c.name) AND s.agent=?
) ORDER BY c.name LIMIT ? OFFSET ?",
)
.bind(self.identity.to_string())
.bind(caller.to_string())
.bind((window.limit + 1) as i64)
.bind(window.offset())
.fetch_all(self.pool.as_ref())
.await
.map_err(storage_error)?;
window.finish(channels)
}
}
impl AgentMessageBoard for LocalAgentMessageBoard {
@@ -1936,6 +1936,34 @@ async fn silent_appends_preserve_evidence_and_explicit_subscriptions()
.await?,
0
);
let first = reader
.subscribed_channels(
child,
PageRequest {
cursor: None,
limit: NonZeroU32::MIN,
},
)
.await?;
let last = reader
.subscribed_channels(
child,
PageRequest {
cursor: first.next_cursor,
limit: NonZeroU32::MIN,
},
)
.await?;
assert_eq!(
(first.results, last),
(
vec![channel.into()],
Page {
results: vec!["release".into()],
next_cursor: None,
}
)
);
// Normal posts on this same board still subscribe their author and notify once.
let discussion = PostRequest {
request_id: "discussion".into(),