Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/APP.Platform/Models/PublicationModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Domain.Models.ViewModels;

public sealed class PublicationModel
{
public string? Link { get; set; }
}
16 changes: 15 additions & 1 deletion src/APP.Platform/Pages/Canal/Index.cshtml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Text.Json;
using Background;
using ClassLib.Follow.Models.ViewModels;
using Domain.Contracts;
using Domain.Entities;
using Domain.Enums;
using Domain.Models.ViewModels;
Expand All @@ -22,6 +23,8 @@ namespace APP.Platform.Pages;

public sealed class CanalIndexModel : CustomPageModel
{
private readonly IPublicationWebService _publicationWebService;

[BindProperty]
public JoinTime? JoinTime { get; set; }
public Dictionary<JoinTime, TimeSelection>? MyEvents { get; set; }
Expand Down Expand Up @@ -62,7 +65,8 @@ public CanalIndexModel(
IMessagePublisher messagePublisher,
Settings settings,
IPerfilWebService perfilWebService,
ILiveService liveService
ILiveService liveService,
IPublicationWebService publicationWebService
)
: base(context, httpClientFactory, httpContextAccessor, settings)
{
Expand All @@ -73,6 +77,7 @@ ILiveService liveService
_context = context;
_messagePublisher = messagePublisher;
_liveService = liveService;
_publicationWebService = publicationWebService;
}

public async Task<IActionResult> OnGetAsync(string usr)
Expand Down Expand Up @@ -540,4 +545,13 @@ em receber mentoria {timeSelection.TituloTemporario}

return Redirect("./?event=" + JoinTime.TimeSelectionId);
}

