fix: change upload name

This commit is contained in:
2026-09-15 22:23:54 +07:00
parent 4078bf01f4
commit 637ca51f47
11 changed files with 62 additions and 46 deletions
@@ -50,6 +50,10 @@ namespace mws.backend.dotnet.infrastructure.Migrations
b.Property<Guid>("ProjectId")
.HasColumnType("uuid");
b.Property<string>("StorageKey")
.HasMaxLength(512)
.HasColumnType("character varying(512)");
b.Property<string>("Title")
.IsRequired()
.HasMaxLength(300)
@@ -147,6 +147,7 @@ namespace mws.backend.dotnet.infrastructure.Migrations
{
Id = table.Column<Guid>(type: "uuid", nullable: false),
ProjectId = table.Column<Guid>(type: "uuid", nullable: false),
StorageKey = table.Column<string>(type: "character varying(512)", maxLength: 512, nullable: true),
Title = table.Column<string>(type: "character varying(300)", maxLength: 300, nullable: false),
Description = table.Column<string>(type: "text", nullable: true),
Status = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: false),
@@ -47,6 +47,10 @@ namespace mws.backend.dotnet.infrastructure.Migrations
b.Property<Guid>("ProjectId")
.HasColumnType("uuid");
b.Property<string>("StorageKey")
.HasMaxLength(512)
.HasColumnType("character varying(512)");
b.Property<string>("Title")
.IsRequired()
.HasMaxLength(300)
@@ -13,6 +13,7 @@ public class DocumentConfiguration : IEntityTypeConfiguration<Document>
e.Property(d => d.Title).HasMaxLength(300).IsRequired();
e.Property(d => d.Type).HasConversion<string>().HasMaxLength(20);
e.Property(d => d.ContentHash).HasMaxLength(64);
e.Property(d => d.StorageKey).HasMaxLength(512);
e.Property(d => d.ContentSize);
e.Property(d => d.UpdatedContentAt);
@@ -15,35 +15,45 @@ public class S3DocumentContentStore(
{
private string Bucket => opt.Value.Bucket;
private static string Key(Guid projectId, Guid documentId) => $"{projectId:N}/{documentId:N}.html";
public Task EnsureBucketAsync(Guid projectId, CancellationToken ct) => Task.CompletedTask;
public async Task UploadAsync(Guid projectId, Guid documentId, string contentType, Stream body, CancellationToken ct)
public static string FileNameNow(string name)
{
var slug = new string(name.Trim().ToLowerInvariant()
.Select(c => char.IsLetterOrDigit(c) ? c : '-')
.ToArray()).Trim('-');
if (slug.Length == 0)
{
slug = "document";
}
return $"{slug}_{DateTime.UtcNow:yyyyMMddHHmmss}";
}
public async Task<string> UploadAsync(Guid projectId, string fileName, string contentType, Stream body, CancellationToken ct)
{
var key = $"{projectId:N}/{FileNameNow(fileName)}.html";
try
{
await s3.PutObjectAsync(new PutObjectRequest
{
BucketName = Bucket,
Key = Key(projectId, documentId),
Key = key,
InputStream = body,
ContentType = contentType,
AutoCloseStream = false,
}, ct);
return key;
}
catch (AmazonS3Exception ex)
{
log.LogError(ex, "MinIO upload failed for document {DocumentId}", documentId);
log.LogError(ex, "MinIO upload failed for {Key}", key);
throw new StorageUnavailableException("Document upload failed", ex);
}
}
public async Task<Stream> DownloadAsync(Guid projectId, Guid documentId, CancellationToken ct)
public async Task<Stream> DownloadAsync(string storageKey, CancellationToken ct)
{
try
{
var response = await s3.GetObjectAsync(Bucket, Key(projectId, documentId), ct);
var response = await s3.GetObjectAsync(Bucket, storageKey, ct);
return response.ResponseStream;
}
catch (AmazonS3Exception ex) when (ex.StatusCode == HttpStatusCode.NotFound)
@@ -52,33 +62,20 @@ public class S3DocumentContentStore(
}
catch (AmazonS3Exception ex)
{
log.LogError(ex, "MinIO download failed for document {DocumentId}", documentId);
log.LogError(ex, "MinIO download failed for {Key}", storageKey);
throw new StorageUnavailableException("Document download failed", ex);
}
}
public async Task<bool> ExistsAsync(Guid projectId, Guid documentId, CancellationToken ct)
public async Task DeleteAsync(string storageKey, CancellationToken ct)
{
try
{
await s3.GetObjectMetadataAsync(Bucket, Key(projectId, documentId), ct);
return true;
}
catch (AmazonS3Exception ex) when (ex.StatusCode == HttpStatusCode.NotFound)
{
return false;
}
}
public async Task DeleteAsync(Guid projectId, Guid documentId, CancellationToken ct)
{
try
{
await s3.DeleteObjectAsync(Bucket, Key(projectId, documentId), ct);
await s3.DeleteObjectAsync(Bucket, storageKey, ct);
}
catch (AmazonS3Exception ex)
{
log.LogWarning(ex, "MinIO delete failed for document {DocumentId}", documentId);
log.LogWarning(ex, "MinIO delete failed for {Key}", storageKey);
}
}
}