All checks were successful
Build and Publish Docker Image / build-and-push (push) Successful in 43s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
29 lines
1.1 KiB
TypeScript
29 lines
1.1 KiB
TypeScript
import type { DatabaseSync } from "node:sqlite";
|
|
|
|
// Chat unread state lives on the server so it survives reloads and agrees
|
|
// across tabs and devices: `users.chat_read_at` is the created_at of the newest
|
|
// message the user has seen. Existing users start caught up (now) rather than
|
|
// with the whole history unread; new users fall back to their own created_at.
|
|
//
|
|
// The history cursor now pages on (created_at, id) so two messages sharing a
|
|
// millisecond can't be skipped at a page boundary; the index follows suit.
|
|
//
|
|
// Idempotent: also runs against fresh databases created from schema.sql, where
|
|
// the column and index already exist.
|
|
export function up(db: DatabaseSync): void {
|
|
const cols = db.prepare(`PRAGMA table_info(users);`).all() as {
|
|
name: string;
|
|
}[];
|
|
if (!cols.some((c) => c.name === "chat_read_at")) {
|
|
db.exec(`ALTER TABLE users ADD COLUMN chat_read_at TEXT;`);
|
|
db.prepare(`UPDATE users SET chat_read_at = ?;`).run(
|
|
new Date().toISOString(),
|
|
);
|
|
}
|
|
|
|
db.exec(`DROP INDEX IF EXISTS idx_chat_messages_created;`);
|
|
db.exec(
|
|
`CREATE INDEX IF NOT EXISTS idx_chat_messages_created_id ON chat_messages(created_at, id);`,
|
|
);
|
|
}
|