Index: src/Clients/Angular/finki-chattery/src/app/core/services/auth.service.ts
===================================================================
--- src/Clients/Angular/finki-chattery/src/app/core/services/auth.service.ts	(revision 1e0d86905c02abe14201bf07ad5a2163900a5602)
+++ src/Clients/Angular/finki-chattery/src/app/core/services/auth.service.ts	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -24,4 +24,5 @@
   public user: ApplicationUser | null = null;
   public oidcUser: User | null = null;
+  public selfUser: SelfUserResponse | null = null;
 
   constructor(private baseApi: BaseApiService) {
@@ -35,4 +36,10 @@
         user?.profile.isVerified
       );
+
+      this.selfUserDto().subscribe((selfUser) => {
+        if (selfUser) {
+          this.selfUser = selfUser;
+        }
+      });
     });
   }
@@ -86,4 +93,12 @@
         user.profile.isVerified
       );
+
+      if (!this.selfUser) {
+        this.selfUserDto().subscribe((selfUser) => {
+          if (selfUser) {
+            this.selfUser = selfUser;
+          }
+        });
+      }
     });
   }
Index: src/Clients/Angular/finki-chattery/src/app/core/state/question-facade.service.ts
===================================================================
--- src/Clients/Angular/finki-chattery/src/app/core/state/question-facade.service.ts	(revision 1e0d86905c02abe14201bf07ad5a2163900a5602)
+++ src/Clients/Angular/finki-chattery/src/app/core/state/question-facade.service.ts	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -2,6 +2,6 @@
 import { Injectable } from '@angular/core';
 import { Action, Store } from '@ngrx/store';
-import { Observable, Subject, throwError } from 'rxjs';
-import { catchError, filter, map } from 'rxjs/operators';
+import { Observable, Subject } from 'rxjs';
+import { filter, map } from 'rxjs/operators';
 
 import {
@@ -9,6 +9,8 @@
   PreviewQuestionViewModel,
   QuestionStateViewModel,
-  SearchQuestionsQueryViewModel
+  SearchQuestionsQueryViewModel,
+  VoteType
 } from 'src/app/shared-app/models';
+import { AuthService } from '../services';
 import {
   EffectStartedWorking,
@@ -16,5 +18,7 @@
   GetPreviewQuestionsPopular,
   GetQuestionState,
-  GetSearchQuestions
+  GetSearchQuestions,
+  SetCorrectAnswer,
+  VoteAnswer
 } from './question-state/question.actions';
 import { questionStateQuery } from './question-state/question.selectors';
@@ -29,18 +33,10 @@
   effectWorking$: Observable<boolean | HttpErrorResponse>;
 
-  constructor(private store: Store<QuestionState>) {
-    this.effectWorking$ = this.store.select(questionStateQuery.effectWorking).pipe(
-      filter((effect) => effect !== null),
-      map((effect) => {
-        if (effect instanceof HttpErrorResponse) {
-          throw effect;
-        } else {
-          return effect;
-        }
-      }),
-      catchError((err) => {
-        return throwError(err);
-      })
-    );
+  constructor(private store: Store<QuestionState>, private auth: AuthService) {
+    this.effectWorking$ = this.store.select(questionStateQuery.effectWorking).pipe(filter((effect) => effect !== null));
+  }
+
+  public currentQuestionOwnedByCurrentUser(): Observable<boolean> {
+    return this.getQuestion().pipe(map((question) => this.auth.selfUser?.student?.uid === question.student.uid));
   }
 
@@ -81,4 +77,12 @@
   }
 
+  public setCorrectAnswer(questionUid: string, answerUid: string): void {
+    this.dispatchEffect(new SetCorrectAnswer(questionUid, answerUid));
+  }
+
+  public voteAnswer(answerUid: string, questionUid: string, voteType: VoteType): void {
+    this.dispatchEffect(new VoteAnswer(questionUid, answerUid, voteType));
+  }
+
   public fetchQuestion(questionUid: string): void {
     this.dispatchEffect(new GetQuestionState(questionUid));
Index: src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question-state-request.models.ts
===================================================================
--- src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question-state-request.models.ts	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question-state-request.models.ts	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,5 @@
+import { VoteType } from 'src/app/shared-app/models';
+
+export class VoteAnswerRequest {
+  constructor(public voteType: VoteType) {}
+}
Index: src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question-state-response.models.ts
===================================================================
--- src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question-state-response.models.ts	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question-state-response.models.ts	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,82 @@
+import { VoteType } from 'src/app/shared-app/models';
+
+export class QuestionStateResponse {
+  public uid!: string;
+  public title!: string;
+  public text!: string;
+  public createdOn!: moment.Moment;
+  public views!: number;
+  public lastActiveOn!: moment.Moment;
+  public studentResponse!: StudentQuestionStateResponse;
+  public answersResponse!: AnswerQuestionStateResponse[];
+  public categoriesResponse!: QuestionCategoryQuestionStateResponse[];
+  public teamResponse!: TeamQuestionStateResponse | null;
+}
+
+export class StudentQuestionStateResponse {
+  public uid!: string;
+  public index!: string;
+  public imageUrl!: string;
+  public reputation!: number;
+}
+
+export class TeamQuestionStateResponse {
+  public uid!: string;
+  public name!: string;
+}
+
+export class QuestionCategoryQuestionStateResponse {
+  public uid!: string;
+  public name!: string;
+}
+
+export class AnswerQuestionStateResponse {
+  public uid!: string;
+  public text!: string;
+  public correctAnswer!: boolean;
+  public createdOn!: moment.Moment;
+  public votesCount!: number;
+  public studentResponse!: AnswerStudentQuestionStateResponse;
+  public answerResponsesResponse!: AnswerResponseQuestionStateResponse[];
+}
+
+export class AnswerStudentQuestionStateResponse {
+  public uid!: string;
+  public index!: string;
+  public imageUrl!: string;
+  public reputation!: number;
+}
+
+export class AnswerResponseQuestionStateResponse {
+  public uid!: string;
+  public text!: string;
+  public createdOn!: moment.Moment;
+  public studentResponse!: AnswerResponseStudentQuestionStateResponse;
+}
+
+export class AnswerResponseStudentQuestionStateResponse {
+  public uid!: string;
+  public index!: string;
+  public imageUrl!: string;
+  public reputation!: number;
+}
+
+export class PreviewQuestionResponse {
+  public uid!: string;
+  public title!: string;
+  public createdOn!: moment.Moment;
+  public views!: number;
+  public answersCount!: number;
+  public categories!: PreviewQuestionCategoryResponse[];
+}
+
+export class PreviewQuestionCategoryResponse {
+  public uid!: string;
+  public text!: string;
+}
+
+export class VoteAnswerResponse {
+  public answerUid!: string;
+  public voteUid!: string;
+  public voteType!: VoteType;
+}
Index: c/Clients/Angular/finki-chattery/src/app/core/state/question-state/question-state.models.ts
===================================================================
--- src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question-state.models.ts	(revision 1e0d86905c02abe14201bf07ad5a2163900a5602)
+++ 	(revision )
@@ -1,74 +1,0 @@
-export class QuestionStateResponse {
-  public uid!: string;
-  public title!: string;
-  public text!: string;
-  public createdOn!: moment.Moment;
-  public views!: number;
-  public lastActiveOn!: moment.Moment;
-  public studentResponse!: StudentQuestionStateResponse;
-  public answersResponse!: AnswerQuestionStateResponse[];
-  public categoriesResponse!: QuestionCategoryQuestionStateResponse[];
-  public teamResponse!: TeamQuestionStateResponse | null;
-}
-
-export class StudentQuestionStateResponse {
-  public uid!: string;
-  public index!: string;
-  public imageUrl!: string;
-  public reputation!: number;
-}
-
-export class TeamQuestionStateResponse {
-  public uid!: string;
-  public name!: string;
-}
-
-export class QuestionCategoryQuestionStateResponse {
-  public uid!: string;
-  public name!: string;
-}
-
-export class AnswerQuestionStateResponse {
-  public uid!: string;
-  public text!: string;
-  public correctAnswer!: boolean;
-  public createdOn!: moment.Moment;
-  public upvotesCount!: number;
-  public studentResponse!: AnswerStudentQuestionStateResponse;
-  public answerResponsesResponse!: AnswerResponseQuestionStateResponse[];
-}
-
-export class AnswerStudentQuestionStateResponse {
-  public uid!: string;
-  public index!: string;
-  public imageUrl!: string;
-  public reputation!: number;
-}
-
-export class AnswerResponseQuestionStateResponse {
-  public uid!: string;
-  public text!: string;
-  public createdOn!: moment.Moment;
-  public studentResponse!: AnswerResponseStudentQuestionStateResponse;
-}
-
-export class AnswerResponseStudentQuestionStateResponse {
-  public uid!: string;
-  public index!: string;
-  public imageUrl!: string;
-  public reputation!: number;
-}
-
-export class PreviewQuestionResponse {
-  public uid!: string;
-  public title!: string;
-  public createdOn!: moment.Moment;
-  public views!: number;
-  public answersCount!: number;
-  public categories!: PreviewQuestionCategoryResponse[];
-}
-
-export class PreviewQuestionCategoryResponse {
-  public uid!: string;
-  public text!: string;
-}
Index: src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.actions.ts
===================================================================
--- src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.actions.ts	(revision 1e0d86905c02abe14201bf07ad5a2163900a5602)
+++ src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.actions.ts	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -2,9 +2,17 @@
 import { Action } from '@ngrx/store';
 
-import { PreviewQuestionViewModel, QuestionStateViewModel, SearchQuestionsQueryViewModel } from 'src/app/shared-app/models';
+import {
+  PreviewQuestionViewModel,
+  QuestionStateViewModel,
+  SearchQuestionsQueryViewModel,
+  VoteAnswerViewModel,
+  VoteType
+} from 'src/app/shared-app/models';
 
 export enum QuestionActionTypes {
   GetQuestionState = '[Question] Get state',
   GetQuestionStateSuccess = '[Question] Get state success',
+  SetCorrectAnswer = '[Question] Set Correct Answer',
+  SetCorrectAnswerSuccess = '[Question] Set Correct Answer success',
   GetPreviewQuestionsLatest = '[Question] Get preview questions Latest',
   GetPreviewQuestionsLatestSuccess = '[Question] Get preview questions Latest Success',
@@ -13,4 +21,6 @@
   GetSearchQuestions = '[Question] Get search questions',
   GetSearchQuestionsSuccess = '[Question] Get search questions Success',
+  VoteAnswer = '[Question] Vote answer',
+  VoteAnswerSuccess = '[Question] Vote answer Success',
   EffectStartedWorking = '[Question] Effect Started Working',
   EffectFinishedWorking = '[Question] Effect Finished Working',
@@ -28,4 +38,16 @@
 
   constructor(public payload: QuestionStateViewModel) {}
+}
+
+export class SetCorrectAnswer implements Action {
+  readonly type = QuestionActionTypes.SetCorrectAnswer;
+
+  constructor(public questionUid: string, public answerUid: string) {}
+}
+
+export class SetCorrectAnswerSuccess implements Action {
+  readonly type = QuestionActionTypes.SetCorrectAnswerSuccess;
+
+  constructor(public payload: string) {}
 }
 
@@ -66,4 +88,16 @@
 }
 
+export class VoteAnswer implements Action {
+  readonly type = QuestionActionTypes.VoteAnswer;
+
+  constructor(public questionUid: string, public answerUid: string, public voteType: VoteType) {}
+}
+
+export class VoteAnswerSuccess implements Action {
+  readonly type = QuestionActionTypes.VoteAnswerSuccess;
+
+  constructor(public payload: VoteAnswerViewModel) {}
+}
+
 export class EffectStartedWorking implements Action {
   readonly type = QuestionActionTypes.EffectStartedWorking;
@@ -89,4 +123,6 @@
   | GetPreviewQuestionsPopularSuccess
   | GetSearchQuestionsSuccess
+  | VoteAnswerSuccess
+  | SetCorrectAnswerSuccess
   | EffectStartedWorking
   | EffectFinishedWorking
Index: src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.effects.ts
===================================================================
--- src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.effects.ts	(revision 1e0d86905c02abe14201bf07ad5a2163900a5602)
+++ src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.effects.ts	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -1,11 +1,13 @@
 import { Injectable } from '@angular/core';
 import { act, Actions, createEffect, ofType } from '@ngrx/effects';
-import { catchError, filter, mergeMap, switchMap, withLatestFrom } from 'rxjs/operators';
+import { catchError, filter, mergeMap, switchMap, tap, withLatestFrom } from 'rxjs/operators';
 import { PreviewQuestionsOrderEnum, SearchQuestionsQueryViewModel } from 'src/app/shared-app/models';
 import { TranslateFromJsonService } from 'src/app/shared-app/services';
 
 import { BaseApiService } from 'src/app/shared-app/services/base-api.service';
+import { NotificationService } from '../../services/notification.service';
 import { QuestionFacadeService } from '../question-facade.service';
-import { PreviewQuestionResponse, QuestionStateResponse } from './question-state.models';
+import { VoteAnswerRequest } from './question-state-request.models';
+import { PreviewQuestionResponse, QuestionStateResponse, VoteAnswerResponse } from './question-state-response.models';
 import {
   EffectFinishedWorking,
@@ -19,5 +21,9 @@
   GetSearchQuestions,
   GetSearchQuestionsSuccess,
-  QuestionActionTypes
+  QuestionActionTypes,
+  SetCorrectAnswer,
+  SetCorrectAnswerSuccess,
+  VoteAnswer,
+  VoteAnswerSuccess
 } from './question.actions';
 import { QuestionMapper } from './question.mapper';
@@ -31,5 +37,6 @@
     private api: BaseApiService,
     private translate: TranslateFromJsonService,
-    private facade: QuestionFacadeService
+    private facade: QuestionFacadeService,
+    private notification: NotificationService
   ) {}
 
@@ -103,3 +110,30 @@
     );
   });
