Files
ZakirovT 057e1f526b init
2026-01-22 00:45:41 +03:00

219 lines
7.9 KiB
C#
Raw Permalink 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 PerfReviewSummarizer.Api.Models;
using PerfReviewSummarizer.Api.Services;
var builder = WebApplication.CreateBuilder(args);
// Добавляем сервисы
builder.Services.AddScoped<IGitService, GitService>();
builder.Services.AddHttpClient<GeminiService>();
builder.Services.AddHttpClient<OpenAiService>();
builder.Services.AddSingleton<IAiServiceFactory, AiServiceFactory>();
builder.Services.AddScoped<IAiService>(sp => sp.GetRequiredService<IAiServiceFactory>().CreateAiService());
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddOpenApi();
builder.Services.AddSwaggerGen();
builder.Services.AddCors(options =>
{
options.AddDefaultPolicy(policy =>
{
policy.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
});
});
var app = builder.Build();
// Настройка статических файлов
app.UseStaticFiles();
// Настройка Swagger
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "PerfReviewSummarizer API v1");
c.RoutePrefix = "swagger"; // Swagger UI на /swagger
});
app.UseCors();
// Эндпоинт для получения summary
app.MapPost("/api/summary", async (SummaryRequest request, IGitService gitService, IConfiguration configuration) =>
{
try
{
var repositoryPath = request.RepositoryPath ?? configuration["GitRepository:DefaultPath"] ?? ".";
DateTime? startDate = request.StartDate;
DateTime? endDate = request.EndDate;
// Если указан период, вычисляем даты
if (!string.IsNullOrEmpty(request.Period) && !startDate.HasValue && !endDate.HasValue)
{
var now = DateTime.Now;
if (request.Period.ToLower() == "quarter")
{
// Текущий квартал
var quarter = (now.Month - 1) / 3;
startDate = new DateTime(now.Year, quarter * 3 + 1, 1);
endDate = startDate.Value.AddMonths(3).AddDays(-1);
}
else if (request.Period.ToLower() == "halfyear")
{
// Текущее полугодие
var half = (now.Month - 1) / 6;
startDate = new DateTime(now.Year, half * 6 + 1, 1);
endDate = startDate.Value.AddMonths(6).AddDays(-1);
}
}
var summary = await gitService.GenerateSummaryAsync(repositoryPath, startDate, endDate);
return Results.Ok(summary);
}
catch (DirectoryNotFoundException ex)
{
return Results.BadRequest(new { error = ex.Message });
}
catch (Exception ex)
{
return Results.Problem($"Ошибка при обработке запроса: {ex.Message}");
}
})
.WithName("GetSummary")
.Produces<SummaryResponse>(StatusCodes.Status200OK)
.Produces(StatusCodes.Status400BadRequest)
.Produces(StatusCodes.Status500InternalServerError);
// Эндпоинт для получения списка коммитов
app.MapGet("/api/commits", async (string? repositoryPath, DateTime? startDate, DateTime? endDate, IGitService gitService, IConfiguration configuration) =>
{
try
{
var repoPath = repositoryPath ?? configuration["GitRepository:DefaultPath"] ?? ".";
var commits = await gitService.GetCommitsAsync(repoPath, startDate, endDate);
return Results.Ok(commits);
}
catch (DirectoryNotFoundException ex)
{
return Results.BadRequest(new { error = ex.Message });
}
catch (Exception ex)
{
return Results.Problem($"Ошибка при обработке запроса: {ex.Message}");
}
})
.WithName("GetCommits")
.Produces<List<CommitInfo>>(StatusCodes.Status200OK)
.Produces(StatusCodes.Status400BadRequest)
.Produces(StatusCodes.Status500InternalServerError);
// Эндпоинт для получения AI summary (OpenAI или Gemini в зависимости от конфигурации)
app.MapPost("/api/summary/ai", async (OpenAiSummaryRequest request, IGitService gitService, IAiService aiService, IConfiguration configuration) =>
{
try
{
var repositoryPath = request.RepositoryPath ?? configuration["GitRepository:DefaultPath"] ?? ".";
DateTime? startDate = request.StartDate;
DateTime? endDate = request.EndDate;
// Если указан период, вычисляем даты
if (!string.IsNullOrEmpty(request.Period) && !startDate.HasValue && !endDate.HasValue)
{
var now = DateTime.Now;
if (request.Period.ToLower() == "quarter")
{
var quarter = (now.Month - 1) / 3;
startDate = new DateTime(now.Year, quarter * 3 + 1, 1);
endDate = startDate.Value.AddMonths(3).AddDays(-1);
}
else if (request.Period.ToLower() == "halfyear")
{
var half = (now.Month - 1) / 6;
startDate = new DateTime(now.Year, half * 6 + 1, 1);
endDate = startDate.Value.AddMonths(6).AddDays(-1);
}
}
// Получаем коммиты
var commits = await gitService.GetCommitsAsync(repositoryPath, startDate, endDate);
if (!commits.Any())
{
return Results.Ok(new OpenAiSummaryResponse
{
Summary = "Нет коммитов за указанный период для анализа",
CommitsCount = 0,
PeriodInfo = new PeriodInfo
{
StartDate = startDate ?? DateTime.MinValue,
EndDate = endDate ?? DateTime.MaxValue,
Description = "Период без коммитов"
}
});
}
var commitMessages = commits.Select(c => c.Message).ToList();
var aiSummary = await aiService.GenerateSummaryFromCommitMessagesAsync(commitMessages);
return Results.Ok(new OpenAiSummaryResponse
{
Summary = aiSummary,
CommitsCount = commits.Count,
CommitMessages = commitMessages,
PeriodInfo = new PeriodInfo
{
StartDate = startDate ?? commits.Min(c => c.When.DateTime),
EndDate = endDate ?? commits.Max(c => c.When.DateTime),
Description = $"С {startDate?.ToString("yyyy-MM-dd") ?? "начала"} по {endDate?.ToString("yyyy-MM-dd") ?? "конца"}"
}
});
}
catch (DirectoryNotFoundException ex)
{
return Results.BadRequest(new { error = ex.Message });
}
catch (InvalidOperationException ex)
{
return Results.BadRequest(new { error = ex.Message });
}
catch (Exception ex)
{
return Results.Problem($"Ошибка при обработке запроса: {ex.Message}");
}
})
.WithName("GetAiSummary")
.Produces<OpenAiSummaryResponse>(StatusCodes.Status200OK)
.Produces(StatusCodes.Status400BadRequest)
.Produces(StatusCodes.Status500InternalServerError);
// Health check
app.MapGet("/health", () => Results.Ok(new { status = "healthy", timestamp = DateTime.UtcNow }))
.WithName("HealthCheck")
.Produces(StatusCodes.Status200OK);
// Корневой эндпоинт - отдаем HTML страницу
app.MapGet("/", () =>
{
var htmlPath = Path.Combine(app.Environment.WebRootPath ?? "", "index.html");
if (File.Exists(htmlPath))
{
return Results.File(htmlPath, "text/html");
}
return Results.Ok(new
{
message = "PerfReviewSummarizer API",
version = "1.0.0",
endpoints = new[]
{
"POST /api/summary - Получить summary за период",
"GET /api/commits?repositoryPath=&startDate=&endDate= - Получить список коммитов",
"GET /health - Health check",
"GET /swagger - Swagger UI"
}
});
})
.WithName("Root");
app.Run();