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,174 @@
namespace FlatRender.StudioSvc.Models.Responses;
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);
public record SavedProjectSummaryResponse(
Guid Id,
Guid UserId,
Guid OriginalProjectId,
string OriginalProjectName,
string? OriginalContainerSlug,
string Name,
string? Image,
string Type,
string Resolution,
string ChooseMode,
decimal ProjectDurationSec,
DateTime LastEditDate,
DateTime CreatedAt
);
public record SavedProjectFullResponse(
Guid Id,
Guid UserId,
Guid OriginalProjectId,
string OriginalProjectName,
string? OriginalContainerSlug,
string Name,
string? Image,
string Type,
int FrameRate,
decimal ProjectDurationSec,
string Resolution,
string ChooseMode,
decimal VipFactor,
Guid? MusicFileId,
Guid? MusicTrackId,
decimal MusicVolume,
Guid? VoiceoverFileId,
decimal VoiceoverVolume,
bool VoiceoverRecordedInBrowser,
decimal SfxVolume,
bool SfxEnabled,
string? AudioVisualizerMusicUrl,
decimal? AudioVisualizerDurationSec,
bool ManualColorPicker,
Guid? SelectedPresetStoryId,
string? LastEditStep,
string EditState,
DateTime LastEditDate,
DateTime CreatedAt,
List<SavedSceneResponse> Scenes,
List<SavedSharedColorResponse> SharedColors,
List<SavedSharedColorPresetResponse> SharedColorPresets,
List<SavedSharedLayerResponse> SharedLayers
);
public record SavedSceneResponse(
long Id,
Guid? OriginalSceneId,
string Key,
string? Title,
string? Image,
string SceneType,
int Sort,
decimal SceneLengthSec,
decimal? MinDurationSec,
decimal? MaxDurationSec,
decimal OverlapAtEndSec,
bool CanHandleDuration,
bool ManualColorSelection,
long? SelectedColorPresetId,
List<SavedSceneContentResponse> Contents,
List<SavedSceneColorResponse> Colors,
List<SavedSceneColorPresetResponse> ColorPresets,
List<SavedSceneCharacterResponse> Characters
);
public record SavedSceneContentResponse(
long Id,
string Key,
string? Title,
string Type,
string? Value,
Guid? ValueFileId,
string? FileUrlCached,
string? FontFace,
int? FontSize,
string? Justify,
int PositionInContainer,
int DirectionLayerValue,
bool IsTextBox,
string? AiInputType,
int? SelectedDp,
string? RepeaterItemKey,
int? RepeaterIndex,
bool IsFocused,
string? MappedList,
int Sort
);
public record SavedSceneColorResponse(
long Id,
string ElementKey,
string? Title,
string? Icon,
string AttrValue,
string Value,
bool IsSelected,
int Sort
);
public record SavedSceneColorPresetResponse(
long Id,
bool IsSelected,
int Sort,
List<SavedColorPresetItemResponse> Items
);
public record SavedColorPresetItemResponse(long Id, string ElementKey, string Value, int Sort);
public record SavedSceneCharacterResponse(
long Id,
Guid Key,
string? Name,
string? Icon,
List<SavedCharacterControllerResponse> Controllers
);
public record SavedCharacterControllerResponse(long Id, string? Name, string Key, string Value, int Sort);
public record SavedSharedColorResponse(
long Id,
string ElementKey,
string? Title,
string? Icon,
string AttrValue,
string Value,
bool IsSelected,
int Sort
);
public record SavedSharedColorPresetResponse(
long Id,
string? Name,
bool IsSelected,
int Sort,
List<SavedColorPresetItemResponse> Items
);
public record SavedSharedLayerResponse(
long Id,
string Key,
string? Title,
string Type,
string? Value,
Guid? ValueFileId,
string? FileUrlCached,
string? FontFace,
int? FontSize,
string? Justify,
int PositionInContainer,
int DirectionLayerValue,
bool IsTextBox,
string? AiInputType,
string? MappedList,
int? Width,
int? Height,
bool IsFocused,
bool IsFontChangeable,
bool IsFontSizeChangeable,
int Sort
);