From dc0582739f8c02be1b7297132872dffd8f3e4755 Mon Sep 17 00:00:00 2001
From: ikasoba <57828948+ikasoba@users.noreply.github.com>
Date: Wed, 25 Oct 2023 21:19:43 +0900
Subject: [PATCH] =?UTF-8?q?Fix:=20STL=E3=81=A7=E3=83=95=E3=82=A9=E3=83=AD?=
 =?UTF-8?q?=E3=83=BC=E3=81=97=E3=81=A6=E3=81=84=E3=81=AA=E3=81=84=E3=83=81?=
 =?UTF-8?q?=E3=83=A3=E3=83=B3=E3=83=8D=E3=83=AB=E3=81=8C=E8=A1=A8=E7=A4=BA?=
 =?UTF-8?q?=E3=81=95=E3=82=8C=E3=82=8B=E5=95=8F=E9=A1=8C=E3=82=92=E4=BF=AE?=
 =?UTF-8?q?=E6=AD=A3=20(#12143)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* タイムラインをpostgresから取得する際にフォローしていないチャンネルが取得されるのを修正

* CHANGELOGに追記
---
 CHANGELOG.md                                   |  1 +
 .../api/endpoints/notes/hybrid-timeline.ts     | 18 +++++++++++++++++-
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index c693748f67..3decae2b9c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -31,6 +31,7 @@
 - Fix: ローカルタイムラインに投稿者自身の投稿への返信が含まれない問題を修正
 - Fix: 自分のフォローしているユーザーの自分のフォローしていないユーザーの visibility: followers な投稿への返信がストリーミングで流れてくる問題を修正
 - Fix: RedisへのTLキャッシュが有効の場合にHTL/LTL/STLが空になることがある問題を修正
+- Fix: STLでフォローしていないチャンネルが取得される問題を修正
 
 ## 2023.10.2
 
diff --git a/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts b/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts
index 7d0c9f1185..4eeec563d7 100644
--- a/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts
+++ b/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts
@@ -5,7 +5,7 @@
 
 import { Brackets } from 'typeorm';
 import { Inject, Injectable } from '@nestjs/common';
-import type { NotesRepository, FollowingsRepository, MiNote } from '@/models/_.js';
+import type { NotesRepository, FollowingsRepository, MiNote, ChannelFollowingsRepository } from '@/models/_.js';
 import { Endpoint } from '@/server/api/endpoint-base.js';
 import ActiveUsersChart from '@/core/chart/charts/active-users.js';
 import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
@@ -69,6 +69,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
 		@Inject(DI.notesRepository)
 		private notesRepository: NotesRepository,
 
+		@Inject(DI.channelFollowingsRepository)
+		private channelFollowingsRepository: ChannelFollowingsRepository,
+
 		private noteEntityService: NoteEntityService,
 		private roleService: RoleService,
 		private activeUsersChart: ActiveUsersChart,
@@ -208,6 +211,11 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
 		withReplies: boolean,
 	}, me: MiLocalUser) {
 		const followees = await this.userFollowingService.getFollowees(me.id);
+		const followingChannels = await this.channelFollowingsRepository.find({
+			where: {
+				followerId: me.id,
+			},
+		});
 
 		const query = this.queryService.makePaginationQuery(this.notesRepository.createQueryBuilder('note'), ps.sinceId, ps.untilId)
 			.andWhere(new Brackets(qb => {
@@ -226,6 +234,14 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
 			.leftJoinAndSelect('reply.user', 'replyUser')
 			.leftJoinAndSelect('renote.user', 'renoteUser');
 
+		if (followingChannels.length > 0) {
+			const followingChannelIds = followingChannels.map(x => x.followeeId);
+
+			query.andWhere('note.channelId IN (:...followingChannelIds) OR note.channelId IS NULL', { followingChannelIds });
+		} else {
+			query.andWhere('note.channelId IS NULL');
+		}
+
 		if (!ps.withReplies) {
 			query.andWhere(new Brackets(qb => {
 				qb