openvibers/openvibe.chat Commits
Chat: history drops the legacy ?scope=stream opt-in (C-06) (#70)
Changes
@@@ -550,20 +550,20 @@ router.get('/:streamId/replay', optionalAuth, async (req, res) => {// broadcaster's stream sessions (not just the one slot/session being viewed),// so viewers keep context when a stream restarts or the streamer runs multiple// slots. Each message carries its source stream (title/slug/live) so the client--// can label it and let viewers hop between the streamer's live slots.--// Pass ?scope=stream to restrict to the single session (legacy behavior).++// can label it and let viewers hop between the streamer's live slots. A stream whose broadcaster is++// unknown reads its own session only. (The legacy ?scope=stream opt-in is gone: compatibility register++// C-06, unused since at least 2026-08-04.)router.get('/:streamId/history', optionalAuth, async (req, res) => {try {const streamId = positiveInt(req.params.streamId);if (streamId === null) return res.status(400).json({ error: 'Invalid stream ID' });const limit = Math.min(parseInt(req.query.limit || '500'), 500);const before = req.query.before; // ISO timestamp for pagination-- const scope = req.query.scope || 'streamer';// Resolve which broadcaster this stream belongs to.const stream = await ctx.ensureStream(streamId);const broadcasterId = stream ? stream.user_id : null;-- const spanStreamer = scope !== 'stream' && broadcasterId;++ const spanStreamer = !!broadcasterId;// COALESCE the channel name from the source stream's owner (live rows) OR the// message's channel_user_id (offline rows) so the streamer/channel tag renders@@@ -139,8 +139,8 @@ t('chat history: global page and cursor delta, deleted and expired rows hidden',const inRoom = [];for (const i of [0, 1]) inRoom.push(Number((await h.db.saveChatMessage({ stream_id: streamId, channel_user_id: streamer.id, user_id: bob.id, username: 'Bob', message: `s${i}`, message_type: 'chat' })).lastInsertRowid));await h.db.deleteChatMessage(inRoom[0], staff.id);-- for (const p of [`/api/chat/${streamId}/history`, `/api/chat/${streamId}/history?scope=stream&`, `/api/chat/channel/${streamer.id}/history`]) {-- const d = await h.http('GET', `${p}${p.endsWith('&') ? '' : '?'}after_id=${inRoom[1]}`);++ for (const p of [`/api/chat/${streamId}/history`, `/api/chat/channel/${streamer.id}/history`]) {++ const d = await h.http('GET', `${p}?after_id=${inRoom[1]}`);assert.strictEqual(d.status, 200, p);assert.deepStrictEqual(d.body.deleted_ids, [inRoom[0]], p);}
@@ -550,20 +550,20 @@ router.get('/:streamId/replay', optionalAuth, async (req, res) => {
@@ -550,20 +550,20 @@ router.get('/:streamId/replay', optionalAuth, async (req, res) => {
// broadcaster's stream sessions (not just the one slot/session being viewed),
// broadcaster's stream sessions (not just the one slot/session being viewed),
// so viewers keep context when a stream restarts or the streamer runs multiple
// so viewers keep context when a stream restarts or the streamer runs multiple
// slots. Each message carries its source stream (title/slug/live) so the client
// slots. Each message carries its source stream (title/slug/live) so the client
-// can label it and let viewers hop between the streamer's live slots.
-// Pass ?scope=stream to restrict to the single session (legacy behavior).
+// can label it and let viewers hop between the streamer's live slots. A stream whose broadcaster is
+// unknown reads its own session only. (The legacy ?scope=stream opt-in is gone: compatibility register
+// C-06, unused since at least 2026-08-04.)
router.get('/:streamId/history', optionalAuth, async (req, res) => {
router.get('/:streamId/history', optionalAuth, async (req, res) => {
try {
try {
const streamId = positiveInt(req.params.streamId);
const streamId = positiveInt(req.params.streamId);
if (streamId === null) return res.status(400).json({ error: 'Invalid stream ID' });
if (streamId === null) return res.status(400).json({ error: 'Invalid stream ID' });
const limit = Math.min(parseInt(req.query.limit || '500'), 500);
const limit = Math.min(parseInt(req.query.limit || '500'), 500);
const before = req.query.before; // ISO timestamp for pagination
const before = req.query.before; // ISO timestamp for pagination
- const scope = req.query.scope || 'streamer';
// Resolve which broadcaster this stream belongs to.
// Resolve which broadcaster this stream belongs to.
const stream = await ctx.ensureStream(streamId);
const stream = await ctx.ensureStream(streamId);
const broadcasterId = stream ? stream.user_id : null;
const broadcasterId = stream ? stream.user_id : null;
- const spanStreamer = scope !== 'stream' && broadcasterId;
+ const spanStreamer = !!broadcasterId;
// COALESCE the channel name from the source stream's owner (live rows) OR the
// COALESCE the channel name from the source stream's owner (live rows) OR the
// message's channel_user_id (offline rows) so the streamer/channel tag renders
// message's channel_user_id (offline rows) so the streamer/channel tag renders
@@ -139,8 +139,8 @@ t('chat history: global page and cursor delta, deleted and expired rows hidden',
@@ -139,8 +139,8 @@ t('chat history: global page and cursor delta, deleted and expired rows hidden',
const inRoom = [];
const inRoom = [];
for (const i of [0, 1]) inRoom.push(Number((await h.db.saveChatMessage({ stream_id: streamId, channel_user_id: streamer.id, user_id: bob.id, username: 'Bob', message: `s${i}`, message_type: 'chat' })).lastInsertRowid));
for (const i of [0, 1]) inRoom.push(Number((await h.db.saveChatMessage({ stream_id: streamId, channel_user_id: streamer.id, user_id: bob.id, username: 'Bob', message: `s${i}`, message_type: 'chat' })).lastInsertRowid));
await h.db.deleteChatMessage(inRoom[0], staff.id);
await h.db.deleteChatMessage(inRoom[0], staff.id);
- for (const p of [`/api/chat/${streamId}/history`, `/api/chat/${streamId}/history?scope=stream&`, `/api/chat/channel/${streamer.id}/history`]) {
- const d = await h.http('GET', `${p}${p.endsWith('&') ? '' : '?'}after_id=${inRoom[1]}`);
+ for (const p of [`/api/chat/${streamId}/history`, `/api/chat/channel/${streamer.id}/history`]) {
+ const d = await h.http('GET', `${p}?after_id=${inRoom[1]}`);
assert.strictEqual(d.status, 200, p);
assert.strictEqual(d.status, 200, p);
assert.deepStrictEqual(d.body.deleted_ids, [inRoom[0]], p);
assert.deepStrictEqual(d.body.deleted_ids, [inRoom[0]], p);
}
}