Files
tnsu-approval-route/backend/Tnsu.ApprovalRoute.Api/Program.cs
T
gorbenko.pavel e4a6cb8167
Tests / frontend-test (push) Successful in 46s
Tests / backend-test (push) Successful in 1m48s
Новые условия (#15)
Co-authored-by: gorbenko.pavel <gorbenko.pavel@tansu.kz>
Reviewed-on: http://git.tnsu.kz/gorbenko.pavel/tnsu-approval-route/pulls/15
2026-08-24 12:27:25 +00:00

138 lines
4.8 KiB
C#

using System.Text.Json.Serialization;
using Extensions.Hosting.AsyncInitialization;
using Hangfire;
using Hangfire.PostgreSql;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi;
using Scalar.AspNetCore;
using Serilog;
using Tnsu.ApprovalRoute.Api.Auth;
using Tnsu.ApprovalRoute.Api.Filters;
using Tnsu.ApprovalRoute.Application;
using Tnsu.ApprovalRoute.Application.ListPartitioning;
using Tnsu.ApprovalRoute.Application.Reminders;
using Tnsu.ApprovalRoute.Application.Common.Interfaces;
using Tnsu.ApprovalRoute.Infrastructure;
const string CorsPolicyName = "Frontend";
var builder = WebApplication.CreateBuilder(args);
// Локальные оверрайды, не попадающие в git (см. .gitignore) — на своей машине
// можно, например, занизить ListPartitioning:ItemCountThreshold, чтобы не
// накапливать тысячи тестовых заявок для проверки создания партиций.
builder.Configuration.AddJsonFile("appsettings.Local.json", optional: true, reloadOnChange: true);
builder.Host.UseSerilog((context, services, configuration) => configuration
.ReadFrom.Configuration(context.Configuration)
.Enrich.FromLogContext()
.WriteTo.Console()
.WriteTo.File(
"logs/log-.txt",
rollingInterval: RollingInterval.Month,
retainedFileCountLimit: 6));
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
options.KnownIPNetworks.Clear();
options.KnownProxies.Clear();
});
var corsAllowedOrigins = builder.Configuration.GetSection("Cors:AllowedOrigins").Get<string[]>() ?? [];
builder.Services.AddCors(options =>
{
options.AddPolicy(CorsPolicyName, policy => policy
.WithOrigins(corsAllowedOrigins)
.AllowAnyHeader()
.AllowAnyMethod());
});
builder.Services.AddApprovalRouteInfrastructure(builder.Configuration);
builder.Services.AddApprovalRouteApplication();
builder.Services.Configure<RemindersOptions>(builder.Configuration.GetSection("Reminders"));
builder.Services.Configure<ListPartitioningOptions>(builder.Configuration.GetSection("ListPartitioning"));
builder.Services.AddHangfire(configuration => configuration
.SetDataCompatibilityLevel(CompatibilityLevel.Version_180)
.UseSimpleAssemblyNameTypeSerializer()
.UseRecommendedSerializerSettings()
.UsePostgreSqlStorage(postgres =>
postgres.UseNpgsqlConnection(builder.Configuration.GetConnectionString("Postgres"))));
builder.Services.AddHangfireServer();
builder.Services.AddApprovalRouteAuth(builder.Configuration);
builder.Services.AddScoped<ICurrentUser, CurrentUserAccessor>();
builder.Services.AddOpenApi(options =>
{
options.AddDocumentTransformer((document, _, _) =>
{
document.Components ??= new OpenApiComponents();
document.Components.SecuritySchemes ??= new Dictionary<string, IOpenApiSecurityScheme>();
document.Components.SecuritySchemes["Bearer"] = new OpenApiSecurityScheme
{
Type = SecuritySchemeType.Http,
Scheme = "bearer",
BearerFormat = "JWT",
Description = "Введите JWT токен"
};
return Task.CompletedTask;
});
options.AddOperationTransformer((operation, context, _) =>
{
operation.Security =
[
new OpenApiSecurityRequirement
{
[new OpenApiSecuritySchemeReference("Bearer", context.Document)] = []
}
];
return Task.CompletedTask;
});
});
builder.Services.AddHealthChecks();
builder.Services.AddControllers(options => options.Filters.Add<ValidationActionFilter>())
.AddJsonOptions(o => o.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()));
builder.Services.ConfigureHttpJsonOptions(o => o.SerializerOptions.Converters.Add(new JsonStringEnumConverter()));
var app = builder.Build();
app.UseForwardedHeaders();
app.MapOpenApi();
app.MapScalarApiReference(options =>
{
options
.WithTitle("Tnsu Approval Route")
.AddPreferredSecuritySchemes("Bearer")
.AddHttpAuthentication("Bearer", _ => { });
});
app.MapHealthChecks("/health");
app.UseCors(CorsPolicyName);
app.UseAuthentication();
app.UseAuthorization();
app.UseHangfireDashboard("/hangfire", new DashboardOptions
{
Authorization =
[
new HangfireDashboardBasicAuthFilter(
app.Configuration["Hangfire:Dashboard:Username"] ?? string.Empty,
app.Configuration["Hangfire:Dashboard:Password"] ?? string.Empty)
]
});
app.MapControllers();
await app.InitAndRunAsync();
public partial class Program;