feat: V2 microservices stack — backend services, gateway, JWT auth
Add full V2 architecture: identity, content, studio (.NET 10) and file, render, notification, gateway (Go) services with vendored deps, plus DB migrations, event/API contracts, and an init-db script. Wire the Next.js frontend to the gateway: server-side JWT auth routes (login/register/refresh/logout/me), gateway fetch helper, and session/ cookie/jwt helpers under src/lib. Containerize the stack via docker-compose.v2.yml and per-service Dockerfiles. Base images resolve through a Nexus mirror (Docker Hub) and MCR directly; npm/NuGet pull from Nexus groups. Self-host fonts via next/font/local to avoid Google Fonts (geo-blocked). Add CI workflow and ignore .env.v2, *.stackdump, and .NET bin/obj. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,452 @@
|
||||
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
|
||||
);
|
||||
|
||||
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
|
||||
);
|
||||
|
||||
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
|
||||
);
|
||||
|
||||
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? 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 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
|
||||
);
|
||||
Reference in New Issue
Block a user