add chat system
This commit is contained in:
@@ -293,6 +293,81 @@ db.run(
|
||||
`CREATE INDEX IF NOT EXISTS idx_auto_deploy_runs_ts ON auto_deploy_runs(ts DESC);`,
|
||||
);
|
||||
|
||||
db.run(`
|
||||
CREATE TABLE IF NOT EXISTS chat_messages (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
user_id INTEGER NOT NULL,
|
||||
username TEXT NOT NULL,
|
||||
user_role TEXT NOT NULL,
|
||||
message TEXT NOT NULL,
|
||||
created_at INTEGER NOT NULL
|
||||
);
|
||||
`);
|
||||
db.run(
|
||||
`CREATE INDEX IF NOT EXISTS idx_chat_messages_created_at ON chat_messages(created_at DESC);`,
|
||||
);
|
||||
|
||||
export type ChatMessageRecord = {
|
||||
id: number;
|
||||
userId: number;
|
||||
username: string;
|
||||
userRole: string;
|
||||
message: string;
|
||||
createdAt: number;
|
||||
};
|
||||
|
||||
export function insertChatMessage(userId: number, username: string, userRole: string, message: string): ChatMessageRecord {
|
||||
const createdAt = Date.now();
|
||||
const result = db.run(
|
||||
`INSERT INTO chat_messages (user_id, username, user_role, message, created_at) VALUES (?, ?, ?, ?, ?)`,
|
||||
userId, username, userRole, message, createdAt,
|
||||
);
|
||||
const id = Number((result as any).lastInsertRowid);
|
||||
return { id, userId, username, userRole, message, createdAt };
|
||||
}
|
||||
|
||||
export function getChatHistory(before?: number, limit: number = 50, retentionMs?: number): ChatMessageRecord[] {
|
||||
const maxLimit = Math.min(Math.max(1, limit), 200);
|
||||
const cutoff = retentionMs && retentionMs > 0 ? Date.now() - retentionMs : 0;
|
||||
let rows: any[];
|
||||
if (before) {
|
||||
if (cutoff > 0) {
|
||||
rows = db.query<any>(
|
||||
`SELECT id, user_id, username, user_role, message, created_at FROM chat_messages WHERE created_at < ? AND created_at > ? ORDER BY created_at DESC LIMIT ?`,
|
||||
).all(before, cutoff, maxLimit);
|
||||
} else {
|
||||
rows = db.query<any>(
|
||||
`SELECT id, user_id, username, user_role, message, created_at FROM chat_messages WHERE created_at < ? ORDER BY created_at DESC LIMIT ?`,
|
||||
).all(before, maxLimit);
|
||||
}
|
||||
} else {
|
||||
if (cutoff > 0) {
|
||||
rows = db.query<any>(
|
||||
`SELECT id, user_id, username, user_role, message, created_at FROM chat_messages WHERE created_at > ? ORDER BY created_at DESC LIMIT ?`,
|
||||
).all(cutoff, maxLimit);
|
||||
} else {
|
||||
rows = db.query<any>(
|
||||
`SELECT id, user_id, username, user_role, message, created_at FROM chat_messages ORDER BY created_at DESC LIMIT ?`,
|
||||
).all(maxLimit);
|
||||
}
|
||||
}
|
||||
return rows.map((r: any) => ({
|
||||
id: r.id,
|
||||
userId: r.user_id,
|
||||
username: r.username,
|
||||
userRole: r.user_role,
|
||||
message: r.message,
|
||||
createdAt: r.created_at,
|
||||
})).reverse();
|
||||
}
|
||||
|
||||
export function deleteExpiredChatMessages(retentionMs: number): number {
|
||||
if (retentionMs <= 0) return 0;
|
||||
const cutoff = Date.now() - retentionMs;
|
||||
const result = db.run(`DELETE FROM chat_messages WHERE created_at < ?`, cutoff);
|
||||
return Number((result as any).changes ?? 0);
|
||||
}
|
||||
|
||||
db.run(`
|
||||
CREATE TABLE IF NOT EXISTS shared_files (
|
||||
id TEXT PRIMARY KEY,
|
||||
@@ -1164,6 +1239,15 @@ export function getClientMetricsSummaryForUser(userId: number): ClientMetricsSum
|
||||
};
|
||||
}
|
||||
|
||||
export function getOnlineClientCountForUser(userId: number): number {
|
||||
const row = db
|
||||
.query<{ online: number }>(
|
||||
`SELECT SUM(CASE WHEN online=1 THEN 1 ELSE 0 END) as online FROM clients WHERE built_by_user_id = ?`,
|
||||
)
|
||||
.get(userId);
|
||||
return Number(row?.online) || 0;
|
||||
}
|
||||
|
||||
export function countBuildsForUser(userId: number): number {
|
||||
const row = db
|
||||
.query<{ c: number }>(`SELECT COUNT(*) as c FROM builds WHERE built_by_user_id = ?`)
|
||||
|
||||
Reference in New Issue
Block a user