fix(api): make read state clear endpoint a no-op (#3015)

This commit is contained in:
Hampus authored and GitHub committed 2026-09-28 16:31:30 +02:00
1 parent 713ae5f7f5
commit 5a4edc0b59
6 files changed
+52 -22

No files matched your search

@@ -333,13 +333,10 @@ export function MessageController(app: HonoApp) {
statusCode: 204,
security: ['botToken', 'bearerToken', 'sessionToken'],
tags: ['Channels', 'Messages'],
description:
'Clears all read state and acknowledgement records for a channel, marking all messages as unread. Returns 204 No Content on success.',
deprecated: true,
description: 'Deprecated. Has no effect on the read state. Returns 204 No Content.',
}),
async (ctx) => {
const userId = ctx.get('user').id;
const channelId = createChannelID(ctx.req.valid('param').channel_id);
await ctx.get('readStateService').deleteReadState({userId, channelId});
return ctx.body(null, 204);
},
);
+2 -1
View File
@@ -3030,7 +3030,8 @@
"content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}
}
},
"description": "Clears all read state and acknowledgement records for a channel, marking all messages as unread. Returns 204 No Content on success.",
"description": "Deprecated. Has no effect on the read state. Returns 204 No Content.",
"deprecated": true,
"security": [{"botToken": []}, {"sessionToken": []}],
"parameters": [
{
@@ -0,0 +1,48 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {createTestAccount} from '@app/api/auth/tests/AuthTestUtils';
import {createChannel, createGuild} from '@app/api/guild/tests/GuildTestUtils';
import {sendMessage} from '@app/api/message/tests/MessageTestUtils';
import {type ApiTestHarness, createApiTestHarness} from '@app/api/test/ApiTestHarness';
import {HTTP_STATUS} from '@app/api/test/TestConstants';
import {createBuilder} from '@app/api/test/TestRequestBuilder';
import {afterEach, beforeEach, describe, expect, test} from 'vitest';
interface AckResponse {
read_states: Array<{
id: string;
last_message_id: string | null;
}>;
}
describe('DELETE /channels/:channel_id/messages/ack', () => {
let harness: ApiTestHarness;
beforeEach(async () => {
harness = await createApiTestHarness();
});
afterEach(async () => {
await harness?.shutdown();
});
test('leaves the read state untouched', async () => {
const account = await createTestAccount(harness);
const guild = await createGuild(harness, account.token, 'Read State Guild');
const channel = await createChannel(harness, account.token, guild.id, 'read-state-channel');
const older = await sendMessage(harness, account.token, channel.id, 'older');
const newer = await sendMessage(harness, account.token, channel.id, 'newer');
await createBuilder<AckResponse>(harness, account.token)
.post('/read-states/ack')
.body({read_states: [{channel_id: channel.id, message_id: newer.id}]})
.expect(HTTP_STATUS.OK)
.execute();
await createBuilder(harness, account.token)
.delete(`/channels/${channel.id}/messages/ack`)
.expect(HTTP_STATUS.NO_CONTENT)
.execute();
const response = await createBuilder<AckResponse>(harness, account.token)
.post('/read-states/ack')
.body({read_states: [{channel_id: channel.id, message_id: older.id}]})
.expect(HTTP_STATUS.OK)
.execute();
expect(response.read_states[0]?.last_message_id).toBe(newer.id);
});
});
@@ -35,8 +35,6 @@ export abstract class IReadStateRepository {
}>
>;
abstract deleteReadState(userId: UserID, channelId: ChannelID): Promise<void>;
abstract bulkAckMessages(
userId: UserID,
readStates: Array<{
@@ -4,7 +4,6 @@ import type {ChannelID, MessageID, UserID} from '@app/api/BrandedTypes';
import {channelIdToMessageId} from '@app/api/BrandedTypes';
import {
BatchBuilder,
deleteOneOrMany,
fetchMany,
fetchManyInChunks,
fetchOne,
@@ -199,15 +198,6 @@ export class ReadStateRepository implements IReadStateRepository {
return appliedUpdates;
}
async deleteReadState(userId: UserID, channelId: ChannelID): Promise<void> {
await deleteOneOrMany(
ReadStates.deleteByPk({
user_id: userId,
channel_id: channelId,
}),
);
}
async bulkAckMessages(
userId: UserID,
readStates: Array<{
@@ -141,10 +141,6 @@ export class ReadStateService {
}
}
async deleteReadState({userId, channelId}: {userId: UserID; channelId: ChannelID}): Promise<void> {
await this.repository.deleteReadState(userId, channelId);
}
async incrementMentionCount({
userId,
channelId,