+
+  voteAnswer$ = createEffect(() => {
+    return this.actions$.pipe(
+      ofType<VoteAnswer>(QuestionActionTypes.VoteAnswer),
+      mergeMap((action) => {
+        const body = new VoteAnswerRequest(action.voteType);
+        return this.api.post<VoteAnswerResponse>(`v1/questions/${action.questionUid}/answers/${action.answerUid}/votes`, body).pipe(
+          tap((state) => this.notification.successNotification('sucess-vote')),
+          switchMap((state) => [new VoteAnswerSuccess(QuestionMapper.ToVoteAnswerViewModel(state)), new EffectFinishedWorking()]),
+          catchError((err) => [new EffectFinishedWorkingError(err)])
+        );
+      })
+    );
+  });
+
+  setCorrectAnswer$ = createEffect(() => {
+    return this.actions$.pipe(
+      ofType<SetCorrectAnswer>(QuestionActionTypes.SetCorrectAnswer),
+      mergeMap((action) => {
+        return this.api.put<string>(`v1/questions/${action.questionUid}/answers/${action.answerUid}/correct`).pipe(
+          tap((state) => this.notification.successNotification('success-correct-answer')),
+          switchMap((state) => [new SetCorrectAnswerSuccess(state), new EffectFinishedWorking()]),
+          catchError((err) => [new EffectFinishedWorkingError(err)])
+        );
+      })
+    );
+  });
 }
Index: src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.mapper.ts
===================================================================
--- src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.mapper.ts	(revision 1e0d86905c02abe14201bf07ad5a2163900a5602)
+++ src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.mapper.ts	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -10,8 +10,9 @@
   QuestionStateViewModel,
   StudentQuestionStateViewModel,
-  TeamQuestionStateViewModel
+  TeamQuestionStateViewModel,
+  VoteAnswerViewModel
 } from 'src/app/shared-app/models';
 import { TranslateFromJsonService } from 'src/app/shared-app/services';
-import { PreviewQuestionResponse, QuestionStateResponse } from './question-state.models';
+import { PreviewQuestionResponse, QuestionStateResponse, VoteAnswerResponse } from './question-state-response.models';
 
 export class QuestionMapper {
@@ -51,5 +52,5 @@
           x.correctAnswer,
           moment(x.createdOn),
-          x.upvotesCount,
+          x.votesCount,
           answerStudent,
           answerResponses
@@ -113,3 +114,7 @@
     return questions;
   }
+
+  public static ToVoteAnswerViewModel(response: VoteAnswerResponse): VoteAnswerViewModel {
+    return new VoteAnswerViewModel(response.answerUid, response.voteUid, response.voteType);
+  }
 }
Index: src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.reducers.ts
===================================================================
--- src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.reducers.ts	(revision 1e0d86905c02abe14201bf07ad5a2163900a5602)
+++ src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.reducers.ts	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -1,2 +1,3 @@
+import { AnswerQuestionStateViewModel, VoteType } from 'src/app/shared-app/models';
 import { QuestionAction, QuestionActionTypes } from './question.actions';
 import { initialState, QuestionState } from './question.state';
@@ -25,4 +26,68 @@
         searchQuestionsQuery: action.query
       };
+    case QuestionActionTypes.VoteAnswerSuccess: {
+      if (state.question) {
+        return {
+          ...state,
+          question: {
+            ...state.question,
+            answers: state.question.answers.map((x) => {
+              if (x.uid === action.payload.answerUid) {
+                let votesCountNew = x.votesCount;
+
+                switch (action.payload.voteType) {
+                  case VoteType.Upvote:
+                    votesCountNew++;
+                    break;
+                  case VoteType.Downvote:
+                    votesCountNew--;
+                    break;
+                }
+
+                return {
+                  ...x,
+                  votesCount: votesCountNew
+                };
+              }
+
+              return x;
+            })
+          }
+        };
+      }
+
+      return {
+        ...state
+      };
+    }
+    case QuestionActionTypes.SetCorrectAnswerSuccess: {
+      if (state.question) {
+        return {
+          ...state,
+          question: {
+            ...state.question,
+            answers: state.question.answers.map((x) => {
+              if (x.correctAnswer) {
+                return {
+                  ...x,
+                  correctAnswer: false
+                };
+              }
+              if (x.uid === action.payload) {
+                return {
+                  ...x,
+                  correctAnswer: true
+                };
+              }
+              return x;
+            })
+          }
+        };
+      }
+
+      return {
+        ...state
+      };
+    }
     case QuestionActionTypes.EffectStartedWorking: {
       return {
Index: src/Clients/Angular/finki-chattery/src/app/shared-app/components/generic/vote/vote.component.html
===================================================================
--- src/Clients/Angular/finki-chattery/src/app/shared-app/components/generic/vote/vote.component.html	(revision 1e0d86905c02abe14201bf07ad5a2163900a5602)
+++ src/Clients/Angular/finki-chattery/src/app/shared-app/components/generic/vote/vote.component.html	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -1,3 +1,3 @@
-<div>
+<div class="main-div">
   <div class="vote-icons" fxLayout="column" fxLayoutAlign="center center">
     <mat-icon class="vote-icon" (click)="voted(VoteType.Upvote)" [inline]="true">arrow_drop_up</mat-icon>
@@ -7,4 +7,11 @@
       >check</mat-icon
     >
+    <mat-icon
+      *ngIf="canSetCorrectAnswer && !correct"
+      [inline]="true"
+      class="text-center text-bold green set-correct-answer"
+      (click)="setCorrectAnswer.emit()"
+      >check</mat-icon
+    >
   </div>
 </div>
Index: src/Clients/Angular/finki-chattery/src/app/shared-app/components/generic/vote/vote.component.scss
===================================================================
--- src/Clients/Angular/finki-chattery/src/app/shared-app/components/generic/vote/vote.component.scss	(revision 1e0d86905c02abe14201bf07ad5a2163900a5602)
+++ src/Clients/Angular/finki-chattery/src/app/shared-app/components/generic/vote/vote.component.scss	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -14,2 +14,19 @@
   cursor: pointer;
 }
+
+.show-on-hover {
+  display: none;
+}
+
+.set-correct-answer {
+  opacity: 0.3;
+  visibility: hidden;
+}
+
+.main-div:hover > .vote-icons > .set-correct-answer {
+  visibility: visible;
+}
+
+.main-div {
+  height: 100%;
+}
Index: src/Clients/Angular/finki-chattery/src/app/shared-app/components/generic/vote/vote.component.ts
===================================================================
--- src/Clients/Angular/finki-chattery/src/app/shared-app/components/generic/vote/vote.component.ts	(revision 1e0d86905c02abe14201bf07ad5a2163900a5602)
+++ src/Clients/Angular/finki-chattery/src/app/shared-app/components/generic/vote/vote.component.ts	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -1,9 +1,5 @@
 import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
+import { VoteType } from 'src/app/shared-app/models';
 import { ButtonType } from '../button/button.models';
-
-export enum VoteType {
-  Upvote,
-  Downvote
-}
 
 @Component({
@@ -14,6 +10,8 @@
 export class VoteComponent implements OnInit {
   @Input() voteCount: number | undefined;
+  @Input() canSetCorrectAnswer: boolean | null = false;
   @Input() correct = false;
   @Output() voteClicked = new EventEmitter<VoteType>();
+  @Output() setCorrectAnswer = new EventEmitter<void>();
 
   VoteType = VoteType;
Index: src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/question-preview/question-preview.component.html
===================================================================
--- src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/question-preview/question-preview.component.html	(revision 1e0d86905c02abe14201bf07ad5a2163900a5602)
+++ src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/question-preview/question-preview.component.html	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -14,5 +14,12 @@
       <mat-card-content>
         <div fxLayout="row wrap" fxLayoutAlign="space-around none">
-          <app-vote [voteCount]="answer.upvotesCount" [correct]="answer.correctAnswer" fxFlex="6%"></app-vote>
+          <app-vote
+            [canSetCorrectAnswer]="canSetCorrectAnswer | async"
+            [voteCount]="answer.votesCount"
+            [correct]="answer.correctAnswer"
+            (voteClicked)="answerVoted($event, answer.uid, question.uid)"
+            (setCorrectAnswer)="setCorrectAnswer(question.uid, answer.uid)"
+            fxFlex="6%"
+          ></app-vote>
           <div fxFlex="92%">
             <app-text-editor
Index: src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/question-preview/question-preview.component.ts
===================================================================
--- src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/question-preview/question-preview.component.ts	(revision 1e0d86905c02abe14201bf07ad5a2163900a5602)
+++ src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/question-preview/question-preview.component.ts	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -1,6 +1,8 @@
+import { HttpErrorResponse } from '@angular/common/http';
 import { Component, OnInit } from '@angular/core';
+import { NotificationService } from 'src/app/core/services/notification.service';
 import { QuestionFacadeService } from 'src/app/core/state/question-facade.service';
 
-import { QuestionStateViewModel } from 'src/app/shared-app/models';
+import { QuestionStateViewModel, VoteType } from 'src/app/shared-app/models';
 import { ButtonType } from '../../generic/button/button.models';
 
@@ -11,8 +13,9 @@
 })
 export class QuestionPreviewComponent implements OnInit {
+  canSetCorrectAnswer = this.questionFacade.currentQuestionOwnedByCurrentUser();
   question!: QuestionStateViewModel;
   working = true;
   ButtonType = ButtonType;
-  constructor(private questionFacade: QuestionFacadeService) {}
+  constructor(private questionFacade: QuestionFacadeService, private notification: NotificationService) {}
 
   ngOnInit(): void {
@@ -21,4 +24,18 @@
       this.working = false;
     });
+
+    this.questionFacade.effectWorking$.subscribe((effect) => {
+      if (effect instanceof HttpErrorResponse) {
+        this.notification.handleErrorsNotification(effect.error);
+      }
+    });
+  }
+
+  answerVoted(voteType: VoteType, answerUid: string, questionUid: string): void {
+    this.questionFacade.voteAnswer(answerUid, questionUid, voteType);
+  }
+
+  setCorrectAnswer(questionUid: string, answerUid: string): void {
+    this.questionFacade.setCorrectAnswer(questionUid, answerUid);
   }
 }
Index: src/Clients/Angular/finki-chattery/src/app/shared-app/models/question-state-enums.models.ts
===================================================================
--- src/Clients/Angular/finki-chattery/src/app/shared-app/models/question-state-enums.models.ts	(revision 1e0d86905c02abe14201bf07ad5a2163900a5602)
+++ src/Clients/Angular/finki-chattery/src/app/shared-app/models/question-state-enums.models.ts	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -3,2 +3,7 @@
   Popular
 }
+
+export enum VoteType {
+  Upvote,
+  Downvote
+}
Index: src/Clients/Angular/finki-chattery/src/app/shared-app/models/question-state-view-models.models.ts
===================================================================
--- src/Clients/Angular/finki-chattery/src/app/shared-app/models/question-state-view-models.models.ts	(revision 1e0d86905c02abe14201bf07ad5a2163900a5602)
+++ src/Clients/Angular/finki-chattery/src/app/shared-app/models/question-state-view-models.models.ts	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -1,2 +1,4 @@
+import { VoteType } from '.';
+
 export class QuestionStateViewModel {
   constructor(
@@ -32,5 +34,5 @@
     public correctAnswer: boolean,
     public createdOn: moment.Moment,
-    public upvotesCount: number,
+    public votesCount: number,
     public student: AnswerStudentQuestionStateViewModel,
     public answerResponses: AnswerResponseQuestionStateViewModel[]
@@ -73,2 +75,6 @@
   constructor(public text: string) {}
 }
+
+export class VoteAnswerViewModel {
+  constructor(public answerUid: string, public voteUid: string, public voteType: VoteType) {}
+}
Index: src/Clients/Angular/finki-chattery/src/app/shared-app/models/user.models.ts
===================================================================
--- src/Clients/Angular/finki-chattery/src/app/shared-app/models/user.models.ts	(revision 1e0d86905c02abe14201bf07ad5a2163900a5602)
+++ src/Clients/Angular/finki-chattery/src/app/shared-app/models/user.models.ts	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -9,8 +9,4 @@
 }
 
-export class SelfUserResponse {
-  uid!: string;
-}
-
 export enum ApplicationUserType {
   Student = 'Student',
@@ -19,2 +15,44 @@
   Guest = 'Guest'
 }
+
+export class SelfUserResponse {
+  public student?: StudentSelfResponse | null;
+  public teacher?: TeacherSelfResponse | null;
+  public moderator?: ModeratorSelfResponse | null;
+}
+
+export class StudentSelfResponse {
+  public uid!: string;
+  public applicationUserId!: number;
+  public index!: string;
+  public reputation!: number;
+  public imageUrl!: string;
+  public questions!: StudentQuestionResponse[];
+  public teams!: StudentTeamResponse[];
+}
+
+export class StudentQuestionResponse {
+  public questionUid!: string;
+  public title!: string;
+}
+
+export class StudentTeamResponse {
+  public teamUid!: string;
+  public name!: string;
+}
+
+export class ModeratorSelfResponse {
+  public uid!: string;
+  public applicationUserId!: number;
+}
+
+export class TeacherSelfResponse {
+  public uid!: string;
+  public applicationUserId!: number;
+  public teams!: TeacherTeamResponse[];
+}
+
+export class TeacherTeamResponse {
+  public teamUid!: string;
+  public name!: string;
+}
Index: src/Clients/Angular/finki-chattery/src/app/shared-app/services/base-api.service.ts
===================================================================
--- src/Clients/Angular/finki-chattery/src/app/shared-app/services/base-api.service.ts	(revision 1e0d86905c02abe14201bf07ad5a2163900a5602)
+++ src/Clients/Angular/finki-chattery/src/app/shared-app/services/base-api.service.ts	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -19,5 +19,5 @@
 
   public getSelfUser(): Observable<SelfUserResponse> {
-    return this.get<SelfUserResponse>('self');
+    return this.get<SelfUserResponse>('v1/self');
   }
 
Index: src/Clients/Angular/finki-chattery/src/assets/translations/en.json
===================================================================
--- src/Clients/Angular/finki-chattery/src/assets/translations/en.json	(revision 1e0d86905c02abe14201bf07ad5a2163900a5602)
+++ src/Clients/Angular/finki-chattery/src/assets/translations/en.json	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -53,4 +53,9 @@
   "ask-question-stepper-ask": "Ask question",
   "ask-question-ask-button-back": "Edit question",
