Skip to content

Commit

Permalink
stuff
Browse files Browse the repository at this point in the history
not using automapper anymore
new post poll endpoint
fixed a lot of stuff
  • Loading branch information
Logerfo committed May 9, 2020
1 parent 2c563eb commit 2c0a9cc
Show file tree
Hide file tree
Showing 18 changed files with 167 additions and 82 deletions.
11 changes: 0 additions & 11 deletions src/VSPoll.API/ConfigurationMapper.cs

This file was deleted.

14 changes: 7 additions & 7 deletions src/VSPoll.API/Controllers/PollController.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Threading.Tasks;
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using VSPoll.API.Models;
using VSPoll.API.Services;
Expand All @@ -14,15 +15,14 @@ public PollController(IPollService pollService)
=> this.pollService = pollService;

[HttpGet("{id}")]
public async Task<ActionResult<Poll>> Get(int id)
//ToDo: use possible authenticated user as an argument
public async Task<ActionResult<Poll>> Get(Guid id)
=> await pollService.GetPollAsync(id);

//POST poll [poll data, user]
//DELETE poll [poll, user]
[HttpPost]
public async Task<ActionResult<Poll>> Post(PollCreate poll)
=> await pollService.InsertPollAsync(poll);

//POST poll/vote [bool, user, option]
//POST poll/block [bool, poll, user, user blocked]
//POST poll/end [poll, user]
//DELETE poll/option [option, user]
}
}
21 changes: 21 additions & 0 deletions src/VSPoll.API/Extensions/ServiceCollection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using Microsoft.Extensions.DependencyInjection;
using VSPoll.API.Persistence.Repository;
using VSPoll.API.Services;

