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:
soroush.asadi
2026-05-29 23:29:31 +03:30
parent 53ea78a00d
commit 90ac0b81d1
7636 changed files with 3707504 additions and 240 deletions
@@ -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
);