Skip to content

Commit

Permalink
Feature/asking question (#9)
Browse files Browse the repository at this point in the history
  • Loading branch information
PawelSzambelan authored Apr 24, 2021
1 parent ad61f08 commit 51f12da
Show file tree
Hide file tree
Showing 10 changed files with 10,470 additions and 3 deletions.
10,280 changes: 10,280 additions & 0 deletions backend/package-lock.json

Large diffs are not rendered by default.

8 changes: 7 additions & 1 deletion backend/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { QuestionsModuleCore } from './modules/questions/core/QuestionsModuleCor
import { MongoQuestionsRepository } from './modules/questions/infrastructure/repository/mongo/MongoQuestionsRepository';
import { InMemoryQuestionsRepository } from './modules/questions/infrastructure/repository/inmemory/InMemoryQuestionsRepository';
import { QuestionsRestApiModule } from './modules/questions/presentation/rest-api/QuestionsRestApiModule';
import { InMemoryGroupQuestionsRepository } from './modules/questions/infrastructure/repository/inmemory/InMemoryGroupQuestionsRepository';

config();

Expand All @@ -55,8 +56,9 @@ export async function IntegramicApplication(
};

const questionsRepository = QuestionsRepository();
const groupQuestionsRepository = GroupQuestionsRepository();
const questionsModule: Module = {
core: QuestionsModuleCore(eventBus, currentTimeProvider, questionsRepository),
core: QuestionsModuleCore(eventBus, commandBus, currentTimeProvider, groupQuestionsRepository, questionsRepository),
restApi: QuestionsRestApiModule(commandBus, eventBus, queryBus),
};

Expand Down Expand Up @@ -146,3 +148,7 @@ function QuestionsRepository() {
}
return new InMemoryQuestionsRepository();
}

function GroupQuestionsRepository() {
return new InMemoryGroupQuestionsRepository();
}
25 changes: 24 additions & 1 deletion backend/src/modules/questions/core/QuestionsModuleCore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,20 @@ import { UserQuestionsRepository } from './application/UserQuestionsRepository';
import { CurrentTimeProvider } from '../../../shared/core/CurrentTimeProvider';
import { DefineQuestion } from './application/command/DefineQuestion';
import { DefineQuestionCommandHandler } from './application/command/DefineQuestionCommandHandler';
import { GroupQuestionWasAsked } from '../../asking-question/core/domain/event/GroupQuestionWasAsked';
import { GroupQuestionAskedEventHandler } from './application/event/GroupQuestionAskedEventHandler';
import { GroupQuestionsRepository } from './application/GroupQuestionsRepository';
import { QuestionWasDefined } from './domain/event/QuestionWasDefined';
import { QuestionWasDefinedEventHandler } from './application/event/QuestionWasDefinedEventHandler';
import { TimeHasPassed } from '../../time/core/domain/event/TimeHasPassed';
import { TimeHasPassedEventHandler } from './application/event/TimeHasPassedEventHandler';
import { CommandPublisher } from '../../../shared/core/application/command/CommandBus';

