feat(meetings): call log, past pagination + date filter; last-seen exact time (batch83)

#7 The past list was hard-capped at 12 (a .slice(0,12) in the client) and there was NO record
   of how many people were ever in a finished call — so the "only calls with >2 people" rule
   was impossible to apply. Added a call_history table: signaling tracks the HIGH-WATER
   participant count per room and logs the call when the room tears down (scheduled meetings
   are skipped — they already have their own row).
   Past meetings now follow the rules asked for:
     • a plain 1:1 direct call is NOT listed — unless it produced a recording/transcript
       (those already surface as recording entries);
     • a call that ever held MORE than 2 people IS listed (e.g. a 1:1 a third person joined),
       showing its participant count and duration;
     • entries are visible only to people who were actually in the call (or the group).
   Server-side pagination (10/page) + a from/to date filter; nothing is double-listed.

#2 Last seen now shows the exact time/date, WhatsApp-style — "last seen today at 1:36 PM",
   "last seen yesterday at 10:15 AM", "last seen 14/07/2026 at 9:00 AM" — instead of "10
   minutes ago".

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-15 00:42:53 +05:30
parent 860a7bd6cf
commit 6fa261b68f
5 changed files with 163 additions and 21 deletions
+10 -1
View File
@@ -323,6 +323,15 @@ const scheduledMeetings = {
remove: (id, teamId) => db.prepare('DELETE FROM scheduled_meetings WHERE id=? AND team_id=?').run(id, teamId),
};
// #7: finished calls (not scheduled meetings — those have their own table).
const callHistory = {
create: ({ id, teamId, room, groupId, kind, title, peak, participants, uids, startedAt, endedAt }) =>
db.prepare('INSERT INTO call_history (id,team_id,room,group_id,kind,title,peak,participants,uids,started_at,ended_at) VALUES (?,?,?,?,?,?,?,?,?,?,?)')
.run(id, teamId, room, groupId || null, kind || null, title || null, peak || 0,
JSON.stringify(participants || []), JSON.stringify(uids || []), startedAt, endedAt),
forTeam: (teamId) => db.prepare('SELECT * FROM call_history WHERE team_id=? ORDER BY ended_at DESC').all(teamId),
};
const recordings = {
create: ({ id, teamId, room, groupId, meetingId, title, kind, file, mime, size, durationMs, createdBy, createdByName }) =>
db.prepare('INSERT INTO recordings (id,team_id,room,group_id,meeting_id,title,kind,file,mime,size,duration_ms,created_by,created_by_name,created_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)')
@@ -388,4 +397,4 @@ const appInstalls = {
listForTenant: (tenantId) => db.prepare('SELECT * FROM app_installs WHERE tenant_id=? ORDER BY last_seen DESC').all(tenantId),
};
module.exports = { teams, users, authSessions, machines, audit, sessionsLog, refreshTokens, apiKeys, webhooks, messages, reactions, attachments, conversations, scheduledMeetings, recordings, polls, pollVotes, pushSubs, favorites, deviceTokens, appInstalls };
module.exports = { teams, users, authSessions, machines, audit, sessionsLog, refreshTokens, apiKeys, webhooks, messages, reactions, attachments, conversations, scheduledMeetings, callHistory, recordings, polls, pollVotes, pushSubs, favorites, deviceTokens, appInstalls };