Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/business/commands/create-comment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Observable } from 'rxjs';
import { CommentInput } from '../models/inputs/comment-input';
import { ICommentRepository } from '../repositories/i-comment-repository';
import { ICreateComment } from './i-create-comment';



export class CreateComment implements ICreateComment {
constructor(private readonly commentRepository: ICommentRepository) { }

execute(input: CommentInput): Observable<any> {
return this.commentRepository.insert(input);
}
}
12 changes: 12 additions & 0 deletions src/business/commands/delete-comment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Observable, iif, of } from 'rxjs';
import { ICommentRepository } from '../repositories/i-comment-repository';
import { IDeleteComment } from './i-delete-comment';
import { flatMap, catchError, tap } from 'rxjs/operators';

export class DeleteComment implements IDeleteComment {
constructor(private readonly commentRepository: ICommentRepository) { }

execute(id: string): Observable<boolean> {
return this.commentRepository.delete(id);
}
}
13 changes: 13 additions & 0 deletions src/business/commands/get-comments.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Observable } from 'rxjs';
import { Comment as CommentResult } from '../../business/models/results/comment';
import { ICommentRepository } from '../repositories/i-comment-repository';
import { IGetComments } from './i-get-comments';


export class GetComments implements IGetComments {
constructor(private commentRepository: ICommentRepository) { }

execute(parameter: string): Observable<CommentResult[]> {
return this.commentRepository.get(parameter);
}
}
5 changes: 5 additions & 0 deletions src/business/commands/i-create-comment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { CommentInput } from '../models/inputs/comment-input';
import { IObservableCommand } from './core/i-observable-command';

export interface ICreateComment extends IObservableCommand<CommentInput, Comment> {
}
4 changes: 4 additions & 0 deletions src/business/commands/i-delete-comment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { IObservableCommand } from './core/i-observable-command';

export interface IDeleteComment extends IObservableCommand<string, boolean> {
}
4 changes: 4 additions & 0 deletions src/business/commands/i-get-comments.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { Comment as CommentResult } from '../../business/models/results/comment';
import { IObservableCommand } from './core/i-observable-command';

export interface IGetComments extends IObservableCommand<string, CommentResult[]> { }
12 changes: 12 additions & 0 deletions src/business/models/inputs/comment-input.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export class CommentInput {
authorId!: string;
eventId!: string;
description!: string;
date!: Date;
isDeleted!: boolean;

constructor(init?: any) {
Object.assign(this, init);
this.isDeleted = false;
}
}
15 changes: 15 additions & 0 deletions src/business/models/results/comment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { User } from '../../../data/entities/user';

export class Comment {
id!: string;
user!: User;
eventId!: string;
description!: string;
date!: Date;
isDeleted!: boolean;

constructor(init?: any) {
Object.assign(this, init);
this.isDeleted = false;
}
}
17 changes: 17 additions & 0 deletions src/business/repositories/i-comment-repository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Observable } from 'rxjs';
import { CommentInput } from '../models/inputs/comment-input';
import { Comment as CommentResult } from '../../business/models/results/comment';


export interface ICommentRepository {

get(eventId: string): Observable<CommentResult[]>;

insert(comment: CommentInput): Observable<CommentResult>;

update(input: CommentInput): Observable<CommentResult>;

getById(id: string): Observable<CommentResult>;

delete(id: string): Observable<boolean>;
}
32 changes: 32 additions & 0 deletions src/data/entities/comment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { BaseEntity, Column, Entity, PrimaryGeneratedColumn, JoinColumn, ManyToOne } from 'typeorm';
import { User } from './user';
import { Event } from './event';


@Entity('comment')
export class Comment extends BaseEntity {
@PrimaryGeneratedColumn('uuid')
id!: string;

@JoinColumn({ name: 'author_id' })
@ManyToOne(() => User, (user) => user.comments)
user!: User;

@JoinColumn({ name: 'event_id'})
@ManyToOne(() => Event, (event) => event.comments)
event!: Event;

@Column()
description!: string;

@Column()
date!: Date;

@Column()
isDeleted!: boolean;

constructor(init?: Partial<Comment>) {
super();
Object.assign(this, init);
}
}
6 changes: 5 additions & 1 deletion src/data/entities/event.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { BaseEntity, Column, Entity, JoinColumn, OneToOne, PrimaryGeneratedColumn, CreateDateColumn } from 'typeorm';
import { BaseEntity, Column, Entity, JoinColumn, OneToOne, PrimaryGeneratedColumn, CreateDateColumn, OneToMany } from 'typeorm';
import { Address } from './address';
import { Sport } from './sport';
import { User } from './user';
import { Comment } from '../entities/comment';

