feat(routines): let each person create a routine for themselves
Open the new-routine action to every member, while keeping assignment to other people and teams limited to managers. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -185,6 +185,7 @@ export function toRoutineDto(
|
||||
entityLink: normalizeEntityLink(row.entityLink),
|
||||
reminderMinutesBefore: row.reminderMinutesBefore,
|
||||
isActive: row.isActive,
|
||||
createdById: row.createdById,
|
||||
recurrenceLabel: describeRecurrence(rule),
|
||||
executionRate: execution.total ? Math.round((execution.done / execution.total) * 100) : null,
|
||||
executionTotal: execution.total,
|
||||
|
||||
@@ -200,8 +200,7 @@ export class RoutinesService {
|
||||
|
||||
async create(actor: Actor, dto: SaveRoutineDto): Promise<RoutineDto> {
|
||||
const scope = await this.scope(actor);
|
||||
assertManager(scope);
|
||||
const data = await this.buildData(actor, scope, dto);
|
||||
const data = await this.buildData(actor, scope, this.ownRoutineInput(actor, scope, dto));
|
||||
const row = await this.prisma.routine.create({
|
||||
data: {
|
||||
...data,
|
||||
@@ -216,10 +215,9 @@ export class RoutinesService {
|
||||
|
||||
async update(actor: Actor, id: string, dto: SaveRoutineDto): Promise<RoutineDto> {
|
||||
const scope = await this.scope(actor);
|
||||
assertManager(scope);
|
||||
const existing = await this.findRoutine(actor.organizationId, id);
|
||||
this.assertCanManageRoutine(scope, existing);
|
||||
const data = await this.buildData(actor, scope, dto);
|
||||
this.assertCanWriteRoutine(scope, existing);
|
||||
const data = await this.buildData(actor, scope, this.ownRoutineInput(actor, scope, dto));
|
||||
const row = await this.prisma.routine.update({
|
||||
where: { id },
|
||||
data: data as Prisma.RoutineUncheckedUpdateInput,
|
||||
@@ -232,9 +230,8 @@ export class RoutinesService {
|
||||
|
||||
async toggle(actor: Actor, id: string, isActive: boolean): Promise<RoutineDto> {
|
||||
const scope = await this.scope(actor);
|
||||
assertManager(scope);
|
||||
const existing = await this.findRoutine(actor.organizationId, id);
|
||||
this.assertCanManageRoutine(scope, existing);
|
||||
this.assertCanWriteRoutine(scope, existing);
|
||||
const row = await this.prisma.routine.update({
|
||||
where: { id },
|
||||
data: { isActive },
|
||||
@@ -251,9 +248,8 @@ export class RoutinesService {
|
||||
dto: ChangeRoutineAssigneeDto,
|
||||
): Promise<RoutineDto> {
|
||||
const scope = await this.scope(actor);
|
||||
assertManager(scope);
|
||||
const existing = await this.findRoutine(actor.organizationId, id);
|
||||
this.assertCanManageRoutine(scope, existing);
|
||||
this.assertCanWriteRoutine(scope, existing);
|
||||
const target = await this.resolveTarget(actor, scope, dto.assigneeId, dto.teamId);
|
||||
await this.cancelTodayPending(id, 'تغییر مسئول روتین');
|
||||
const row = await this.prisma.routine.update({
|
||||
@@ -268,9 +264,8 @@ export class RoutinesService {
|
||||
|
||||
async duplicate(actor: Actor, id: string): Promise<RoutineDto> {
|
||||
const scope = await this.scope(actor);
|
||||
assertManager(scope);
|
||||
const src = await this.findRoutine(actor.organizationId, id);
|
||||
this.assertCanManageRoutine(scope, src);
|
||||
this.assertCanWriteRoutine(scope, src);
|
||||
const {
|
||||
id: _id,
|
||||
createdAt: _c,
|
||||
@@ -295,9 +290,8 @@ export class RoutinesService {
|
||||
|
||||
async remove(actor: Actor, id: string) {
|
||||
const scope = await this.scope(actor);
|
||||
assertManager(scope);
|
||||
const existing = await this.findRoutine(actor.organizationId, id);
|
||||
this.assertCanManageRoutine(scope, existing);
|
||||
this.assertCanWriteRoutine(scope, existing);
|
||||
await this.prisma.routine.update({
|
||||
where: { id },
|
||||
data: { deletedAt: new Date(), isActive: false },
|
||||
@@ -345,6 +339,27 @@ export class RoutinesService {
|
||||
return row;
|
||||
}
|
||||
|
||||
/** عضو عادی فقط روتینی را مینویسد که خودش برای خودش ساخته است. */
|
||||
private ownRoutineInput(actor: Actor, scope: RoutineScope, dto: SaveRoutineDto): SaveRoutineDto {
|
||||
if (scope.isManager) return dto;
|
||||
if (dto.teamId || (dto.assigneeId && dto.assigneeId !== actor.userId)) {
|
||||
throw new ForbiddenException('فقط میتوانید برای خودتان روتین بسازید');
|
||||
}
|
||||
return { ...dto, assigneeId: actor.userId, teamId: null };
|
||||
}
|
||||
|
||||
private assertCanWriteRoutine(
|
||||
scope: RoutineScope,
|
||||
row: { assigneeId: string | null; teamId: string | null; createdById: string | null },
|
||||
) {
|
||||
if (scope.isManager) {
|
||||
this.assertCanManageRoutine(scope, row);
|
||||
return;
|
||||
}
|
||||
if (row.createdById === scope.userId && row.assigneeId === scope.userId && !row.teamId) return;
|
||||
throw new ForbiddenException('فقط روتینی که برای خودتان ساختهاید را میتوانید تغییر دهید');
|
||||
}
|
||||
|
||||
private assertCanManageRoutine(
|
||||
scope: RoutineScope,
|
||||
row: { assigneeId: string | null; teamId: string | null; createdById: string | null },
|
||||
|
||||
Reference in New Issue
Block a user