From 0ba868cc3cd9f0b632bfd652301f633bf3fc65e8 Mon Sep 17 00:00:00 2001
From: naskya <m@naskya.net>
Date: Thu, 25 Jul 2024 07:29:21 +0900
Subject: [PATCH] refactor (backend): remove publishUserListStream

---
 packages/backend-rs/src/service/stream.rs     |  4 ---
 .../server/api/endpoints/users/lists/pull.ts  | 34 ++++++++-----------
 .../src/server/api/mastodon/helpers/list.ts   | 24 +++++--------
 .../server/api/stream/channels/user-list.ts   |  5 +--
 .../backend/src/server/api/stream/types.ts    | 10 ------
 packages/backend/src/services/stream.ts       | 14 --------
 .../backend/src/services/user-list/pull.ts    | 11 ------
 .../backend/src/services/user-list/push.ts    |  3 --
 8 files changed, 25 insertions(+), 80 deletions(-)
 delete mode 100644 packages/backend/src/services/user-list/pull.ts

diff --git a/packages/backend-rs/src/service/stream.rs b/packages/backend-rs/src/service/stream.rs
index cd386e7115..a3f34c4185 100644
--- a/packages/backend-rs/src/service/stream.rs
+++ b/packages/backend-rs/src/service/stream.rs
@@ -32,9 +32,6 @@ pub enum Stream {
     },
     Notes,
     NoteEdit,
-    UserList {
-        list_id: String,
-    },
     Main {
         user_id: String,
     },
