using MediatR;
using BuildFlow.Domain.Interfaces;
using File.Application.Features.Files.Commands;
using File.Application.Features.Files.Queries;
namespace BuildFlow.Host;
///
/// 进程内文件存储实现,替代 rag-backend 原有的 HTTP 版 FileStorageClient。
/// 通过 MediatR 查询/命令调用 file-system 模块的处理器( /
/// ),而非直接注入 file 的 Infrastructure 类型(IS3StorageService)。
/// 这样 rag 模块对 file 的依赖从「直接引用 Infrastructure 类型」降级为「发 MediatR 消息」,
/// 实现模块间解耦——rag 只依赖消息契约,不感知 file 的存储实现细节。
///
/// 注册为 IFileStorageClient 的同接口覆盖(后注册者胜出),HTTP 版自动被取代;
/// 本类只在 BuildFlow Host 中参与 DI,不影响模块级测试或设计时工具。
///
public class InProcessFileStorageClient(IMediator mediator) : IFileStorageClient
{
public async Task UploadAsync(
string bucket,
string objectKey,
Stream content,
string contentType,
string? authToken, // 进程内调用无需鉴权,token 忽略
CancellationToken ct = default)
{
// 通过 MediatR 命令调用 file 模块的 UploadFileCommandHandler(它内部走 IS3StorageService)
await mediator.Send(new UploadFileCommand(bucket, objectKey, content, contentType, content.Length), ct);
}
public async Task DownloadAsync(
string bucket,
string objectKey,
string? authToken, // 同上,忽略
CancellationToken ct = default)
{
// 通过 MediatR 查询调用 file 模块的 DownloadFileQueryHandler。
// 注意:DownloadFileQuery 把对象 buffer 成 byte[](file 模块的查询契约),这里包成 MemoryStream 还原成 Stream。
// 文档处理场景下文件多为 MB 级,内存拷贝可接受;如需真正的流式,可在 file 模块加一个返回 Stream 的查询。
var result = await mediator.Send(new DownloadFileQuery(bucket, objectKey), ct);
return new MemoryStream(result.Data);
}
}