feat: stabilize social backend contracts

هذا الالتزام موجود في:
boutmoun123
2026-05-31 16:13:23 +03:00
الأصل ad6da6754d
التزام 49e132909e
40 ملفات معدلة مع 12037 إضافات و9562 حذوفات

عرض الملف

@@ -1,6 +1,7 @@
import { BadRequestException, ForbiddenException, Injectable, Logger, NotFoundException } from '@nestjs/common';
import { extname } from 'path';
import { Types } from 'mongoose';
import { Connection, Types } from 'mongoose';
import { InjectConnection } from '@nestjs/mongoose';
import { ModerationStatus } from '../../common/enums/moderation-status.enum';
import { PostType } from '../../common/enums/post-type.enum';
import { PostVisibility } from '../../common/enums/post-visibility.enum';
@@ -72,6 +73,7 @@ export class PostsService {
private readonly logger = new Logger(PostsService.name);
constructor(
@InjectConnection() private readonly connection: Connection,
private readonly postsRepository: PostsRepository,
private readonly usersRepository: UsersRepository,
private readonly storageService: ManagedStorageService,
@@ -525,7 +527,7 @@ export class PostsService {
return post;
}
async findUserPosts(userId: string, query: PostQueryDto) {
async findUserPosts(userId: string, query: PostQueryDto, viewerUserId?: string) {
if (!Types.ObjectId.isValid(userId)) {
throw new BadRequestException('Invalid user id');
}
@@ -538,6 +540,21 @@ export class PostsService {
authorId: new Types.ObjectId(userId),
isArchived: { $ne: true },
};
if (viewerUserId && viewerUserId !== userId) {
const isBlocked = await this.hasBlockBetween(viewerUserId, userId);
if (isBlocked) {
return buildPaginatedResponse([], {
page,
limit,
total: 0,
offset: skip,
});
}
const isFollowing = await this.isFollowing(viewerUserId, userId);
filter.visibility = isFollowing
? { $in: [PostVisibility.PUBLIC, PostVisibility.FOLLOWERS] }
: PostVisibility.PUBLIC;
}
if (query.visibility) {
filter.visibility = query.visibility;
}
@@ -1602,4 +1619,30 @@ export class PostsService {
return '';
}
private async isFollowing(followerId: string, followingId: string): Promise<boolean> {
if (!Types.ObjectId.isValid(followerId) || !Types.ObjectId.isValid(followingId)) {
return false;
}
const count = await this.connection.collection('follows').countDocuments({
followerId: new Types.ObjectId(followerId),
followingId: new Types.ObjectId(followingId),
});
return count > 0;
}
private async hasBlockBetween(userA: string, userB: string): Promise<boolean> {
if (!Types.ObjectId.isValid(userA) || !Types.ObjectId.isValid(userB)) {
return false;
}
const userAId = new Types.ObjectId(userA);
const userBId = new Types.ObjectId(userB);
const count = await this.connection.collection('blocks').countDocuments({
$or: [
{ blockerId: userAId, blockedId: userBId },
{ blockerId: userBId, blockedId: userAId },
],
});
return count > 0;
}
}