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/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/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..c290582 --- /dev/null +++ b/asker-analytics/backend/src/event-handlers/split-questions-into-words.ts @@ -0,0 +1,14 @@ +import { QuestionCreated } from '../events/question-created' +import { WordPicked } from '../events/word-picked' +import { EventHandler } from '@boostercloud/framework-core' +import { Register, UUID } from '@boostercloud/framework-types' + +@EventHandler(QuestionCreated) +export class SplitQuestionsIntoWords { + 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)) + } + } +} 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 + ) + } + +}