Spaces:
Sleeping
Sleeping
Sasha commited on
Commit ·
79047e1
1
Parent(s): 81cc161
fix: merge and preserve user roles during chat logging upsert
Browse files- server/db.js +91 -39
server/db.js
CHANGED
|
@@ -627,11 +627,10 @@ export async function logChatMessagesBatch(messages) {
|
|
| 627 |
VALUES (?, ?, ?, ?, ?, ?)
|
| 628 |
ON CONFLICT(username) DO UPDATE SET
|
| 629 |
display_name = excluded.display_name,
|
| 630 |
-
is_mod = excluded.is_mod,
|
| 631 |
-
is_sub = excluded.is_sub,
|
| 632 |
-
is_vip = excluded.is_vip,
|
| 633 |
-
last_seen = excluded.last_seen
|
| 634 |
-
WHERE excluded.last_seen > chat_users.last_seen
|
| 635 |
`);
|
| 636 |
|
| 637 |
const runTransaction = sqliteDb.transaction((msgs) => {
|
|
@@ -703,16 +702,18 @@ export async function logChatMessagesBatch(messages) {
|
|
| 703 |
is_streamer: msg.isStreamer || false
|
| 704 |
});
|
| 705 |
|
| 706 |
-
|
| 707 |
-
|
| 708 |
-
|
| 709 |
-
|
| 710 |
-
|
| 711 |
-
|
| 712 |
-
|
| 713 |
-
|
| 714 |
-
|
| 715 |
-
|
|
|
|
|
|
|
| 716 |
|
| 717 |
const userKey = username;
|
| 718 |
chatUsersToUpsert.set(userKey, {
|
|
@@ -749,15 +750,44 @@ export async function logChatMessagesBatch(messages) {
|
|
| 749 |
if (uniqueChatUsers.length > 0) {
|
| 750 |
const { data: existingUsers } = await supabase
|
| 751 |
.from('chat_users')
|
| 752 |
-
.select('username, last_seen')
|
| 753 |
.in('username', uniqueChatUsers.map(u => u.username));
|
| 754 |
|
| 755 |
-
const existingMap = new Map((existingUsers || []).map(u => [
|
| 756 |
-
|
| 757 |
-
|
| 758 |
-
|
| 759 |
-
|
| 760 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 761 |
|
| 762 |
if (toUpsert.length > 0) {
|
| 763 |
const { error: chatUserError } = await supabase
|
|
@@ -800,11 +830,10 @@ export async function logRolesBatch(users) {
|
|
| 800 |
VALUES (?, ?, ?, ?, ?, ?)
|
| 801 |
ON CONFLICT(username) DO UPDATE SET
|
| 802 |
display_name = excluded.display_name,
|
| 803 |
-
is_mod = excluded.is_mod,
|
| 804 |
-
is_sub = excluded.is_sub,
|
| 805 |
-
is_vip = excluded.is_vip,
|
| 806 |
-
last_seen = excluded.last_seen
|
| 807 |
-
WHERE excluded.last_seen > chat_users.last_seen
|
| 808 |
`);
|
| 809 |
|
| 810 |
const runTransaction = sqliteDb.transaction((usersToInsert) => {
|
|
@@ -829,21 +858,44 @@ export async function logRolesBatch(users) {
|
|
| 829 |
// Supabase Mode
|
| 830 |
const { data: existingUsers } = await supabase
|
| 831 |
.from('chat_users')
|
| 832 |
-
.select('username, last_seen')
|
| 833 |
.in('username', uniqueChatUsers.map(u => u.username));
|
| 834 |
|
| 835 |
-
const existingMap = new Map((existingUsers || []).map(u => [
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 836 |
|
| 837 |
-
|
| 838 |
-
const
|
| 839 |
-
|
| 840 |
-
|
| 841 |
-
|
| 842 |
-
|
| 843 |
-
|
| 844 |
-
|
| 845 |
-
|
| 846 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 847 |
|
| 848 |
if (toUpsert.length > 0) {
|
| 849 |
const { error: chatUserError } = await supabase
|
|
|
|
| 627 |
VALUES (?, ?, ?, ?, ?, ?)
|
| 628 |
ON CONFLICT(username) DO UPDATE SET
|
| 629 |
display_name = excluded.display_name,
|
| 630 |
+
is_mod = CASE WHEN excluded.is_mod = 1 THEN 1 ELSE chat_users.is_mod END,
|
| 631 |
+
is_sub = CASE WHEN excluded.is_sub = 1 THEN 1 ELSE chat_users.is_sub END,
|
| 632 |
+
is_vip = CASE WHEN excluded.is_vip = 1 THEN 1 ELSE chat_users.is_vip END,
|
| 633 |
+
last_seen = CASE WHEN excluded.last_seen > chat_users.last_seen THEN excluded.last_seen ELSE chat_users.last_seen END
|
|
|
|
| 634 |
`);
|
| 635 |
|
| 636 |
const runTransaction = sqliteDb.transaction((msgs) => {
|
|
|
|
| 702 |
is_streamer: msg.isStreamer || false
|
| 703 |
});
|
| 704 |
|
| 705 |
+
if (streamId) {
|
| 706 |
+
const viewerKey = `${streamId}-${username}`;
|
| 707 |
+
viewersToUpsert.set(viewerKey, {
|
| 708 |
+
stream_id: streamId,
|
| 709 |
+
username: msg.username.toLowerCase(),
|
| 710 |
+
display_name: msg.displayName || msg.username,
|
| 711 |
+
has_chatted: true,
|
| 712 |
+
is_mod: msg.isMod || false,
|
| 713 |
+
is_sub: msg.isSub || false,
|
| 714 |
+
first_seen: ts
|
| 715 |
+
});
|
| 716 |
+
}
|
| 717 |
|
| 718 |
const userKey = username;
|
| 719 |
chatUsersToUpsert.set(userKey, {
|
|
|
|
| 750 |
if (uniqueChatUsers.length > 0) {
|
| 751 |
const { data: existingUsers } = await supabase
|
| 752 |
.from('chat_users')
|
| 753 |
+
.select('username, last_seen, is_mod, is_sub, is_vip')
|
| 754 |
.in('username', uniqueChatUsers.map(u => u.username));
|
| 755 |
|
| 756 |
+
const existingMap = new Map((existingUsers || []).map(u => [
|
| 757 |
+
u.username,
|
| 758 |
+
{
|
| 759 |
+
last_seen: new Date(u.last_seen).getTime(),
|
| 760 |
+
is_mod: u.is_mod || false,
|
| 761 |
+
is_sub: u.is_sub || false,
|
| 762 |
+
is_vip: u.is_vip || false
|
| 763 |
+
}
|
| 764 |
+
]));
|
| 765 |
+
|
| 766 |
+
const toUpsert = [];
|
| 767 |
+
for (const u of uniqueChatUsers) {
|
| 768 |
+
const existing = existingMap.get(u.username);
|
| 769 |
+
if (existing) {
|
| 770 |
+
const oldTime = existing.last_seen;
|
| 771 |
+
const newTime = new Date(u.last_seen).getTime();
|
| 772 |
+
|
| 773 |
+
const isUpgraded = (!existing.is_mod && u.is_mod) ||
|
| 774 |
+
(!existing.is_sub && u.is_sub) ||
|
| 775 |
+
(!existing.is_vip && u.is_vip);
|
| 776 |
+
|
| 777 |
+
u.is_mod = u.is_mod || existing.is_mod;
|
| 778 |
+
u.is_sub = u.is_sub || existing.is_sub;
|
| 779 |
+
u.is_vip = u.is_vip || existing.is_vip;
|
| 780 |
+
|
| 781 |
+
if (newTime > oldTime || isUpgraded) {
|
| 782 |
+
if (oldTime > newTime) {
|
| 783 |
+
u.last_seen = new Date(oldTime).toISOString();
|
| 784 |
+
}
|
| 785 |
+
toUpsert.push(u);
|
| 786 |
+
}
|
| 787 |
+
} else {
|
| 788 |
+
toUpsert.push(u);
|
| 789 |
+
}
|
| 790 |
+
}
|
| 791 |
|
| 792 |
if (toUpsert.length > 0) {
|
| 793 |
const { error: chatUserError } = await supabase
|
|
|
|
| 830 |
VALUES (?, ?, ?, ?, ?, ?)
|
| 831 |
ON CONFLICT(username) DO UPDATE SET
|
| 832 |
display_name = excluded.display_name,
|
| 833 |
+
is_mod = CASE WHEN excluded.is_mod = 1 THEN 1 ELSE chat_users.is_mod END,
|
| 834 |
+
is_sub = CASE WHEN excluded.is_sub = 1 THEN 1 ELSE chat_users.is_sub END,
|
| 835 |
+
is_vip = CASE WHEN excluded.is_vip = 1 THEN 1 ELSE chat_users.is_vip END,
|
| 836 |
+
last_seen = CASE WHEN excluded.last_seen > chat_users.last_seen THEN excluded.last_seen ELSE chat_users.last_seen END
|
|
|
|
| 837 |
`);
|
| 838 |
|
| 839 |
const runTransaction = sqliteDb.transaction((usersToInsert) => {
|
|
|
|
| 858 |
// Supabase Mode
|
| 859 |
const { data: existingUsers } = await supabase
|
| 860 |
.from('chat_users')
|
| 861 |
+
.select('username, last_seen, is_mod, is_sub, is_vip')
|
| 862 |
.in('username', uniqueChatUsers.map(u => u.username));
|
| 863 |
|
| 864 |
+
const existingMap = new Map((existingUsers || []).map(u => [
|
| 865 |
+
u.username,
|
| 866 |
+
{
|
| 867 |
+
last_seen: new Date(u.last_seen).getTime(),
|
| 868 |
+
is_mod: u.is_mod || false,
|
| 869 |
+
is_sub: u.is_sub || false,
|
| 870 |
+
is_vip: u.is_vip || false
|
| 871 |
+
}
|
| 872 |
+
]));
|
| 873 |
|
| 874 |
+
const toUpsert = [];
|
| 875 |
+
for (const u of uniqueChatUsers) {
|
| 876 |
+
const existing = existingMap.get(u.username);
|
| 877 |
+
if (existing) {
|
| 878 |
+
const oldTime = existing.last_seen;
|
| 879 |
+
const newTime = new Date(u.last_seen).getTime();
|
| 880 |
+
|
| 881 |
+
const isUpgraded = (!existing.is_mod && u.is_mod) ||
|
| 882 |
+
(!existing.is_sub && u.is_sub) ||
|
| 883 |
+
(!existing.is_vip && u.is_vip);
|
| 884 |
+
|
| 885 |
+
u.is_mod = u.is_mod || existing.is_mod;
|
| 886 |
+
u.is_sub = u.is_sub || existing.is_sub;
|
| 887 |
+
u.is_vip = u.is_vip || existing.is_vip;
|
| 888 |
+
|
| 889 |
+
if (newTime > oldTime || isUpgraded) {
|
| 890 |
+
if (oldTime > newTime) {
|
| 891 |
+
u.last_seen = new Date(oldTime).toISOString();
|
| 892 |
+
}
|
| 893 |
+
toUpsert.push(u);
|
| 894 |
+
}
|
| 895 |
+
} else {
|
| 896 |
+
toUpsert.push(u);
|
| 897 |
+
}
|
| 898 |
+
}
|
| 899 |
|
| 900 |
if (toUpsert.length > 0) {
|
| 901 |
const { error: chatUserError } = await supabase
|