fix(activities): allow assignees to attach files when commenting under creator-only edit

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-11-12 09:49:22 +03:30
co-authored by Cursor
parent 68fcece743
commit 453ff1a5f6
+14 -6
View File
@@ -99,7 +99,9 @@ function canCollaborateActivity(
/** فقط dueAt / description → تعویق و ثبت نظر */
function isCollaboratorPatch(dto: UpdateActivityRequest): boolean {
const keys = Object.keys(dto);
const keys = Object.keys(dto).filter(
(key) => (dto as Record<string, unknown>)[key] !== undefined,
);
return keys.length > 0 && keys.every((key) => key === 'dueAt' || key === 'description');
}
@@ -1199,8 +1201,9 @@ export class ActivitiesService {
assignees: { select: { id: true } },
},
});
if (!gate || !canMutateActivity(actor, gate)) {
throw new ForbiddenException('شما مجوز ویرایش این فعالیت را ندارید');
// پیوست در مسیر ثبت نظر — مسئولان هم مجازند حتی با editPolicy=creator
if (!gate || !canCollaborateActivity(actor, gate)) {
throw new ForbiddenException('شما مجوز ثبت نظر یا پیوست برای این فعالیت را ندارید');
}
if (!file?.buffer?.length) {
throw new BadRequestException('فایلی ارسال نشده است');
@@ -1305,13 +1308,18 @@ export class ActivitiesService {
assignees: { select: { id: true } },
},
});
if (!gate || !canMutateActivity(actor, gate)) {
throw new ForbiddenException('شما مجوز ویرایش این فعالیت را ندارید');
}
const row = await this.prisma.activityImage.findFirst({
where: { id: imageId, activityId, organizationId },
});
if (!row) throw new NotFoundException('فایل پیدا نشد');
const canMutate = !!gate && canMutateActivity(actor, gate);
const canRemoveOwn =
!!gate &&
canCollaborateActivity(actor, gate) &&
row.uploadedById === actor.userId;
if (!canMutate && !canRemoveOwn) {
throw new ForbiddenException('شما مجوز حذف این پیوست را ندارید');
}
await this.files.remove(row.storageKey);
await this.prisma.activityImage.delete({ where: { id: row.id } });
await this.storage.addLocal(organizationId, -row.sizeBytes);