62fa1d5c4c
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
91 lines
2.7 KiB
C#
91 lines
2.7 KiB
C#
using System.Globalization;
|
|
using MoneyMap.Core;
|
|
using MoneyMap.Services;
|
|
using MoneyMap.WebApp.Services;
|
|
|
|
// Set default culture to en-US for currency formatting ($)
|
|
var culture = new CultureInfo("en-US");
|
|
CultureInfo.DefaultThreadCurrentCulture = culture;
|
|
CultureInfo.DefaultThreadCurrentUICulture = culture;
|
|
|
|
var builder = WebApplication.CreateBuilder(args);
|
|
|
|
builder.Services.AddMoneyMapCore(builder.Configuration);
|
|
builder.Services.AddSingleton<IReceiptStorageOptions, WebReceiptStorageOptions>();
|
|
|
|
// Add session support
|
|
builder.Services.AddDistributedMemoryCache();
|
|
builder.Services.AddSession(options =>
|
|
{
|
|
options.IdleTimeout = TimeSpan.FromMinutes(30);
|
|
options.Cookie.HttpOnly = true;
|
|
options.Cookie.IsEssential = true;
|
|
options.IOTimeout = TimeSpan.FromMinutes(5);
|
|
});
|
|
|
|
// Use session-based TempData provider to avoid cookie size limits
|
|
builder.Services.AddRazorPages()
|
|
.AddSessionStateTempDataProvider();
|
|
|
|
// Receipt parse queue and background worker
|
|
builder.Services.AddSingleton<IReceiptParseQueue, ReceiptParseQueue>();
|
|
builder.Services.AddHostedService<ReceiptParseWorkerService>();
|
|
|
|
// AI vision clients and tool-use support
|
|
builder.Services.AddHttpClient<OpenAIVisionClient>();
|
|
builder.Services.AddHttpClient<ClaudeVisionClient>();
|
|
builder.Services.AddHttpClient<OllamaVisionClient>();
|
|
builder.Services.AddHttpClient<LlamaCppVisionClient>();
|
|
builder.Services.AddScoped<IAIVisionClientResolver, AIVisionClientResolver>();
|
|
builder.Services.AddScoped<IReceiptParser, AIReceiptParser>();
|
|
|
|
// AI categorization service
|
|
builder.Services.AddHttpClient<ITransactionAICategorizer, TransactionAICategorizer>();
|
|
|
|
// Model warmup service
|
|
builder.Services.AddHostedService<ModelWarmupService>();
|
|
|
|
var app = builder.Build();
|
|
|
|
// Seed default category mappings on startup
|
|
using (var scope = app.Services.CreateScope())
|
|
{
|
|
var categorizer = scope.ServiceProvider.GetRequiredService<ITransactionCategorizer>();
|
|
await categorizer.SeedDefaultMappingsAsync();
|
|
}
|
|
|
|
// Configure the HTTP request pipeline.
|
|
if (!app.Environment.IsDevelopment())
|
|
{
|
|
app.UseExceptionHandler("/Error");
|
|
app.UseHsts();
|
|
}
|
|
|
|
app.UseHttpsRedirection();
|
|
app.UseStaticFiles();
|
|
|
|
app.UseRouting();
|
|
|
|
app.UseSession();
|
|
|
|
app.UseAuthorization();
|
|
|
|
app.MapRazorPages();
|
|
|
|
// Financial Audit API endpoint
|
|
app.MapGet("/api/audit", async (
|
|
IFinancialAuditService auditService,
|
|
DateTime? startDate,
|
|
DateTime? endDate,
|
|
bool includeTransactions = false) =>
|
|
{
|
|
var end = endDate ?? DateTime.Today;
|
|
var start = startDate ?? end.AddDays(-90);
|
|
|
|
var result = await auditService.GenerateAuditAsync(start, end, includeTransactions);
|
|
return Results.Ok(result);
|
|
})
|
|
.WithName("GetFinancialAudit");
|
|
|
|
app.Run();
|