feat(backend): restructure API into layers with OpenAPI, versioning and error handling

Split the backend into API host, Domain, Application and Infrastructure projects. Add Swagger/OpenAPI per API version, Asp.Versioning (query/header), ProblemDetails with a global exception handler and SurrealQL migrations applied at startup (namespace/database ensured). Infrastructure owns the SurrealDB client, settings and DI.
This commit is contained in:
Rafał Tyński
2026-10-04 01:49:51 +02:00
parent 0a5ef715eb
commit b3756238a3
26 changed files with 437 additions and 63 deletions
@@ -0,0 +1,21 @@
namespace TarninaHub.Infrastructure.Settings;
public static class SurrealDbEndpoint
{
/// <summary>
/// Builds the SurrealDB endpoint. Remote mode uses the configured URL;
/// embedded mode uses the RocksDB provider persisted to the data directory
/// (forward slashes, so the same endpoint works on Windows and Linux).
/// </summary>
public static string Build(SurrealDbSettings settings)
{
if (!string.IsNullOrWhiteSpace(settings.RemoteUrl))
{
return settings.RemoteUrl;
}
var dataDirectory = Path.Combine(AppContext.BaseDirectory, settings.DataDirectory);
return $"rocksdb://{dataDirectory.Replace('\\', '/')}";
}
}
@@ -0,0 +1,27 @@
namespace TarninaHub.Infrastructure.Settings;
public sealed class SurrealDbSettings
{
public string Namespace { get; set; } = "hubmi";
public string Database { get; set; } = "hubmi";
public string DataDirectory { get; set; } = "data";
/// <summary>
/// Directory (relative to the app base directory) with ordered *.surql
/// migration files applied at startup. Copied from backend/migrations.
/// </summary>
public string MigrationsDirectory { get; set; } = "migrations";
/// <summary>
/// When set (e.g. ws://127.0.0.1:8010/rpc), the backend connects to a
/// dedicated SurrealDB server instead of the embedded RocksDB engine.
/// The server must persist to ./data, not to memory.
/// </summary>
public string? RemoteUrl { get; set; }
public string? Username { get; set; }
public string? Password { get; set; }
}