From 051a52eb7ab3547a6be7a1ca38defe75f2f00925 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Verdu=CC=81?= Date: Thu, 25 Mar 2021 12:31:14 +0000 Subject: [PATCH 1/3] create events, entity and read model --- asker-analytics/backend/src/entities/word.ts | 21 +++++++++ .../backend/src/events/question-created.ts | 15 ++++++ .../backend/src/events/word-picked.ts | 16 +++++++ .../conference-statistics-read-model.ts | 47 +++++++++++++++++++ 4 files changed, 99 insertions(+) create mode 100644 asker-analytics/backend/src/entities/word.ts create mode 100644 asker-analytics/backend/src/events/question-created.ts create mode 100644 asker-analytics/backend/src/events/word-picked.ts create mode 100644 asker-analytics/backend/src/read-models/conference-statistics-read-model.ts diff --git a/asker-analytics/backend/src/entities/word.ts b/asker-analytics/backend/src/entities/word.ts new file mode 100644 index 0000000..9f7682a --- /dev/null +++ b/asker-analytics/backend/src/entities/word.ts @@ -0,0 +1,21 @@ +import { Entity, Reduces } from '@boostercloud/framework-core' +import { UUID } from '@boostercloud/framework-types' +import { WordPicked } from '../events/word-picked' + +@Entity +export class Word { + public constructor( + public id: UUID, + readonly name: string, + readonly questionId: UUID, + readonly conferenceId: UUID, + readonly type: string, + ) {} + + @Reduces(WordPicked) + public static reduceWordPicked(event: WordPicked, currentWord?: Word): Word { + const type: string = 'TODO' + return new Word(event.id, event.name, event.questionId, event.conferenceId, type) + } + +} diff --git a/asker-analytics/backend/src/events/question-created.ts b/asker-analytics/backend/src/events/question-created.ts new file mode 100644 index 0000000..7313ef1 --- /dev/null +++ b/asker-analytics/backend/src/events/question-created.ts @@ -0,0 +1,15 @@ +import { Event } from '@boostercloud/framework-core' +import { UUID } from '@boostercloud/framework-types' + +@Event +export class QuestionCreated { + public constructor( + readonly text: string, + readonly id: UUID, + readonly conferenceId: UUID, + ) {} + + public entityID(): UUID { + return this.id + } +} diff --git a/asker-analytics/backend/src/events/word-picked.ts b/asker-analytics/backend/src/events/word-picked.ts new file mode 100644 index 0000000..d60b976 --- /dev/null +++ b/asker-analytics/backend/src/events/word-picked.ts @@ -0,0 +1,16 @@ +import { Event } from '@boostercloud/framework-core' +import { UUID } from '@boostercloud/framework-types' + +@Event +export class WordPicked { + public constructor( + readonly name: string, + readonly id: UUID, + readonly questionId: UUID, + readonly conferenceId: UUID, + ) {} + + public entityID(): UUID { + return this.id + } +} diff --git a/asker-analytics/backend/src/read-models/conference-statistics-read-model.ts b/asker-analytics/backend/src/read-models/conference-statistics-read-model.ts new file mode 100644 index 0000000..102cbd6 --- /dev/null +++ b/asker-analytics/backend/src/read-models/conference-statistics-read-model.ts @@ -0,0 +1,47 @@ +import { ReadModel, Projects } from '@boostercloud/framework-core' +import { UUID, ProjectionResult } from '@boostercloud/framework-types' +import { Word } from '../entities/word' + +@ReadModel({ + authorize: 'all' // Specify authorized roles here. Use 'all' to authorize anyone +}) +export class ConferenceStatisticsReadModel { + public constructor( + public id: UUID, + readonly verbs: number, + readonly noums: number, + readonly adjectives: number, + readonly interjections: number, + readonly pronouns: number, + readonly conjuctionPrepositions: number, + readonly spokenContractions: number, + ) {} + + @Projects(Word, "conferenceId") + public static projectWord(entity: Word, currentConferenceStatisticsReadModel?: ConferenceStatisticsReadModel): ProjectionResult { + if (!currentConferenceStatisticsReadModel) { + currentConferenceStatisticsReadModel = new ConferenceStatisticsReadModel(entity.conferenceId,0,0,0,0,0,0,0) + } + let verbs = currentConferenceStatisticsReadModel.verbs + let noums = currentConferenceStatisticsReadModel.noums + let adjectives = currentConferenceStatisticsReadModel.adjectives + let interjections = currentConferenceStatisticsReadModel.interjections + let pronouns = currentConferenceStatisticsReadModel.pronouns + let conjuctionPrepositions = currentConferenceStatisticsReadModel.conjuctionPrepositions + let spokenContractions = currentConferenceStatisticsReadModel.spokenContractions + if (entity.type === 'TODO') { + verbs += 1 + } + return new ConferenceStatisticsReadModel( + entity.conferenceId, + verbs, + noums, + adjectives, + interjections, + pronouns, + conjuctionPrepositions, + spokenContractions + ) + } + +} From b03020d6721f509aaeeeac611e870004b97ae7eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Verdu=CC=81?= Date: Thu, 25 Mar 2021 12:41:59 +0000 Subject: [PATCH 2/3] Add event handler to split questions into words --- .../src/event-handlers/split-questions-into-words.ts | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 asker-analytics/backend/src/event-handlers/split-questions-into-words.ts diff --git a/asker-analytics/backend/src/event-handlers/split-questions-into-words.ts b/asker-analytics/backend/src/event-handlers/split-questions-into-words.ts new file mode 100644 index 0000000..2686bc9 --- /dev/null +++ b/asker-analytics/backend/src/event-handlers/split-questions-into-words.ts @@ -0,0 +1,8 @@ +import { QuestionCreated } from '../events/question-created' +import { EventHandler } from '@boostercloud/framework-core' +import { Register } from '@boostercloud/framework-types' + +@EventHandler(QuestionCreated) +export class SplitQuestionsIntoWords { + public static async handle(event: QuestionCreated, register: Register): Promise {} +} From 5d1b25d94a9c9a01a06f9dd1b1d3bee64599fb20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Verdu=CC=81?= Date: Thu, 25 Mar 2021 13:05:55 +0000 Subject: [PATCH 3/3] command to debug. Split event handler --- .../backend/src/commands/post-question.ts | 17 +++++++++++++++++ .../split-questions-into-words.ts | 10 ++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 asker-analytics/backend/src/commands/post-question.ts diff --git a/asker-analytics/backend/src/commands/post-question.ts b/asker-analytics/backend/src/commands/post-question.ts new file mode 100644 index 0000000..185f5c4 --- /dev/null +++ b/asker-analytics/backend/src/commands/post-question.ts @@ -0,0 +1,17 @@ +import { Command } from '@boostercloud/framework-core' +import { Register, UUID } from '@boostercloud/framework-types' +import { QuestionCreated } from '../events/question-created'; + +@Command({ + authorize: 'all' // Specify authorized roles here. Use 'all' to authorize anyone +}) +export class PostQuestion { + public constructor( + readonly conferenceId: UUID, + readonly text: string, + ) {} + + public static async handle(command: PostQuestion , register: Register): Promise { + register.events(new QuestionCreated(command.text, UUID.generate(), command.conferenceId)) + } +} diff --git a/asker-analytics/backend/src/event-handlers/split-questions-into-words.ts b/asker-analytics/backend/src/event-handlers/split-questions-into-words.ts index 2686bc9..c290582 100644 --- a/asker-analytics/backend/src/event-handlers/split-questions-into-words.ts +++ b/asker-analytics/backend/src/event-handlers/split-questions-into-words.ts @@ -1,8 +1,14 @@ import { QuestionCreated } from '../events/question-created' +import { WordPicked } from '../events/word-picked' import { EventHandler } from '@boostercloud/framework-core' -import { Register } from '@boostercloud/framework-types' +import { Register, UUID } from '@boostercloud/framework-types' @EventHandler(QuestionCreated) export class SplitQuestionsIntoWords { - public static async handle(event: QuestionCreated, register: Register): Promise {} + public static async handle(event: QuestionCreated, register: Register): Promise { + const words = event.text.split(' ') + for (const word in words) { + register.events(new WordPicked(word, UUID.generate(), event.id, event.conferenceId)) + } + } }