From bb651bb54714d1d0b130a2a60f128b5ff5f99906 Mon Sep 17 00:00:00 2001 From: Arthur Bassi Date: Tue, 8 Sep 2026 11:08:26 -0300 Subject: [PATCH] feat(work-orders): add file storage OpenRead port --- .../Infrastructure/PortAdapters.cs | 27 +++++++++++++++++++ SeaHaven.Services/Interfaces/IServicePorts.cs | 6 +++++ 2 files changed, 33 insertions(+) diff --git a/Api.SeaHavenIndustries/Infrastructure/PortAdapters.cs b/Api.SeaHavenIndustries/Infrastructure/PortAdapters.cs index adcc357..a3ebbf3 100644 --- a/Api.SeaHavenIndustries/Infrastructure/PortAdapters.cs +++ b/Api.SeaHavenIndustries/Infrastructure/PortAdapters.cs @@ -70,6 +70,33 @@ namespace Api.SeaHavenIndustries.Infrastructure } } + public Stream? OpenRead(string fileUrl) + { + if (string.IsNullOrWhiteSpace(fileUrl)) + return null; + + try + { + if (!Uri.TryCreate(fileUrl, UriKind.Absolute, out var uri)) + return null; + + var relativePath = uri.AbsolutePath.TrimStart('/'); + if (string.IsNullOrWhiteSpace(relativePath) + || relativePath.Contains("..", StringComparison.Ordinal) + || !relativePath.StartsWith("Assets/Documents/", StringComparison.OrdinalIgnoreCase)) + { + return null; + } + + var fullPath = Path.Combine(ResolveWebRoot(), relativePath.Replace('/', Path.DirectorySeparatorChar)); + return System.IO.File.Exists(fullPath) ? System.IO.File.OpenRead(fullPath) : null; + } + catch + { + return null; + } + } + private string ResolveWebRoot() => _webHostEnvironment.WebRootPath ?? Path.Combine(_webHostEnvironment.ContentRootPath, "wwwroot"); diff --git a/SeaHaven.Services/Interfaces/IServicePorts.cs b/SeaHaven.Services/Interfaces/IServicePorts.cs index 10c1718..c2d00a6 100644 --- a/SeaHaven.Services/Interfaces/IServicePorts.cs +++ b/SeaHaven.Services/Interfaces/IServicePorts.cs @@ -24,6 +24,12 @@ namespace SeaHaven.Services.Interfaces /// cannot be resolved or removed; never throws for missing paths. /// bool TryDelete(string fileUrl); + + /// + /// Opens a previously saved file URL for reading. Returns null when the URL or file + /// cannot be safely resolved. + /// + Stream? OpenRead(string fileUrl); } ///