feat: add organization onboarding
All checks were successful
deploy-socialize / image (push) Successful in 1m8s
deploy-socialize / deploy (push) Successful in 19s

This commit is contained in:
2026-05-07 20:07:50 -04:00
parent 4aaa1a7f90
commit db16e79d9f
9 changed files with 699 additions and 80 deletions

View File

@@ -0,0 +1,64 @@
using FastEndpoints;
using Socialize.Api.Data;
using Socialize.Api.Infrastructure.Security;
using Socialize.Api.Modules.Organizations.Data;
using Socialize.Api.Modules.Organizations.Services;
namespace Socialize.Api.Modules.Organizations.Handlers;
internal record CreateOrganizationRequest(
string Name);
internal class CreateOrganizationRequestValidator
: Validator<CreateOrganizationRequest>
{
public CreateOrganizationRequestValidator()
{
RuleFor(x => x.Name).NotEmpty().MaximumLength(256);
}
}
internal class CreateOrganizationHandler(
AppDbContext dbContext)
: Endpoint<CreateOrganizationRequest, OrganizationDto>
{
public override void Configure()
{
Post("/api/organizations");
Options(o => o.WithTags("Organizations"));
}
public override async Task HandleAsync(CreateOrganizationRequest request, CancellationToken ct)
{
ArgumentNullException.ThrowIfNull(request);
Guid userId = User.GetUserId();
Organization organization = new()
{
Id = Guid.NewGuid(),
Name = request.Name.Trim(),
OwnerUserId = userId,
CreatedAt = DateTimeOffset.UtcNow,
};
OrganizationMembership ownerMembership = new()
{
Id = Guid.NewGuid(),
OrganizationId = organization.Id,
UserId = userId,
Role = OrganizationRoles.Owner,
CreatedAt = DateTimeOffset.UtcNow,
};
dbContext.Organizations.Add(organization);
dbContext.OrganizationMemberships.Add(ownerMembership);
await dbContext.SaveChangesAsync(ct);
await SendAsync(
OrganizationDto.FromOrganization(
organization,
OrganizationPermissionRules.GetPermissionsForRole(OrganizationRoles.Owner)),
StatusCodes.Status201Created,
ct);
}
}