@Entity('event')
export class Event extends BaseEntity {
Expand Down Expand Up @@ -54,6 +55,9 @@ export class Event extends BaseEntity {
@Column()
status!: number;

@OneToMany(() => Comment, (comment) => comment.event, { cascade: true, nullable : true, eager : true })
comments!: Comment[];

constructor(init?: Partial<Event>) {
super();
Object.assign(this, init);
Expand Down
6 changes: 5 additions & 1 deletion src/data/entities/user.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { BaseEntity, Column, Entity, PrimaryGeneratedColumn, OneToOne, JoinColumn, CreateDateColumn, UpdateDateColumn } from 'typeorm';
import { BaseEntity, Column, Entity, PrimaryGeneratedColumn, OneToOne, JoinColumn, CreateDateColumn, UpdateDateColumn, OneToMany } from 'typeorm';
import { UserDetails } from './user-details';
import { Comment } from '../entities/comment';

@Entity('user')
export class User extends BaseEntity {
Expand Down Expand Up @@ -29,6 +30,9 @@ export class User extends BaseEntity {
@UpdateDateColumn({ name: 'modified_date' })
modifiedDate!: Date;

@OneToMany(() => Comment, (comment) => comment.user, { cascade: true })
comments!: Comment[];

constructor(init?: any) {
super();
Object.assign(this, init);
Expand Down
30 changes: 30 additions & 0 deletions src/data/factories/comment-factory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { from } from 'rxjs';
import { Comment as CommentResult } from '../../business/models/results/comment';
import { Comment, Comment as CommentEntity } from '../entities/comment';
import { CommentInput } from '../../business/models/inputs/comment-input';
import { UserFactory } from './user-factory';
import { EventFactory } from './event-factory';

export class CommentFactory {

static entity = {
fromCommentResult: (comment: CommentResult) => new CommentEntity(comment),
fromId: (id: string) => from(Comment.findOne(id)),
fromCommentInput: (comment: CommentInput, userId: string): CommentEntity => new CommentEntity({
...comment,
description: comment.description,
date: comment.date,
user: UserFactory.entity.fromId(userId),
event: EventFactory.entity.fromId(comment.eventId),
}),
};

static result = {
fromCommentEntity: (comment: CommentEntity) => new CommentResult(comment),
};

static results = {
fromCommentEntities: (comments: CommentEntity[]): CommentResult[] =>
comments.map((comment) => new CommentResult(comment)),
};
}
5 changes: 3 additions & 2 deletions src/data/factories/event-factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { UserFactory } from './user-factory';
import { UserEvents } from '../entities/user-events';
import { NotificationType } from '../enums/notification-type';
import { EventStatus } from '../enums/event-status';
import { CommentFactory } from './comment-factory';

export class EventFactory {
static entity = {
Expand All @@ -19,15 +20,15 @@ export class EventFactory {
owner: UserFactory.entity.fromId(userId),
status: event.id ? EventStatus.Edited : EventStatus.Active,
}),
fromId: (id: string) => new EventEntity({ id }),
};

static result = {
fromEventEntity: (event: EventEntity): EventResult => new EventResult({
...event,
address: Address.findOne(event.address.id),
sport: Sport.findOne(event.sport.id),
numberOfParticipants: UserEvents.count({ eventId: event.id, status: NotificationType.ApproveJoin }),
}),
numberOfParticipants: UserEvents.count({ eventId: event.id, status: NotificationType.ApproveJoin })}),
};

static results = {
Expand Down
2 changes: 1 addition & 1 deletion src/data/factories/user-events-factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export class UserEventsFactory {
fromUserEventsEntities: (userEvents: UserEventsEntity[]): UserEventsResult[] => {
return userEvents.map((userEvent) => new UserEventsResult({
...userEvent,
user: User.findOne(userEvent.userId),
user: User.findOne(userEvent.userId, { relations: ['details']}),
}));
},

Expand Down
60 changes: 60 additions & 0 deletions src/data/migrations/1596093629882-create-comment-table.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { MigrationInterface, QueryRunner, Table, TableForeignKey } from 'typeorm';

export class CreateCommentsTable1596093629882 implements MigrationInterface {

async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.createTable(new Table({
columns: [
{
isPrimary: true,
name: 'id',
type: 'varchar(36)',
},
{
name: 'author_id',
type: 'varchar(36)',
},
{
name: 'event_id',
type: 'varchar(36)',
},
{
name: 'description',
type: 'varchar(200)',
},
{
name: 'date',
type: 'DATETIME',
},
{
name: 'isDeleted',
type: 'boolean',
default: 'false',
},
],
name: 'comment',
}), true);

await queryRunner.createForeignKey('comment', new TableForeignKey({
columnNames: ['author_id'],
name: 'FK_comment_users',
onDelete: 'CASCADE',
onUpdate: 'CASCADE',
referencedColumnNames: ['id'],
referencedTableName: 'user',
}));

await queryRunner.createForeignKey('comment', new TableForeignKey({
columnNames: ['event_id'],
name: 'FK_comment_events',
onDelete: 'CASCADE',
onUpdate: 'CASCADE',
referencedColumnNames: ['id'],
referencedTableName: 'event',
}));
}

async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.dropTable('comment');
}
}
49 changes: 49 additions & 0 deletions src/data/repositories/comment-repository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { from, Observable, of, throwError, zip } from 'rxjs';
import { catchError, flatMap, map, switchMap, tap } from 'rxjs/operators';
import { CommentInput } from '../../business/models/inputs/comment-input';
import { Comment as CommentResult } from '../../business/models/results/comment';
import { ICommentRepository } from '../../business/repositories/i-comment-repository';
import { UserContext } from '../../utilities/user-context';
import { Comment } from '../entities/comment';
import { CommentFactory } from '../factories/comment-factory';

export class CommentRepository implements ICommentRepository {
constructor(private readonly userContext: UserContext) {
}
get(eventId: string): Observable<CommentResult[]> {
return from(Comment.find({ relations: ['user', 'user.details'], where: { event: eventId , isDeleted: false}, order: { date: 'ASC'}}))
.pipe(map((results) => CommentFactory.results.fromCommentEntities(results)));
}

insert(input: CommentInput): Observable<CommentResult> {
const commentInput = of(CommentFactory.entity.fromCommentInput(input, this.userContext.userId));

return zip(commentInput)
.pipe(flatMap((result) => {
return result[0].save();
}))
.pipe(catchError((e) => throwError(new Error(e))))
.pipe(map((comment) => CommentFactory.result.fromCommentEntity(comment)));
}

update(input: CommentInput): Observable<CommentResult> {
return of(CommentFactory.entity.fromCommentInput(input, input.authorId))
.pipe(switchMap((entity) => entity.save()))
.pipe(map((entity) => CommentFactory.result.fromCommentEntity(entity)));
}

getById(id: any): Observable<CommentResult> {
return from(Comment.findOneOrFail(id, { relations: ['user'] }))
.pipe(map((event) => CommentFactory.result.fromCommentEntity(event)));
}

delete(id: string): Observable<boolean> {
return from(Comment.findOneOrFail(id))
.pipe(map((entity) => {
entity.isDeleted = true;
entity.save();
return true;
}))
.pipe(catchError(() => of(false)));
}
}
2 changes: 1 addition & 1 deletion src/data/repositories/event-repository.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { from, Observable, of, zip } from 'rxjs';
import { map, switchMap, flatMap, catchError } from 'rxjs/operators';
import { map, switchMap, flatMap, catchError, tap } from 'rxjs/operators';
import { EventInput } from '../../business/models/inputs/event-input';
import { Event as EventResult } from '../../business/models/results/event';
import { Pagination } from '../../business/models/results/pagination';
Expand Down
Loading