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,71 @@
using System.ComponentModel.DataAnnotations;
namespace FlatRender.IdentitySvc.Models.Requests;
public record CreateTenantRequest(
[Required] string Slug,
[Required] string Name,
string? Kind,
string? ContactName,
[Required, EmailAddress] string ContactEmail,
string? ContactPhone
);
public record UpdateTenantRequest(
string? Name,
string? ContactName,
string? ContactEmail,
string? ContactPhone,
string? BillingEmail,
string[]? AllowedOrigins
);
public record TenantBrandingRequest(
string? DisplayName,
string? LogoUrl,
string? LogoDarkUrl,
string? FaviconUrl,
string? OgImageUrl,
string? PrimaryColor,
string? SecondaryColor,
string? AccentColor,
string? BackgroundColor,
string? FontFamily,
string? EmailFromName,
string? EmailFromAddress,
string? EmailReplyTo,
string? EmailFooterHtml,
string? SupportUrl,
string? TermsUrl,
string? PrivacyUrl,
bool? EmbedEnabled,
string[]? EmbedAllowedHosts,
string? WatermarkText,
string? WatermarkImageUrl,
bool? WatermarkEnabled
);
public record StartDomainVerificationRequest([Required] string Domain, string Method = "DNS_TXT");
public record CreateApiKeyRequest(
[Required] string Name,
string Environment = "Live",
[Required] string[] Scopes = default!,
string[]? AllowedIps = null,
int RateLimitRpm = 60,
DateTime? ExpiresAt = null
);
public record RevokeApiKeyRequest(string? Reason);
public record ValidateApiKeyRequest(
[Required] string KeyPrefix,
[Required] string KeyHash,
string? IpAddress
);
public record CreateWebhookRequest(
[Required] string Name,
[Required] string Url,
[Required] string[] Events
);