@@ -90,7 +87,6 @@ pub async fn publish_to_stream(
         Stream::Note { note_id } => format!("noteStream:{note_id}"),
         Stream::NoteEdit => format!("noteUpdatesStream"),
         Stream::Notes => "notesStream".to_owned(),
-        Stream::UserList { list_id } => format!("userListStream:{list_id}"),
         Stream::Main { user_id } => format!("mainStream:{user_id}"),
         Stream::Drive { user_id } => format!("driveStream:{user_id}"),
         Stream::Antenna { antenna_id } => format!("antennaStream:{antenna_id}"),
diff --git a/packages/backend/src/server/api/endpoints/users/lists/pull.ts b/packages/backend/src/server/api/endpoints/users/lists/pull.ts
index ffca5b205a..a0ae191c9a 100644
--- a/packages/backend/src/server/api/endpoints/users/lists/pull.ts
+++ b/packages/backend/src/server/api/endpoints/users/lists/pull.ts
@@ -1,8 +1,6 @@
-import { publishUserListStream } from "@/services/stream.js";
 import { UserLists, UserListJoinings, Users } from "@/models/index.js";
 import define from "@/server/api/define.js";
 import { ApiError } from "@/server/api/error.js";
-import { getUser } from "@/server/api/common/getters.js";
 
 export const meta = {
 	tags: ["lists", "users"],
@@ -38,25 +36,23 @@ export const paramDef = {
 } as const;
 
 export default define(meta, paramDef, async (ps, me) => {
-	// Fetch the list
-	const userList = await UserLists.findOneBy({
-		id: ps.listId,
-		userId: me.id,
-	});
+	const [userExists, listExists] = await Promise.all([
+		Users.existsBy({
+			id: ps.userId,
+		}),
+		UserLists.existsBy({
+			id: ps.listId,
+			userId: me.id,
+		}),
+	]);
 
-	if (userList == null) {
+	if (!userExists) {
+		throw new ApiError(meta.errors.noSuchUser);
+	}
+	if (!listExists) {
 		throw new ApiError(meta.errors.noSuchList);
 	}
 
-	// Fetch the user
-	const user = await getUser(ps.userId).catch((e) => {
-		if (e.id === "15348ddd-432d-49c2-8a5a-8069753becff")
-			throw new ApiError(meta.errors.noSuchUser);
-		throw e;
-	});
-
-	// Pull the user
-	await UserListJoinings.delete({ userListId: userList.id, userId: user.id });
-
-	publishUserListStream(userList.id, "userRemoved", await Users.pack(user));
+	// Remove the user from the list
+	await UserListJoinings.delete({ userListId: ps.listId, userId: ps.userId });
 });
diff --git a/packages/backend/src/server/api/mastodon/helpers/list.ts b/packages/backend/src/server/api/mastodon/helpers/list.ts
index ef59473167..b7564c1048 100644
--- a/packages/backend/src/server/api/mastodon/helpers/list.ts
+++ b/packages/backend/src/server/api/mastodon/helpers/list.ts
@@ -12,8 +12,6 @@ import { pushUserToUserList } from "@/services/user-list/push.js";
 import { genId } from "backend-rs";
 import { MastoApiError } from "@/server/api/mastodon/middleware/catch-errors.js";
 import type { MastoContext } from "@/server/api/mastodon/index.js";
-import { pullUserFromUserList } from "@/services/user-list/pull.js";
-import { publishUserEvent } from "@/services/stream.js";
 
 export class ListHelpers {
 	public static async getLists(
@@ -123,14 +121,12 @@ export class ListHelpers {
 					throw Error("Can’t add users you’re not following to list");
 			}
 
-			const exist = await UserListJoinings.exists({
-				where: {
-					userListId: list.id,
-					userId: user.id,
-				},
+			const exists = await UserListJoinings.existsBy({
+				userListId: list.id,
+				userId: user.id,
 			});
 
-			if (exist) continue;
+			if (exists) continue;
 			await pushUserToUserList(user, list);
 		}
 	}
@@ -144,15 +140,13 @@ export class ListHelpers {
 		if (localUser.id !== list.userId)
 			throw new Error("List is not owned by user");
 		for (const user of usersToRemove) {
-			const exist = await UserListJoinings.exists({
-				where: {
-					userListId: list.id,
-					userId: user.id,
-				},
+			const exists = await UserListJoinings.existsBy({
+				userListId: list.id,
+				userId: user.id,
 			});
 
-			if (!exist) continue;
-			await pullUserFromUserList(user, list);
+			if (!exists) continue;
+			await UserListJoinings.delete({ userListId: list.id, userId: user.id });
 		}
 	}
 
diff --git a/packages/backend/src/server/api/stream/channels/user-list.ts b/packages/backend/src/server/api/stream/channels/user-list.ts
index d8d2fbb378..f699ffcf50 100644
--- a/packages/backend/src/server/api/stream/channels/user-list.ts
+++ b/packages/backend/src/server/api/stream/channels/user-list.ts
@@ -29,12 +29,10 @@ export default class extends Channel {
 		if (!exists) return;
 
 		// Subscribe stream
-		this.subscriber.on(`userListStream:${this.listId}`, this.send);
-
 		this.subscriber.on("notesStream", this.onNote);
 
 		this.updateListUsers();
-		this.listUsersClock = setInterval(this.updateListUsers, 5000);
+		this.listUsersClock = setInterval(this.updateListUsers, 10000);
 	}
 
 	private async updateListUsers() {
@@ -65,7 +63,6 @@ export default class extends Channel {
 
 	public dispose() {
 		// Unsubscribe events
-		this.subscriber.off(`userListStream:${this.listId}`, this.send);
 		this.subscriber.off("notesStream", this.onNote);
 
 		clearInterval(this.listUsersClock);
diff --git a/packages/backend/src/server/api/stream/types.ts b/packages/backend/src/server/api/stream/types.ts
index b9d5bb6fc2..138bcedfae 100644
--- a/packages/backend/src/server/api/stream/types.ts
+++ b/packages/backend/src/server/api/stream/types.ts
@@ -7,7 +7,6 @@ import type { Note } from "@/models/entities/note.js";
 import type { Antenna } from "@/models/entities/antenna.js";
 import type { DriveFile } from "@/models/entities/drive-file.js";
 import type { DriveFolder } from "@/models/entities/drive-folder.js";
-import type { UserList } from "@/models/entities/user-list.js";
 import type { MessagingMessage } from "@/models/entities/messaging-message.js";
 import type { UserGroup } from "@/models/entities/user-group.js";
 import type { AbuseUserReport } from "@/models/entities/abuse-user-report.js";
@@ -165,11 +164,6 @@ export interface ChannelStreamTypes {
 	typing: User["id"];
 }
 
-export interface UserListStreamTypes {
-	userAdded: Packed<"User">;
-	userRemoved: Packed<"User">;
-}
-
 export interface AntennaStreamTypes {
 	note: Note;
 }
@@ -242,10 +236,6 @@ export type StreamMessages = {
 		name: `channelStream:${Channel["id"]}`;
 		payload: EventUnionFromDictionary<ChannelStreamTypes>;
 	};
-	userList: {
-		name: `userListStream:${UserList["id"]}`;
-		payload: EventUnionFromDictionary<UserListStreamTypes>;
-	};
 	antenna: {
 		name: `antennaStream:${Antenna["id"]}`;
 		payload: EventUnionFromDictionary<AntennaStreamTypes>;
diff --git a/packages/backend/src/services/stream.ts b/packages/backend/src/services/stream.ts
index d5a89c82c5..d4a38797bb 100644
--- a/packages/backend/src/services/stream.ts
+++ b/packages/backend/src/services/stream.ts
@@ -19,7 +19,6 @@ import type {
 	// MessagingIndexStreamTypes,
 	// MessagingStreamTypes,
 	NoteStreamTypes,
-	UserListStreamTypes,
 	UserStreamTypes,
 	// NoteUpdatesStreamTypes,
 } from "@/server/api/stream/types.js";
@@ -134,18 +133,6 @@ class Publisher {
 	// 	);
 	// };
 
-	public publishUserListStream = <K extends keyof UserListStreamTypes>(
-		listId: UserList["id"],
-		type: K,
-		value?: UserListStreamTypes[K],
-	): void => {
-		this.publish(
-			`userListStream:${listId}`,
-			type,
-			typeof value === "undefined" ? null : value,
-		);
-	};
-
 	/* ported to backend-rs */
 	// public publishAntennaStream = <K extends keyof AntennaStreamTypes>(
 	// 	antennaId: Antenna["id"],
@@ -235,7 +222,6 @@ export const publishNoteStream = publisher.publishNoteStream;
 // export const publishNotesStream = publisher.publishNotesStream;
 // export const publishNoteUpdatesStream = publisher.publishNoteUpdatesStream;
 // export const publishChannelStream = publisher.publishChannelStream;
-export const publishUserListStream = publisher.publishUserListStream;
 // export const publishAntennaStream = publisher.publishAntennaStream;
 // export const publishMessagingStream = publisher.publishMessagingStream;
 // export const publishGroupMessagingStream = publisher.publishGroupMessagingStream;
diff --git a/packages/backend/src/services/user-list/pull.ts b/packages/backend/src/services/user-list/pull.ts
deleted file mode 100644
index 9d6bd16b31..0000000000
--- a/packages/backend/src/services/user-list/pull.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import { publishUserListStream } from "@/services/stream.js";
-import type { User } from "@/models/entities/user.js";
-import type { UserList } from "@/models/entities/user-list.js";
-import { UserListJoinings, Users } from "@/models/index.js";
-
-export async function pullUserFromUserList(target: User, list: UserList) {
-	await UserListJoinings.delete({ userListId: list.id, userId: target.id });
-
-	const packed = await Users.pack(target);
-	publishUserListStream(list.id, "userRemoved", packed);
-}
diff --git a/packages/backend/src/services/user-list/push.ts b/packages/backend/src/services/user-list/push.ts
index 1ec4289672..e34bb59aeb 100644
--- a/packages/backend/src/services/user-list/push.ts
+++ b/packages/backend/src/services/user-list/push.ts
@@ -1,4 +1,3 @@
-import { publishUserListStream } from "@/services/stream.js";
 import type { User } from "@/models/entities/user.js";
 import type { UserList } from "@/models/entities/user-list.js";
 import { UserListJoinings, Users } from "@/models/index.js";
@@ -17,8 +16,6 @@ export async function pushUserToUserList(target: User, list: UserList) {
 		userListId: list.id,
 	} as UserListJoining);
 
-	publishUserListStream(list.id, "userAdded", await Users.pack(target));
-
 	// このインスタンス内にこのリモートユーザーをフォローしているユーザーがいなくても投稿を受け取るためにダミーのユーザーがフォローしたということにする
 	if (Users.isRemoteUser(target)) {
 		const proxy = await fetchProxyAccount();