export function QuestionsModuleCore(
eventPublisher: DomainEventPublisher,
commandPublisher: CommandPublisher,
currentTimeProvider: CurrentTimeProvider,
groupQuestionsRepository: GroupQuestionsRepository,
questionsRepository: UserQuestionsRepository,
): ModuleCore {
return {
Expand All @@ -17,7 +27,20 @@ export function QuestionsModuleCore(
handler: new DefineQuestionCommandHandler(eventPublisher, currentTimeProvider, questionsRepository),
},
],
eventHandlers: [],
eventHandlers: [
{
eventType: GroupQuestionWasAsked,
handler: new GroupQuestionAskedEventHandler(groupQuestionsRepository),
},
{
eventType: QuestionWasDefined,
handler: new QuestionWasDefinedEventHandler(groupQuestionsRepository),
},
{
eventType: TimeHasPassed,
handler: new TimeHasPassedEventHandler(groupQuestionsRepository, commandPublisher),
},
],
queryHandlers: [],
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { GroupQuestions } from '../domain/GroupQuestions';

export interface GroupQuestionsRepository {
save(groupQuestions: GroupQuestions): Promise<void>;

findByGroupId(groupId: string): Promise<GroupQuestions | undefined>;

findAll(): Promise<GroupQuestions[]>;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { EventHandler } from '../../../../../shared/core/application/event/EventHandler';
import { GroupQuestionsRepository } from '../GroupQuestionsRepository';
import { GroupQuestions } from '../../domain/GroupQuestions';
import { GroupQuestionWasAsked } from '../../../../asking-question/core/domain/event/GroupQuestionWasAsked';

export class GroupQuestionAskedEventHandler implements EventHandler<GroupQuestionWasAsked> {
constructor(private readonly groupQuestionsRepository: GroupQuestionsRepository) {}

async handle(event: GroupQuestionWasAsked): Promise<void> {
const questionId = event.questionId;
const groupId = event.groupId;

const groupQuestions = await this.groupQuestionsRepository.findByGroupId(groupId);

const existingQuestions = groupQuestions!.questionList.filter((elem) => elem.questionId !== questionId);

const newGroupQuestions = new GroupQuestions({
questionList: existingQuestions,
questionAskedLastlyDate: new Date(),
groupId: groupQuestions!.groupId,
questionAskedLastly: {
questionId: questionId,
text: event.text,
authorId: event.askedBy,
groupId: groupId,
},
});
await this.groupQuestionsRepository.save(newGroupQuestions);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { EventHandler } from '../../../../../shared/core/application/event/EventHandler';
import { GroupQuestionsRepository } from '../GroupQuestionsRepository';
import { Question } from '../../domain/Question';
import { GroupQuestions } from '../../domain/GroupQuestions';
import { QuestionWasDefined } from '../../domain/event/QuestionWasDefined';

export class QuestionWasDefinedEventHandler implements EventHandler<QuestionWasDefined> {
constructor(private readonly groupQuestionsRepository: GroupQuestionsRepository) {}

async handle(event: QuestionWasDefined): Promise<void> {
const questionId = event.questionId;
const groupId = event.groupId;
const question = {
questionId: questionId,
text: event.text,
authorId: event.authorId,
groupId: groupId,
};
const groupQuestions = await this.groupQuestionsRepository.findByGroupId(groupId);

if (!groupQuestions) {
const questionList: Question[] = [question];
const groupQuestions = new GroupQuestions({
groupId: groupId,
questionAskedLastly: undefined,
questionAskedLastlyDate: new Date(),
questionList: questionList,
});
await this.groupQuestionsRepository.save(groupQuestions);
} else {
const existingQuestions = groupQuestions.questionList.filter((elem) => elem.authorId !== event.authorId);

existingQuestions.push(question);
const newGroupQuestions = new GroupQuestions({ ...groupQuestions, questionList: existingQuestions });
await this.groupQuestionsRepository.save(newGroupQuestions);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { EventHandler } from '../../../../../shared/core/application/event/EventHandler';
import { TimeHasPassed } from '../../../../time/core/domain/event/TimeHasPassed';
import { GroupQuestionsRepository } from '../GroupQuestionsRepository';
import { GroupQuestions } from '../../domain/GroupQuestions';
import { CommandPublisher } from '../../../../../shared/core/application/command/CommandBus';
import { AskGroupQuestion } from '../../../../asking-question/core/application/command/AskGroupQuestion';

export class TimeHasPassedEventHandler implements EventHandler<TimeHasPassed> {
constructor(private readonly groupQuestionsRepository: GroupQuestionsRepository, private readonly commandPublisher: CommandPublisher) {}

async handle(event: TimeHasPassed): Promise<void> {
const groupQuestions = await this.groupQuestionsRepository.findAll();
if (groupQuestions.length === 0) {
return;
}
const actualDate = event.occurredAt;
const actualDay = actualDate.getDay();
if (actualDay === 0 || actualDay === 6) {
return;
}
if (actualDay !== groupQuestions[0].questionAskedLastlyDate!.getDay()) {
getQuestionsToAsk(groupQuestions, this.commandPublisher);
}
}
}

function getQuestionsToAsk(groupsQuestions: GroupQuestions[], commandPublisher: CommandPublisher) {
groupsQuestions.forEach(async (groupQuestions) => {
const randomQuestion = groupQuestions.questionList[Math.floor(Math.random() * groupQuestions.questionList.length)];
await commandPublisher.execute(
new AskGroupQuestion({
questionId: randomQuestion.questionId,
groupId: randomQuestion.groupId,
authorId: randomQuestion.authorId,
text: randomQuestion.text,
}),
);
});
}
20 changes: 20 additions & 0 deletions backend/src/modules/questions/core/domain/GroupQuestions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Question } from './Question';

export class GroupQuestions {
readonly groupId: string;
readonly questionAskedLastly: Question | undefined;
readonly questionAskedLastlyDate: Date;
readonly questionList: Question[];

constructor(props: {
groupId: string;
questionAskedLastly: Question | undefined;
questionAskedLastlyDate: Date;
questionList: Question[];
}) {
this.groupId = props.groupId;
this.questionAskedLastly = props.questionAskedLastly;
this.questionAskedLastlyDate = props.questionAskedLastlyDate;
this.questionList = props.questionList;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { GroupQuestionsRepository } from '../../../core/application/GroupQuestionsRepository';
import { GroupQuestions } from '../../../core/domain/GroupQuestions';

export class InMemoryGroupQuestionsRepository implements GroupQuestionsRepository {
private readonly entities: { [groupId: string]: GroupQuestions } = {};

findByGroupId(groupId: string): Promise<GroupQuestions | undefined> {
return Promise.resolve(this.entities[groupId]);
}

async save(groupQuestions: GroupQuestions): Promise<void> {
this.entities[groupQuestions.groupId] = groupQuestions;
}

findAll(): Promise<GroupQuestions[]> {
return Promise.resolve(Object.keys(this.entities).map((groupId) => this.entities[groupId]));
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { InMemoryQuestionsRepository } from '../../../../../src/modules/questions/infrastructure/repository/inmemory/InMemoryQuestionsRepository';
import { TestModuleCore, testModuleCore } from '../../../../test-support/shared/core/TestModuleCore';
import { QuestionsModuleCore } from '../../../../../src/modules/questions/core/QuestionsModuleCore';
import { InMemoryGroupQuestionsRepository } from '../../../../../src/modules/questions/infrastructure/repository/inmemory/InMemoryGroupQuestionsRepository';

export function testQuestionsModule(currentTime: Date): TestModuleCore {
const questionsRepository = new InMemoryQuestionsRepository();
return testModuleCore((commandBus, eventBus, queryBus) => QuestionsModuleCore(eventBus, () => currentTime, questionsRepository));
const groupQuestionsRepository = new InMemoryGroupQuestionsRepository();
return testModuleCore((commandBus, eventBus, queryBus) =>
QuestionsModuleCore(eventBus, commandBus, () => currentTime, groupQuestionsRepository, questionsRepository),
);
}

0 comments on commit 51f12da

Please sign in to comment.