Files
idoklad/Program.cs
T
2026-06-12 14:18:21 +02:00

100 lines
3.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Microsoft.OpenApi.Models;
using Newtonsoft.Json;
using Idoklad.Client;
using Idoklad.Configuration;
using Idoklad.Credentials;
using Idoklad.Infrastructure;
using Idoklad.Services;
var builder = WebApplication.CreateBuilder(args);
// Configuration resolved from environment variables (single shared instance).
var settings = new IdokladSettings();
builder.Services.AddSingleton(settings);
// HttpClient for the iDoklad SDK, managed by IHttpClientFactory (recommended SDK usage).
builder.Services.AddHttpClient(DokladApiFactory.HttpClientName, client =>
{
client.Timeout = TimeSpan.FromSeconds(settings.RequestTimeoutSeconds);
});
builder.Services.AddHttpContextAccessor();
// Credential resolution + SDK client wiring.
builder.Services.AddScoped<RequestCredentialsProvider>();
builder.Services.AddScoped<DokladApiFactory>();
builder.Services.AddScoped<IdokladApiAccessor>();
// Agenda services.
builder.Services.AddScoped<ContactsService>();
builder.Services.AddScoped<IssuedInvoicesService>();
builder.Services.AddScoped<ReceivedInvoicesService>();
builder.Services.AddScoped<RegistersService>();
builder.Services.AddScoped<AccountService>();
builder.Services.AddScoped<CodeListsService>();
builder.Services.AddScoped<SalesDocumentsService>();
builder.Services.AddScoped<PurchaseCashService>();
builder.Services.AddScoped<PaymentsService>();
builder.Services.AddScoped<CatalogService>();
builder.Services.AddScoped<IntegrationService>();
builder.Services.AddScoped<StatisticsService>();
// Use Newtonsoft.Json so request/response binding matches the iDoklad SDK model attributes.
builder.Services
.AddControllers()
.AddNewtonsoftJson(options =>
{
options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
});
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1", new OpenApiInfo
{
Title = settings.AppName,
Version = settings.AppVersion,
Description =
"REST integration with iDoklad built on the official IdokladSdk (.NET) 5.3.0, " +
"using the OAuth2 client credentials flow.\n\n" +
"**Credentials.** Every agenda endpoint needs an iDoklad ClientId, ClientSecret and ApplicationId. " +
"Sensitive values are required in request headers and are never accepted in the query string or body:\n\n" +
"- `X-ClientId` — iDoklad OAuth2 ClientId\n" +
"- `X-ClientSecret` — iDoklad OAuth2 ClientSecret (sensitive; TLS only)\n" +
"- `X-ApplicationId` — iDoklad ApplicationId from the developer portal\n" +
"- `X-Idoklad-Language` — optional response language (Cz, Sk, En)\n\n" +
"If a header is omitted, the matching environment default " +
"(`IDOKLAD_CLIENT_ID`, `IDOKLAD_CLIENT_SECRET`, `IDOKLAD_APPLICATION_ID`) is used. " +
"If neither a header nor a default is available, the request is rejected with 401.",
});
options.OperationFilter<CredentialHeadersOperationFilter>();
var xmlPath = Path.Combine(AppContext.BaseDirectory, $"{System.Reflection.Assembly.GetExecutingAssembly().GetName().Name}.xml");
if (File.Exists(xmlPath))
{
options.IncludeXmlComments(xmlPath, includeControllerXmlComments: true);
}
});
var app = builder.Build();
if (!string.IsNullOrWhiteSpace(settings.RootPath))
{
app.UsePathBase(settings.RootPath);
}
app.UseMiddleware<ExceptionHandlingMiddleware>();
app.UseSwagger();
app.UseSwaggerUI(options =>
{
// Serve the interactive docs at /docs (matching the sibling microsoft-365-service).
options.RoutePrefix = "docs";
options.SwaggerEndpoint("/swagger/v1/swagger.json", $"{settings.AppName} v1");
options.DocumentTitle = $"{settings.AppName} API docs";
});
app.MapControllers();
app.Run();