-  "ask-question-ask-button": "Ask question"
+  "sucess-vote": "Successfully voted answer",
+  "success-correct-answer": "Successfully set correct answer",
+  "ask-question-ask-button": "Ask question",
+  "AnswerAlreadyUpvoted": "You have already upvoted this answer",
+  "AnswerAlreadyDownvoted": "You have already downvoted this answer",
+  "StudentHasBadReputation": "You have bad reputation and can not vote"
 }
Index: src/FinkiChattery/FinkiChattery.Api/ApplicationServices/Questioning/EventHandlers/RemoveOtherCorrectAnswersAppartFromTheNewOneAndUpdateStudentReputationsEventHandler.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Api/ApplicationServices/Questioning/EventHandlers/RemoveOtherCorrectAnswersAppartFromTheNewOneAndUpdateStudentReputationsEventHandler.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Api/ApplicationServices/Questioning/EventHandlers/RemoveOtherCorrectAnswersAppartFromTheNewOneAndUpdateStudentReputationsEventHandler.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,43 @@
+﻿using FinkiChattery.Commands.Questioning;
+using FinkiChattery.Common.Mediator.Contracs;
+using FinkiChattery.Persistence.UnitOfWork;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace FinkiChattery.Api.ApplicationServices.Questioning.EventHandlers
+{
+    public class RemoveOtherCorrectAnswersAppartFromTheNewOneAndUpdateStudentReputationsEventHandler : IEventHandler<AnswerMarkedAsCorrectEvent>
+    {
+        public RemoveOtherCorrectAnswersAppartFromTheNewOneAndUpdateStudentReputationsEventHandler(IUnitOfWork unitOfWork)
+        {
+            UnitOfWork = unitOfWork;
+        }
+
+        public IUnitOfWork UnitOfWork { get; }
+
+        public async Task Handle(AnswerMarkedAsCorrectEvent notification, CancellationToken cancellationToken)
+        {
+            var questionWithAnswers = await UnitOfWork.Questions.GetQuestionWithAnswersAndStudents(notification.QuestionUid);
+
+            if (questionWithAnswers == null)
+            {
+                return;
+            }
+
+            foreach (var answer in questionWithAnswers.Answers)
+            {
+                if (answer.CorrectAnswer && answer.Uid != notification.AnswerUid)
+                {
+                    answer.CorrectAnswer = false;
+                    answer.Student.Reputation = answer.Student.Reputation - 5;
+                }
+                if (answer.Uid == notification.AnswerUid)
+                {
+                    answer.Student.Reputation = answer.Student.Reputation + 5;
+                }
+            }
+
+            await UnitOfWork.SaveAsync();
+        }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Api/ApplicationServices/Questioning/EventHandlers/UpdateAnswerVotesEventHandler.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Api/ApplicationServices/Questioning/EventHandlers/UpdateAnswerVotesEventHandler.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Api/ApplicationServices/Questioning/EventHandlers/UpdateAnswerVotesEventHandler.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,41 @@
+﻿using FinkiChattery.Commands.Questioning;
+using FinkiChattery.Common.Mediator.Contracs;
+using FinkiChattery.Persistence.Helpers;
+using FinkiChattery.Persistence.UnitOfWork;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace FinkiChattery.Api.ApplicationServices.Questioning.EventHandlers
+{
+    public class UpdateAnswerVotesEventHandler : IEventHandler<AnswerVotedEvent>
+    {
+        public UpdateAnswerVotesEventHandler(IUnitOfWork unitOfWork)
+        {
+            UnitOfWork = unitOfWork;
+        }
+
+        public IUnitOfWork UnitOfWork { get; }
+
+        public async Task Handle(AnswerVotedEvent notification, CancellationToken cancellationToken)
+        {
+            var answer = await UnitOfWork.Answers.GetByUidAsync(notification.AnswerUid);
+
+            if (answer == null)
+            {
+                return;
+            }
+
+            switch (notification.VoteType)
+            {
+                case VoteType.Upvote:
+                    answer.VotesCount++;
+                    break;
+                case VoteType.Downvote:
+                    answer.VotesCount--;
+                    break;
+            }
+
+            await UnitOfWork.SaveAsync();
+        }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Api/ApplicationServices/Questioning/EventHandlers/UpdateQuestionAnswersCountAndLastActivityEventHandler.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Api/ApplicationServices/Questioning/EventHandlers/UpdateQuestionAnswersCountAndLastActivityEventHandler.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Api/ApplicationServices/Questioning/EventHandlers/UpdateQuestionAnswersCountAndLastActivityEventHandler.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,34 @@
+﻿using FinkiChattery.Commands.Questioning;
+using FinkiChattery.Common.Mediator.Contracs;
+using FinkiChattery.Persistence.UnitOfWork;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace FinkiChattery.Api.ApplicationServices.Questioning.EventHandlers
+{
+    public class UpdateQuestionAnswersCountAndLastActivityEventHandler : IEventHandler<QuestionAnsweredEvent>
+    {
+        public UpdateQuestionAnswersCountAndLastActivityEventHandler(IUnitOfWork unitOfWork)
+        {
+            UnitOfWork = unitOfWork;
+        }
+
+        public IUnitOfWork UnitOfWork { get; }
+
+        public async Task Handle(QuestionAnsweredEvent notification, CancellationToken cancellationToken)
+        {
+            var question = await UnitOfWork.Questions.GetByUidAsync(notification.QuestionUid);
+
+            if (question == null)
+            {
+                return;
+            }
+
+            question.AnswersCount++;
+            question.LastActiveOn = DateTime.UtcNow;
+
+            await UnitOfWork.SaveAsync();
+        }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Api/ApplicationServices/Questioning/EventHandlers/UpdateStudentReputationEventHandler.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Api/ApplicationServices/Questioning/EventHandlers/UpdateStudentReputationEventHandler.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Api/ApplicationServices/Questioning/EventHandlers/UpdateStudentReputationEventHandler.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,41 @@
+﻿using FinkiChattery.Commands.Questioning;
+using FinkiChattery.Common.Mediator.Contracs;
+using FinkiChattery.Persistence.Helpers;
+using FinkiChattery.Persistence.UnitOfWork;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace FinkiChattery.Api.ApplicationServices.Questioning.EventHandlers
+{
+    public class UpdateStudentReputationEventHandler : IEventHandler<AnswerVotedEvent>
+    {
+        public UpdateStudentReputationEventHandler(IUnitOfWork unitOfWork)
+        {
+            UnitOfWork = unitOfWork;
+        }
+
+        public IUnitOfWork UnitOfWork { get; }
+
+        public async Task Handle(AnswerVotedEvent notification, CancellationToken cancellationToken)
+        {
+            var student = await UnitOfWork.Students.GetByUidAsync(notification.StudentUid);
+
+            if (student == null)
+            {
+                return;
+            }
+
+            switch (notification.VoteType)
+            {
+                case VoteType.Upvote:
+                    student.Reputation++;
+                    break;
+                case VoteType.Downvote:
+                    student.Reputation--;
+                    break;
+            }
+
+            await UnitOfWork.SaveAsync();
+        }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Api/ApplicationServices/Questioning/Mapper/QuestionMapper.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Api/ApplicationServices/Questioning/Mapper/QuestionMapper.cs	(revision 1e0d86905c02abe14201bf07ad5a2163900a5602)
+++ src/FinkiChattery/FinkiChattery.Api/ApplicationServices/Questioning/Mapper/QuestionMapper.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -54,5 +54,5 @@
                     var answerStudent = new AnswerStudentQuestionStateResponse(x.StudentDto.Id, x.StudentDto.Uid, x.StudentDto.Index, x.StudentDto.ImageUrl, x.StudentDto.Reputation);
 
-                    return new AnswerQuestionStateResponse(x.Id, x.Uid, x.Text, x.CorrectAnswer, x.CreatedOn, x.UpvotesCount, answerStudent, answerResponses);
+                    return new AnswerQuestionStateResponse(x.Id, x.Uid, x.Text, x.CorrectAnswer, x.CreatedOn, x.VotesCount, answerStudent, answerResponses);
                 });
             }
Index: src/FinkiChattery/FinkiChattery.Api/ApplicationServices/User/Mapper/SelfUserMapper.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Api/ApplicationServices/User/Mapper/SelfUserMapper.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Api/ApplicationServices/User/Mapper/SelfUserMapper.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,41 @@
+﻿using FinkiChattery.Contracts.User;
+using FinkiChattery.Queries.User;
+using System.Linq;
+
+namespace FinkiChattery.Api.ApplicationServices.User
+{
+    public static class SelfUserMapper
+    {
+        public static SelfUserResponse ToSelfUserResponse(this SelfUserDto dto)
+        {
+            if (dto.StudentSelf != null)
+            {
+                var student = new StudentSelfResponse(dto.StudentSelf.Uid,
+                                                      dto.StudentSelf.ApplicationUserId,
+                                                      dto.StudentSelf.Index,
+                                                      dto.StudentSelf.Reputation,
+                                                      dto.StudentSelf.ImageUrl,
+                                                      dto.StudentSelf.Questions.Select(x => new StudentQuestionResponse(x.QuestionUid, x.Title)),
+                                                      dto.StudentSelf.Teams.Select(x => new StudentTeamResponse(x.TeamUid, x.Name)));
+
+                return new SelfUserResponse(student);
+            }
+
+            if (dto.TeacherSelf != null)
+            {
+                var teacher = new TeacherSelfResponse(dto.TeacherSelf.Uid, dto.TeacherSelf.ApplicationUserId, dto.TeacherSelf.Teams.Select(x => new TeacherTeamResponse(x.TeamUid, x.Name)));
+
+                return new SelfUserResponse(null, teacher);
+            }
+
+            if (dto.ModeratorSelf != null)
+            {
+                var moderator = new ModeratorSelfResponse(dto.ModeratorSelf.Uid, dto.ModeratorSelf.ApplicationUserId);
+
+                return new SelfUserResponse(null, null, moderator);
+            }
+
+            return new SelfUserResponse();
+        }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Api/Controllers/v1/AnswersController.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Api/Controllers/v1/AnswersController.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Api/Controllers/v1/AnswersController.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,41 @@
+﻿using FinkiChattery.Api.ApplicationServices.Authentication;
+using FinkiChattery.Commands.Questioning;
+using FinkiChattery.Common.Mediator.Interfaces;
+using FinkiChattery.Contracts.Questioning;
+using IdentityServer4.AccessTokenValidation;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using System;
+using System.Threading.Tasks;
+
+namespace FinkiChattery.Api.Controllers.v1
+{
+    [ApiVersion(ApiVersions.ApiVersion1)]
+    [Route("api/v{version:apiVersion}/questions/{questionUid:Guid}/[controller]/")]
+    [ApiController]
+    public class AnswersController : ControllerBase
+    {
+        public AnswersController(IMediatorService mediatorService)
+        {
+            MediatorService = mediatorService;
+        }
+
+        public IMediatorService MediatorService { get; }
+
+        [HttpPost]
+        [Authorize(AuthenticationSchemes = IdentityServerAuthenticationDefaults.AuthenticationScheme, Policy = AuthenticationPolicy.Student)]
+        public async Task<IActionResult> AnswerQuestion([FromRoute] Guid questionUid, [FromBody] AnswerQuestionRequest request)
+        {
+            var answerUid = await MediatorService.SendAsync(new AnswerQuestionCommand(questionUid, request.Text));
+            return Ok(answerUid);
+        }
+
+        [HttpPut("{answerUid:Guid}/correct")]
+        [Authorize(AuthenticationSchemes = IdentityServerAuthenticationDefaults.AuthenticationScheme, Policy = AuthenticationPolicy.Student)]
+        public async Task<IActionResult> MarkAnswerCorrect([FromRoute] Guid questionUid, [FromRoute] Guid answerUid)
+        {
+            await MediatorService.SendAsync(new MarkAnswerCorrectCommand(questionUid, answerUid));
+            return Ok(answerUid);
+        }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Api/Controllers/v1/SelfController.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Api/Controllers/v1/SelfController.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Api/Controllers/v1/SelfController.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,30 @@
+﻿using FinkiChattery.Api.ApplicationServices.User;
+using FinkiChattery.Common.Mediator.Interfaces;
+using FinkiChattery.Queries.User;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using System.Threading.Tasks;
+
+namespace FinkiChattery.Api.Controllers.v1
+{
+    [ApiVersion(ApiVersions.ApiVersion1)]
+    [Route("api/v{version:apiVersion}/[controller]/")]
+    [ApiController]
+    public class SelfController : ControllerBase
+    {
+        public SelfController(IMediatorService mediatorService)
+        {
+            MediatorService = mediatorService;
+        }
+
+        public IMediatorService MediatorService { get; }
+
+        [HttpGet]
+        [Authorize]
+        public async Task<IActionResult> Getself()
+        {
+            var selfUserDto = await MediatorService.SendQueryAsync(new GetSelfUserQuery());
+            return Ok(selfUserDto.ToSelfUserResponse());
+        }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Api/Controllers/v1/VotesController.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Api/Controllers/v1/VotesController.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Api/Controllers/v1/VotesController.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,35 @@
+﻿using FinkiChattery.Api.ApplicationServices.Authentication;
+using FinkiChattery.Commands.Questioning;
+using FinkiChattery.Common.Mediator.Interfaces;
+using FinkiChattery.Contracts.Questioning;
+using FinkiChattery.Persistence.Helpers;
+using IdentityServer4.AccessTokenValidation;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using System;
+using System.Threading.Tasks;
+
+namespace FinkiChattery.Api.Controllers.v1
+{
+    [ApiVersion(ApiVersions.ApiVersion1)]
+    [Route("api/v{version:apiVersion}/questions/{questionUid:Guid}/answers/{answerUid:Guid}/[controller]")]
+    [ApiController]
+    public class VotesController : ControllerBase
+    {
+        public VotesController(IMediatorService mediatorService)
+        {
+            MediatorService = mediatorService;
+        }
+
+        public IMediatorService MediatorService { get; }
+
+        [HttpPost]
+        [Authorize(AuthenticationSchemes = IdentityServerAuthenticationDefaults.AuthenticationScheme, Policy = AuthenticationPolicy.Student)]
+        public async Task<IActionResult> VoteAnswer([FromRoute] Guid questionUid, [FromRoute] Guid answerUid, [FromBody] VoteAnswerRequest request)
+        {
+            VoteType voteType = request.VoteType == VoteTypeRequest.Upvote ? VoteType.Upvote : VoteType.Downvote;
+            var voteUid = await MediatorService.SendAsync(new VoteAnswerCommand(voteType, answerUid, questionUid));
+            return Ok(new VoteAnswerResponse(answerUid, voteUid, request.VoteType));
+        }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Api/Services/RegisterServices.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Api/Services/RegisterServices.cs	(revision 1e0d86905c02abe14201bf07ad5a2163900a5602)
+++ src/FinkiChattery/FinkiChattery.Api/Services/RegisterServices.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -1,3 +1,4 @@
 ﻿using FinkiChattery.Api.ApplicationServices.Authentication;
+using FinkiChattery.Api.ApplicationServices.Questioning.EventHandlers;
 using FinkiChattery.Api.Services;
 using FinkiChattery.Commands.Questioning;
@@ -31,5 +32,5 @@
             services.AddScoped<IEventService, EventService>();
             services.AddTransient(typeof(IPipelineBehavior<,>), typeof(ValidationBehavior<,>));
-            services.AddMediatR(typeof(AskQuestionCommand), typeof(GetQuestionStateQuery));
+            services.AddMediatR(typeof(AskQuestionCommand), typeof(GetQuestionStateQuery), typeof(UpdateAnswerVotesEventHandler));
         }
 
@@ -54,4 +55,9 @@
             });
             services.AddHangfireServer();
+
+            services.AddScoped<IBackgroundJobClient>(provider =>
+            {
+                return new BackgroundJobClient(JobStorage.Current);
+            });
         }
 
Index: src/FinkiChattery/FinkiChattery.Commands/Questioning/AnswerQuestion/AnswerQuestionCommand.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Commands/Questioning/AnswerQuestion/AnswerQuestionCommand.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Commands/Questioning/AnswerQuestion/AnswerQuestionCommand.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,57 @@
+﻿using FinkiChattery.Common.Mediator.Contracs;
+using FinkiChattery.Common.Mediator.Interfaces;
+using FinkiChattery.Common.User;
+using FinkiChattery.Persistence.Models;
+using FinkiChattery.Persistence.UnitOfWork;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace FinkiChattery.Commands.Questioning
+{
+    public class AnswerQuestionCommand : ICommand<Guid>
+    {
+        public AnswerQuestionCommand(Guid questionUid, string text)
+        {
+            QuestionUid = questionUid;
+            Text = text;
+        }
+
+        public Guid QuestionUid { get; }
+        public string Text { get; }
+    }
+
+    public class AnswerQuestionHandler : ICommandHandler<AnswerQuestionCommand, Guid>
+    {
+        public AnswerQuestionHandler(IUnitOfWork unitOfWork, ICurrentUser currentUser, IEventService eventService)
+        {
+            UnitOfWork = unitOfWork;
+            CurrentUser = currentUser;
+            EventService = eventService;
+        }
+
+        public IUnitOfWork UnitOfWork { get; }
+        public ICurrentUser CurrentUser { get; }
+        public IEventService EventService { get; }
+
+        public async Task<Guid> Handle(AnswerQuestionCommand request, CancellationToken cancellationToken)
+        {
+            var question = await UnitOfWork.Questions.GetByUidAsync(request.QuestionUid);
+            var student = await UnitOfWork.Students.GetStudent(CurrentUser.Id);
+
+            var answer = new Answer()
+            {
+                Text = request.Text,
+                QuestionFk = question.Id,
+                StudentFk = student.Id,
+            };
+
+            UnitOfWork.Answers.Add(answer);
+            await UnitOfWork.SaveAsync();
+
+            EventService.Enqueue(new QuestionAnsweredEvent(question.Uid, answer.Uid, student.Uid));
+
+            return answer.Uid;
+        }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Commands/Questioning/AnswerQuestion/AnswerQuestionValidator.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Commands/Questioning/AnswerQuestion/AnswerQuestionValidator.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Commands/Questioning/AnswerQuestion/AnswerQuestionValidator.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,19 @@
+﻿using FinkiChattery.Commands.Questioning.Validators;
+using FinkiChattery.Common.User;
+using FinkiChattery.Persistence.UnitOfWork;
+using FluentValidation;
+
+namespace FinkiChattery.Commands.Questioning
+{
+    public class AnswerQuestionValidator : AbstractValidator<AnswerQuestionCommand>
+    {
+        public AnswerQuestionValidator(IUnitOfWork unitOfWork, ICurrentUser currentUser)
+        {
+            CascadeMode = CascadeMode.Stop;
+
+            RuleFor(x => x.Text).AnswerTextValidate();
+            RuleFor(x => x.QuestionUid).SetValidator(new QuestionWithUidsExist(unitOfWork));
+            RuleFor(x => x).SetValidator(new StudentHasGoodReputationAndCanVoteAndAnswer(unitOfWork, currentUser));
+        }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Commands/Questioning/AnswerQuestion/QuestionAnsweredEvent.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Commands/Questioning/AnswerQuestion/QuestionAnsweredEvent.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Commands/Questioning/AnswerQuestion/QuestionAnsweredEvent.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,19 @@
+﻿using FinkiChattery.Common.Mediator.Contracs;
+using System;
+
+namespace FinkiChattery.Commands.Questioning
+{
+    public class QuestionAnsweredEvent : IEvent
+    {
+        public QuestionAnsweredEvent(Guid questionUid, Guid answerUid, Guid studentUid)
+        {
+            QuestionUid = questionUid;
+            AnswerUid = answerUid;
+            StudentUid = studentUid;
+        }
+
+        public Guid QuestionUid { get; }
+        public Guid AnswerUid { get; }
+        public Guid StudentUid { get; }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Commands/Questioning/MarkAnswerCorrect/AnswerMarkedAsCorrectEvent.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Commands/Questioning/MarkAnswerCorrect/AnswerMarkedAsCorrectEvent.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Commands/Questioning/MarkAnswerCorrect/AnswerMarkedAsCorrectEvent.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,17 @@
+﻿using FinkiChattery.Common.Mediator.Contracs;
+using System;
+
+namespace FinkiChattery.Commands.Questioning
+{
+    public class AnswerMarkedAsCorrectEvent : IEvent
+    {
+        public AnswerMarkedAsCorrectEvent(Guid questionUid, Guid answerUid)
+        {
+            QuestionUid = questionUid;
+            AnswerUid = answerUid;
+        }
+
+        public Guid QuestionUid { get; }
+        public Guid AnswerUid { get; }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Commands/Questioning/MarkAnswerCorrect/MarkAnswerCorrectCommand.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Commands/Questioning/MarkAnswerCorrect/MarkAnswerCorrectCommand.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Commands/Questioning/MarkAnswerCorrect/MarkAnswerCorrectCommand.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,45 @@
+﻿using FinkiChattery.Common.Mediator.Contracs;
+using FinkiChattery.Common.Mediator.Interfaces;
+using FinkiChattery.Persistence.UnitOfWork;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace FinkiChattery.Commands.Questioning
+{
+    public class MarkAnswerCorrectCommand : ICommand<Guid>
+    {
+        public MarkAnswerCorrectCommand(Guid questionUid, Guid answerUid)
+        {
+            QuestionUid = questionUid;
+            AnswerUid = answerUid;
+        }
+
+        public Guid QuestionUid { get; }
+        public Guid AnswerUid { get; }
+    }
+
+    public class MarkAnswerCorrectHandler : ICommandHandler<MarkAnswerCorrectCommand, Guid>
+    {
+        public MarkAnswerCorrectHandler(IUnitOfWork unitOfWork, IEventService eventService)
+        {
+            UnitOfWork = unitOfWork;
+            EventService = eventService;
+        }
+
+        public IUnitOfWork UnitOfWork { get; }
+        public IEventService EventService { get; }
+
+        public async Task<Guid> Handle(MarkAnswerCorrectCommand request, CancellationToken cancellationToken)
+        {
+            var answer = await UnitOfWork.Answers.GetByUidAsync(request.AnswerUid);
+            answer.CorrectAnswer = true;
+
+            await UnitOfWork.SaveAsync();
+
+            EventService.Enqueue(new AnswerMarkedAsCorrectEvent(request.QuestionUid, request.AnswerUid));
+
+            return answer.Uid;
+        }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Commands/Questioning/MarkAnswerCorrect/MarkAnswerCorrectValidator.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Commands/Questioning/MarkAnswerCorrect/MarkAnswerCorrectValidator.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Commands/Questioning/MarkAnswerCorrect/MarkAnswerCorrectValidator.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,20 @@
+﻿using FinkiChattery.Commands.Questioning.Validators;
+using FinkiChattery.Commands.Questioning.Validators.Contracts;
+using FinkiChattery.Common.User;
+using FinkiChattery.Persistence.UnitOfWork;
+using FluentValidation;
+
+namespace FinkiChattery.Commands.Questioning
+{
+    public class MarkAnswerCorrectValidator : AbstractValidator<MarkAnswerCorrectCommand>
+    {
+        public MarkAnswerCorrectValidator(IUnitOfWork unitOfWork, ICurrentUser currentUser)
+        {
+            CascadeMode = CascadeMode.Stop;
+
+            RuleFor(x => x.QuestionUid).SetValidator(new StudentIsOwnerOfQuestion(unitOfWork, currentUser));
+            RuleFor(x => new AnswerInQuestionWithUidExistsDto(x.QuestionUid, x.AnswerUid)).SetValidator(new AnswerInQuestionWithUidExists(unitOfWork));
+            RuleFor(x => x.AnswerUid).SetValidator(new AnswerIsNotAlreadyMarkedAsCorrect(unitOfWork));
+        }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Commands/Questioning/QuestioningErrorCodes.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Commands/Questioning/QuestioningErrorCodes.cs	(revision 1e0d86905c02abe14201bf07ad5a2163900a5602)
+++ src/FinkiChattery/FinkiChattery.Commands/Questioning/QuestioningErrorCodes.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -9,4 +9,12 @@
         public const string CategoriesDontExist = "CategoriesDontExist";
         public const string TeamDontExist = "TeamDontExist";
+        public const string AnswerAlreadyUpvoted = "AnswerAlreadyUpvoted";
+        public const string AnswerAlreadyDownvoted = "AnswerAlreadyDownvoted";
+        public const string StudentHasBadReputation = "StudentHasBadReputation"; 
+        public const string AnswerTextLengthInvalid = "AnswerTextLengthInvalid";
+        public const string QuestionNotFound = "QuestionNotFound";
+        public const string AnswerInQuestionNotFound = "AnswerInQuestionNotFound"; 
+        public const string StudentDoesNotOwnQuestion = "StudentDoesNotOwnQuestion";
+        public const string AnswerIsAlreadyMarkedAsCorrect = "AnswerIsAlreadyMarkedAsCorrect";
     }
 }
Index: src/FinkiChattery/FinkiChattery.Commands/Questioning/Validators/AnswerInQuestionWithUidExists.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Commands/Questioning/Validators/AnswerInQuestionWithUidExists.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Commands/Questioning/Validators/AnswerInQuestionWithUidExists.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,30 @@
+﻿using FinkiChattery.Commands.Questioning.Validators.Contracts;
+using FinkiChattery.Persistence.UnitOfWork;
+using FluentValidation.Validators;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace FinkiChattery.Commands.Questioning.Validators
+{
+    public class AnswerInQuestionWithUidExists : AsyncValidatorBase
+    {
+        public AnswerInQuestionWithUidExists(IUnitOfWork unitOfWork)
+        {
+            UnitOfWork = unitOfWork;
+        }
+
+        public IUnitOfWork UnitOfWork { get; }
+
+        protected override async Task<bool> IsValidAsync(PropertyValidatorContext context, CancellationToken cancellation)
+        {
+            var dto = (AnswerInQuestionWithUidExistsDto)context.PropertyValue;
+
+            return await UnitOfWork.Answers.AnswerInQuestionExists(dto.QuestionUid, dto.AnswerUid);
+        }
+
+        protected override string GetDefaultMessageTemplate()
+        {
+            return QuestioningErrorCodes.AnswerInQuestionNotFound;
+        }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Commands/Questioning/Validators/AnswerIsNotAlreadyMarkedAsCorrect.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Commands/Questioning/Validators/AnswerIsNotAlreadyMarkedAsCorrect.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Commands/Questioning/Validators/AnswerIsNotAlreadyMarkedAsCorrect.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,32 @@
+﻿using FinkiChattery.Persistence.UnitOfWork;
+using FluentValidation.Validators;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace FinkiChattery.Commands.Questioning.Validators
+{
+    public class AnswerIsNotAlreadyMarkedAsCorrect : AsyncValidatorBase
+    {
+        public AnswerIsNotAlreadyMarkedAsCorrect(IUnitOfWork unitOfWork)
+        {
+            UnitOfWork = unitOfWork;
+        }
+
+        public IUnitOfWork UnitOfWork { get; }
+
+        protected override async Task<bool> IsValidAsync(PropertyValidatorContext context, CancellationToken cancellation)
+        {
+            var answerUid = (Guid)context.PropertyValue;
+
+            var answer = await UnitOfWork.Answers.GetByUidAsync(answerUid);
+
+            return !answer.CorrectAnswer;
+        }
+
+        protected override string GetDefaultMessageTemplate()
+        {
+            return QuestioningErrorCodes.AnswerIsAlreadyMarkedAsCorrect;
+        }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Commands/Questioning/Validators/CategoriesUidsExist.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Commands/Questioning/Validators/CategoriesUidsExist.cs	(revision 1e0d86905c02abe14201bf07ad5a2163900a5602)
+++ src/FinkiChattery/FinkiChattery.Commands/Questioning/Validators/CategoriesUidsExist.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -1,4 +1,3 @@
-﻿using FinkiChattery.Persistence.Repositories;
-using FinkiChattery.Persistence.UnitOfWork;
+﻿using FinkiChattery.Persistence.UnitOfWork;
 using FluentValidation.Validators;
 using System;
Index: src/FinkiChattery/FinkiChattery.Commands/Questioning/Validators/Contracts/AnswerInQuestionWithUidExistsDto.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Commands/Questioning/Validators/Contracts/AnswerInQuestionWithUidExistsDto.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Commands/Questioning/Validators/Contracts/AnswerInQuestionWithUidExistsDto.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,16 @@
+﻿using System;
+
+namespace FinkiChattery.Commands.Questioning.Validators.Contracts
+{
+    public class AnswerInQuestionWithUidExistsDto
+    {
+        public AnswerInQuestionWithUidExistsDto(Guid questionUid, Guid answerUid)
+        {
+            QuestionUid = questionUid;
+            AnswerUid = answerUid;
+        }
+
+        public Guid QuestionUid { get; }
+        public Guid AnswerUid { get; }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Commands/Questioning/Validators/Contracts/VoteAnswerByStudentIsValidDto.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Commands/Questioning/Validators/Contracts/VoteAnswerByStudentIsValidDto.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Commands/Questioning/Validators/Contracts/VoteAnswerByStudentIsValidDto.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,17 @@
+﻿using FinkiChattery.Persistence.Helpers;
+using System;
+
+namespace FinkiChattery.Commands.Questioning.Validators.Contracts
+{
+    public class VoteAnswerByStudentIsValidDto
+    {
+        public VoteAnswerByStudentIsValidDto(VoteType voteType, Guid answerUid)
+        {
+            VoteType = voteType;
+            AnswerUid = answerUid;
+        }
+
+        public VoteType VoteType { get; }
+        public Guid AnswerUid { get; }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Commands/Questioning/Validators/QuestionWithUidsExist.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Commands/Questioning/Validators/QuestionWithUidsExist.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Commands/Questioning/Validators/QuestionWithUidsExist.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,30 @@
+﻿using FinkiChattery.Persistence.UnitOfWork;
+using FluentValidation.Validators;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace FinkiChattery.Commands.Questioning.Validators
+{
+    public class QuestionWithUidsExist : AsyncValidatorBase
+    {
+        public QuestionWithUidsExist(IUnitOfWork unitOfWork)
+        {
+            UnitOfWork = unitOfWork;
+        }
+
+        public IUnitOfWork UnitOfWork { get; }
+
+        protected override async Task<bool> IsValidAsync(PropertyValidatorContext context, CancellationToken cancellation)
+        {
+            var questionUid = (Guid)context.PropertyValue;
+
+            return (await UnitOfWork.Questions.GetByUidAsync(questionUid)) != null;
+        }
+
+        protected override string GetDefaultMessageTemplate()
+        {
+            return QuestioningErrorCodes.QuestionNotFound;
+        }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Commands/Questioning/Validators/QuestioningFluentValidationRules.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Commands/Questioning/Validators/QuestioningFluentValidationRules.cs	(revision 1e0d86905c02abe14201bf07ad5a2163900a5602)
+++ src/FinkiChattery/FinkiChattery.Commands/Questioning/Validators/QuestioningFluentValidationRules.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -16,4 +16,9 @@
         }
 
+        public static IRuleBuilderOptions<T, string> AnswerTextValidate<T>(this IRuleBuilder<T, string> ruleBuilder)
+        {
+            return ruleBuilder.NotNull().WithMessage(QuestioningErrorCodes.CantBeNull).MaximumLength(4000).WithMessage(QuestioningErrorCodes.AnswerTextLengthInvalid);
+        }
+
         public static IRuleBuilderOptions<T, IEnumerable<U>> ListNotNull<T, U>(this IRuleBuilder<T, IEnumerable<U>> ruleBuilder)
         {
Index: src/FinkiChattery/FinkiChattery.Commands/Questioning/Validators/StudentHasGoodReputationAndCanVoteAndAnswer.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Commands/Questioning/Validators/StudentHasGoodReputationAndCanVoteAndAnswer.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Commands/Questioning/Validators/StudentHasGoodReputationAndCanVoteAndAnswer.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,37 @@
+﻿using FinkiChattery.Common.User;
+using FinkiChattery.Persistence.UnitOfWork;
+using FluentValidation.Validators;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace FinkiChattery.Commands.Questioning.Validators
+{
+    public class StudentHasGoodReputationAndCanVoteAndAnswer : AsyncValidatorBase
+    {
+        public StudentHasGoodReputationAndCanVoteAndAnswer(IUnitOfWork unitOfWork, ICurrentUser currentUser)
+        {
+            UnitOfWork = unitOfWork;
+            CurrentUser = currentUser;
+        }
+
+        public IUnitOfWork UnitOfWork { get; }
+        public ICurrentUser CurrentUser { get; }
+
+        protected override async Task<bool> IsValidAsync(PropertyValidatorContext context, CancellationToken cancellation)
+        {
+            var student = await UnitOfWork.Students.GetStudent(CurrentUser.Id);
+
+            if (student.ReportReputation > 100)
+            {
+                return false;
+            }
+
+            return true;
+        }
+
+        protected override string GetDefaultMessageTemplate()
+        {
+            return QuestioningErrorCodes.StudentHasBadReputation;
+        }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Commands/Questioning/Validators/StudentIsOwnerOfQuestion.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Commands/Questioning/Validators/StudentIsOwnerOfQuestion.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Commands/Questioning/Validators/StudentIsOwnerOfQuestion.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,33 @@
+﻿using FinkiChattery.Common.User;
+using FinkiChattery.Persistence.UnitOfWork;
+using FluentValidation.Validators;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace FinkiChattery.Commands.Questioning.Validators
+{
+    public class StudentIsOwnerOfQuestion : AsyncValidatorBase
+    {
+        public StudentIsOwnerOfQuestion(IUnitOfWork unitOfWork, ICurrentUser currentUser)
+        {
+            UnitOfWork = unitOfWork;
+            CurrentUser = currentUser;
+        }
+
+        public IUnitOfWork UnitOfWork { get; }
+        public ICurrentUser CurrentUser { get; }
+
+        protected override async Task<bool> IsValidAsync(PropertyValidatorContext context, CancellationToken cancellation)
+        {
+            var questionUid = (Guid)context.PropertyValue;
+
+            return await UnitOfWork.Questions.QuestionIsOwnedByStudent(questionUid, CurrentUser.Id);
+        }
+
+        protected override string GetDefaultMessageTemplate()
+        {
+            return QuestioningErrorCodes.StudentDoesNotOwnQuestion;
+        }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Commands/Questioning/Validators/VoteAnswerByStudentIsValid.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Commands/Questioning/Validators/VoteAnswerByStudentIsValid.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Commands/Questioning/Validators/VoteAnswerByStudentIsValid.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,47 @@
+﻿using FinkiChattery.Commands.Questioning.Validators.Contracts;
+using FinkiChattery.Common.User;
+using FinkiChattery.Persistence.Helpers;
+using FinkiChattery.Persistence.UnitOfWork;
+using FluentValidation.Validators;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace FinkiChattery.Commands.Questioning.Validators
+{
+    public class VoteAnswerByStudentIsValid : AsyncValidatorBase
+    {
+        public VoteAnswerByStudentIsValid(IUnitOfWork unitOfWork, ICurrentUser currentUser)
+        {
+            UnitOfWork = unitOfWork;
+            CurrentUser = currentUser;
+        }
+
+        public IUnitOfWork UnitOfWork { get; }
+        public ICurrentUser CurrentUser { get; }
+        private VoteType _voteType { get; set; }
+
+        protected override async Task<bool> IsValidAsync(PropertyValidatorContext context, CancellationToken cancellation)
+        {
+            var dto = (VoteAnswerByStudentIsValidDto)context.PropertyValue;
+
+            _voteType = dto.VoteType;
+
+            return dto.VoteType switch
+            {
+                VoteType.Upvote => !await UnitOfWork.Votes.StudentHasUpvotedAnswer(dto.AnswerUid, CurrentUser.Id),
+                VoteType.Downvote => !await UnitOfWork.Votes.StudentHasDownvotedAnswer(dto.AnswerUid, CurrentUser.Id),
+                _ => !await UnitOfWork.Votes.StudentHasUpvotedAnswer(dto.AnswerUid, CurrentUser.Id),
+            };
+        }
+
+        protected override string GetDefaultMessageTemplate()
+        {
+            return _voteType switch
+            {
+                VoteType.Upvote => QuestioningErrorCodes.AnswerAlreadyUpvoted,
+                VoteType.Downvote => QuestioningErrorCodes.AnswerAlreadyDownvoted,
+                _ => QuestioningErrorCodes.AnswerAlreadyUpvoted
+            };
+        }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Commands/Questioning/VoteAnswer/AnswerVotedEvent.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Commands/Questioning/VoteAnswer/AnswerVotedEvent.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Commands/Questioning/VoteAnswer/AnswerVotedEvent.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,22 @@
+﻿using FinkiChattery.Common.Mediator.Contracs;
+using FinkiChattery.Persistence.Helpers;
+using System;
+
+namespace FinkiChattery.Commands.Questioning
+{
+    public class AnswerVotedEvent : IEvent
+    {
+        public AnswerVotedEvent(Guid questionUid, Guid answerUid, Guid studentUid, VoteType voteType)
+        {
+            QuestionUid = questionUid;
+            AnswerUid = answerUid;
+            StudentUid = studentUid;
+            VoteType = voteType;
+        }
+
+        public Guid QuestionUid { get; }
+        public Guid AnswerUid { get; }
+        public Guid StudentUid { get; }
+        public VoteType VoteType { get; }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Commands/Questioning/VoteAnswer/VoteAnswerCommand.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Commands/Questioning/VoteAnswer/VoteAnswerCommand.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Commands/Questioning/VoteAnswer/VoteAnswerCommand.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,69 @@
+﻿using FinkiChattery.Common.Mediator.Contracs;
+using FinkiChattery.Common.Mediator.Interfaces;
+using FinkiChattery.Common.User;
+using FinkiChattery.Persistence.Helpers;
+using FinkiChattery.Persistence.Models;
+using FinkiChattery.Persistence.UnitOfWork;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace FinkiChattery.Commands.Questioning
+{
+    public class VoteAnswerCommand : ICommand<Guid>
+    {
+        public VoteAnswerCommand(VoteType voteType, Guid answerUid, Guid questionUid)
+        {
+            VoteType = voteType;
+            AnswerUid = answerUid;
+            QuestionUid = questionUid;
+        }
+
+        public VoteType VoteType { get; }
+        public Guid AnswerUid { get; }
+        public Guid QuestionUid { get; }
+    }
+
+    public class VoteAnswerHandler : ICommandHandler<VoteAnswerCommand, Guid>
+    {
+        public VoteAnswerHandler(IUnitOfWork unitOfWork, ICurrentUser currentUser, IEventService eventService)
+        {
+            UnitOfWork = unitOfWork;
+            CurrentUser = currentUser;
+            EventService = eventService;
+        }
+
+        public IUnitOfWork UnitOfWork { get; }
+        public ICurrentUser CurrentUser { get; }
+        public IEventService EventService { get; }
+
+        public async Task<Guid> Handle(VoteAnswerCommand request, CancellationToken cancellationToken)
+        {
+            var student = await UnitOfWork.Students.GetStudent(CurrentUser.Id);
+            var answer = await UnitOfWork.Answers.GetByUidAsync(request.AnswerUid);
+            var vote = await UnitOfWork.Votes.GetVoteForAnswerByStudent(request.AnswerUid, CurrentUser.Id);
+
+            if (vote == null)
+            {
+                vote = new Vote()
+                {
+                    AnswerFk = answer.Id,
+                    StudentFk = student.Id,
+                    VoteType = request.VoteType
+                };
+
+                UnitOfWork.Votes.Add(vote);
+            } 
+            else
+            {
+                vote.VoteType = request.VoteType;
+            }
+
+            await UnitOfWork.SaveAsync();
+
+            EventService.Enqueue(new AnswerVotedEvent(request.QuestionUid, request.AnswerUid, student.Uid, request.VoteType));
+
+            return vote.Uid;
+        }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Commands/Questioning/VoteAnswer/VoteAnswerValidator.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Commands/Questioning/VoteAnswer/VoteAnswerValidator.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Commands/Questioning/VoteAnswer/VoteAnswerValidator.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,19 @@
+﻿using FinkiChattery.Commands.Questioning.Validators;
+using FinkiChattery.Commands.Questioning.Validators.Contracts;
+using FinkiChattery.Common.User;
+using FinkiChattery.Persistence.UnitOfWork;
+using FluentValidation;
+
+namespace FinkiChattery.Commands.Questioning
+{
+    public class VoteAnswerValidator : AbstractValidator<VoteAnswerCommand>
+    {
+        public VoteAnswerValidator(IUnitOfWork unitOfWork, ICurrentUser currentUser)
+        {
+            CascadeMode = CascadeMode.Stop;
+
+            RuleFor(x => x).SetValidator(new StudentHasGoodReputationAndCanVoteAndAnswer(unitOfWork, currentUser));
+            RuleFor(x => new VoteAnswerByStudentIsValidDto(x.VoteType, x.AnswerUid)).SetValidator(new VoteAnswerByStudentIsValid(unitOfWork, currentUser));
+        }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Contracts/Questioning/AnswerQuestion/AnswerQuestionRequest.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Contracts/Questioning/AnswerQuestion/AnswerQuestionRequest.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Contracts/Questioning/AnswerQuestion/AnswerQuestionRequest.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,7 @@
+﻿namespace FinkiChattery.Contracts.Questioning
+{
+    public class AnswerQuestionRequest
+    {
+        public string Text { get; set; }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Contracts/Questioning/GetQuestionState/QuestionStateResponse.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Contracts/Questioning/GetQuestionState/QuestionStateResponse.cs	(revision 1e0d86905c02abe14201bf07ad5a2163900a5602)
+++ src/FinkiChattery/FinkiChattery.Contracts/Questioning/GetQuestionState/QuestionStateResponse.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -89,5 +89,5 @@
     public class AnswerQuestionStateResponse
     {
-        public AnswerQuestionStateResponse(long id, Guid uid, string text, bool correctAnswer, DateTime createdOn, long upvotesCount, AnswerStudentQuestionStateResponse studentResponse, IEnumerable<AnswerResponseQuestionStateResponse> answerResponsesResponse)
+        public AnswerQuestionStateResponse(long id, Guid uid, string text, bool correctAnswer, DateTime createdOn, long votesCount, AnswerStudentQuestionStateResponse studentResponse, IEnumerable<AnswerResponseQuestionStateResponse> answerResponsesResponse)
         {
             Id = id;
@@ -96,5 +96,5 @@
             CorrectAnswer = correctAnswer;
             CreatedOn = createdOn;
-            UpvotesCount = upvotesCount;
+            VotesCount = votesCount;
             StudentResponse = studentResponse;
             AnswerResponsesResponse = answerResponsesResponse;
@@ -107,5 +107,5 @@
         public bool CorrectAnswer { get; }
         public DateTime CreatedOn { get; }
-        public long UpvotesCount { get; }
+        public long VotesCount { get; }
         public AnswerStudentQuestionStateResponse StudentResponse { get; }
         public IEnumerable<AnswerResponseQuestionStateResponse> AnswerResponsesResponse { get; }
Index: src/FinkiChattery/FinkiChattery.Contracts/Questioning/VoteAnswer/VoteAnswerRequest.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Contracts/Questioning/VoteAnswer/VoteAnswerRequest.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Contracts/Questioning/VoteAnswer/VoteAnswerRequest.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,10 @@
+﻿using System.ComponentModel.DataAnnotations;
+
+namespace FinkiChattery.Contracts.Questioning
+{
+    public class VoteAnswerRequest
+    {
+        [EnumDataType(typeof(VoteTypeRequest))]
+        public VoteTypeRequest VoteType { get; set; }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Contracts/Questioning/VoteAnswer/VoteAnswerResponse.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Contracts/Questioning/VoteAnswer/VoteAnswerResponse.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Contracts/Questioning/VoteAnswer/VoteAnswerResponse.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,18 @@
+﻿using System;
+
+namespace FinkiChattery.Contracts.Questioning
+{
+    public class VoteAnswerResponse
+    {
+        public VoteAnswerResponse(Guid answerUid, Guid voteUid, VoteTypeRequest voteType)
+        {
+            AnswerUid = answerUid;
+            VoteUid = voteUid;
+            VoteType = voteType;
+        }
+
+        public Guid AnswerUid { get; }
+        public Guid VoteUid { get; }
+        public VoteTypeRequest VoteType { get; }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Contracts/Questioning/VoteAnswer/VoteTypeRequest.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Contracts/Questioning/VoteAnswer/VoteTypeRequest.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Contracts/Questioning/VoteAnswer/VoteTypeRequest.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,8 @@
+﻿namespace FinkiChattery.Contracts.Questioning
+{
+    public enum VoteTypeRequest
+    {
+        Upvote,
+        Downvote
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Contracts/User/GetSelfUser/SelfUserResponse.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Contracts/User/GetSelfUser/SelfUserResponse.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Contracts/User/GetSelfUser/SelfUserResponse.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,106 @@
+﻿#nullable enable
+
+using System;
+using System.Collections.Generic;
+
+
+namespace FinkiChattery.Contracts.User
+{
+    public class SelfUserResponse
+    {
+        public SelfUserResponse(StudentSelfResponse? student = null, TeacherSelfResponse? teacher = null, ModeratorSelfResponse? moderator = null)
+        {
+            Student = student;
+            Teacher = teacher;
+            Moderator = moderator;
+        }
+
+        public StudentSelfResponse? Student { get; }
+        public TeacherSelfResponse? Teacher { get; }
+        public ModeratorSelfResponse? Moderator { get; }
+    }
+
+    public class StudentSelfResponse
+    {
+        public StudentSelfResponse(Guid uid, long applicationUserId, string index, long reputation, string imageUrl, IEnumerable<StudentQuestionResponse> questions, IEnumerable<StudentTeamResponse> teams)
+        {
+            Uid = uid;
+            ApplicationUserId = applicationUserId;
+            Index = index;
+            Reputation = reputation;
+            ImageUrl = imageUrl;
+            Questions = questions;
+            Teams = teams;
+        }
+
+        public Guid Uid { get; }
+        public long ApplicationUserId { get; }
+        public string Index { get; }
+        public long Reputation { get; }
+        public string ImageUrl { get; }
+        public IEnumerable<StudentQuestionResponse> Questions { get; }
+        public IEnumerable<StudentTeamResponse> Teams { get; }
+    }
+
+    public class StudentQuestionResponse
+    {
+        public StudentQuestionResponse(Guid questionUid, string title)
+        {
+            QuestionUid = questionUid;
+            Title = title;
+        }
+
+        public Guid QuestionUid { get; }
+        public string Title { get; }
+    }
+
+    public class StudentTeamResponse
+    {
+        public StudentTeamResponse(Guid teamUid, string name)
+        {
+            TeamUid = teamUid;
+            Name = name;
+        }
+
+        public Guid TeamUid { get; }
+        public string Name { get; }
+    }
+
+    public class ModeratorSelfResponse
+    {
+        public ModeratorSelfResponse(Guid uid, long applicationUserId)
+        {
+            Uid = uid;
+            ApplicationUserId = applicationUserId;
+        }
+
+        public Guid Uid { get; }
+        public long ApplicationUserId { get; }
+    }
+
+    public class TeacherSelfResponse
+    {
+        public TeacherSelfResponse(Guid uid, long applicationUserId, IEnumerable<TeacherTeamResponse> teams)
+        {
+            Uid = uid;
+            ApplicationUserId = applicationUserId;
+            Teams = teams;
+        }
+
+        public Guid Uid { get; }
+        public long ApplicationUserId { get; }
+        public IEnumerable<TeacherTeamResponse> Teams { get; }
+    }
+
+    public class TeacherTeamResponse
+    {
+        public TeacherTeamResponse(Guid teamUid, string name)
+        {
+            TeamUid = teamUid;
+            Name = name;
+        }
+
+        public Guid TeamUid { get; }
+        public string Name { get; }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Database/FinkiChattery.Database.sqlproj
===================================================================
--- src/FinkiChattery/FinkiChattery.Database/FinkiChattery.Database.sqlproj	(revision 1e0d86905c02abe14201bf07ad5a2163900a5602)
+++ src/FinkiChattery/FinkiChattery.Database/FinkiChattery.Database.sqlproj	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -75,4 +75,5 @@
     <Folder Include="dbo\Tables\QuestionCategory" />
     <Folder Include="Snapshots" />
+    <Folder Include="dbo\Tables\Vote" />
   </ItemGroup>
   <ItemGroup>
@@ -81,5 +82,4 @@
     <Build Include="dbo\Tables\StudentTeam.sql" />
     <Build Include="dbo\Tables\TeacherTeam.sql" />
-    <Build Include="dbo\Tables\Upvote.sql" />
     <Build Include="dbo\Tables\User\AspNetRoleClaims.sql" />
     <Build Include="dbo\Tables\User\AspNetRoles.sql" />
@@ -100,4 +100,5 @@
     <Build Include="dbo\Tables\QuestionCategory\QuestionCategory.sql" />
     <None Include="dbo\Tables\QuestionCategory\QuestionCategory.Debug.Seed.sql" />
+    <Build Include="dbo\Tables\Vote\Vote.sql" />
   </ItemGroup>
   <ItemGroup>
Index: src/FinkiChattery/FinkiChattery.Database/dbo/Tables/Answer/Answer.Debug.Seed.sql
===================================================================
--- src/FinkiChattery/FinkiChattery.Database/dbo/Tables/Answer/Answer.Debug.Seed.sql	(revision 1e0d86905c02abe14201bf07ad5a2163900a5602)
+++ src/FinkiChattery/FinkiChattery.Database/dbo/Tables/Answer/Answer.Debug.Seed.sql	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -12,5 +12,5 @@
             (3, N'cee193c3-9d36-4ed8-81b2-15eb4ff305f1', N'Answer 3', 2, 1, 1, GETUTCDATE(), 5),
             (4, N'dee193c3-9d36-4ed8-81b2-15eb4ff305f1', N'Answer 4', 2, 1, 0, GETUTCDATE(), 5)
-    ) AS temp ([Id], [Uid], [Text], [QuestionFk], [StudentFk], [CorrectAnswer], [CreatedOn], [UpvotesCount])
+    ) AS temp ([Id], [Uid], [Text], [QuestionFk], [StudentFk], [CorrectAnswer], [CreatedOn], [VotesCount])
     ) AS S
     ON T.[ID] = S.[ID]
@@ -21,5 +21,5 @@
                    T.[StudentFk] = S.[StudentFk],
                    T.[CorrectAnswer] = S.[CorrectAnswer],
-                   T.[UpvotesCount] = S.[UpvotesCount]
+                   T.[VotesCount] = S.[VotesCount]
     WHEN NOT MATCHED THEN
         INSERT
@@ -32,8 +32,8 @@
             [CorrectAnswer],
             [CreatedOn],
-            [UpvotesCount]
+            [VotesCount]
         )
         VALUES
-        (S.[Id], S.[Uid], S.[Text], S.[QuestionFk], S.[StudentFk], S.[CorrectAnswer], S.[CreatedOn], S.[UpvotesCount]);
+        (S.[Id], S.[Uid], S.[Text], S.[QuestionFk], S.[StudentFk], S.[CorrectAnswer], S.[CreatedOn], S.[VotesCount]);
     SET IDENTITY_INSERT [dbo].[Answer] OFF
 END
Index: src/FinkiChattery/FinkiChattery.Database/dbo/Tables/Answer/Answer.sql
===================================================================
--- src/FinkiChattery/FinkiChattery.Database/dbo/Tables/Answer/Answer.sql	(revision 1e0d86905c02abe14201bf07ad5a2163900a5602)
+++ src/FinkiChattery/FinkiChattery.Database/dbo/Tables/Answer/Answer.sql	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -7,5 +7,5 @@
     [CorrectAnswer] BIT              NOT NULL,
     [CreatedOn]     SMALLDATETIME    NOT NULL,
-    [UpvotesCount] BIGINT NOT NULL DEFAULT 0, 
+    [VotesCount] BIGINT NOT NULL DEFAULT 0, 
     CONSTRAINT [PK_Answer] PRIMARY KEY CLUSTERED ([Id] ASC),
     CONSTRAINT [FK_Answer_Question_QuestionFk] FOREIGN KEY ([QuestionFk]) REFERENCES [dbo].[Question] ([Id]),
Index: c/FinkiChattery/FinkiChattery.Database/dbo/Tables/Upvote.sql
===================================================================
--- src/FinkiChattery/FinkiChattery.Database/dbo/Tables/Upvote.sql	(revision 1e0d86905c02abe14201bf07ad5a2163900a5602)
+++ 	(revision )
@@ -1,20 +1,0 @@
-﻿CREATE TABLE [dbo].[Upvote] (
-    [Id]        BIGINT           IDENTITY (1, 1) NOT NULL,
-    [Uid]       UNIQUEIDENTIFIER NOT NULL,
-    [StudentFk] BIGINT           NOT NULL,
-    [AnswerFk]  BIGINT           NOT NULL,
-    CONSTRAINT [PK_Upvote] PRIMARY KEY CLUSTERED ([Id] ASC),
-    CONSTRAINT [FK_Upvote_Answer_AnswerFk] FOREIGN KEY ([AnswerFk]) REFERENCES [dbo].[Answer] ([Id]),
-    CONSTRAINT [FK_Upvote_Student_StudentFk] FOREIGN KEY ([StudentFk]) REFERENCES [dbo].[Student] ([Id])
-);
-
-
-GO
-CREATE NONCLUSTERED INDEX [IX_Upvote_AnswerFk]
-    ON [dbo].[Upvote]([AnswerFk] ASC);
-
-
-GO
-CREATE NONCLUSTERED INDEX [IX_Upvote_StudentFk]
-    ON [dbo].[Upvote]([StudentFk] ASC);
-
Index: src/FinkiChattery/FinkiChattery.Database/dbo/Tables/Vote/Vote.sql
===================================================================
--- src/FinkiChattery/FinkiChattery.Database/dbo/Tables/Vote/Vote.sql	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Database/dbo/Tables/Vote/Vote.sql	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,21 @@
+﻿CREATE TABLE [dbo].[Vote] (
+    [Id]        BIGINT           IDENTITY (1, 1) NOT NULL,
+    [Uid]       UNIQUEIDENTIFIER NOT NULL,
+    [StudentFk] BIGINT           NOT NULL,
+    [AnswerFk]  BIGINT           NOT NULL,
+    [VoteType] TINYINT           NOT NULL, 
+    CONSTRAINT [PK_Vote] PRIMARY KEY CLUSTERED ([Id] ASC),
+    CONSTRAINT [FK_Vote_Answer_AnswerFk] FOREIGN KEY ([AnswerFk]) REFERENCES [dbo].[Answer] ([Id]),
+    CONSTRAINT [FK_Vote_Student_StudentFk] FOREIGN KEY ([StudentFk]) REFERENCES [dbo].[Student] ([Id])
+);
+
+
+GO
+CREATE NONCLUSTERED INDEX [IX_Vote_AnswerFk]
+    ON [dbo].[Vote]([AnswerFk] ASC);
+
+
+GO
+CREATE NONCLUSTERED INDEX [IX_Vote_StudentFk]
+    ON [dbo].[Vote]([StudentFk] ASC);
+
Index: src/FinkiChattery/FinkiChattery.Persistence/Configurations/AnswerConfig.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Persistence/Configurations/AnswerConfig.cs	(revision 1e0d86905c02abe14201bf07ad5a2163900a5602)
+++ src/FinkiChattery/FinkiChattery.Persistence/Configurations/AnswerConfig.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -22,5 +22,5 @@
             builder.Property(x => x.CorrectAnswer).HasColumnName(@"CorrectAnswer").HasColumnType("bit").IsRequired();
             builder.Property(x => x.CreatedOn).HasColumnName(@"CreatedOn").HasColumnType("smalldatetime").IsRequired();
-            builder.Property(x => x.UpvotesCount).HasColumnName(@"UpvotesCount").HasColumnType("bigint").IsRequired().HasDefaultValue(0);
+            builder.Property(x => x.VotesCount).HasColumnName(@"VotesCount").HasColumnType("bigint").IsRequired().HasDefaultValue(0);
 
             builder.HasOne(x => x.Question).WithMany(x => x.Answers).HasForeignKey(x => x.QuestionFk).OnDelete(DeleteBehavior.Restrict);
Index: c/FinkiChattery/FinkiChattery.Persistence/Configurations/UpvoteConfig.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Persistence/Configurations/UpvoteConfig.cs	(revision 1e0d86905c02abe14201bf07ad5a2163900a5602)
+++ 	(revision )
@@ -1,31 +1,0 @@
-﻿using Microsoft.EntityFrameworkCore;
-using Microsoft.EntityFrameworkCore.Metadata.Builders;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using FinkiChattery.Persistence.Models;
-
-namespace FinkiChattery.Persistence.Configurations
-{
-    public class UpvoteConfig : BaseConfig<Upvote>
-    {
-        public UpvoteConfig(string schema) : base(schema)
-        {
-        }
-
-        public override void Configure(EntityTypeBuilder<Upvote> builder)
-        {
-            base.Configure(builder);
-
-            builder.ToTable("Upvote", Schema);
-
-            builder.Property(x => x.StudentFk).HasColumnName(@"StudentFk").HasColumnType("bigint").IsRequired();
-            builder.Property(x => x.AnswerFk).HasColumnName(@"AnswerFk").HasColumnType("bigint").IsRequired();
-
-            builder.HasOne(x => x.Student).WithMany().HasForeignKey(x => x.StudentFk).OnDelete(DeleteBehavior.Restrict);
-            builder.HasOne(x => x.Answer).WithMany(x => x.Upvotes).HasForeignKey(x => x.AnswerFk).OnDelete(DeleteBehavior.Restrict);
-        }
-    }
-}
Index: src/FinkiChattery/FinkiChattery.Persistence/Configurations/VoteConfig.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Persistence/Configurations/VoteConfig.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Persistence/Configurations/VoteConfig.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,27 @@
+﻿using FinkiChattery.Persistence.Models;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace FinkiChattery.Persistence.Configurations
+{
+    public class VoteConfig : BaseConfig<Vote>
+    {
+        public VoteConfig(string schema) : base(schema)
+        {
+        }
+
+        public override void Configure(EntityTypeBuilder<Vote> builder)
+        {
+            base.Configure(builder);
+
+            builder.ToTable("Vote", Schema);
+
+            builder.Property(x => x.StudentFk).HasColumnName(@"StudentFk").HasColumnType("bigint").IsRequired();
+            builder.Property(x => x.AnswerFk).HasColumnName(@"AnswerFk").HasColumnType("bigint").IsRequired();
+            builder.Property(x => x.VoteType).HasColumnName(@"VoteType").HasColumnType("tinyint").IsRequired();
+
+            builder.HasOne(x => x.Student).WithMany().HasForeignKey(x => x.StudentFk).OnDelete(DeleteBehavior.Restrict);
+            builder.HasOne(x => x.Answer).WithMany(x => x.Votes).HasForeignKey(x => x.AnswerFk).OnDelete(DeleteBehavior.Restrict);
+        }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Persistence/Context/ApplicationDbContext.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Persistence/Context/ApplicationDbContext.cs	(revision 1e0d86905c02abe14201bf07ad5a2163900a5602)
+++ src/FinkiChattery/FinkiChattery.Persistence/Context/ApplicationDbContext.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -23,5 +23,5 @@
         public DbSet<TeacherTeam> TeacherTeams { get; set; }
         public DbSet<Team> Teams { get; set; }
-        public DbSet<Upvote> Upvotes { get; set; }
+        public DbSet<Vote> Votes { get; set; }
 
         protected override void OnModelCreating(ModelBuilder builder)
@@ -42,5 +42,5 @@
             builder.ApplyConfiguration(new TeacherTeamConfig(schema));
             builder.ApplyConfiguration(new TeamConfig(schema));
-            builder.ApplyConfiguration(new UpvoteConfig(schema));
+            builder.ApplyConfiguration(new VoteConfig(schema));
         }
     }
Index: src/FinkiChattery/FinkiChattery.Persistence/Helpers/Enums/VoteType.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Persistence/Helpers/Enums/VoteType.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Persistence/Helpers/Enums/VoteType.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,8 @@
+﻿namespace FinkiChattery.Persistence.Helpers
+{
+    public enum VoteType
+    {
+        Upvote,
+        Downvote
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Persistence/Models/Answer.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Persistence/Models/Answer.cs	(revision 1e0d86905c02abe14201bf07ad5a2163900a5602)
+++ src/FinkiChattery/FinkiChattery.Persistence/Models/Answer.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -6,4 +6,11 @@
     public class Answer : BaseEntity
     {
+        public Answer() : base()
+        {
+            CreatedOn = DateTime.UtcNow;
+            VotesCount = 0;
+            CorrectAnswer = false;
+        }
+
         public string Text { get; set; }
 
@@ -20,7 +27,7 @@
         public DateTime CreatedOn { get; set; }
 
-        public long UpvotesCount { get; set; }
+        public long VotesCount { get; set; }
 
-        public virtual ICollection<Upvote> Upvotes { get; set; }
+        public virtual ICollection<Vote> Votes { get; set; }
 
         public virtual ICollection<AnswerResponse> AnswerResponses { get; set; }
Index: src/FinkiChattery/FinkiChattery.Persistence/Models/Moderator.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Persistence/Models/Moderator.cs	(revision 1e0d86905c02abe14201bf07ad5a2163900a5602)
+++ src/FinkiChattery/FinkiChattery.Persistence/Models/Moderator.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -1,9 +1,3 @@
-﻿using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace FinkiChattery.Persistence.Models
+﻿namespace FinkiChattery.Persistence.Models
 {
     public class Moderator : BaseEntity
Index: src/FinkiChattery/FinkiChattery.Persistence/Models/Student.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Persistence/Models/Student.cs	(revision 1e0d86905c02abe14201bf07ad5a2163900a5602)
+++ src/FinkiChattery/FinkiChattery.Persistence/Models/Student.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -1,7 +1,3 @@
-﻿using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+﻿using System.Collections.Generic;
 
 namespace FinkiChattery.Persistence.Models
@@ -22,7 +18,7 @@
 
         public virtual ICollection<Question> Questions { get; set; }
-        
+
         public virtual ICollection<Answer> Answers { get; set; }
-        
+
         public virtual ICollection<StudentTeam> StudentTeams { get; set; }
     }
Index: c/FinkiChattery/FinkiChattery.Persistence/Models/Upvote.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Persistence/Models/Upvote.cs	(revision 1e0d86905c02abe14201bf07ad5a2163900a5602)
+++ 	(revision )
@@ -1,19 +1,0 @@
-﻿using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace FinkiChattery.Persistence.Models
-{
-    public class Upvote : BaseEntity
-    {
-        public long StudentFk { get; set; }
-
-        public virtual Student Student { get; set; }
-
-        public long AnswerFk { get; set; }
-
-        public virtual Answer Answer { get; set; }
-    }
-}
Index: src/FinkiChattery/FinkiChattery.Persistence/Models/Vote.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Persistence/Models/Vote.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Persistence/Models/Vote.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,21 @@
+﻿using FinkiChattery.Persistence.Helpers;
+
+namespace FinkiChattery.Persistence.Models
+{
+    public class Vote : BaseEntity
+    {
+        public Vote() : base()
+        {
+        }
+
+        public long StudentFk { get; set; }
+
+        public virtual Student Student { get; set; }
+
+        public long AnswerFk { get; set; }
+
+        public virtual Answer Answer { get; set; }
+
+        public VoteType VoteType { get; set; }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/IAnswerRepo.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/IAnswerRepo.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/IAnswerRepo.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,11 @@
+﻿using FinkiChattery.Persistence.Models;
+using System;
+using System.Threading.Tasks;
+
+namespace FinkiChattery.Persistence.Repositories
+{
+    public interface IAnswerRepo : IRepository<Answer>
+    {
+        Task<bool> AnswerInQuestionExists(Guid questionUid, Guid answerUid);
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/IModeratorRepo.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/IModeratorRepo.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/IModeratorRepo.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,11 @@
+﻿using FinkiChattery.Persistence.Models;
+using FinkiChattery.Persistence.Repositories.Contracts;
+using System.Threading.Tasks;
+
+namespace FinkiChattery.Persistence.Repositories
+{
+    public interface IModeratorRepo : IRepository<Moderator>
+    {
+        Task<ModeratorSelfDto> GetModeratorSelfDto(long applicationUserId);
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/IQuestionRepo.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/IQuestionRepo.cs	(revision 1e0d86905c02abe14201bf07ad5a2163900a5602)
+++ src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/IQuestionRepo.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -16,4 +16,8 @@
      
         Task<List<QuestionPreviewDto>> GetPreviewQuestionsPopular();
+
+        Task<bool> QuestionIsOwnedByStudent(Guid questionUid, long applicationUserId);
+
+        Task<Question> GetQuestionWithAnswersAndStudents(Guid questionUid);
     }
 }
Index: src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/IStudentRepo.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/IStudentRepo.cs	(revision 1e0d86905c02abe14201bf07ad5a2163900a5602)
+++ src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/IStudentRepo.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -1,3 +1,4 @@
 ﻿using FinkiChattery.Persistence.Models;
+using FinkiChattery.Persistence.Repositories.Contracts;
 using System.Threading.Tasks;
 
@@ -7,4 +8,5 @@
     {
         public Task<Student> GetStudent(long applicationUserFk);
+        public Task<StudentSelfDto> GetStudentSelfDto(long applicationUserFk);
     }
 }
Index: src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/ITeacherRepo.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/ITeacherRepo.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/ITeacherRepo.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,11 @@
+﻿using FinkiChattery.Persistence.Models;
+using FinkiChattery.Persistence.Repositories.Contracts;
+using System.Threading.Tasks;
+
+namespace FinkiChattery.Persistence.Repositories
+{
+    public interface ITeacherRepo : IRepository<Teacher>
+    {
+        Task<TeacherSelfDto> GetTeacherSelfDto(long applicationUserId);
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/IVoteRepo.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/IVoteRepo.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/IVoteRepo.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,13 @@
+﻿using FinkiChattery.Persistence.Models;
+using System;
+using System.Threading.Tasks;
+
+namespace FinkiChattery.Persistence.Repositories
+{
+    public interface IVoteRepo : IRepository<Vote>
+    {
+        Task<bool> StudentHasUpvotedAnswer(Guid answerUid, long userId);
+        Task<bool> StudentHasDownvotedAnswer(Guid answerUid, long userId);
+        Task<Vote> GetVoteForAnswerByStudent(Guid answerUid, long userId);
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/Moderator/ModeratorSelfDto.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/Moderator/ModeratorSelfDto.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/Moderator/ModeratorSelfDto.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,16 @@
+﻿using System;
+
+namespace FinkiChattery.Persistence.Repositories.Contracts
+{
+    public class ModeratorSelfDto
+    {
+        public ModeratorSelfDto(Guid uid, long applicationUserId)
+        {
+            Uid = uid;
+            ApplicationUserId = applicationUserId;
+        }
+
+        public Guid Uid { get; }
+        public long ApplicationUserId { get; }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/Question/QuestionStateDto.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/Question/QuestionStateDto.cs	(revision 1e0d86905c02abe14201bf07ad5a2163900a5602)
+++ src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/Question/QuestionStateDto.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -84,5 +84,5 @@
     public class AnswerQuestionStateDto
     {
-        public AnswerQuestionStateDto(long id, Guid uid, string text, bool correctAnswer, DateTime createdOn, long upvotesCount, AnswerStudentQuestionStateDto studentDto, IEnumerable<AnswerResponseQuestionStateDto> answerResponsesDto)
+        public AnswerQuestionStateDto(long id, Guid uid, string text, bool correctAnswer, DateTime createdOn, long votesCount, AnswerStudentQuestionStateDto studentDto, IEnumerable<AnswerResponseQuestionStateDto> answerResponsesDto)
         {
             Id = id;
@@ -91,5 +91,5 @@
             CorrectAnswer = correctAnswer;
             CreatedOn = createdOn;
-            UpvotesCount = upvotesCount;
+            VotesCount = votesCount;
             StudentDto = studentDto;
             AnswerResponsesDto = answerResponsesDto;
@@ -101,5 +101,5 @@
         public bool CorrectAnswer { get; }
         public DateTime CreatedOn { get; }
-        public long UpvotesCount { get; }
+        public long VotesCount { get; }
         public AnswerStudentQuestionStateDto StudentDto { get; }
         public IEnumerable<AnswerResponseQuestionStateDto> AnswerResponsesDto { get; }
Index: src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/Question/StudentQuestionDto.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/Question/StudentQuestionDto.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/Question/StudentQuestionDto.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,16 @@
+﻿using System;
+
+namespace FinkiChattery.Persistence.Repositories.Contracts
+{
+    public class StudentQuestionDto
+    {
+        public StudentQuestionDto(Guid questionUid, string title)
+        {
+            QuestionUid = questionUid;
+            Title = title;
+        }
+
+        public Guid QuestionUid { get; }
+        public string Title { get; }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/Student/StudentSelfDto.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/Student/StudentSelfDto.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/Student/StudentSelfDto.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,27 @@
+﻿using System;
+using System.Collections.Generic;
+
+namespace FinkiChattery.Persistence.Repositories.Contracts
+{
+    public class StudentSelfDto
+    {
+        public StudentSelfDto(Guid uid, long applicationUserId, string index, long reputation, string imageUrl, IEnumerable<StudentQuestionDto> questions, IEnumerable<StudentTeamDto> teams)
+        {
+            Uid = uid;
+            ApplicationUserId = applicationUserId;
+            Index = index;
+            Reputation = reputation;
+            ImageUrl = imageUrl;
+            Questions = questions;
+            Teams = teams;
+        }
+
+        public Guid Uid { get; }
+        public long ApplicationUserId { get; }
+        public string Index { get; }
+        public long Reputation { get; }
+        public string ImageUrl { get; }
+        public IEnumerable<StudentQuestionDto> Questions { get; }
+        public IEnumerable<StudentTeamDto> Teams { get; }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/Teacher/TeacherSelfDto.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/Teacher/TeacherSelfDto.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/Teacher/TeacherSelfDto.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,19 @@
+﻿using System;
+using System.Collections.Generic;
+
+namespace FinkiChattery.Persistence.Repositories.Contracts
+{
+    public class TeacherSelfDto
+    {
+        public TeacherSelfDto(Guid uid, long applicationUserId, IEnumerable<TeacherTeamDto> teams)
+        {
+            Uid = uid;
+            ApplicationUserId = applicationUserId;
+            Teams = teams;
+        }
+
+        public Guid Uid { get; }
+        public long ApplicationUserId { get; }
+        public IEnumerable<TeacherTeamDto> Teams { get; }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/Team/StudentTeamDto.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/Team/StudentTeamDto.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/Team/StudentTeamDto.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,16 @@
+﻿using System;
+
+namespace FinkiChattery.Persistence.Repositories.Contracts
+{
+    public class StudentTeamDto
+    {
+        public StudentTeamDto(Guid teamUid, string name)
+        {
+            TeamUid = teamUid;
+            Name = name;
+        }
+
+        public Guid TeamUid { get; }
+        public string Name { get; }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/Team/TeacherTeamDto.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/Team/TeacherTeamDto.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/Team/TeacherTeamDto.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,16 @@
+﻿using System;
+
+namespace FinkiChattery.Persistence.Repositories.Contracts
+{
+    public class TeacherTeamDto
+    {
+        public TeacherTeamDto(Guid teamUid, string name)
+        {
+            TeamUid = teamUid;
+            Name = name;
+        }
+
+        public Guid TeamUid { get; }
+        public string Name { get; }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Persistence/Repositories/Implementations/AnswerRepo.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Persistence/Repositories/Implementations/AnswerRepo.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Persistence/Repositories/Implementations/AnswerRepo.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,24 @@
+﻿using FinkiChattery.Persistence.Context;
+using FinkiChattery.Persistence.Models;
+using Microsoft.EntityFrameworkCore;
+using System;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace FinkiChattery.Persistence.Repositories
+{
+    public class AnswerRepo : Repository<Answer>, IAnswerRepo
+    {
+        public AnswerRepo(ApplicationDbContext dbContext) : base(dbContext)
+        {
+        }
+
+        public async Task<bool> AnswerInQuestionExists(Guid questionUid, Guid answerUid)
+        {
+            return await DbSet
+                .AsNoTracking()
+                .Where(x => x.Question.Uid == questionUid && x.Uid == answerUid)
+                .AnyAsync();
+        }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Persistence/Repositories/Implementations/ModeratorRepo.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Persistence/Repositories/Implementations/ModeratorRepo.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Persistence/Repositories/Implementations/ModeratorRepo.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,25 @@
+﻿using FinkiChattery.Persistence.Context;
+using FinkiChattery.Persistence.Models;
+using FinkiChattery.Persistence.Repositories.Contracts;
+using Microsoft.EntityFrameworkCore;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace FinkiChattery.Persistence.Repositories
+{
+    public class ModeratorRepo : Repository<Moderator>, IModeratorRepo
+    {
+        public ModeratorRepo(ApplicationDbContext dbContext) : base(dbContext)
+        {
+        }
+
+        public async Task<ModeratorSelfDto> GetModeratorSelfDto(long applicationUserId)
+        {
+            return await DbSet
+                .AsNoTracking()
+                .Where(x => x.ApplicationUserFk == applicationUserId)
+                .Select(x => new ModeratorSelfDto(x.Uid, x.ApplicationUserFk))
+                .FirstOrDefaultAsync();
+        }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Persistence/Repositories/Implementations/QuestionRepo.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Persistence/Repositories/Implementations/QuestionRepo.cs	(revision 1e0d86905c02abe14201bf07ad5a2163900a5602)
+++ src/FinkiChattery/FinkiChattery.Persistence/Repositories/Implementations/QuestionRepo.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -80,5 +80,5 @@
                                                     y.CorrectAnswer,
                                                     y.CreatedOn,
-                                                    y.UpvotesCount,
+                                                    y.VotesCount,
                                                     new AnswerStudentQuestionStateDto(
                                                         y.Student.Id,
@@ -144,4 +144,18 @@
                 .ToListAsync();
         }
+
+        public async Task<bool> QuestionIsOwnedByStudent(Guid questionUid, long applicationUserId)
+        {
+            return await DbSet
+                .Where(x => x.Uid == questionUid && x.Student.ApplicationUserFk == applicationUserId)
+                .AnyAsync();
+        }
+
+        public async Task<Question> GetQuestionWithAnswersAndStudents(Guid questionUid)
+        {
+            return await DbSet
+                .Include(x => x.Answers).ThenInclude(x => x.Student)
+                .FirstOrDefaultAsync(x => x.Uid == questionUid);
+        }
     }
 }
Index: src/FinkiChattery/FinkiChattery.Persistence/Repositories/Implementations/StudentRepo.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Persistence/Repositories/Implementations/StudentRepo.cs	(revision 1e0d86905c02abe14201bf07ad5a2163900a5602)
+++ src/FinkiChattery/FinkiChattery.Persistence/Repositories/Implementations/StudentRepo.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -1,5 +1,7 @@
 ﻿using FinkiChattery.Persistence.Context;
 using FinkiChattery.Persistence.Models;
+using FinkiChattery.Persistence.Repositories.Contracts;
 using Microsoft.EntityFrameworkCore;
+using System.Linq;
 using System.Threading.Tasks;
 
@@ -16,4 +18,21 @@
             return await DbSet.FirstOrDefaultAsync(x => x.ApplicationUserFk == applicationUserFk);
         }
+
+        public async Task<StudentSelfDto> GetStudentSelfDto(long applicationUserFk)
+        {
+            return await DbSet
+                .AsNoTracking()
+                .Include(x => x.Questions)
+                .Include(x => x.StudentTeams).ThenInclude(x => x.Team)
+                .Where(x => x.ApplicationUserFk == applicationUserFk)
+                .Select(x => new StudentSelfDto(x.Uid,
+                                                x.ApplicationUserFk,
+                                                x.IndexNumber,
+                                                x.Reputation,
+                                                x.ImageUrl,
+                                                x.Questions.Select(y => new StudentQuestionDto(y.Uid, y.Title)),
+                                                x.StudentTeams.Select(y => new StudentTeamDto(y.Team.Uid, y.Team.Name))))
+                .FirstOrDefaultAsync();
+        }
     }
 }
Index: src/FinkiChattery/FinkiChattery.Persistence/Repositories/Implementations/TeacherRepo.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Persistence/Repositories/Implementations/TeacherRepo.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Persistence/Repositories/Implementations/TeacherRepo.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,26 @@
+﻿using FinkiChattery.Persistence.Context;
+using FinkiChattery.Persistence.Models;
+using FinkiChattery.Persistence.Repositories.Contracts;
+using Microsoft.EntityFrameworkCore;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace FinkiChattery.Persistence.Repositories
+{
+    public class TeacherRepo : Repository<Teacher>, ITeacherRepo
+    {
+        public TeacherRepo(ApplicationDbContext dbContext) : base(dbContext)
+        {
+        }
+
+        public async Task<TeacherSelfDto> GetTeacherSelfDto(long applicationUserId)
+        {
+            return await DbSet
+                .AsNoTracking()
+                .Include(x => x.TeacherTeams).ThenInclude(x => x.Team)
+                .Where(x => x.ApplicationUserFk == applicationUserId)
+                .Select(x => new TeacherSelfDto(x.Uid, x.ApplicationUserFk, x.TeacherTeams.Select(y => new TeacherTeamDto(y.Team.Uid, y.Team.Name))))
+                .FirstOrDefaultAsync();
+        }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Persistence/Repositories/Implementations/VoteRepo.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Persistence/Repositories/Implementations/VoteRepo.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Persistence/Repositories/Implementations/VoteRepo.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,40 @@
+﻿using FinkiChattery.Persistence.Context;
+using FinkiChattery.Persistence.Helpers;
+using FinkiChattery.Persistence.Models;
+using Microsoft.EntityFrameworkCore;
+using System;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace FinkiChattery.Persistence.Repositories
+{
+    public class VoteRepo : Repository<Vote>, IVoteRepo
+    {
+        public VoteRepo(ApplicationDbContext dbContext) : base(dbContext)
+        {
+        }
+
+        public async Task<Vote> GetVoteForAnswerByStudent(Guid answerUid, long userId)
+        {
+            return await DbSet
+                .Where(x => x.Answer.Uid == answerUid &&  x.Student.ApplicationUserFk == userId)
+                .FirstOrDefaultAsync();
+        }
+
+        public async Task<bool> StudentHasDownvotedAnswer(Guid answerUid, long userId)
+        {
+            return await DbSet
+                .AsNoTracking()
+                .Where(x => x.Answer.Uid == answerUid && x.VoteType == VoteType.Downvote && x.Student.ApplicationUserFk == userId)
+                .AnyAsync();
+        }
+
+        public async Task<bool> StudentHasUpvotedAnswer(Guid answerUid, long userId)
+        {
+            return await DbSet
+                .AsNoTracking()
+                .Where(x => x.Answer.Uid == answerUid && x.VoteType == VoteType.Upvote && x.Student.ApplicationUserFk == userId)
+                .AnyAsync();
+        }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Persistence/UnitOfWork/Contracts/IUnitOfWork.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Persistence/UnitOfWork/Contracts/IUnitOfWork.cs	(revision 1e0d86905c02abe14201bf07ad5a2163900a5602)
+++ src/FinkiChattery/FinkiChattery.Persistence/UnitOfWork/Contracts/IUnitOfWork.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -11,4 +11,8 @@
         IStudentRepo Students { get; }
         ITeamRepo Teams { get; }
+        IVoteRepo Votes { get; }
+        IAnswerRepo Answers { get; }
+        ITeacherRepo Teachers { get; }
+        IModeratorRepo Moderators { get; }
         Task<int> SaveAsync();
     }
Index: src/FinkiChattery/FinkiChattery.Persistence/UnitOfWork/Implementations/UnitOfWork.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Persistence/UnitOfWork/Implementations/UnitOfWork.cs	(revision 1e0d86905c02abe14201bf07ad5a2163900a5602)
+++ src/FinkiChattery/FinkiChattery.Persistence/UnitOfWork/Implementations/UnitOfWork.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -12,8 +12,38 @@
         private StudentRepo _students;
         private TeamRepo _teams;
+        private VoteRepo _votes;
+        private AnswerRepo _answers;
+        private ModeratorRepo _moderators;
+        private TeacherRepo _teachers;
 
         public UnitOfWork(ApplicationDbContext dbContext)
         {
             DbContext = dbContext;
+        }
+
+        public IModeratorRepo Moderators
+        {
+            get
+            {
+                if (_moderators == null)
+                {
+                    _moderators = new ModeratorRepo(DbContext);
+                }
+
+                return _moderators;
+            }
+        }
+
+        public ITeacherRepo Teachers
+        {
+            get
+            {
+                if (_teachers == null)
+                {
+                    _teachers = new TeacherRepo(DbContext);
+                }
+
+                return _teachers;
+            }
         }
 
@@ -70,4 +100,30 @@
         }
 
+        public IVoteRepo Votes
+        {
+            get
+            {
+                if (_votes == null)
+                {
+                    _votes = new VoteRepo(DbContext);
+                }
+
+                return _votes;
+            }
+        }
+
+        public IAnswerRepo Answers
+        {
+            get
+            {
+                if (_answers == null)
+                {
+                    _answers = new AnswerRepo(DbContext);
+                }
+
+                return _answers;
+            }
+        }
+
         public ApplicationDbContext DbContext { get; }
 
Index: src/FinkiChattery/FinkiChattery.Queries/User/GetSelfUser/GetSelfUserQuery.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Queries/User/GetSelfUser/GetSelfUserQuery.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Queries/User/GetSelfUser/GetSelfUserQuery.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,46 @@
+﻿using FinkiChattery.Common.Mediator.Contracs;
+using FinkiChattery.Common.User;
+using FinkiChattery.Persistence.UnitOfWork;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace FinkiChattery.Queries.User
+{
+    public class GetSelfUserQuery : IQuery<SelfUserDto>
+    {
+        public GetSelfUserQuery()
+        {
+        }
+    }
+
+    public class GetSelfUserQueryHandler : IQueryHandler<GetSelfUserQuery, SelfUserDto>
+    {
+        public GetSelfUserQueryHandler(IUnitOfWork unitOfWork, ICurrentUser currentUser)
+        {
+            UnitOfWork = unitOfWork;
+            CurrentUser = currentUser;
+        }
+
+        public IUnitOfWork UnitOfWork { get; }
+        public ICurrentUser CurrentUser { get; }
+
+        public async Task<SelfUserDto> Handle(GetSelfUserQuery request, CancellationToken cancellationToken)
+        {
+            switch (CurrentUser.Role)
+            {
+                case UserRole.Student:
+                    var student = await UnitOfWork.Students.GetStudentSelfDto(CurrentUser.Id);
+                    return new SelfUserDto(student);
+                case UserRole.Teacher:
+                    var teacher = await UnitOfWork.Teachers.GetTeacherSelfDto(CurrentUser.Id);
+                    return new SelfUserDto(null, teacher);
+                case UserRole.Moderator:
+                    var moderator = await UnitOfWork.Moderators.GetModeratorSelfDto(CurrentUser.Id);
+                    return new SelfUserDto(null, null, moderator);
+                case UserRole.Guest:
+                default:
+                    return null;
+            }
+        }
+    }
+}
Index: src/FinkiChattery/FinkiChattery.Queries/User/GetSelfUser/SelfUserDto.cs
===================================================================
--- src/FinkiChattery/FinkiChattery.Queries/User/GetSelfUser/SelfUserDto.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
+++ src/FinkiChattery/FinkiChattery.Queries/User/GetSelfUser/SelfUserDto.cs	(revision 6901f8b9e6373705c4ebfc4799374f1e79f6d3e5)
@@ -0,0 +1,20 @@
+﻿#nullable enable
+
+using FinkiChattery.Persistence.Repositories.Contracts;
+
+namespace FinkiChattery.Queries.User
+{
+    public class SelfUserDto
+    {
+        public SelfUserDto(StudentSelfDto? studentSelf = null, TeacherSelfDto? teacherSelf = null, ModeratorSelfDto? moderatorSelf = null)
+        {
+            StudentSelf = studentSelf;
+            TeacherSelf = teacherSelf;
+            ModeratorSelf = moderatorSelf;
+        }
+
+        public StudentSelfDto? StudentSelf { get; }
+        public TeacherSelfDto? TeacherSelf { get; }
+        public ModeratorSelfDto? ModeratorSelf { get; }
+    }
+}
