feat: rename comment thread into activity (#939)

* feat: rename commentThread into activity server

* feat: rename commentThread into activity front

* feat: migration only create tables


feat: migration only create tables

* Update activities

* fix: rebase partial fix

* fix: all rebase problems and drop activity target alter

* fix: lint

* Update migration

* Update migration

* Fix conflicts

* Fix conflicts

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
Jérémy M
2023-07-28 08:22:16 +02:00
committed by GitHub
parent fcdde024a3
commit d0641084f9
95 changed files with 2112 additions and 1725 deletions

View File

@ -3,7 +3,8 @@ import { Injectable } from '@nestjs/common';
import { PureAbility, AbilityBuilder } from '@casl/ability';
import { createPrismaAbility, PrismaQuery, Subjects } from '@casl/prisma';
import {
CommentThread,
Attachment,
Activity,
Company,
Comment,
Person,
@ -11,11 +12,10 @@ import {
User,
Workspace,
WorkspaceMember,
CommentThreadTarget,
ActivityTarget,
Pipeline,
PipelineStage,
PipelineProgress,
Attachment,
UserSettings,
ViewField,
} from '@prisma/client';
@ -29,9 +29,9 @@ type SubjectsAbility = Subjects<{
Company: Company;
Person: Person;
RefreshToken: RefreshToken;
CommentThread: CommentThread;
Activity: Activity;
Comment: Comment;
CommentThreadTarget: CommentThreadTarget;
ActivityTarget: ActivityTarget;
Pipeline: Pipeline;
PipelineStage: PipelineStage;
PipelineProgress: PipelineProgress;
@ -86,11 +86,11 @@ export class AbilityFactory {
// RefreshToken
cannot(AbilityAction.Manage, 'RefreshToken');
// CommentThread
can(AbilityAction.Read, 'CommentThread', { workspaceId: workspace.id });
can(AbilityAction.Create, 'CommentThread');
can(AbilityAction.Update, 'CommentThread', { workspaceId: workspace.id });
can(AbilityAction.Delete, 'CommentThread', { workspaceId: workspace.id });
// Activity
can(AbilityAction.Read, 'Activity', { workspaceId: workspace.id });
can(AbilityAction.Create, 'Activity');
can(AbilityAction.Update, 'Activity', { workspaceId: workspace.id });
can(AbilityAction.Delete, 'Activity', { workspaceId: workspace.id });
// Comment
can(AbilityAction.Read, 'Comment', { workspaceId: workspace.id });
@ -104,9 +104,9 @@ export class AbilityFactory {
authorId: user.id,
});
// CommentThreadTarget
can(AbilityAction.Read, 'CommentThreadTarget');
can(AbilityAction.Create, 'CommentThreadTarget');
// ActivityTarget
can(AbilityAction.Read, 'ActivityTarget');
can(AbilityAction.Create, 'ActivityTarget');
// Attachment
can(AbilityAction.Read, 'Attachment', { workspaceId: workspace.id });

View File

@ -46,12 +46,12 @@ import {
DeleteRefreshTokenAbilityHandler,
} from './handlers/refresh-token.ability-handler';
import {
ManageCommentThreadAbilityHandler,
ReadCommentThreadAbilityHandler,
CreateCommentThreadAbilityHandler,
UpdateCommentThreadAbilityHandler,
DeleteCommentThreadAbilityHandler,
} from './handlers/comment-thread.ability-handler';
ManageActivityAbilityHandler,
ReadActivityAbilityHandler,
CreateActivityAbilityHandler,
UpdateActivityAbilityHandler,
DeleteActivityAbilityHandler,
} from './handlers/activity.ability-handler';
import {
ManageCommentAbilityHandler,
ReadCommentAbilityHandler,
@ -60,12 +60,12 @@ import {
DeleteCommentAbilityHandler,
} from './handlers/comment.ability-handler';
import {
ManageCommentThreadTargetAbilityHandler,
ReadCommentThreadTargetAbilityHandler,
CreateCommentThreadTargetAbilityHandler,
UpdateCommentThreadTargetAbilityHandler,
DeleteCommentThreadTargetAbilityHandler,
} from './handlers/comment-thread-target.ability-handler';
ManageActivityTargetAbilityHandler,
ReadActivityTargetAbilityHandler,
CreateActivityTargetAbilityHandler,
UpdateActivityTargetAbilityHandler,
DeleteActivityTargetAbilityHandler,
} from './handlers/activity-target.ability-handler';
import {
ManagePipelineAbilityHandler,
ReadPipelineAbilityHandler,
@ -140,24 +140,24 @@ import {
CreateRefreshTokenAbilityHandler,
UpdateRefreshTokenAbilityHandler,
DeleteRefreshTokenAbilityHandler,
// CommentThread
ManageCommentThreadAbilityHandler,
ReadCommentThreadAbilityHandler,
CreateCommentThreadAbilityHandler,
UpdateCommentThreadAbilityHandler,
DeleteCommentThreadAbilityHandler,
// Activity
ManageActivityAbilityHandler,
ReadActivityAbilityHandler,
CreateActivityAbilityHandler,
UpdateActivityAbilityHandler,
DeleteActivityAbilityHandler,
// Comment
ManageCommentAbilityHandler,
ReadCommentAbilityHandler,
CreateCommentAbilityHandler,
UpdateCommentAbilityHandler,
DeleteCommentAbilityHandler,
// CommentThreadTarget
ManageCommentThreadTargetAbilityHandler,
ReadCommentThreadTargetAbilityHandler,
CreateCommentThreadTargetAbilityHandler,
UpdateCommentThreadTargetAbilityHandler,
DeleteCommentThreadTargetAbilityHandler,
// ActivityTarget
ManageActivityTargetAbilityHandler,
ReadActivityTargetAbilityHandler,
CreateActivityTargetAbilityHandler,
UpdateActivityTargetAbilityHandler,
DeleteActivityTargetAbilityHandler,
//Attachment
ManageAttachmentAbilityHandler,
ReadAttachmentAbilityHandler,
@ -224,24 +224,24 @@ import {
CreateRefreshTokenAbilityHandler,
UpdateRefreshTokenAbilityHandler,
DeleteRefreshTokenAbilityHandler,
// CommentThread
ManageCommentThreadAbilityHandler,
ReadCommentThreadAbilityHandler,
CreateCommentThreadAbilityHandler,
UpdateCommentThreadAbilityHandler,
DeleteCommentThreadAbilityHandler,
// Activity
ManageActivityAbilityHandler,
ReadActivityAbilityHandler,
CreateActivityAbilityHandler,
UpdateActivityAbilityHandler,
DeleteActivityAbilityHandler,
// Comment
ManageCommentAbilityHandler,
ReadCommentAbilityHandler,
CreateCommentAbilityHandler,
UpdateCommentAbilityHandler,
DeleteCommentAbilityHandler,
// CommentThreadTarget
ManageCommentThreadTargetAbilityHandler,
ReadCommentThreadTargetAbilityHandler,
CreateCommentThreadTargetAbilityHandler,
UpdateCommentThreadTargetAbilityHandler,
DeleteCommentThreadTargetAbilityHandler,
// ActivityTarget
ManageActivityTargetAbilityHandler,
ReadActivityTargetAbilityHandler,
CreateActivityTargetAbilityHandler,
UpdateActivityTargetAbilityHandler,
DeleteActivityTargetAbilityHandler,
//Attachment
ManageAttachmentAbilityHandler,
ReadAttachmentAbilityHandler,

View File

@ -0,0 +1,79 @@
import {
ExecutionContext,
Injectable,
NotFoundException,
} from '@nestjs/common';
import { GqlExecutionContext } from '@nestjs/graphql';
import { subject } from '@casl/ability';
import { IAbilityHandler } from 'src/ability/interfaces/ability-handler.interface';
import { PrismaService } from 'src/database/prisma.service';
import { AbilityAction } from 'src/ability/ability.action';
import { AppAbility } from 'src/ability/ability.factory';
import { assert } from 'src/utils/assert';
import { ActivityTargetWhereInput } from 'src/core/@generated/activity-target/activity-target-where.input';
class ActivityTargetArgs {
where?: ActivityTargetWhereInput;
}
@Injectable()
export class ManageActivityTargetAbilityHandler implements IAbilityHandler {
async handle(ability: AppAbility) {
return ability.can(AbilityAction.Manage, 'ActivityTarget');
}
}
@Injectable()
export class ReadActivityTargetAbilityHandler implements IAbilityHandler {
handle(ability: AppAbility) {
return ability.can(AbilityAction.Read, 'ActivityTarget');
}
}
@Injectable()
export class CreateActivityTargetAbilityHandler implements IAbilityHandler {
handle(ability: AppAbility) {
return ability.can(AbilityAction.Create, 'ActivityTarget');
}
}
@Injectable()
export class UpdateActivityTargetAbilityHandler implements IAbilityHandler {
constructor(private readonly prismaService: PrismaService) {}
async handle(ability: AppAbility, context: ExecutionContext) {
const gqlContext = GqlExecutionContext.create(context);
const args = gqlContext.getArgs<ActivityTargetArgs>();
const ActivityTarget = await this.prismaService.client.activityTarget.findFirst({
where: args.where,
});
assert(ActivityTarget, '', NotFoundException);
return ability.can(
AbilityAction.Update,
subject('ActivityTarget', ActivityTarget),
);
}
}
@Injectable()
export class DeleteActivityTargetAbilityHandler implements IAbilityHandler {
constructor(private readonly prismaService: PrismaService) {}
async handle(ability: AppAbility, context: ExecutionContext) {
const gqlContext = GqlExecutionContext.create(context);
const args = gqlContext.getArgs<ActivityTargetArgs>();
const ActivityTarget = await this.prismaService.client.activityTarget.findFirst({
where: args.where,
});
assert(ActivityTarget, '', NotFoundException);
return ability.can(
AbilityAction.Delete,
subject('ActivityTarget', ActivityTarget),
);
}
}

View File

@ -0,0 +1,73 @@
import {
ExecutionContext,
Injectable,
NotFoundException,
} from '@nestjs/common';
import { GqlExecutionContext } from '@nestjs/graphql';
import { subject } from '@casl/ability';
import { IAbilityHandler } from 'src/ability/interfaces/ability-handler.interface';
import { PrismaService } from 'src/database/prisma.service';
import { AbilityAction } from 'src/ability/ability.action';
import { AppAbility } from 'src/ability/ability.factory';
import { assert } from 'src/utils/assert';
import { ActivityWhereInput } from 'src/core/@generated/activity/activity-where.input';
class ActivityArgs {
where?: ActivityWhereInput;
}
@Injectable()
export class ManageActivityAbilityHandler implements IAbilityHandler {
async handle(ability: AppAbility) {
return ability.can(AbilityAction.Manage, 'Activity');
}
}
@Injectable()
export class ReadActivityAbilityHandler implements IAbilityHandler {
handle(ability: AppAbility) {
return ability.can(AbilityAction.Read, 'Activity');
}
}
@Injectable()
export class CreateActivityAbilityHandler implements IAbilityHandler {
handle(ability: AppAbility) {
return ability.can(AbilityAction.Create, 'Activity');
}
}
@Injectable()
export class UpdateActivityAbilityHandler implements IAbilityHandler {
constructor(private readonly prismaService: PrismaService) {}
async handle(ability: AppAbility, context: ExecutionContext) {
const gqlContext = GqlExecutionContext.create(context);
const args = gqlContext.getArgs<ActivityArgs>();
const Activity = await this.prismaService.client.activity.findFirst({
where: args.where,
});
assert(Activity, '', NotFoundException);
return ability.can(AbilityAction.Update, subject('Activity', Activity));
}
}
@Injectable()
export class DeleteActivityAbilityHandler implements IAbilityHandler {
constructor(private readonly prismaService: PrismaService) {}
async handle(ability: AppAbility, context: ExecutionContext) {
const gqlContext = GqlExecutionContext.create(context);
const args = gqlContext.getArgs<ActivityArgs>();
const Activity = await this.prismaService.client.activity.findFirst({
where: args.where,
});
assert(Activity, '', NotFoundException);
return ability.can(AbilityAction.Delete, subject('Activity', Activity));
}
}

View File

@ -42,16 +42,12 @@ export class CreateAttachmentAbilityHandler implements IAbilityHandler {
const args = gqlContext.getArgs<AttachmentArgs>();
assert(args.activityId, '', ForbiddenException);
const activity = await this.prismaService.client.commentThread.findUnique({
const activity = await this.prismaService.client.activity.findUnique({
where: { id: args.activityId },
include: { workspace: true },
});
assert(activity, '', NotFoundException);
return ability.can(
AbilityAction.Update,
subject('Workspace', activity.workspace),
);
return ability.can(AbilityAction.Update, subject('Activity', activity));
}
}

View File

@ -1,118 +0,0 @@
import {
ExecutionContext,
Injectable,
NotFoundException,
} from '@nestjs/common';
import { GqlExecutionContext } from '@nestjs/graphql';
import { subject } from '@casl/ability';
import { IAbilityHandler } from 'src/ability/interfaces/ability-handler.interface';
import { PrismaService } from 'src/database/prisma.service';
import { AbilityAction } from 'src/ability/ability.action';
import { AppAbility } from 'src/ability/ability.factory';
import { CommentThreadTargetWhereInput } from 'src/core/@generated/comment-thread-target/comment-thread-target-where.input';
import { relationAbilityChecker } from 'src/ability/ability.util';
import { assert } from 'src/utils/assert';
class CommentThreadTargetArgs {
where?: CommentThreadTargetWhereInput;
[key: string]: any;
}
@Injectable()
export class ManageCommentThreadTargetAbilityHandler
implements IAbilityHandler
{
async handle(ability: AppAbility) {
return ability.can(AbilityAction.Manage, 'CommentThreadTarget');
}
}
@Injectable()
export class ReadCommentThreadTargetAbilityHandler implements IAbilityHandler {
handle(ability: AppAbility) {
return ability.can(AbilityAction.Read, 'CommentThreadTarget');
}
}
@Injectable()
export class CreateCommentThreadTargetAbilityHandler
implements IAbilityHandler
{
constructor(private readonly prismaService: PrismaService) {}
async handle(ability: AppAbility, context: ExecutionContext) {
const gqlContext = GqlExecutionContext.create(context);
const args = gqlContext.getArgs();
const allowed = await relationAbilityChecker(
'CommentThreadTarget',
ability,
this.prismaService.client,
args,
);
if (!allowed) {
return false;
}
return ability.can(AbilityAction.Create, 'CommentThreadTarget');
}
}
@Injectable()
export class UpdateCommentThreadTargetAbilityHandler
implements IAbilityHandler
{
constructor(private readonly prismaService: PrismaService) {}
async handle(ability: AppAbility, context: ExecutionContext) {
const gqlContext = GqlExecutionContext.create(context);
const args = gqlContext.getArgs<CommentThreadTargetArgs>();
const commentThreadTarget =
await this.prismaService.client.commentThreadTarget.findFirst({
where: args.where,
});
assert(commentThreadTarget, '', NotFoundException);
const allowed = await relationAbilityChecker(
'CommentThreadTarget',
ability,
this.prismaService.client,
args,
);
if (!allowed) {
return false;
}
return ability.can(
AbilityAction.Update,
subject('CommentThreadTarget', commentThreadTarget),
);
}
}
@Injectable()
export class DeleteCommentThreadTargetAbilityHandler
implements IAbilityHandler
{
constructor(private readonly prismaService: PrismaService) {}
async handle(ability: AppAbility, context: ExecutionContext) {
const gqlContext = GqlExecutionContext.create(context);
const args = gqlContext.getArgs<CommentThreadTargetArgs>();
const commentThreadTarget =
await this.prismaService.client.commentThreadTarget.findFirst({
where: args.where,
});
assert(commentThreadTarget, '', NotFoundException);
return ability.can(
AbilityAction.Delete,
subject('CommentThreadTarget', commentThreadTarget),
);
}
}

View File

@ -1,110 +0,0 @@
import {
ExecutionContext,
Injectable,
NotFoundException,
} from '@nestjs/common';
import { GqlExecutionContext } from '@nestjs/graphql';
import { subject } from '@casl/ability';
import { IAbilityHandler } from 'src/ability/interfaces/ability-handler.interface';
import { PrismaService } from 'src/database/prisma.service';
import { AbilityAction } from 'src/ability/ability.action';
import { AppAbility } from 'src/ability/ability.factory';
import { CommentThreadWhereInput } from 'src/core/@generated/comment-thread/comment-thread-where.input';
import { relationAbilityChecker } from 'src/ability/ability.util';
import { assert } from 'src/utils/assert';
class CommentThreadArgs {
where?: CommentThreadWhereInput;
[key: string]: any;
}
@Injectable()
export class ManageCommentThreadAbilityHandler implements IAbilityHandler {
async handle(ability: AppAbility) {
return ability.can(AbilityAction.Manage, 'CommentThread');
}
}
@Injectable()
export class ReadCommentThreadAbilityHandler implements IAbilityHandler {
handle(ability: AppAbility) {
return ability.can(AbilityAction.Read, 'CommentThread');
}
}
@Injectable()
export class CreateCommentThreadAbilityHandler implements IAbilityHandler {
constructor(private readonly prismaService: PrismaService) {}
async handle(ability: AppAbility, context: ExecutionContext) {
const gqlContext = GqlExecutionContext.create(context);
const args = gqlContext.getArgs();
const allowed = await relationAbilityChecker(
'CommentThread',
ability,
this.prismaService.client,
args,
);
if (!allowed) {
return false;
}
return ability.can(AbilityAction.Create, 'CommentThread');
}
}
@Injectable()
export class UpdateCommentThreadAbilityHandler implements IAbilityHandler {
constructor(private readonly prismaService: PrismaService) {}
async handle(ability: AppAbility, context: ExecutionContext) {
const gqlContext = GqlExecutionContext.create(context);
const args = gqlContext.getArgs<CommentThreadArgs>();
const commentThread =
await this.prismaService.client.commentThread.findFirst({
where: args.where,
});
assert(commentThread, '', NotFoundException);
const allowed = await relationAbilityChecker(
'CommentThread',
ability,
this.prismaService.client,
args,
);
if (!allowed) {
return false;
}
return ability.can(
AbilityAction.Update,
subject('CommentThread', commentThread),
);
}
}
@Injectable()
export class DeleteCommentThreadAbilityHandler implements IAbilityHandler {
constructor(private readonly prismaService: PrismaService) {}
async handle(ability: AppAbility, context: ExecutionContext) {
const gqlContext = GqlExecutionContext.create(context);
const args = gqlContext.getArgs<CommentThreadArgs>();
const commentThread =
await this.prismaService.client.commentThread.findFirst({
where: args.where,
});
assert(commentThread, '', NotFoundException);
return ability.can(
AbilityAction.Delete,
subject('CommentThread', commentThread),
);
}
}