All files / src/utils system-pm.js

100% Statements 27/27
87.5% Branches 7/8
100% Functions 4/4
100% Lines 25/25

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 841x 1x 1x   1x 1x     8x 8x 7x 7x                     19x       8x   8x 8x 8x   8x 8x                             8x 8x   8x                   8x 8x                   8x 8x         1x       1x  
const { db, rtdb, FieldValue } = require('./firebase');
const { generateId, now } = require('./helpers');
const log = require('./log');
 
const SYSTEM_UID = 'SHYTALK_SYSTEM';
const SYSTEM_DISPLAY_NAME = 'ShyTalk System';
 
async function ensureSystemUser() {
  const snap = await db.doc(`users/${SYSTEM_UID}`).get();
  if (!snap.exists) {
    const timestamp = now();
    await db.doc(`users/${SYSTEM_UID}`).set({
      id: SYSTEM_UID,
      displayName: SYSTEM_DISPLAY_NAME,
      userType: 'SYSTEM',
      createdAt: timestamp,
      lastSeenAt: timestamp,
    });
  }
}
 
function systemConversationId(recipientUid) {
  return [recipientUid, SYSTEM_UID].sort((a, b) => String(a).localeCompare(String(b))).join('_');
}
 
async function sendSystemPm(recipientUid, text) {
  await ensureSystemUser();
 
  const convId = systemConversationId(recipientUid);
  const timestamp = now();
  const msgId = generateId();
 
  const convSnap = await db.doc(`conversations/${convId}`).get();
  const convData = {
    id: convId,
    isGroup: false,
    participantIds: convSnap.exists
      ? convSnap.data().participantIds || [recipientUid, SYSTEM_UID]
      : [recipientUid, SYSTEM_UID],
    lastMessage: {
      text,
      senderId: SYSTEM_UID,
      senderName: SYSTEM_DISPLAY_NAME,
      type: 'SYSTEM',
      createdAt: timestamp,
    },
    lastMessageAt: timestamp,
  };
  if (!convSnap.exists) convData.createdAt = timestamp;
  await db.doc(`conversations/${convId}`).set(convData, { merge: true });
 
  await db.doc(`conversations/${convId}/messages/${msgId}`).set({
    id: msgId,
    conversationId: convId,
    senderId: SYSTEM_UID,
    senderName: SYSTEM_DISPLAY_NAME,
    text,
    type: 'SYSTEM',
    createdAt: timestamp,
  });
 
  const settingsPath = `conversations/${convId}/userSettings/${recipientUid}`;
  await db.doc(settingsPath).set(
    {
      userId: recipientUid,
      conversationId: convId,
      unreadCount: FieldValue.increment(1),
      isHidden: false,
    },
    { merge: true },
  );
 
  try {
    await rtdb.ref(`conversations/${convId}/events/lastEvent`).set({
      type: 'new_message',
      ts: Date.now(),
    });
  } catch (err) {
    log.warn('system-pm', 'Failed to write RTDB event', { convId, error: err.message });
  }
}
 
module.exports = { sendSystemPm, SYSTEM_UID, systemConversationId };