Răsfoiți Sursa

fix: fix critical problems by slash review

Ryotaro Nagahara 1 lună în urmă
părinte
comite
a08d7662e4

+ 1 - 1
apps/app/src/features/news/client/components/NewsItem.tsx

@@ -4,7 +4,7 @@ import { useTranslation } from 'next-i18next';
 
 import unreadDotStyles from '~/client/components/InAppNotification/UnreadDot.module.scss';
 import { apiv3Post } from '~/client/util/apiv3-client';
-import { getLocale } from '~/server/util/locale-utils';
+import { getLocale } from '~/utils/locale-utils';
 
 import type { INewsItemWithReadStatus } from '../../interfaces/news-item';
 

+ 2 - 2
apps/app/src/features/news/server/routes/news.ts

@@ -110,7 +110,7 @@ export const createNewsRouter = (crowi?: {
    */
   router.post(
     '/mark-read',
-    accessTokenParser([SCOPE.READ.USER_SETTINGS.IN_APP_NOTIFICATION], {
+    accessTokenParser([SCOPE.WRITE.USER_SETTINGS.IN_APP_NOTIFICATION], {
       acceptLegacy: true,
     }),
     loginRequiredStrictly,
@@ -145,7 +145,7 @@ export const createNewsRouter = (crowi?: {
    */
   router.post(
     '/mark-all-read',
-    accessTokenParser([SCOPE.READ.USER_SETTINGS.IN_APP_NOTIFICATION], {
+    accessTokenParser([SCOPE.WRITE.USER_SETTINGS.IN_APP_NOTIFICATION], {
       acceptLegacy: true,
     }),
     loginRequiredStrictly,

+ 8 - 11
apps/app/src/features/news/server/services/news-service.spec.ts

@@ -191,30 +191,27 @@ describe('NewsService', () => {
   describe('getUnreadCount', () => {
     test('should return the number of unread items', async () => {
       const id1 = new mongoose.Types.ObjectId();
-      const id2 = new mongoose.Types.ObjectId();
-      const id3 = new mongoose.Types.ObjectId();
 
-      mocks.newsItemFind.mockReturnValue({
-        lean: vi
-          .fn()
-          .mockResolvedValue([{ _id: id1 }, { _id: id2 }, { _id: id3 }]),
-      });
       mocks.newsReadStatusDistinct.mockResolvedValue([id1]);
+      mocks.newsItemCountDocuments.mockResolvedValue(2);
 
       const userId = new mongoose.Types.ObjectId();
       const count = await service.getUnreadCount(userId, ['general']);
-      // 3 total - 1 read = 2 unread
       expect(count).toBe(2);
+
+      expect(mocks.newsItemCountDocuments).toHaveBeenCalledWith(
+        expect.objectContaining({
+          _id: { $nin: [id1] },
+        }),
+      );
     });
 
     test('should return 0 when all items are read', async () => {
       const id1 = new mongoose.Types.ObjectId();
       const id2 = new mongoose.Types.ObjectId();
 
-      mocks.newsItemFind.mockReturnValue({
-        lean: vi.fn().mockResolvedValue([{ _id: id1 }, { _id: id2 }]),
-      });
       mocks.newsReadStatusDistinct.mockResolvedValue([id1, id2]);
+      mocks.newsItemCountDocuments.mockResolvedValue(0);
 
       const userId = new mongoose.Types.ObjectId();
       const count = await service.getUnreadCount(userId, ['general']);

+ 5 - 7
apps/app/src/features/news/server/services/news-service.ts

@@ -87,14 +87,12 @@ export class NewsService {
   ): Promise<number> {
     const roleFilter = buildRoleFilter(userRoles);
 
-    const [allItems, readItemIds] = await Promise.all([
-      NewsItem.find(roleFilter).lean(),
-      NewsReadStatus.distinct('newsItemId', { userId }),
-    ]);
+    const readItemIds = await NewsReadStatus.distinct('newsItemId', { userId });
 
-    const readIdSet = new Set(readItemIds.map((id) => id.toString()));
-    return allItems.filter((item) => !readIdSet.has(item._id.toString()))
-      .length;
+    return NewsItem.countDocuments({
+      ...roleFilter,
+      _id: { $nin: readItemIds },
+    });
   }
 
   /**