public async Task<ActionResult> OnPostPublication([FromBody] PublicationModel publicationModel)
{
await _publicationWebService.Add(
new CreatePublicationRequest(UserProfile.Id, publicationModel.Link)
);

return Page();
}
}
1 change: 1 addition & 0 deletions src/Core/Application/DependencyInjection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public static IServiceCollection AddApplication(this IServiceCollection services
services.AddScoped<IFollowBusinessLogic, FollowBusinessLogic>();
services.AddScoped<ILikeBusinessLogic, LikeBusinessLogic>();
services.AddScoped<IHelpResponseBusinessLogic, HelpResponseBusinessLogic>();
services.AddScoped<IPublicationBusinessLogic, PublicationBusinessLogic>();
return services;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Domain.Contracts;

//using Domain.Entities;

namespace Application.Logic;

public interface IPublicationBusinessLogic
{
public Task AddPublication(CreatePublicationRequest createPublicationRequest);
}
18 changes: 18 additions & 0 deletions src/Core/Application/Logic/Publication/PublicationBusinessLogic.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using Domain.Contracts;
using Domain.Entities;
using Domain.Repositories;

namespace Application.Logic;

public sealed class PublicationBusinessLogic(IPublicationRepository _repository)
: IPublicationBusinessLogic
{
public async Task AddPublication(CreatePublicationRequest createPublicationRequest)
{
var publication =
Publication.Create(createPublicationRequest)
?? throw new UriFormatException("A URL fornecida é inválida!");

await _repository.AddAsync(publication);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
namespace Domain.Contracts;

public record CreatePublicationRequest(Guid PerfilId, string? Link);
27 changes: 25 additions & 2 deletions src/Core/Domain/Entities/Publication.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System.Text.RegularExpressions;
using Domain.Contracts;
using Domain.Primitives;

namespace Domain.Entities;
Expand All @@ -8,9 +10,13 @@ public sealed class Publication(Guid id, Guid perfilId, string link, bool isVali
public string Link { get; private set; } = link;
public bool IsValid { get; private set; } = isValid;

public static Publication Create(Guid perfilId, string link)
public static Publication? Create(CreatePublicationRequest createPublicationRequest)
{
return new Publication(Guid.NewGuid(), perfilId, link, true);
string? url = createPublicationRequest.Link;
if (url == null || !UrlIsValid(url))
return null;

return new Publication(Guid.NewGuid(), createPublicationRequest.PerfilId, url, true);
}

public void NotValid()
Expand All @@ -22,4 +28,21 @@ public void Valid()
{
IsValid = true;
}

public static bool UrlIsValid(string url)
{
string[] allowedDomains =
{
@"^https:\/\/(www\.)?linkedin\.com(\/.*)?$",
@"^https:\/\/x\.com(\/.*)?$",
@"^https:\/\/dev\.to(\/.*)?$",
@"^https:\/\/tabnews\.com\.br(\/.*)?$",
@"^https:\/\/medium\.com(\/.*)?$",
};

if (!allowedDomains.Any(domain => Regex.IsMatch(url, domain, RegexOptions.IgnoreCase)))
return false;

return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using Domain.Entities;

namespace Domain.Repositories
{
public interface IPublicationRepository
{
public Task AddAsync(Publication publication);
}
}
10 changes: 10 additions & 0 deletions src/Core/Domain/Interfaces/WebServices/IPublicationWebService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Domain.Contracts;
using Domain.Entities;
using Microsoft.AspNetCore.Http;

namespace Domain.WebServices;

public interface IPublicationWebService
{
public Task Add(CreatePublicationRequest request);
}
2 changes: 2 additions & 0 deletions src/Core/Infrastructure/DependencyInjection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ IConfiguration configuration
services.AddScoped<ICommentWebService, CommentWebService>();
services.AddScoped<IJoinTimeWebService, JoinTimeWebService>();
services.AddScoped<IHelpResponseWebService, HelpResponseWebService>();
services.AddScoped<IPublicationWebService, PublicationWebService>();

return services;
}
Expand Down Expand Up @@ -274,6 +275,7 @@ public static IServiceCollection AddRepositories(this IServiceCollection service
services.AddScoped<ILikeRepository, LikeRepository>();
services.AddScoped<ITagRepository, TagRepository>();
services.AddScoped<IHelpResponseRepository, HelpResponseRepository>();
services.AddScoped<IPublicationRepository, PublicationRepository>();
return services;
}
}
18 changes: 18 additions & 0 deletions src/Core/Infrastructure/Repositories/PublicationRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;
using Domain.Entities;
using Domain.Repositories;
using Infrastructure.Contexts;
using Microsoft.EntityFrameworkCore;

namespace Infrastructure.Repositories;

public sealed class PublicationRepository(ApplicationDbContext context)
: GenericRepository<Publication>(context),
IPublicationRepository
{
public async Task AddAsync(Publication publication)
{
await DbContext.Publications.AddAsync(publication);
await DbContext.SaveChangesAsync();
}
}
25 changes: 25 additions & 0 deletions src/Core/Infrastructure/WebServices/Core/PublicationWebService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Domain.Contracts;
using Domain.WebServices;

namespace Infrastructure.WebServices;

public sealed class PublicationWebService(CoreClient client) : IPublicationWebService
{
const string baseRoute = "api/publication";

public async Task Add(CreatePublicationRequest request)
{
var route = Path.Combine(baseRoute, string.Empty);

try
{
await client.PostAsync(route, request);
}
catch
{
throw new Exception(
"Erro! Não foi possível adicionar sua publicação. Verifique a URL ou se o formato do arquivo JSON está correto."
);
}
}
}
1 change: 1 addition & 0 deletions src/Core/Presentation/DependencyInjection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,7 @@ public static IEndpointRouteBuilder AddEndPoints(this IEndpointRouteBuilder app)
app.AddFollowEndPoints();
app.AddLikeEndPoints();
app.AddHelpResponseEndPoints();
app.AddPublicationEndPoints();

return app;
}
Expand Down
36 changes: 36 additions & 0 deletions src/Core/Presentation/EndPoints/PublicationEndPoints.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using Application.Logic;
using Domain.Contracts;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Routing;

namespace Presentation.EndPoints;

public static class PublicationEndPoints
{
public static void AddPublicationEndPoints(this IEndpointRouteBuilder app)
{
var group = app.MapGroup("api/publication");

group.WithOpenApi();

group.MapPost(string.Empty, Add);
}

public static async Task<IResult> Add(
[FromServices] IPublicationBusinessLogic _logic,
[FromBody] CreatePublicationRequest _request
)
{
try
{
await _logic.AddPublication(_request);
return Results.Ok();
}
catch (Exception ex)
{
return Results.BadRequest(ex.Message);
}
}
}