Catch up on replies missed while the app was in the background

The reply catch-up read the page's stale face, so after an interim
message it stopped while the thinking row stayed up. It now reads the
live face, checks at once when the page comes back into view or online,
and replays the bot's face and task too, so a reply that ended silently
can't leave the bot working on screen.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-10-28 04:14:13 +01:00
co-authored by Claude Opus 5.5
parent 4061a317bc
commit e51f2aa9a4
5 changed files with 74 additions and 25 deletions
+16 -10
View File
@@ -1,24 +1,23 @@
import userAuth from "@/src/functions/backend/auth/user-auth";
import grabUserBotSession from "@/src/functions/backend/db/bot-sessions/grab-user-bot-session";
import grabBotMessages from "@/src/functions/backend/db/bots/grab-bot-messages";
import grabBotFace from "@/src/functions/backend/db/bots/grab-bot-face";
import grabActiveBotTask from "@/src/functions/backend/db/bots/grab-active-bot-task";
import { AppData } from "@/src/data/app-data";
import { BotSessionIdRequestSchema } from "@/src/schemas/bot-schema";
import type { BotMessageWithAttachments } from "@/src/types";
import type { SessionMessagesResponse } from "@/src/types";
import AppError from "@/src/utils/app-error";
import parseWithSchema from "@/src/utils/parse-with-schema";
import safeErrorMessage from "@/src/utils/safe-error-message";
import type {
APIResponseObject,
BunextAPIRouteHandler,
} from "@moduletrace/bunext/types";
import type { BunextAPIRouteHandler } from "@moduletrace/bunext/types";
/**
* The latest messages of one of the session user's own sessions, so the
* open conversation can catch up on a reply whose live push it missed.
* The latest messages of one of the session user's own sessions, and the
* bot's face, status line and active task for that user (as
* `server:bot-updated` carries them), so the open conversation can catch
* up on a reply or a face change whose live push it missed.
*/
export const handler: BunextAPIRouteHandler<
APIResponseObject<BotMessageWithAttachments>
> = async ({ req, body }) => {
export const handler: BunextAPIRouteHandler<SessionMessagesResponse> = async ({ req, body }) => {
try {
if (req.method != "POST") {
throw new AppError(`Method not allowed`);
@@ -38,6 +37,8 @@ export const handler: BunextAPIRouteHandler<
throw new AppError(`Session not found.`);
}
const bot_id = Number(session.bot_id);
return {
success: true,
payload: await grabBotMessages({
@@ -45,6 +46,11 @@ export const handler: BunextAPIRouteHandler<
limit: AppData.BotReplyCatchUpMessages,
user_id: user.id,
}),
bot: {
id: bot_id,
...(await grabBotFace({ bot_id, user_id: user.id })),
task: await grabActiveBotTask({ bot_id, user_id: user.id }),
},
};
} catch (error: unknown) {
return { success: false, msg: safeErrorMessage({ error }) };