Add media image handling and related endpoints
CI / Backend (build + test) (push) Failing after 1m35s
CI / Frontend (lint + typecheck + build) (push) Successful in 43s

- Introduced `MediaImage` entity to manage images for markdown in instructions and news.
- Updated `IAppDbContext` and `AppDbContext` to include `MediaImages` DbSet.
- Implemented `DeleteMediaImageFilesAsync` method in `FactoryResetCommandHandler` to remove media images during factory reset.
- Added new API endpoints for uploading and retrieving media images, enhancing markdown support.
- Updated frontend components to utilize the new `MarkdownEditor` for image uploads in instructions and news.
- Enhanced documentation to reflect the new media handling features and API specifications.
This commit is contained in:
Leonid Pershin
2026-07-30 04:05:01 +03:00
parent cc7e2a7f8f
commit c2ed3240bd
37 changed files with 2052 additions and 63 deletions
@@ -0,0 +1,41 @@
using PnvPanel.Domain.Common;
namespace PnvPanel.Domain.Media;
/// <summary>
/// Картинка, загруженная админом для вставки в markdown (инструкции, новости). StoredFileName —
/// серверное имя на диске (GUID-based), FileName — оригинальное имя только для отображения
/// (не участвует в построении пути — не доверяем пользовательскому вводу для файловой системы).
/// Отдаётся анонимно по непрозрачному Id: markdown рендерится обычным &lt;img&gt;, который не шлёт JWT.
/// </summary>
public sealed class MediaImage : Entity
{
public string FileName { get; private set; } = string.Empty;
public string StoredFileName { get; private set; } = string.Empty;
public string ContentType { get; private set; } = string.Empty;
public long SizeBytes { get; private set; }
public Guid UploadedBy { get; private set; }
public DateTimeOffset CreatedAt { get; private set; }
private MediaImage() { }
public static MediaImage Create(
string fileName,
string storedFileName,
string contentType,
long sizeBytes,
Guid uploadedBy
)
{
return new MediaImage
{
Id = Guid.NewGuid(),
FileName = fileName,
StoredFileName = storedFileName,
ContentType = contentType,
SizeBytes = sizeBytes,
UploadedBy = uploadedBy,
CreatedAt = DateTimeOffset.UtcNow,
};
}
}