Skip to content

Commit 853bd27

Browse files
committed
Publish recorded events at the CourseCreator
1 parent 516a4db commit 853bd27

File tree

20 files changed

+226
-46
lines changed

20 files changed

+226
-46
lines changed

package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
"mandrill-api": "^1.0.45",
4141
"node-dependency-injection": "^2.4.2",
4242
"ts-node": "^8.3.0",
43-
"typescript": "^3.4.5",
43+
"typescript": "^3.7.2",
4444
"uuid": "^3.3.3",
4545
"winston": "^3.2.1"
4646
},
Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,24 @@
11
import CourseRepository from '../domain/CourseRepository';
22
import Course from '../domain/Course';
3+
import { CourseId } from '../domain/CourseId';
4+
import { CourseName } from '../domain/CourseName';
5+
import { CourseDuration } from '../domain/CourseDuration';
6+
import { EventBus } from '../../../Shared/domain/EventBus';
37

48
export default class CourseCreator {
59
private repository: CourseRepository;
10+
private eventBus: EventBus;
611

7-
constructor(repository: CourseRepository) {
12+
constructor(repository: CourseRepository, eventBus: EventBus) {
813
this.repository = repository;
14+
this.eventBus = eventBus;
915
}
1016

11-
async run(id: string, name: string, duration: string): Promise<void> {
17+
async run(id: CourseId, name: CourseName, duration: CourseDuration): Promise<void> {
1218
const course = new Course(id, name, duration);
1319

14-
return this.repository.save(course);
20+
await this.repository.save(course);
21+
22+
this.eventBus.publish(course.pullDomainEvents());
1523
}
1624
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { DomainEvent } from '../../../Shared/domain/DomainEvent';
2+
3+
export abstract class AggregateRoot {
4+
private domainEvents: Array<DomainEvent>;
5+
6+
constructor() {
7+
this.domainEvents = [];
8+
}
9+
10+
pullDomainEvents(): Array<DomainEvent> {
11+
return this.domainEvents;
12+
}
13+
14+
record(event: DomainEvent): void {
15+
this.domainEvents.push(event);
16+
}
17+
}
Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,32 @@
1-
export default class Course {
2-
readonly id: string;
3-
readonly name: string;
4-
readonly duration: string;
1+
import { AggregateRoot } from './AggregateRoot';
2+
import { CourseCreatedDomainEvent } from './CourseCreatedDomainEvent';
3+
import { CourseId } from './CourseId';
4+
import { CourseName } from './CourseName';
5+
import { CourseDuration } from './CourseDuration';
56

6-
constructor(id: string, name: string, duration: string) {
7+
export default class Course extends AggregateRoot {
8+
readonly id: CourseId;
9+
readonly name: CourseName;
10+
readonly duration: CourseDuration;
11+
12+
constructor(id: CourseId, name: CourseName, duration: CourseDuration) {
13+
super();
714
this.id = id;
815
this.name = name;
916
this.duration = duration;
1017
}
18+
19+
static create(id: CourseId, name: CourseName, duration: CourseDuration): Course {
20+
const course = new Course(id, name, duration);
21+
22+
course.record(
23+
new CourseCreatedDomainEvent({
24+
id: course.id.value(),
25+
duration: course.duration.value(),
26+
name: course.name.value()
27+
})
28+
);
29+
30+
return course;
31+
}
1132
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { DomainEvent } from '../../../Shared/domain/DomainEvent';
2+
3+
type CreateCourseDomainEventBody = {
4+
readonly duration: number;
5+
readonly name: string;
6+
};
7+
8+
export class CourseCreatedDomainEvent extends DomainEvent {
9+
static readonly EVENT_NAME = 'course.created';
10+
11+
readonly duration: number;
12+
readonly name: string;
13+
14+
constructor({
15+
id,
16+
eventId,
17+
duration,
18+
name,
19+
occurredOn
20+
}: {
21+
id: string;
22+
eventId?: string;
23+
duration: number;
24+
name: string;
25+
occurredOn?: Date;
26+
}) {
27+
super(CourseCreatedDomainEvent.EVENT_NAME, id, eventId, occurredOn);
28+
this.duration = duration;
29+
this.name = name;
30+
}
31+
32+
toPrimitive(): CreateCourseDomainEventBody {
33+
const { name, duration } = this;
34+
return {
35+
name,
36+
duration
37+
};
38+
}
39+
40+
static fromPrimitive(
41+
aggregateId: string,
42+
body: CreateCourseDomainEventBody,
43+
eventId: string,
44+
occurredOn: Date
45+
): CourseCreatedDomainEvent {
46+
return new CourseCreatedDomainEvent({
47+
id: aggregateId,
48+
duration: body.duration,
49+
name: body.name,
50+
eventId,
51+
occurredOn
52+
});
53+
}
54+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { ValueObject } from '../../../Shared/domain/ValueObject';
2+
3+
export class CourseDuration extends ValueObject<number> {}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { ValueObject } from '../../../Shared/domain/ValueObject';
2+
3+
export class CourseId extends ValueObject<string> {}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { ValueObject } from '../../../Shared/domain/ValueObject';
2+
3+
export class CourseName extends ValueObject<string> {}

src/Contexts/Mooc/Courses/infrastructure/FileCourseRepository.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export default class FileCourseRepository implements CourseRepository {
88
private FILE_PATH = `${__dirname}/courses`;
99

1010
async save(course: Course): Promise<void> {
11-
const filePath = this.filePath(course.id);
11+
const filePath = this.filePath(course.id.value());
1212
const data = BSON.serialize(course);
1313

1414
return fs.writeFileSync(filePath, data);

0 commit comments

Comments
 (0)