Handler.cs 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940
  1. using Application.Abstractions.Data;
  2. using Application.Abstractions.Messaging;
  3. using Application.Helpers;
  4. using Domain.Entities.Developers;
  5. using SharedKernel.Results;
  6. namespace Application.Features.Api.Developers.Apps.CreateApp;
  7. internal sealed class Handler(IAppDbContext db) : ICommandHandler<Command, Result<Response>>
  8. {
  9. public async Task<Result<Response>> Handle(Command request, CancellationToken ct)
  10. {
  11. if (string.IsNullOrWhiteSpace(request.Name) || request.Name.Length > 100)
  12. {
  13. return Result.Failure<Response>(Error.Problem("App.NameInvalid", "Name is required (1-100 chars)."));
  14. }
  15. var app = ApiApplication.Create(request.OwnerMemberID, request.Name, request.Description, request.HomepageUrl);
  16. app.Approve();
  17. var clientID = ApiTokenGenerator.GenerateClientID();
  18. var secret = ApiTokenGenerator.GenerateClientSecret();
  19. await db.ApiApplication.AddAsync(app, ct);
  20. await db.SaveChangesAsync(ct);
  21. var credential = ApiCredential.Create(app.ID, clientID, ApiTokenGenerator.Hash(secret), ApiTokenGenerator.Hint(secret));
  22. await db.ApiCredential.AddAsync(credential, ct);
  23. foreach (var scope in request.Scopes ?? [])
  24. {
  25. if (string.IsNullOrWhiteSpace(scope)) { continue; }
  26. await db.ApiApplicationScope.AddAsync(ApiApplicationScope.Create(app.ID, scope.Trim()), ct);
  27. }
  28. await db.SaveChangesAsync(ct);
  29. return Result.Success(new Response(app.ID, clientID, secret));
  30. }
  31. }