a36e96d933
The card + detail read template.sceneCount, but the API never sent one — so the frontend mapper hardcoded sceneCount:0 for every DB-backed template. - content-svc: ContainerSummaryResponse + ContainerDetailResponse now carry SceneCount. The list computes it with one grouped query (scenes per aspect project, max across aspects); the detail loads scenes and counts them. - frontend: V2ContainerSummary.scene_count → AdminProject.sceneCount → the catalog card/detail (adminProjectToCatalogTemplate no longer hardcodes 0). Verified on the live local API: fr-instagram-promo → 5, single-scene templates → 1. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
490 lines
11 KiB
C#
490 lines
11 KiB
C#
using FlatRender.ContentSvc.Domain.Enums;
|
|
|
|
namespace FlatRender.ContentSvc.Models.Responses;
|
|
|
|
// ── Pagination ───────────────────────────────────────────────────────────────
|
|
|
|
public record PagedResponse<T>(IEnumerable<T> Items, PaginationMeta Meta);
|
|
public record PaginationMeta(int Page, int PageSize, long Total, int TotalPages);
|
|
public record ApiError(string Code, string Message, string? TraceId = null);
|
|
|
|
// ── Taxonomy ─────────────────────────────────────────────────────────────────
|
|
|
|
public record CategoryResponse(
|
|
Guid Id,
|
|
Guid? ParentId,
|
|
string Name,
|
|
string Slug,
|
|
string? Description,
|
|
string? ImageUrl,
|
|
string? Icon,
|
|
bool IsActive,
|
|
int Sort,
|
|
List<CategoryResponse> Children
|
|
);
|
|
|
|
public record TagResponse(
|
|
Guid Id,
|
|
string Name,
|
|
string? LatinName,
|
|
string Slug,
|
|
string? AppliesToMode,
|
|
bool IsActive
|
|
);
|
|
|
|
public record FontResponse(
|
|
Guid Id,
|
|
string Name,
|
|
string? OriginalName,
|
|
string? SystemName,
|
|
string? Family,
|
|
int? Weight,
|
|
string? Style,
|
|
string Direction,
|
|
string? FileUrl,
|
|
string? SampleImageUrl,
|
|
bool IsPremium,
|
|
bool IsActive,
|
|
bool InstalledOnNodes
|
|
);
|
|
|
|
public record MusicTrackResponse(
|
|
Guid Id,
|
|
string Name,
|
|
string? Caption,
|
|
string Url,
|
|
string? WaveformData,
|
|
decimal DurationSec,
|
|
int? Bpm,
|
|
string? Genre,
|
|
string? Mood,
|
|
bool IsPremium
|
|
);
|
|
|
|
// ── Templates ────────────────────────────────────────────────────────────────
|
|
|
|
public record ContainerSummaryResponse(
|
|
Guid Id,
|
|
string Slug,
|
|
string Name,
|
|
string? Description,
|
|
string? Image,
|
|
string? Demo,
|
|
string? MiniDemo,
|
|
bool IsPublished,
|
|
bool IsPremium,
|
|
bool IsMockup,
|
|
string PrimaryMode,
|
|
decimal? RateAvg,
|
|
int RateCount,
|
|
long ViewCount,
|
|
long UseCount,
|
|
int Sort,
|
|
DateTime SortDate,
|
|
List<string> CategorySlugs,
|
|
List<string> Tags,
|
|
int SceneCount
|
|
);
|
|
|
|
public record ContainerDetailResponse(
|
|
Guid Id,
|
|
string Slug,
|
|
string Name,
|
|
string? Description,
|
|
string? Keywords,
|
|
string? NewsText,
|
|
string? Image,
|
|
string? Demo,
|
|
string? FullDemo,
|
|
string? MiniDemo,
|
|
string? DemoScriptTag,
|
|
bool IsPublished,
|
|
bool IsPremium,
|
|
bool IsMockup,
|
|
string PrimaryMode,
|
|
decimal? RateAvg,
|
|
int RateCount,
|
|
long ViewCount,
|
|
long UseCount,
|
|
int Sort,
|
|
DateTime SortDate,
|
|
List<ProjectResponse> Projects,
|
|
List<CategoryResponse> Categories,
|
|
List<TagResponse> Tags,
|
|
int SceneCount
|
|
);
|
|
|
|
public record ProjectResponse(
|
|
Guid Id,
|
|
Guid ContainerId,
|
|
string Name,
|
|
string? Image,
|
|
string? FullDemo,
|
|
int OriginalWidth,
|
|
int OriginalHeight,
|
|
string? Aspect,
|
|
decimal ProjectDurationSec,
|
|
decimal? MinDurationSec,
|
|
decimal? MaxDurationSec,
|
|
int FreeFps,
|
|
string ChooseMode,
|
|
string Resolution,
|
|
bool IsPublished,
|
|
int Sort,
|
|
string? AepFileUrl,
|
|
long? AepFileSizeBytes,
|
|
string RenderAepComp,
|
|
string RenderEngine,
|
|
string? RenderRemotionComp
|
|
);
|
|
|
|
public record ProjectListItemResponse(
|
|
Guid Id,
|
|
Guid ContainerId,
|
|
string ContainerName,
|
|
string ContainerSlug,
|
|
string Name,
|
|
string? Image,
|
|
string? Aspect,
|
|
string Resolution,
|
|
string? AepFileUrl,
|
|
string RenderAepComp,
|
|
bool IsPublished,
|
|
int Sort,
|
|
string RenderEngine,
|
|
string? RenderRemotionComp
|
|
);
|
|
|
|
public record ProjectAssetResponse(Guid Id, Guid ProjectId, string Name, string Kind, string Url, long? SizeBytes, int Sort);
|
|
|
|
public record ProjectDetailResponse(
|
|
Guid Id,
|
|
Guid ContainerId,
|
|
string Name,
|
|
string? Description,
|
|
string? Image,
|
|
string? FullDemo,
|
|
string? DemoScriptTag,
|
|
string? DownloadLink,
|
|
int OriginalWidth,
|
|
int OriginalHeight,
|
|
string? Aspect,
|
|
decimal ProjectDurationSec,
|
|
decimal? MinDurationSec,
|
|
decimal? MaxDurationSec,
|
|
int FreeFps,
|
|
string ChooseMode,
|
|
string Resolution,
|
|
decimal VipFactor,
|
|
string RenderAepComp,
|
|
string RenderEngine,
|
|
string? RenderRemotionComp,
|
|
string? SharedLayerImage,
|
|
bool IsPublished,
|
|
int Sort,
|
|
List<SceneResponse> Scenes,
|
|
List<SharedColorResponse> SharedColors,
|
|
List<SharedLayerResponse> SharedLayers
|
|
);
|
|
|
|
// ── Scenes ───────────────────────────────────────────────────────────────────
|
|
|
|
public record SceneResponse(
|
|
Guid Id,
|
|
Guid ProjectId,
|
|
string Key,
|
|
string Title,
|
|
string? LocalizedTitle,
|
|
string SceneType,
|
|
string? Image,
|
|
string? Demo,
|
|
string? SnapshotUrl,
|
|
bool GenerateKf,
|
|
decimal? DefaultDurationSec,
|
|
decimal? MinDurationSec,
|
|
decimal? MaxDurationSec,
|
|
decimal OverlapAtEndSec,
|
|
bool CanHandleDuration,
|
|
bool ManualColorSelection,
|
|
int Sort,
|
|
bool IsActive
|
|
);
|
|
|
|
public record SceneDetailResponse(
|
|
Guid Id,
|
|
Guid ProjectId,
|
|
string Key,
|
|
string Title,
|
|
string? LocalizedTitle,
|
|
string SceneType,
|
|
string? Image,
|
|
string? Demo,
|
|
string? SnapshotUrl,
|
|
bool GenerateKf,
|
|
decimal? DefaultDurationSec,
|
|
decimal? MinDurationSec,
|
|
decimal? MaxDurationSec,
|
|
decimal OverlapAtEndSec,
|
|
bool CanHandleDuration,
|
|
bool ManualColorSelection,
|
|
int Sort,
|
|
bool IsActive,
|
|
List<RepeaterItemResponse> RepeaterItems,
|
|
List<ContentElementResponse> ContentElements,
|
|
List<ColorElementResponse> ColorElements,
|
|
List<ColorPresetResponse> ColorPresets,
|
|
List<CharacterResponse> Characters
|
|
);
|
|
|
|
public record RepeaterItemResponse(
|
|
Guid Id,
|
|
string Title,
|
|
string RepeatBoxKey,
|
|
string RepeatItemKey,
|
|
int MaxRepeatCount,
|
|
bool UserCanChangeSort,
|
|
string RepeatSortStrategy,
|
|
int Sort,
|
|
List<ContentElementResponse> ContentElements
|
|
);
|
|
|
|
public record ContentElementResponse(
|
|
Guid Id,
|
|
Guid? RepeaterItemId,
|
|
string Key,
|
|
string Title,
|
|
string? LocalizedTitle,
|
|
string? Hint,
|
|
string Type,
|
|
string? DefaultValue,
|
|
Guid? FontId,
|
|
string? FontFace,
|
|
string? FontFaceName,
|
|
int? FontSize,
|
|
int? DefaultFontSize,
|
|
string? DefaultFontFace,
|
|
bool IsFontChangeable,
|
|
bool IsFontSizeChangeable,
|
|
string Justify,
|
|
bool CanJustify,
|
|
int PositionInContainer,
|
|
bool IsTextBox,
|
|
int? MaxSize,
|
|
string? DirectionLayerKey,
|
|
int DirectionLayerValue,
|
|
bool VideoSupport,
|
|
decimal? MinDurationSec,
|
|
decimal? MaxDurationSec,
|
|
int? Width,
|
|
int? Height,
|
|
string? Thumbnail,
|
|
string? MappedList,
|
|
string? CounterMode,
|
|
string AiInputType,
|
|
bool IsHidden,
|
|
bool IsFocused,
|
|
string? OpacityControllerKey,
|
|
int VirtualCount,
|
|
int Sort
|
|
);
|
|
|
|
public record ColorElementResponse(
|
|
Guid Id,
|
|
string ElementKey,
|
|
string Title,
|
|
string? Icon,
|
|
string AttrValue,
|
|
string DefaultColor,
|
|
int Sort
|
|
);
|
|
|
|
public record ColorPresetResponse(
|
|
Guid Id,
|
|
string? Name,
|
|
int Sort,
|
|
List<ColorPresetItemResponse> Items
|
|
);
|
|
|
|
public record ColorPresetItemResponse(
|
|
Guid Id,
|
|
string ElementKey,
|
|
string Value,
|
|
int Sort
|
|
);
|
|
|
|
public record SharedColorResponse(
|
|
Guid Id,
|
|
string ElementKey,
|
|
string Title,
|
|
string? Icon,
|
|
string AttrValue,
|
|
string DefaultColor,
|
|
int Sort
|
|
);
|
|
|
|
public record SharedLayerResponse(
|
|
Guid Id,
|
|
string Key,
|
|
string Title,
|
|
string? LocalizedTitle,
|
|
string? Hint,
|
|
string Type,
|
|
string? DefaultValue,
|
|
Guid? FontId,
|
|
string? FontFace,
|
|
int? FontSize,
|
|
bool IsFontChangeable,
|
|
bool IsFontSizeChangeable,
|
|
string Justify,
|
|
bool CanJustify,
|
|
int PositionInContainer,
|
|
bool IsTextBox,
|
|
int? MaxSize,
|
|
bool VideoSupport,
|
|
decimal? MinDurationSec,
|
|
decimal? MaxDurationSec,
|
|
int? Width,
|
|
int? Height,
|
|
string? MappedList,
|
|
string AiInputType,
|
|
bool IsHidden,
|
|
bool IsFocused,
|
|
int VirtualCount,
|
|
int Sort
|
|
);
|
|
|
|
// ── Characters ───────────────────────────────────────────────────────────────
|
|
|
|
public record CharacterResponse(
|
|
Guid Id,
|
|
string Key,
|
|
string Name,
|
|
string? Icon,
|
|
int Sort,
|
|
List<CharacterControllerResponse> Controllers
|
|
);
|
|
|
|
public record CharacterControllerResponse(
|
|
Guid Id,
|
|
string Name,
|
|
string Key,
|
|
string? DefaultValue,
|
|
int Sort,
|
|
List<ControllerOptionResponse> Options
|
|
);
|
|
|
|
public record ControllerOptionResponse(
|
|
Guid Id,
|
|
string Name,
|
|
string? Icon,
|
|
string Value,
|
|
int Sort
|
|
);
|
|
|
|
// ── CMS ──────────────────────────────────────────────────────────────────────
|
|
|
|
public record BlogSummaryResponse(
|
|
Guid Id,
|
|
string Slug,
|
|
string Title,
|
|
string? ShortDescription,
|
|
string? Image,
|
|
string? Cover,
|
|
string? AuthorDisplayName,
|
|
bool IsPublished,
|
|
DateTime? PublishDate,
|
|
long ViewCount,
|
|
DateTime CreatedAt
|
|
);
|
|
|
|
public record BlogDetailResponse(
|
|
Guid Id,
|
|
string Slug,
|
|
string Title,
|
|
string? ShortDescription,
|
|
string Content,
|
|
string? MetaTitle,
|
|
string? MetaDescription,
|
|
string? MetaKeywords,
|
|
bool IncludeInSiteMap,
|
|
string? Image,
|
|
string? Cover,
|
|
Guid? AuthorUserId,
|
|
string? AuthorDisplayName,
|
|
bool IsPublished,
|
|
DateTime? PublishDate,
|
|
long ViewCount,
|
|
DateTime CreatedAt,
|
|
DateTime UpdatedAt
|
|
);
|
|
|
|
public record CommentResponse(
|
|
Guid Id,
|
|
Guid UserId,
|
|
Guid? BlogId,
|
|
Guid? ContainerId,
|
|
Guid? ParentCommentId,
|
|
string Content,
|
|
decimal? Rate,
|
|
bool IsApproved,
|
|
bool IsPinned,
|
|
DateTime CreatedAt
|
|
);
|
|
|
|
public record SlideResponse(
|
|
Guid Id,
|
|
string? Keyword,
|
|
string? Title,
|
|
string? Image,
|
|
string? Parameter,
|
|
string SlideType,
|
|
DateTime? ExpireDate,
|
|
int Sort,
|
|
bool IsActive
|
|
);
|
|
|
|
public record InternalRouteResponse(
|
|
Guid Id,
|
|
string? Name,
|
|
string? Image,
|
|
string Slug,
|
|
int Priority,
|
|
DateTime? LastDate
|
|
);
|
|
|
|
public record HomePageEventResponse(
|
|
Guid Id,
|
|
string? Title,
|
|
string? Subtitle,
|
|
string? Description,
|
|
string? Badge,
|
|
string? BadgeClass,
|
|
string? ButtonText,
|
|
string? ButtonUrl,
|
|
string? ButtonClass,
|
|
string? Color,
|
|
string? BackgroundColor,
|
|
string? TextColor,
|
|
string? Image,
|
|
bool IsActive,
|
|
int Sort,
|
|
DateTime? StartsAt,
|
|
DateTime? EndsAt
|
|
);
|
|
|
|
public record WebsiteSettingResponse(
|
|
Guid Id,
|
|
string Key,
|
|
string Value,
|
|
string? Description,
|
|
bool IsSecret
|
|
);
|
|
|
|
public record FavoriteFolderResponse(
|
|
Guid Id,
|
|
string Name,
|
|
string? Description,
|
|
int ContainerCount,
|
|
DateTime CreatedAt
|
|
);
|