Compare commits

...

4 Commits

Author SHA1 Message Date
khwezi 1a03355e84 Merge pull request 'Added S3 support' (#31) from s3service into master
Reviewed-on: #31
2026-05-19 10:24:05 +02:00
Khwezi Mngoma f245bc94e1 Added S3 support
continuous-integration/drone/pr Build is passing
2026-05-19 10:23:36 +02:00
khwezi 7743c3178e Merge pull request 'Simplified notification updating' (#30) from emailjobs into master
Reviewed-on: #30
2026-05-17 16:01:24 +02:00
Khwezi Mngoma da141311ff Simplified notification updating
continuous-integration/drone/pr Build is passing
2026-05-17 16:00:35 +02:00
6 changed files with 86 additions and 7 deletions
@@ -40,7 +40,7 @@ public class NotificationsFeatureTests(CommonFixture fixture, ITestOutputHelper
{ {
DateRange range = new() DateRange range = new()
{ {
From = DateOnly.FromDateTime(new DateTime(2026, 05, 01, 0, 0, 0, DateTimeKind.Utc)), From = DateOnly.FromDateTime(new DateTime(2026, 04, 01, 0, 0, 0, DateTimeKind.Utc)),
To = DateOnly.FromDateTime(DateTime.UtcNow), To = DateOnly.FromDateTime(DateTime.UtcNow),
MaxRecords = 10 MaxRecords = 10
}; };
+31
View File
@@ -0,0 +1,31 @@
using Amazon.Runtime;
using LiteCharms.Features.S3;
using LiteCharms.Features.S3.Configuration;
namespace LiteCharms.Features.Extensions;
public static class S3
{
public static IServiceCollection AddGarageS3(this IServiceCollection services, IConfiguration configuration)
{
var optionsSection = configuration.GetSection(nameof(S3Settings));
services.Configure<S3Settings>(optionsSection);
var options = optionsSection.Get<S3Settings>()
?? throw new InvalidOperationException("S3 configuration section is missing.");
var credentials = new BasicAWSCredentials(options.AccessKey, options.SecretKey);
var s3Config = new AmazonS3Config
{
ServiceURL = options.ServiceUrl,
AuthenticationRegion = options.Region,
ForcePathStyle = true,
};
services.AddSingleton<IAmazonS3>(new AmazonS3Client(credentials, s3Config));
services.AddScoped<S3Service>();
return services;
}
}
@@ -128,6 +128,16 @@
<Using Include="FluentResults" /> <Using Include="FluentResults" />
<Using Include="Mediator" /> <Using Include="Mediator" />
</ItemGroup> </ItemGroup>
<!-- Amazon S3 SDK -->
<ItemGroup>
<PackageReference Include="AWSSDK.Extensions.NetCore.Setup" Version="4.0.3.40" />
<PackageReference Include="AWSSDK.S3" Version="4.0.23.3" />
<!-- global Usings -->
<Using Include="Amazon.S3" />
<Using Include="Amazon.S3.Model" />
</ItemGroup>
<!-- Shared Usings --> <!-- Shared Usings -->
<ItemGroup> <ItemGroup>
@@ -0,0 +1,14 @@
namespace LiteCharms.Features.S3.Configuration;
public class S3Settings
{
public string? ServiceUrl { get; set; }
public string? AccessKey { get; set; }
public string? SecretKey { get; set; }
public string? BucketName { get; set; }
public string? Region { get; set; }
}
+28
View File
@@ -0,0 +1,28 @@
namespace LiteCharms.Features.S3;
public class S3Service(IAmazonS3 amazonS3)
{
public async Task<Result<string>> UploadFileAsync(string bucketName, string fileName, Stream fileStream, string contentType, string cdnBaseUrl, CancellationToken cancellationToken = default)
{
try
{
var putRequest = new PutObjectRequest
{
BucketName = bucketName,
Key = fileName,
InputStream = fileStream,
ContentType = contentType
};
var response = await amazonS3.PutObjectAsync(putRequest, cancellationToken);
return response.HttpStatusCode != System.Net.HttpStatusCode.OK
? Result.Fail<string>($"Failed to upload {fileName} to S3.")
: Result.Ok(string.Format(cdnBaseUrl, bucketName, fileName));
}
catch (Exception ex)
{
return Result.Fail<string>(new Error($"Error uploading {fileName} to S3: {ex.Message}").CausedBy(ex));
}
}
}
@@ -97,12 +97,8 @@ public class NotificationService(IDbContextFactory<ShopDbContext> contextFactory
notification.Processed = request.Processed; notification.Processed = request.Processed;
notification.UpdatedAt = DateTime.UtcNow; notification.UpdatedAt = DateTime.UtcNow;
notification.HasError = request.HasError;
if (request.HasError) notification.Errors = request.Errors;
{
notification.HasError = request.HasError;
notification.Errors = request.Errors;
}
return await context.SaveChangesAsync(cancellationToken) > 0 return await context.SaveChangesAsync(cancellationToken) > 0
? Result.Ok() ? Result.Ok()