Skip to content

Commit 2790a8a

Browse files
authored
Backoffice backend application (#78)
* Create new backoffice backend application * Prepare feature testing for the new app and create status route * Create get-courses feature * Create get courses route * Create CoursesGetController * Create BackofficeCourse aggregate root * Create SearchAllCourses query and CoursesFinder * Implement MongoBackofficeCourseRepository * Ask SearchAllCoursesQuery from controller * Fix tslint issues * Fix import typo * Fix test
1 parent 9f90731 commit 2790a8a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+604
-6
lines changed

cucumber.js

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,19 @@
1-
let common = [
2-
'tests/**/features/**/*.feature', // Specify our feature files
3-
'--require-module ts-node/register', // Load TypeScript module
4-
'--require tests/**/features/step_definitions/*.steps.ts' // Load step definitions
1+
const common = [
2+
'--require-module ts-node/register' // Load TypeScript module
3+
];
4+
5+
const backoffice_backend = [
6+
...common,
7+
'tests/apps/backoffice/backend/features/**/*.feature',
8+
'--require tests/apps/backoffice/backend/features/step_definitions/*.steps.ts'
9+
].join(' ');
10+
const mooc_backend = [
11+
...common,
12+
'tests/apps/mooc_backend/features/**/*.feature',
13+
'--require tests/apps/mooc_backend/features/step_definitions/*.steps.ts'
514
].join(' ');
615

716
module.exports = {
8-
default: common
17+
backoffice_backend,
18+
mooc_backend
919
};

package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,16 @@
1313
"scripts": {
1414
"dev": "NODE_ENV=dev ts-node-dev --ignore-watch node_modules --inspect=0.0.0.0:9267 ./src/apps/mooc_backend/server.ts",
1515
"dev:backoffice:frontend": "NODE_ENV=dev ts-node-dev --ignore-watch node_modules ./src/apps/backoffice/frontend/server.ts",
16+
"dev:backoffice:backend": "NODE_ENV=dev ts-node-dev --ignore-watch node_modules ./src/apps/backoffice/backend/server.ts",
1617
"test": "npm run test:unit && npm run test:features && npm run cypress:run",
1718
"test:unit": "NODE_ENV=test jest",
18-
"test:features": "NODE_ENV=test cucumber-js -p default",
19+
"test:features": "npm run test:mooc:backend:features && npm run test:backoffice:backend:features",
20+
"test:mooc:backend:features": "NODE_ENV=test cucumber-js -p mooc_backend",
21+
"test:backoffice:backend:features": "NODE_ENV=test cucumber-js -p backoffice_backend",
1922
"lint": "tslint src/**/*.ts{,x}",
2023
"start": "NODE_ENV=production node dist/src/apps/mooc_backend/server",
2124
"start:backoffice:frontend": "NODE_ENV=production node dist/src/apps/backoffice/frontend/server",
25+
"start:backoffice:backend": "NODE_ENV=production node dist/src/apps/backoffice/backend/server",
2226
"build": "npm run build:clean && npm run build:tsc && npm run build:di",
2327
"build:tsc": "tsc -p tsconfig.prod.json",
2428
"build:di": "copy 'src/**/*.{json,yaml,html,png}' dist/src",
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { BackofficeCourseRepository } from '../../domain/BackofficeCourseRepository';
2+
import { SearchAllCoursesResponse } from './SearchAllCoursesResponse';
3+
4+
export class CoursesFinder {
5+
constructor(private coursesRepository: BackofficeCourseRepository) {}
6+
7+
async run() {
8+
const courses = await this.coursesRepository.searchAll();
9+
10+
return new SearchAllCoursesResponse(courses);
11+
}
12+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { Query } from '../../../Shared/domain/Query';
2+
3+
export class SearchAllCoursesQuery implements Query {}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { Query } from '../../../Shared/domain/Query';
2+
import { QueryHandler } from '../../../Shared/domain/QueryHandler';
3+
import { CoursesFinder } from './CoursesFinder';
4+
import { SearchAllCoursesQuery } from './SearchAllCoursesQuery';
5+
import { SearchAllCoursesResponse } from './SearchAllCoursesResponse';
6+
7+
export class SearchAllCoursesQueryHandler implements QueryHandler<SearchAllCoursesQuery, SearchAllCoursesResponse> {
8+
constructor(private coursesFinder: CoursesFinder) {}
9+
10+
subscribedTo(): Query {
11+
return SearchAllCoursesQuery;
12+
}
13+
14+
async handle(_query: SearchAllCoursesQuery): Promise<SearchAllCoursesResponse> {
15+
return this.coursesFinder.run();
16+
}
17+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { BackofficeCourse } from '../../domain/BackofficeCourse';
2+
3+
export class SearchAllCoursesResponse {
4+
readonly courses: Array<BackofficeCourse>;
5+
6+
constructor(courses: Array<BackofficeCourse>) {
7+
this.courses = courses;
8+
}
9+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
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+
18+
abstract toPrimitives(): any;
19+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { AggregateRoot } from '../../Mooc/Courses/domain/AggregateRoot';
2+
import { BackofficeCourseDuration } from './BackofficeCourseDuration';
3+
import { BackofficeCourseId } from './BackofficeCourseId';
4+
import { BackofficeCourseName } from './BackofficeCourseName';
5+
6+
export class BackofficeCourse extends AggregateRoot {
7+
readonly id: BackofficeCourseId;
8+
readonly name: BackofficeCourseName;
9+
readonly duration: BackofficeCourseDuration;
10+
11+
constructor(id: BackofficeCourseId, name: BackofficeCourseName, duration: BackofficeCourseDuration) {
12+
super();
13+
this.id = id;
14+
this.name = name;
15+
this.duration = duration;
16+
}
17+
18+
static create(
19+
id: BackofficeCourseId,
20+
name: BackofficeCourseName,
21+
duration: BackofficeCourseDuration
22+
): BackofficeCourse {
23+
const course = new BackofficeCourse(id, name, duration);
24+
25+
return course;
26+
}
27+
28+
static fromPrimitives(plainData: { id: string; name: string; duration: string }): BackofficeCourse {
29+
return new BackofficeCourse(
30+
new BackofficeCourseId(plainData.id),
31+
new BackofficeCourseName(plainData.name),
32+
new BackofficeCourseDuration(plainData.duration)
33+
);
34+
}
35+
36+
toPrimitives() {
37+
return {
38+
id: this.id.value,
39+
name: this.name.value,
40+
duration: this.duration.value
41+
};
42+
}
43+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { StringValueObject } from '../../Shared/domain/value-object/StringValueObject';
2+
3+
export class BackofficeCourseDuration extends StringValueObject {}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { Uuid } from '../../Shared/domain/value-object/Uuid';
2+
3+
export class BackofficeCourseId extends Uuid {}

0 commit comments

Comments
 (0)