Changeset dd731cd


Ignore:
Timestamp:
10/21/21 20:19:15 (3 years ago)
Author:
Стојков Марко <mst@…>
Branches:
dev
Children:
3bb1377
Parents:
b499ba7 (diff), 45cf412 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merged dev

Location:
src
Files:
62 added
1 deleted
44 edited
4 moved

Legend:

Unmodified
Added
Removed
  • src/Clients/Angular/finki-chattery/src/app/app-routing.module.ts

    rb499ba7 rdd731cd  
    11import { NgModule } from '@angular/core';
    22import { Routes, RouterModule } from '@angular/router';
     3import { AuthorizedGuard } from './core/guards/authorized.guard';
    34
    45const routes: Routes = [
    56  {
     7    path: 'questioning',
     8    canActivate: [AuthorizedGuard],
     9    loadChildren: () => import('./modules/questioning/questioning.module').then((x) => x.QuestioningModule)
     10  },
     11  {
    612    path: '**',
    7     redirectTo: 'public/home'
     13    redirectTo: 'questioning/preview'
    814  }
    915];
  • src/Clients/Angular/finki-chattery/src/app/app.component.html

    rb499ba7 rdd731cd  
    22  <mat-progress-bar class="global-loader" [class.hidden]="!(loader.isLoading | async)" mode="indeterminate"></mat-progress-bar>
    33  <router-outlet></router-outlet>
    4   <button (click)="login()">LOGIN</button>
    54</main>
  • src/Clients/Angular/finki-chattery/src/app/app.component.ts

    rb499ba7 rdd731cd  
    11import { Component, OnInit } from '@angular/core';
    2 import { AuthService, LoaderService, RedirectService } from './core/services';
     2import { LoaderService, RedirectService } from './core/services';
    33
    44@Component({
     
    88})
    99export class AppComponent implements OnInit {
    10   constructor(public loader: LoaderService, private redirect: RedirectService, private auth: AuthService) {}
     10  constructor(public loader: LoaderService, private redirect: RedirectService) {}
    1111
    1212  ngOnInit(): void {
    1313    this.redirect.redirectLoggedInUser();
    1414  }
    15 
    16   public login(): void {
    17     this.auth.login();
    18   }
    1915}
  • src/Clients/Angular/finki-chattery/src/app/core/core.module.ts

    rb499ba7 rdd731cd  
    1414import { reducers } from './state';
    1515import { TokenInterceptor } from './interceptors/token.interceptor';
     16import { EffectsModule } from '@ngrx/effects';
     17import { QuestionEffects } from './state/question-state/question.effects';
     18import { CategoriesEffects } from './state/category-state/category.effects';
    1619
    1720@NgModule({
     
    3336      maxAge: 25,
    3437      logOnly: !environment.production
    35     })
     38    }),
     39    EffectsModule.forRoot([QuestionEffects, CategoriesEffects])
    3640  ],
    3741  exports: [HttpClientModule, COMPONENTS]
  • src/Clients/Angular/finki-chattery/src/app/core/services/auth.service.ts

    rb499ba7 rdd731cd  
    3535      map((user) => {
    3636        if (user) {
     37          if (user.expired) {
     38            return false;
     39          }
     40
    3741          return true;
    3842        }
  • src/Clients/Angular/finki-chattery/src/app/core/services/notification.service.ts

    rb499ba7 rdd731cd  
    2222
    2323  public successNotification(title: string, description?: string): void {
    24     this.toastr.success(this.translate.instant(description), this.translate.instant(title));
     24    if (description) {
     25      this.toastr.success(this.translate.instant(description), this.translate.instant(title));
     26    }
     27    this.toastr.success(this.translate.instant(title));
    2528  }
    2629}
  • src/Clients/Angular/finki-chattery/src/app/core/state/index.ts

    rb499ba7 rdd731cd  
    11import { ActionReducerMap } from '@ngrx/store';
     2import { QuestionState } from './question-state/question.state';
     3import { reducer as questionReducer } from './question-state/question.reducers';
     4import { CategoryState } from './category-state/category.state';
     5import { reducer as categoryReducer } from './category-state/category.reducers';
    26
    3 export interface State {}
     7export interface State {
     8  question: QuestionState;
     9  category: CategoryState;
     10}
    411
    5 export const reducers: ActionReducerMap<State, any> = {};
     12export const reducers: ActionReducerMap<State, any> = {
     13  question: questionReducer,
     14  category: categoryReducer
     15};
  • src/Clients/Angular/finki-chattery/src/app/shared-app/directives/directives.ts

    rb499ba7 rdd731cd  
    1 import { HandleInputFormErrorsDirective, HoverElevationDirective, LoaderDirective, HandleSelectFormErrorsDirective } from '.';
     1import {
     2  HandleInputFormErrorsDirective,
     3  HoverElevationDirective,
     4  LoaderDirective,
     5  HandleSelectFormErrorsDirective,
     6  ShareLinkDirective
     7} from '.';
    28
    39export const DIRECTIVES: any[] = [
     
    511  LoaderDirective,
    612  HoverElevationDirective,
    7   HandleSelectFormErrorsDirective
     13  HandleSelectFormErrorsDirective,
     14  ShareLinkDirective
    815];
  • src/Clients/Angular/finki-chattery/src/app/shared-app/directives/index.ts

    rb499ba7 rdd731cd  
    33export * from './hover-elevation.directive';
    44export * from './handle-select-form-errors.directive';
     5export * from './share-link.directive';
  • src/Clients/Angular/finki-chattery/src/app/shared-app/models/index.ts

    rb499ba7 rdd731cd  
    11export * from './error.models';
    22export * from './user.models';
     3export * from './question-state-view-models.models';
     4export * from './category-state-view-models.models';
  • src/Clients/Angular/finki-chattery/src/app/shared-app/services/translate-from-json.service.ts

    rb499ba7 rdd731cd  
    4343  }
    4444
    45   public instant(key?: string): string | undefined {
    46     if (key) {
    47       return this.translateService.instant(key);
    48     }
    49     return undefined;
     45  public instant(key: string): string {
     46    return this.translateService.instant(key);
    5047  }
    5148}
  • src/Clients/Angular/finki-chattery/src/app/shared-app/shared-app.module.ts

    rb499ba7 rdd731cd  
    88import { FileUploadModule } from 'ng2-file-upload';
    99
    10 import { COMPONENTS } from './components/generic/components';
     10import { COMPONENTS } from './components/components';
    1111import { SharedMaterialModule } from '../shared-material/shared-material.module';
    1212import { DIRECTIVES } from './directives/directives';
    1313import { SERVICES } from './services/services';
    1414import { PIPES } from './pipes/pipes';
    15 import { FileUploadComponent } from './components/generic/file-upload/file-upload.component';
    16 import { HandleSelectFormErrorsDirective } from './directives/handle-select-form-errors.directive';
    1715
    1816@NgModule({
    19   declarations: [COMPONENTS, DIRECTIVES, PIPES, FileUploadComponent, HandleSelectFormErrorsDirective],
     17  declarations: [COMPONENTS, DIRECTIVES, PIPES],
    2018  providers: [SERVICES],
    2119  imports: [
     
    3937    COMPONENTS,
    4038    DIRECTIVES,
    41     PIPES
     39    PIPES,
     40    SharedMaterialModule
    4241  ]
    4342})
  • src/Clients/Angular/finki-chattery/src/app/shared-material/shared-material.module.ts

    rb499ba7 rdd731cd  
    2020import { MatDatepickerModule } from '@angular/material/datepicker';
    2121import { MatNativeDateModule } from '@angular/material/core';
     22import { MatChipsModule } from '@angular/material/chips';
     23import { MatTooltipModule } from '@angular/material/tooltip';
     24import { MatButtonToggleModule } from '@angular/material/button-toggle';
     25
    2226@NgModule({
    2327  imports: [
     
    4044    MatTableModule,
    4145    MatDatepickerModule,
    42     MatNativeDateModule
     46    MatNativeDateModule,
     47    MatChipsModule,
     48    MatTooltipModule,
     49    MatButtonToggleModule
    4350  ],
    4451  exports: [
     
    6067    MatTableModule,
    6168    MatDatepickerModule,
    62     MatNativeDateModule
     69    MatNativeDateModule,
     70    MatChipsModule,
     71    MatTooltipModule,
     72    MatButtonToggleModule
    6373  ]
    6474})
  • src/Clients/Angular/finki-chattery/src/assets/translations/en.json

    rb499ba7 rdd731cd  
    1414  "password-not-match": "Passwords don't match",
    1515  "code-date-passed": "The code date has passed",
    16   "not-found": "Not found"
     16  "not-found": "Not found",
     17  "question-preview-subtitle": "Asked <b>{{createdOn}}</b>, Last active <b>{{lastActive}}</b>, Viewed <b>{{views}}</b> times",
     18  "share-link": "Share",
     19  "share-link-success": "Successfully copied link for sharing",
     20  "question-asked-by-subtitle": "Asked on: {{date}}",
     21  "question-answers": "{{answerCount}} Answers",
     22  "question-answered-by-subtitle": "Answered on: {{date}}",
     23  "student-reputation": "{{reputation}} reputation",
     24  "vote-correct-answer": "This has been accepted as the correct answer by the owner of the question",
     25  "answer-sort-oldest": "Oldest",
     26  "answer-sort-votes": "Votes",
     27  "internet-techologies": "Internet technologies",
     28  "software-engineering": "Software engineering",
     29  "visual-programming": "Visual programming",
     30  "operating-systems": "Operating systems"
    1731}
  • src/Clients/Angular/finki-chattery/src/styles.scss

    rb499ba7 rdd731cd  
    264264
    265265.avatar-image {
    266   width: 100px;
    267   height: 100px;
     266  width: 80px;
     267  height: 80px;
    268268  display: block;
    269269  border-radius: 50%;
  • src/FinkiChattery/FinkiChattery.Api/Controllers/v1/QuestionsController.cs

    rb499ba7 rdd731cd  
    11using FinkiChattery.Api.ApplicationServices.Authentication;
     2using FinkiChattery.Api.ApplicationServices.Questioning;
    23using FinkiChattery.Commands.Questioning;
    34using FinkiChattery.Common.Mediator.Interfaces;
    45using FinkiChattery.Contracts.Questioning;
     6using FinkiChattery.Queries.Questioning;
    57using IdentityServer4.AccessTokenValidation;
    68using Microsoft.AspNetCore.Authorization;
    79using Microsoft.AspNetCore.Mvc;
     10using System;
    811using System.Threading.Tasks;
    912
     
    2932            return Ok();
    3033        }
     34
     35        [HttpGet("{questionUid:Guid}")]
     36        [Authorize]
     37        public async Task<IActionResult> GetQuestionState([FromRoute]Guid questionUid)
     38        {
     39            var questionDto = await MediatorService.SendQueryAsync(new GetQuestionStateQuery(questionUid));
     40            return Ok(questionDto.ToQuestionStateResponse());
     41        }
    3142    }
    3243}
  • src/FinkiChattery/FinkiChattery.Api/FinkiChattery.Api.csproj

    rb499ba7 rdd731cd  
    2626    <ProjectReference Include="..\FinkiChattery.Contracts\FinkiChattery.Contracts.csproj" />
    2727    <ProjectReference Include="..\FinkiChattery.Persistence\FinkiChattery.Persistence.csproj" />
     28    <ProjectReference Include="..\FinkiChattery.Queries\FinkiChattery.Queries.csproj" />
    2829  </ItemGroup>
    2930
  • src/FinkiChattery/FinkiChattery.Api/Services/RegisterServices.cs

    rb499ba7 rdd731cd  
    99using FinkiChattery.Persistence.Models;
    1010using FinkiChattery.Persistence.Repositories;
     11using FinkiChattery.Persistence.UnitOfWork;
     12using FinkiChattery.Queries.Questioning;
    1113using Hangfire;
    1214using Hangfire.SqlServer;
     
    2931            services.AddScoped<IEventService, EventService>();
    3032            services.AddTransient(typeof(IPipelineBehavior<,>), typeof(ValidationBehavior<,>));
    31             services.AddMediatR(typeof(AskQuestionCommand));
     33            services.AddMediatR(typeof(AskQuestionCommand), typeof(GetQuestionStateQuery));
    3234        }
    3335
     
    100102        }
    101103
    102         public static void AddRepos(this IServiceCollection services)
     104        public static void AddUnitOfWork(this IServiceCollection services)
    103105        {
    104             services.AddScoped<ICategoriesRepo, CategoriesRepo>();
    105             services.AddScoped<ITeamRepo, TeamRepo>();
    106             services.AddScoped<IQuestionRepo, QuestionRepo>();
    107             services.AddScoped<IStudentRepo, StudentRepo>();
     106            services.AddScoped<IUnitOfWork, UnitOfWork>();
    108107        }
    109108
     
    143142                        services.AddScoped<IStorageService, AwsStorageService>();*/
    144143        }
    145 
    146         // TODO: ADD HANGFIRE AND SCAFOLD DB IN HANGFIREDB
    147144    }
    148145
  • src/FinkiChattery/FinkiChattery.Api/Startup.cs

    rb499ba7 rdd731cd  
    3535            services.AddOriginUrlSettings();
    3636            services.AddCurrentUser();
    37             services.AddRepos();
     37            services.AddUnitOfWork();
    3838            services.AddAwsClient(Configuration);
    3939            services.AddHangfireService(Configuration);
  • src/FinkiChattery/FinkiChattery.Commands/Questioning/AskQuestion/AskQuestionCommand.cs

    rb499ba7 rdd731cd  
    11using FinkiChattery.Common.Mediator.Contracs;
    22using FinkiChattery.Common.User;
    3 using FinkiChattery.Persistence.Context;
    43using FinkiChattery.Persistence.Models;
    5 using FinkiChattery.Persistence.Repositories;
     4using FinkiChattery.Persistence.UnitOfWork;
    65using System;
    76using System.Collections.Generic;
     
    2726    public class AskQuestionHandler : ICommandHandler<AskQuestionCommand, Guid>
    2827    {
    29         public AskQuestionHandler(ApplicationDbContext dbContext, ICategoriesRepo categoriesRepo, IStudentRepo studentRepo, ICurrentUser currentUser)
     28        public AskQuestionHandler(IUnitOfWork unitOfWork, ICurrentUser currentUser)
    3029        {
    31             DbContext = dbContext;
    32             CategoriesRepo = categoriesRepo;
    33             StudentRepo = studentRepo;
     30            UnitOfWork = unitOfWork;
    3431            CurrentUser = currentUser;
    3532        }
    3633
    37         public ApplicationDbContext DbContext { get; }
    38         public ICategoriesRepo CategoriesRepo { get; }
    39         public IStudentRepo StudentRepo { get; }
     34        public IUnitOfWork UnitOfWork { get; }
    4035        public ICurrentUser CurrentUser { get; }
    4136
    4237        public async Task<Guid> Handle(AskQuestionCommand request, CancellationToken cancellationToken)
    4338        {
    44             var questionCategories = await CategoriesRepo.GetCategories(request.Categories);
    45             var currentStudent = await StudentRepo.GetStudent(CurrentUser.Id);
     39            var questionCategories = await UnitOfWork.Categories.GetCategories(request.Categories);
     40            var currentStudent = await UnitOfWork.Students.GetStudent(CurrentUser.Id);
    4641
    4742            var questionDatabaseEntity = new Question()
     
    6055            }
    6156
    62             DbContext.Questions.Add(questionDatabaseEntity);
    63             await DbContext.SaveChangesAsync();
     57            UnitOfWork.Questions.Add(questionDatabaseEntity);
     58            await UnitOfWork.SaveAsync();
    6459            return questionDatabaseEntity.Uid;
    6560        }
  • src/FinkiChattery/FinkiChattery.Commands/Questioning/AskQuestion/AskQuestionValidator.cs

    rb499ba7 rdd731cd  
    11using FinkiChattery.Commands.Questioning.Validators;
    2 using FinkiChattery.Persistence.Repositories;
     2using FinkiChattery.Persistence.UnitOfWork;
    33using FluentValidation;
    44
     
    77    public class AskQuestionValidator : AbstractValidator<AskQuestionCommand>
    88    {
    9         public AskQuestionValidator(ICategoriesRepo categoriesRepo)
     9        public AskQuestionValidator(IUnitOfWork unitOfWork)
    1010        {
    1111            RuleFor(x => x.Title).QuestionTitleValidate();
    1212            RuleFor(x => x.Text).QuestionTextValidate();
    13             RuleFor(x => x.Categories).Cascade(CascadeMode.Stop).ListNotNull().SetValidator(new CategoriesUidsExist(categoriesRepo));
     13            RuleFor(x => x.Categories).Cascade(CascadeMode.Stop).ListNotNull().SetValidator(new CategoriesUidsExist(unitOfWork));
    1414        }
    1515    }
  • src/FinkiChattery/FinkiChattery.Commands/Questioning/Validators/CategoriesUidsExist.cs

    rb499ba7 rdd731cd  
    11using FinkiChattery.Persistence.Repositories;
     2using FinkiChattery.Persistence.UnitOfWork;
    23using FluentValidation.Validators;
    34using System;
     
    1011    public class CategoriesUidsExist : AsyncValidatorBase
    1112    {
    12         public CategoriesUidsExist(ICategoriesRepo categoriesRepo)
     13        public CategoriesUidsExist(IUnitOfWork unitOfWork)
    1314        {
    14             CategoriesRepo = categoriesRepo;
     15            UnitOfWork = unitOfWork;
    1516        }
    1617
    17         public ICategoriesRepo CategoriesRepo { get; }
     18        public IUnitOfWork UnitOfWork { get; }
    1819
    1920        protected override async Task<bool> IsValidAsync(PropertyValidatorContext context, CancellationToken cancellation)
     
    2122            var categoriesUids = (IEnumerable<Guid>)context.PropertyValue;
    2223
    23             return await CategoriesRepo.CategoriesExist(categoriesUids);
     24            return await UnitOfWork.Categories.CategoriesExist(categoriesUids);
    2425        }
    2526
  • src/FinkiChattery/FinkiChattery.Commands/Questioning/Validators/TeamWithUidExist.cs

    rb499ba7 rdd731cd  
    1 using FinkiChattery.Persistence.Repositories;
     1using FinkiChattery.Persistence.UnitOfWork;
    22using FluentValidation.Validators;
    33using System;
     
    99    public class TeamWithUidExist : AsyncValidatorBase
    1010    {
    11         public TeamWithUidExist(ITeamRepo teamRepo)
     11        public TeamWithUidExist(IUnitOfWork unitOfWork)
    1212        {
    13             TeamRepo = teamRepo;
     13            UnitOfWork = unitOfWork;
    1414        }
    1515
    16         public ITeamRepo TeamRepo { get; }
     16        public IUnitOfWork UnitOfWork { get; }
    1717
    1818        protected override async Task<bool> IsValidAsync(PropertyValidatorContext context, CancellationToken cancellation)
    1919        {
    2020            var teamUid = (Guid)context.PropertyValue;
    21             return await TeamRepo.TeamWithUidExists(teamUid);       
     21            return await UnitOfWork.Teams.TeamWithUidExists(teamUid);
    2222        }
    2323
  • src/FinkiChattery/FinkiChattery.Common/Mediator/Interfaces/IMediatorService.cs

    rb499ba7 rdd731cd  
    1111        Task<TResponse> SendAsync<TResponse>(ICommand<TResponse> request);
    1212
     13        Task<TResponse> SendQueryAsync<TResponse>(IQuery<TResponse> request, CancellationToken cancellationToken);
     14
     15        Task<TResponse> SendQueryAsync<TResponse>(IQuery<TResponse> request);
     16
    1317        Task PublishAsync<TNotification>(TNotification notification) where TNotification : IEvent;
    1418
  • src/FinkiChattery/FinkiChattery.Common/Mediator/MediatorService.cs

    rb499ba7 rdd731cd  
    3737            await mediator.Publish(notification, default);
    3838        }
     39
     40        public async Task<TResponse> SendQueryAsync<TResponse>(IQuery<TResponse> request, CancellationToken cancellationToken)
     41        {
     42            return await mediator.Send(request, cancellationToken);
     43        }
     44
     45        public async Task<TResponse> SendQueryAsync<TResponse>(IQuery<TResponse> request)
     46        {
     47            return await mediator.Send(request);
     48        }
    3949    }
    4050}
  • src/FinkiChattery/FinkiChattery.Database/FinkiChattery.Database.sqlproj

    rb499ba7 rdd731cd  
    7070    <Folder Include="dbo\Tables\Student" />
    7171    <Folder Include="FullTextSearch" />
     72    <Folder Include="dbo\Tables\Answer" />
     73    <Folder Include="dbo\Tables\AnswerResponse" />
     74    <Folder Include="dbo\Tables\Question" />
     75    <Folder Include="dbo\Tables\QuestionCategory" />
     76    <Folder Include="Snapshots" />
    7277  </ItemGroup>
    7378  <ItemGroup>
    7479    <Build Include="dbo\Tables\Moderator.sql" />
    7580    <Build Include="dbo\Tables\Teacher.sql" />
    76     <Build Include="dbo\Tables\Question.sql" />
    7781    <Build Include="dbo\Tables\StudentTeam.sql" />
    7882    <Build Include="dbo\Tables\TeacherTeam.sql" />
    79     <Build Include="dbo\Tables\Answer.sql" />
    80     <Build Include="dbo\Tables\QuestionCategory.sql" />
    81     <Build Include="dbo\Tables\AnswerResponse.sql" />
    8283    <Build Include="dbo\Tables\Upvote.sql" />
    8384    <Build Include="dbo\Tables\User\AspNetRoleClaims.sql" />
     
    9192    <Build Include="FullTextSearch\FullTextIndexQuestion.sql" />
    9293    <Build Include="FullTextSearch\QuestionFullTextCatalog.sql" />
     94    <Build Include="dbo\Tables\Question\Question.sql" />
     95    <None Include="dbo\Tables\Question\Question.Debug.Seed.sql" />
     96    <Build Include="dbo\Tables\Answer\Answer.sql" />
     97    <None Include="dbo\Tables\Answer\Answer.Debug.Seed.sql" />
     98    <Build Include="dbo\Tables\AnswerResponse\AnswerResponse.sql" />
     99    <None Include="dbo\Tables\AnswerResponse\AnswerResponse.Debug.Seed.sql" />
     100    <Build Include="dbo\Tables\QuestionCategory\QuestionCategory.sql" />
     101    <None Include="dbo\Tables\QuestionCategory\QuestionCategory.Debug.Seed.sql" />
    93102  </ItemGroup>
    94103  <ItemGroup>
     
    97106    <PreDeploy Include="dbo\Scripts\Script.PreDeployment.sql" />
    98107    <None Include="FinkiChattery.Database.publish.xml" />
     108    <None Include="Snapshots\FinkiChattery.Database_20210922_17-47-58.dacpac" />
    99109  </ItemGroup>
    100110  <ItemGroup>
     
    120130    </SqlCmdVariable>
    121131  </ItemGroup>
     132  <ItemGroup>
     133    <RefactorLog Include="FinkiChattery.Database.refactorlog" />
     134  </ItemGroup>
    122135</Project>
  • src/FinkiChattery/FinkiChattery.Database/FullTextSearch/FullTextIndexQuestion.sql

    rb499ba7 rdd731cd  
    1 CREATE FULLTEXT INDEX ON [dbo].[Question] ([Title], [Text])
     1CREATE FULLTEXT INDEX ON [dbo].[Question] ([Search])
    22KEY INDEX [PK_Question] ON [QuestionFullTextCatalog]
    3 WITH (CHANGE_TRACKING AUTO, STOPLIST OFF)
     3WITH (CHANGE_TRACKING AUTO)
  • src/FinkiChattery/FinkiChattery.Database/dbo/Scripts/PostDeploymentScripts/Debug.PostDeployment.sql

    rb499ba7 rdd731cd  
    1 :r .\..\..\Tables\User\Seed\Users.Debug.Seed.sql
    2 :r .\..\..\Tables\Category\Category.Seed.sql
    3 :r .\..\..\Tables\Student\Student.Debug.Seed.sql
     1:r ./../../Tables/User/Seed/Users.Debug.Seed.sql
     2:r ./../../Tables/Category/Category.Seed.sql
     3:r ./../../Tables/Student/Student.Debug.Seed.sql
     4:r ./../../Tables/Question/Question.Debug.Seed.sql
     5:r ./../../Tables/Answer/Answer.Debug.Seed.sql
     6:r ./../../Tables/AnswerResponse/AnswerResponse.Debug.Seed.sql
     7:r ./../../Tables/QuestionCategory/QuestionCategory.Debug.Seed.sql
  • src/FinkiChattery/FinkiChattery.Database/dbo/Scripts/PostDeploymentScripts/Production.PostDeployment.sql

    rb499ba7 rdd731cd  
    1 :r .\..\..\Tables\Category\Category.Seed.sql
     1:r ./../../Tables/Category/Category.Seed.sql
  • src/FinkiChattery/FinkiChattery.Database/dbo/Scripts/Script.PostDeployment.sql

    rb499ba7 rdd731cd  
    44                PRINT 'Deploying DEBUG scripts';
    55        END
    6         :r .\PostDeploymentScripts\Debug.PostDeployment.sql
     6        :r ./PostDeploymentScripts/Debug.PostDeployment.sql
    77        BEGIN --Run scripts
    88                PRINT 'End deploying DEBUG scripts';
     
    1515                PRINT 'Deploying PRODUCTION scripts'
    1616        END
    17                 :r .\PostDeploymentScripts\Production.PostDeployment.sql
     17                :r ./PostDeploymentScripts/Production.PostDeployment.sql
    1818                BEGIN --Run scripts
    1919                PRINT 'End deploying PRODUCTION scripts'
  • src/FinkiChattery/FinkiChattery.Database/dbo/Scripts/Script.PreDeployment.sql

    rb499ba7 rdd731cd  
    44                PRINT 'Deploying DEBUG pre deployment scripts';
    55        END
    6         :r .\PreDeploymentScripts\Debug.PreDeployment.sql
     6        :r ./PreDeploymentScripts/Debug.PreDeployment.sql
    77        BEGIN --Run scripts
    88                PRINT 'End deploying DEBUG pre deployment scripts';
     
    1515                PRINT 'Deploying PRODUCTION pre deployment scripts'
    1616        END
    17         :r .\PreDeploymentScripts\Production.PreDeployment.sql
     17        :r ./PreDeploymentScripts/Production.PreDeployment.sql
    1818        BEGIN --Run scripts
    1919                PRINT 'End deploying PRODUCTION pre deployment scripts'
  • src/FinkiChattery/FinkiChattery.Database/dbo/Tables/Answer/Answer.sql

    rb499ba7 rdd731cd  
    77    [CorrectAnswer] BIT              NOT NULL,
    88    [CreatedOn]     SMALLDATETIME    NOT NULL,
     9    [UpvotesCount] BIGINT NOT NULL DEFAULT 0,
    910    CONSTRAINT [PK_Answer] PRIMARY KEY CLUSTERED ([Id] ASC),
    1011    CONSTRAINT [FK_Answer_Question_QuestionFk] FOREIGN KEY ([QuestionFk]) REFERENCES [dbo].[Question] ([Id]),
  • src/FinkiChattery/FinkiChattery.Database/dbo/Tables/AnswerResponse/AnswerResponse.sql

    rb499ba7 rdd731cd  
    88    CONSTRAINT [PK_AnswerResponse] PRIMARY KEY CLUSTERED ([Id] ASC),
    99    CONSTRAINT [FK_AnswerResponse_Answer_AnswerFk] FOREIGN KEY ([AnswerFk]) REFERENCES [dbo].[Answer] ([Id]),
    10     CONSTRAINT [FK_AnswerResponse_Student_AnswerFk] FOREIGN KEY ([AnswerFk]) REFERENCES [dbo].[Student] ([Id])
     10    CONSTRAINT [FK_AnswerResponse_Student_AnswerFk] FOREIGN KEY ([StudentFk]) REFERENCES [dbo].[Student] ([Id])
    1111);
    1212
  • src/FinkiChattery/FinkiChattery.Database/dbo/Tables/Question/Question.sql

    rb499ba7 rdd731cd  
    99    [Views]        BIGINT           DEFAULT (CONVERT([bigint],(0))) NOT NULL,
    1010    [LastActiveOn] SMALLDATETIME    NOT NULL,
     11    [Search]       AS ([Title] + ' ' + [Text]),
    1112    CONSTRAINT [PK_Question] PRIMARY KEY CLUSTERED ([Id] ASC),
    1213    CONSTRAINT [FK_Question_Student_StudentFk] FOREIGN KEY ([StudentFk]) REFERENCES [dbo].[Student] ([Id]),
  • src/FinkiChattery/FinkiChattery.Database/dbo/Tables/QuestionCategory/QuestionCategory.sql

    rb499ba7 rdd731cd  
    55    [CategoryFk] BIGINT           NOT NULL,
    66    CONSTRAINT [PK_QuestionCategory] PRIMARY KEY CLUSTERED ([Id] ASC),
    7     CONSTRAINT [FK_QuestionCategory_Category_QuestionFk] FOREIGN KEY ([QuestionFk]) REFERENCES [dbo].[Category] ([Id]),
     7    CONSTRAINT [FK_QuestionCategory_Category_CategoryFk] FOREIGN KEY ([CategoryFk]) REFERENCES [dbo].[Category] ([Id]),
    88    CONSTRAINT [FK_QuestionCategory_Question_QuestionFk] FOREIGN KEY ([QuestionFk]) REFERENCES [dbo].[Question] ([Id])
    99);
  • src/FinkiChattery/FinkiChattery.Persistence/Configurations/AnswerConfig.cs

    rb499ba7 rdd731cd  
    2222            builder.Property(x => x.CorrectAnswer).HasColumnName(@"CorrectAnswer").HasColumnType("bit").IsRequired();
    2323            builder.Property(x => x.CreatedOn).HasColumnName(@"CreatedOn").HasColumnType("smalldatetime").IsRequired();
     24            builder.Property(x => x.UpvotesCount).HasColumnName(@"UpvotesCount").HasColumnType("bigint").IsRequired().HasDefaultValue(0);
    2425
    2526            builder.HasOne(x => x.Question).WithMany(x => x.Answers).HasForeignKey(x => x.QuestionFk).OnDelete(DeleteBehavior.Restrict);
  • src/FinkiChattery/FinkiChattery.Persistence/Configurations/AnswerResponseConfig.cs

    rb499ba7 rdd731cd  
    2828
    2929            builder.HasOne(x => x.Answer).WithMany(x => x.AnswerResponses).HasForeignKey(x => x.AnswerFk).OnDelete(DeleteBehavior.Restrict);
    30             builder.HasOne(x => x.Student).WithMany().HasForeignKey(x => x.AnswerFk).OnDelete(DeleteBehavior.Restrict);
     30            builder.HasOne(x => x.Student).WithMany().HasForeignKey(x => x.StudentFk).OnDelete(DeleteBehavior.Restrict);
    3131        }
    3232    }
  • src/FinkiChattery/FinkiChattery.Persistence/Configurations/QuestionCategoryConfig.cs

    rb499ba7 rdd731cd  
    2626
    2727            builder.HasOne(x => x.Question).WithMany(x => x.QuestionCategories).HasForeignKey(x => x.QuestionFk).OnDelete(DeleteBehavior.Restrict);
    28             builder.HasOne(x => x.Category).WithMany().HasForeignKey(x => x.QuestionFk).OnDelete(DeleteBehavior.Restrict);
     28            builder.HasOne(x => x.Category).WithMany().HasForeignKey(x => x.CategoryFk).OnDelete(DeleteBehavior.Restrict);
    2929        }
    3030    }
  • src/FinkiChattery/FinkiChattery.Persistence/Configurations/QuestionConfig.cs

    rb499ba7 rdd731cd  
    2424            builder.Property(x => x.Views).HasColumnName(@"Views").HasColumnType("bigint").IsRequired().HasDefaultValue(0);
    2525            builder.Property(x => x.LastActiveOn).HasColumnName(@"LastActiveOn").HasColumnType("smalldatetime").IsRequired();
     26            builder.Property(x => x.Search).HasColumnType(@"Search").HasColumnType("nvarchar").HasMaxLength(4000).IsRequired();
    2627
    2728            builder.HasOne(x => x.Student).WithMany(x => x.Questions).HasForeignKey(x => x.StudentFk).OnDelete(DeleteBehavior.NoAction);
  • src/FinkiChattery/FinkiChattery.Persistence/Models/Answer.cs

    rb499ba7 rdd731cd  
    2020        public DateTime CreatedOn { get; set; }
    2121
     22        public long UpvotesCount { get; set; }
     23
    2224        public virtual ICollection<Upvote> Upvotes { get; set; }
    2325
  • src/FinkiChattery/FinkiChattery.Persistence/Models/Question.cs

    rb499ba7 rdd731cd  
    3232        public DateTime LastActiveOn { get; set; }
    3333
     34        public string Search { get; set; }
     35
    3436        public virtual ICollection<Answer> Answers { get; set; }
    3537
    3638        public virtual ICollection<QuestionCategory> QuestionCategories { get; set; }
    37 
    38         // TODO: Pole po koe ke pravime queries
    3939    }
    4040}
  • src/FinkiChattery/FinkiChattery.Persistence/Repositories/Base/Repository.cs

    rb499ba7 rdd731cd  
    88namespace FinkiChattery.Persistence.Repositories
    99{
    10     public abstract class Repository<T> where T : BaseEntity
     10    public abstract class Repository<T> : IRepository<T> where T : BaseEntity
    1111    {
    1212        public Repository(ApplicationDbContext dbContext)
  • src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/ICategoriesRepo.cs

    rb499ba7 rdd731cd  
    88namespace FinkiChattery.Persistence.Repositories
    99{
    10     public interface ICategoriesRepo
     10    public interface ICategoriesRepo : IRepository<Category>
    1111    {
    1212        public Task<bool> CategoriesExist(IEnumerable<Guid> categoriesUids);
  • src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/IQuestionRepo.cs

    rb499ba7 rdd731cd  
    1 namespace FinkiChattery.Persistence.Repositories
     1using FinkiChattery.Persistence.Models;
     2using FinkiChattery.Persistence.Repositories.Contracts;
     3using System;
     4using System.Threading.Tasks;
     5
     6namespace FinkiChattery.Persistence.Repositories
    27{
    3     public interface IQuestionRepo
     8    public interface IQuestionRepo : IRepository<Question>
    49    {
     10        Task<QuestionStateDto> GetQuestionState(Guid questionUid);
    511    }
    612}
  • src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/IStudentRepo.cs

    rb499ba7 rdd731cd  
    44namespace FinkiChattery.Persistence.Repositories
    55{
    6     public interface IStudentRepo
     6    public interface IStudentRepo : IRepository<Student>
    77    {
    88        public Task<Student> GetStudent(long applicationUserFk);
  • src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/ITeamRepo.cs

    rb499ba7 rdd731cd  
    1 using System;
     1using FinkiChattery.Persistence.Models;
     2using System;
    23using System.Threading.Tasks;
    34
    45namespace FinkiChattery.Persistence.Repositories
    56{
    6     public interface ITeamRepo
     7    public interface ITeamRepo : IRepository<Team>
    78    {
    89        public Task<bool> TeamWithUidExists(Guid teamUid);
  • src/FinkiChattery/FinkiChattery.Persistence/Repositories/Implementations/QuestionRepo.cs

    rb499ba7 rdd731cd  
    11using FinkiChattery.Persistence.Context;
    22using FinkiChattery.Persistence.Models;
     3using FinkiChattery.Persistence.Repositories.Contracts;
     4using Microsoft.EntityFrameworkCore;
     5using System;
     6using System.Linq;
     7using System.Threading.Tasks;
    38
    49namespace FinkiChattery.Persistence.Repositories
     
    914        {
    1015        }
     16
     17        public async Task<QuestionStateDto> GetQuestionState(Guid questionUid)
     18        {
     19            // TODO: MAYBE WRITE THIS QUERY AS SP ??
     20            var questionDto = await DbSet
     21              .AsNoTracking()
     22              .Include(x => x.Student)
     23              .Include(x => x.Team)
     24              .Include(x => x.Answers).ThenInclude(y => y.Student)
     25              .Include(x => x.Answers).ThenInclude(y => y.AnswerResponses).ThenInclude(y => y.Student)
     26              .Include(x => x.QuestionCategories).ThenInclude(y => y.Category)
     27              .Where(x => x.Uid == questionUid)
     28              .Select(x => new QuestionStateDto(
     29                                                x.Id,
     30                                                x.Uid,
     31                                                x.Title,
     32                                                x.Text,
     33                                                x.CreatedOn,
     34                                                x.Views,
     35                                                x.LastActiveOn,
     36                                                new StudentQuestionStateDto(
     37                                                  x.Student.Id,
     38                                                  x.Student.Uid,
     39                                                  x.Student.IndexNumber,
     40                                                  x.Student.ImageUrl,
     41                                                  x.Student.Reputation),
     42                                                x.Answers.Select(y =>
     43                                                new AnswerQuestionStateDto(
     44                                                    y.Id,
     45                                                    y.Uid,
     46                                                    y.Text,
     47                                                    y.CorrectAnswer,
     48                                                    y.CreatedOn,
     49                                                    y.UpvotesCount,
     50                                                    new AnswerStudentQuestionStateDto(
     51                                                        y.Student.Id,
     52                                                        y.Student.Uid,
     53                                                        y.Student.IndexNumber,
     54                                                        y.Student.ImageUrl,
     55                                                        y.Student.Reputation),
     56                                                    y.AnswerResponses.Select(z =>
     57                                                    new AnswerResponseQuestionStateDto(
     58                                                        z.Id,
     59                                                        z.Uid,
     60                                                        z.Text,
     61                                                        z.CreatedOn,
     62                                                        new AnswerResponseStudentQuestionStateDto(
     63                                                            z.Student.Id,
     64                                                            z.Student.Uid,
     65                                                            z.Student.IndexNumber,
     66                                                            z.Student.ImageUrl,
     67                                                            z.Student.Reputation))))),
     68                                                x.QuestionCategories.Select(y =>
     69                                                new QuestionCategoryQuestionStateDto(
     70                                                    y.Id,
     71                                                    y.Uid,
     72                                                    y.Category.Name)),
     73                                                x.Team == null ? null : new TeamQuestionStateDto(
     74                                                    x.Team.Id,
     75                                                    x.Team.Uid,
     76                                                    x.Team.Name)))
     77              .FirstOrDefaultAsync();
     78
     79            return questionDto;
     80        }
    1181    }
    1282}
  • src/FinkiChattery/FinkiChattery.Queries/FinkiChattery.Queries.csproj

    rb499ba7 rdd731cd  
    1 <Project Sdk="Microsoft.NET.Sdk">
     1<Project Sdk="Microsoft.NET.Sdk">
    22
    33  <PropertyGroup>
     
    55  </PropertyGroup>
    66
     7  <ItemGroup>
     8    <ProjectReference Include="..\FinkiChattery.Common\FinkiChattery.Common.csproj" />
     9    <ProjectReference Include="..\FinkiChattery.Persistence\FinkiChattery.Persistence.csproj" />
     10  </ItemGroup>
     11
    712</Project>
Note: See TracChangeset for help on using the changeset viewer.