namespace VSPoll.API.Extensions
{
public static class ServiceCollection
{
public static IServiceCollection AddRepositories(this IServiceCollection services)
{
services.AddTransient<IPollRepository, PollRepository>();
return services;
}

public static IServiceCollection AddServices(this IServiceCollection services)
{
services.AddTransient<IPollService, PollService>();
return services;
}
}
}
20 changes: 10 additions & 10 deletions src/VSPoll.API/Migrations/V1__Create_table.sql
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
create table "user" (
"id" text primary key,
create table users (
id text primary key,
first_name text not null,
last_name text not null,
username text not null,
photo_url text not null
);

create table poll (
id integer generated always as identity primary key,
create table polls (
id uuid primary key,
multi_vote boolean not null default false,
show_voters boolean not null default true,
allow_add boolean not null default false,
end_date timestamp without time zone not null default now() + '7 days'
);

create table poll_option (
id integer generated always as identity primary key,
poll_id integer not null references poll on delete cascade on update cascade,
create table poll_options (
id uuid primary key,
poll_id uuid not null references polls on delete cascade on update cascade,
description text not null,
unique (poll_id, description)
);

create table poll_vote (
option_id integer not null references poll_option on delete cascade on update cascade,
user_id text not null references "user" on delete cascade on update cascade,
create table poll_votes (
option_id uuid not null references poll_options on delete cascade on update cascade,
user_id text not null references users on delete cascade on update cascade,
constraint pk_poll_vote primary key (option_id, user_id)
);
17 changes: 15 additions & 2 deletions src/VSPoll.API/Models/Poll.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Entity = VSPoll.API.Persistence.Entity;

namespace VSPoll.API.Models
{
public class Poll
{
public Guid Id { get; set; }

public bool MultiVote { get; set; }

public bool ShowVoters { get; set; }
Expand All @@ -14,8 +17,18 @@ public class Poll

public DateTime EndDate { get; set; }

public User? User { get; set; }

public IEnumerable<PollOption> Options { get; set; } = Enumerable.Empty<PollOption>();

public Poll() { }

public Poll(Entity.Poll poll)
{
Id = poll.Id;
MultiVote = poll.MultiVote;
ShowVoters = poll.ShowVoters;
AllowAdd = poll.AllowAdd;
EndDate = poll.EndDate;
Options = poll.Options.Select(option => new PollOption(option));
}
}
}
19 changes: 19 additions & 0 deletions src/VSPoll.API/Models/PollCreate.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;

namespace VSPoll.API.Models
{
public class PollCreate
{
public bool MultiVote { get; set; }

public bool ShowVoters { get; set; }

public bool AllowAdd { get; set; }

public DateTime EndDate { get; set; }

public IEnumerable<string> Options { get; set; } = Enumerable.Empty<string>();
}
}
19 changes: 17 additions & 2 deletions src/VSPoll.API/Models/PollOption.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using Entity = VSPoll.API.Persistence.Entity;

namespace VSPoll.API.Models
{
public class PollOption
{
public int Id { get; set; }
public Guid Id { get; set; }

public string Description { get; set; } = null!;

Expand All @@ -14,5 +16,18 @@ public class PollOption
public decimal Percentage { get; set; }

public IEnumerable<User> Voters { get; set; } = Enumerable.Empty<User>();

public PollOption() { }

public PollOption(Entity.PollOption option)
{
Id = option.Id;
Description = option.Description;
Votes = option.Votes.Count;
//ToDo: normalize
var totalVotes = option.Poll.Options.Sum(opt => opt.Votes.Count);
Percentage = totalVotes == 0 ? 0 : option.Votes.Count / totalVotes;
Voters = option.Votes.Select(vote => new User(vote.User));
}
}
}
15 changes: 14 additions & 1 deletion src/VSPoll.API/Models/User.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace VSPoll.API.Models
using Entity = VSPoll.API.Persistence.Entity;

namespace VSPoll.API.Models
{
public class User
{
Expand All @@ -11,5 +13,16 @@ public class User
public string Username { get; set; } = null!;

public string PhotoUrl { get; set; } = null!;

public User() { }

public User(Entity.User user)
{
Id = user.Id;
FirstName = user.FirstName;
LastName = user.LastName;
Username = user.Username;
PhotoUrl = user.PhotoUrl;
}
}
}
2 changes: 1 addition & 1 deletion src/VSPoll.API/Persistence/Context/PollContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public class PollContext : DbContext
public DbSet<User> Users { get; set; } = null!;

protected override void OnModelCreating(ModelBuilder modelBuilder)
=> modelBuilder.UseIdentityAlwaysColumns();
=> modelBuilder.Entity<PollVote>().HasKey(vote => new { vote.OptionId, vote.UserId });

public PollContext(DbContextOptions<PollContext> contextOptions) : base(contextOptions) { }
}
Expand Down
18 changes: 17 additions & 1 deletion src/VSPoll.API/Persistence/Entity/Poll.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using VSPoll.API.Models;

namespace VSPoll.API.Persistence.Entity
{
public class Poll
{
public int Id { get; set; }
public Guid Id { get; set; }

public bool MultiVote { get; set; }

Expand All @@ -16,5 +18,19 @@ public class Poll
public DateTime EndDate { get; set; } = DateTime.Now.AddDays(7);

public List<PollOption> Options { get; set; } = new List<PollOption>();

public Poll() { }

public Poll(PollCreate poll)
{
AllowAdd = poll.AllowAdd;
EndDate = poll.EndDate;
MultiVote = poll.MultiVote;
Options = poll.Options.Select(option => new PollOption
{
Description = option,
}).ToList();
ShowVoters = poll.ShowVoters;
}
}
}
7 changes: 4 additions & 3 deletions src/VSPoll.API/Persistence/Entity/PollOption.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;

namespace VSPoll.API.Persistence.Entity
{
public class PollOption
{
public int Id { get; set; }
public Guid Id { get; set; }

public int PollId { get; set; }
public Guid PollId { get; set; }
public Poll Poll { get; set; } = null!;

public string Description { get; set; } = null!;
Expand Down
6 changes: 4 additions & 2 deletions src/VSPoll.API/Persistence/Entity/PollVote.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
namespace VSPoll.API.Persistence.Entity
using System;

namespace VSPoll.API.Persistence.Entity
{
public class PollVote
{
public int OptionId { get; set; }
public Guid OptionId { get; set; }
public PollOption Option { get; set; } = null!;

public string UserId { get; set; } = null!;
Expand Down
7 changes: 5 additions & 2 deletions src/VSPoll.API/Persistence/Repository/IPollRepository.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
using System.Threading.Tasks;
using System;
using System.Threading.Tasks;
using VSPoll.API.Persistence.Entity;

namespace VSPoll.API.Persistence.Repository
{
public interface IPollRepository
{
Task<Entity.Poll> GetByIdAsync(int id);
Task<Poll> GetByIdAsync(Guid id);
Task InsertPollAsync(Poll poll);
}
}
12 changes: 10 additions & 2 deletions src/VSPoll.API/Persistence/Repository/PollRepository.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System.Threading.Tasks;
using System;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using VSPoll.API.Persistence.Context;
using VSPoll.API.Persistence.Entity;

namespace VSPoll.API.Persistence.Repository
{
Expand All @@ -9,7 +11,13 @@ public class PollRepository : IPollRepository
private readonly PollContext context;
public PollRepository(PollContext context) => this.context = context;

public async Task<Entity.Poll> GetByIdAsync(int id)
public async Task<Poll> GetByIdAsync(Guid id)
=> await context.Polls.SingleAsync(poll => poll.Id == id);

public async Task InsertPollAsync(Poll poll)
{
await context.Polls.AddAsync(poll);
await context.SaveChangesAsync();
}
}
}
6 changes: 4 additions & 2 deletions src/VSPoll.API/Services/IPollService.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
using System.Threading.Tasks;
using System;
using System.Threading.Tasks;
using VSPoll.API.Models;

namespace VSPoll.API.Services
{
public interface IPollService
{
Task<Poll> GetPollAsync(int id);
Task<Poll> GetPollAsync(Guid id);
Task<Poll> InsertPollAsync(PollCreate pollCreate);
}
}
35 changes: 12 additions & 23 deletions src/VSPoll.API/Services/PollService.cs
Original file line number Diff line number Diff line change
@@ -1,39 +1,28 @@
using System.Linq;
using System;
using System.Threading.Tasks;
using AutoMapper;
using VSPoll.API.Models;
using VSPoll.API.Persistence.Repository;
using Entity = VSPoll.API.Persistence.Entity;

namespace VSPoll.API.Services
{
public class PollService : IPollService
{
private readonly IPollRepository pollRepository;
private readonly IMapper mapper;
public PollService(IPollRepository pollRepository, IMapper mapper)
public PollService(IPollRepository pollRepository)
=> this.pollRepository = pollRepository;

public async Task<Poll> GetPollAsync(Guid id)
{
this.pollRepository = pollRepository;
this.mapper = mapper;
var poll = await pollRepository.GetByIdAsync(id);
return new Poll(poll);
}

public async Task<Poll> GetPollAsync(int id)
public async Task<Poll> InsertPollAsync(PollCreate pollCreate)
{
var poll = await pollRepository.GetByIdAsync(id);
return new Poll
{
AllowAdd = poll.AllowAdd,
EndDate = poll.EndDate,
MultiVote = poll.MultiVote,
Options = poll.Options.Select(option => new PollOption
{
Description = option.Description,
Id = option.Id,
Percentage = option.Votes.Count / poll.Options.Sum(opt => opt.Votes.Count),
Voters = option.Votes.Select(vote => mapper.Map<User>(vote.User)),
Votes = option.Votes.Count,
}),
ShowVoters = poll.ShowVoters,
};
var poll = new Entity.Poll(pollCreate);
await pollRepository.InsertPollAsync(poll);
return new Poll(poll);
}
}
}
Loading

0 comments on commit 2c0a9cc

Please sign in to comment.