first commit

This commit is contained in:
Vitalii Litvinchuk
2026-06-13 23:23:50 +03:00
commit 23958e8e2c
72 changed files with 6142 additions and 0 deletions
@@ -0,0 +1,37 @@
using MediatR;
using Microsoft.EntityFrameworkCore;
using SequenceAuth.Example.Domain;
using SequenceAuth.Example.Infrastructure;
namespace SequenceAuth.Example.Features.Todos;
public enum ChangeTodoStatusOutcome { Success, NotFound, Unauthorized }
public record ChangeTodoStatusResult(ChangeTodoStatusOutcome Outcome, TodoItem? Item);
public record ChangeTodoStatusCommand(Guid TodoId, Guid UserId, TodoStatus NewStatus) : IRequest<ChangeTodoStatusResult>;
public class ChangeTodoStatusCommandHandler(AppDbContext dbContext) : IRequestHandler<ChangeTodoStatusCommand, ChangeTodoStatusResult>
{
public async Task<ChangeTodoStatusResult> Handle(ChangeTodoStatusCommand request, CancellationToken cancellationToken)
{
var todo = await dbContext.Todos.FirstOrDefaultAsync(t => t.Id == request.TodoId, cancellationToken);
return todo switch
{
null => new ChangeTodoStatusResult(ChangeTodoStatusOutcome.NotFound, null),
{ UserId: var userId } when userId != request.UserId => new ChangeTodoStatusResult(ChangeTodoStatusOutcome.Unauthorized, null),
_ => await UpdateStatusAsync(todo, request.NewStatus, cancellationToken)
};
}
private async Task<ChangeTodoStatusResult> UpdateStatusAsync(TodoItem todo, TodoStatus newStatus, CancellationToken cancellationToken)
{
var updatedTodo = todo with { Status = newStatus };
dbContext.Entry(todo).CurrentValues.SetValues(updatedTodo);
await dbContext.SaveChangesAsync(cancellationToken);
return new ChangeTodoStatusResult(ChangeTodoStatusOutcome.Success, updatedTodo);
}
}
@@ -0,0 +1,18 @@
using MediatR;
using SequenceAuth.Example.Domain;
using SequenceAuth.Example.Infrastructure;
namespace SequenceAuth.Example.Features.Todos;
public record CreateTodoCommand(Guid UserId, string Title) : IRequest<TodoItem>;
public class CreateTodoCommandHandler(AppDbContext dbContext) : IRequestHandler<CreateTodoCommand, TodoItem>
{
public async Task<TodoItem> Handle(CreateTodoCommand request, CancellationToken cancellationToken)
{
var todo = new TodoItem(Guid.NewGuid(), request.UserId, request.Title, TodoStatus.Pending);
dbContext.Todos.Add(todo);
await dbContext.SaveChangesAsync(cancellationToken);
return todo;
}
}
@@ -0,0 +1,24 @@
using MediatR;
using Microsoft.EntityFrameworkCore;
using SequenceAuth.Example.Domain;
using SequenceAuth.Example.Infrastructure;
namespace SequenceAuth.Example.Features.Todos;
public record GetTodosQuery(Guid UserId, TodoStatus? StatusFilter) : IRequest<List<TodoItem>>;
public class GetTodosQueryHandler(AppDbContext dbContext) : IRequestHandler<GetTodosQuery, List<TodoItem>>
{
public async Task<List<TodoItem>> Handle(GetTodosQuery request, CancellationToken cancellationToken)
{
var query = dbContext.Todos.Where(t => t.UserId == request.UserId);
query = request.StatusFilter switch
{
null => query,
var status => query.Where(t => t.Status == status)
};
return await query.ToListAsync(cancellationToken);
}
}