Skip to content

Горшенин Дмитрий Лаб. 1 Группа 6511#2

Open
dmgorshenin wants to merge 8 commits intoitsecd:mainfrom
dmgorshenin:main
Open

Горшенин Дмитрий Лаб. 1 Группа 6511#2
dmgorshenin wants to merge 8 commits intoitsecd:mainfrom
dmgorshenin:main

Conversation

@dmgorshenin
Copy link

ФИО: Горшенин Дмитрий
Номер группы: 6511
Номер лабораторной: 1
Номер варианта: 4
Краткое описание предметной области: Генератор кредитной заявки
Краткое описание добавленных фич: Добавлен сервис генерации и кэширования кредитных заявок

dmgorshenin and others added 4 commits February 13, 2026 18:27
…аб. роботы

В решение добавлены проекты CreditApplication.AppHost (Aspire-хост), CreditApplication.Generator (API генерации кредитных заявок с кэшированием в Redis) и CreditApplication.ServiceDefaults (общие настройки сервисов: логирование, OpenTelemetry, resilience, health checks).
Реализована модель заявки, генератор на Bogus, сервис с кэшированием, API-эндпоинт /credit-application.
Copilot AI review requested due to automatic review settings February 13, 2026 14:54
@github-actions github-actions bot added In progress Код в процессе проверки Lab 1 Лабораторная №1. Кэширование labels Feb 13, 2026
@github-actions github-actions bot requested a review from danlla February 13, 2026 14:54
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request implements Lab 1 for a student assignment, creating a microservices-based credit application generator with caching functionality. The solution demonstrates modern .NET 8 development practices including Bogus for data generation, Redis for distributed caching, Serilog for structured logging, OpenTelemetry for observability, and .NET Aspire for orchestration.

Changes:

  • Implemented a credit application generator service using Bogus to create synthetic credit application data with Russian localization
  • Added Redis-based distributed caching to improve performance and reduce redundant data generation
  • Configured .NET Aspire orchestration to manage the generator service, Redis cache, and Blazor WebAssembly client
  • Set up comprehensive logging and telemetry infrastructure using Serilog and OpenTelemetry

Reviewed changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
README.md Replaced generic lab instructions with project-specific documentation including architecture diagrams and screenshots
CreditApplication.ServiceDefaults/Extensions.cs Implemented shared service configuration for logging, OpenTelemetry, health checks, and service discovery
CreditApplication.ServiceDefaults/CreditApplication.ServiceDefaults.csproj Defined dependencies for Serilog, OpenTelemetry, and Aspire service discovery
CreditApplication.Generator/Services/CreditApplicationGenerator.cs Core generator using Bogus to create credit applications with locale-specific data
CreditApplication.Generator/Services/CreditApplicationService.cs Service layer implementing caching logic with IDistributedCache
CreditApplication.Generator/Models/CreditApplicationModel.cs Data model for credit applications with XML documentation
CreditApplication.Generator/Program.cs API endpoint configuration with validation, error handling, and CORS
CreditApplication.Generator/CreditApplication.Generator.csproj Project dependencies including Bogus and Aspire Redis integration
CreditApplication.Generator/appsettings.json Logging configuration for the generator service
CreditApplication.Generator/appsettings.Development.json Development-specific logging configuration
CreditApplication.Generator/Properties/launchSettings.json Launch profiles for local development
CreditApplication.AppHost/Program.cs Aspire orchestration configuration for Redis and microservices
CreditApplication.AppHost/CreditApplication.AppHost.csproj Aspire hosting dependencies
CreditApplication.AppHost/appsettings.json AppHost logging configuration
CreditApplication.AppHost/appsettings.Development.json Development-specific AppHost configuration
CreditApplication.AppHost/Properties/launchSettings.json AppHost launch profiles with Aspire dashboard endpoints
CloudDevelopment.sln Added three new projects to the solution
Client.Wasm/wwwroot/appsettings.json Updated API endpoint URL to credit application service
Client.Wasm/Properties/launchSettings.json Updated client port configuration
Client.Wasm/Components/StudentCard.razor Updated student information and lab details

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 18 to 20
policy.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CORS policy allows any origin, method, and header which is insecure for production environments. While this may be acceptable for a development/lab environment, consider restricting CORS to specific origins in production scenarios or documenting this as a development-only configuration.

Suggested change
policy.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
if (builder.Environment.IsDevelopment())
{
// In development, allow any origin/method/header for ease of testing.
policy.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
}
else
{
// In production, restrict CORS to specific trusted origins and limit methods/headers as needed.
policy.WithOrigins("https://your-production-frontend.example")
.WithMethods("GET")
.WithHeaders("Content-Type", "Authorization");
}

Copilot uses AI. Check for mistakes.
{
_logger.LogInformation("Credit application {Id} found in cache", id);
var cachedApplication = JsonSerializer.Deserialize<CreditApplicationModel>(cachedData);
return cachedApplication!;
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The deserialized object could be null if the cached JSON is invalid or malformed. The null-forgiving operator (!) suppresses this warning but doesn't handle the case where deserialization returns null. Consider adding explicit null checking and appropriate error handling, or at least returning a fallback value.

Suggested change
return cachedApplication!;
if (cachedApplication is not null)
{
return cachedApplication;
}
_logger.LogWarning(
"Failed to deserialize cached credit application {Id}. Cached data will be ignored and a new application will be generated.",
id);

Copilot uses AI. Check for mistakes.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
.RuleFor(x => x.RequestedAmount, f => Math.Round(f.Random.Decimal(50_000m, 10_000_000m), 2))
.RuleFor(x => x.TermInMonths, f => f.Random.Int(6, 360))
.RuleFor(x => x.InterestRate, f => Math.Round(f.Random.Double(MinInterestRate, 35.0), 2))
.RuleFor(x => x.ApplicationDate, f => GenerateApplicationDate(f))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Есть PastDateOnly

.RuleFor(x => x.ApplicationDate, f => f.Date.PastDateOnly(2))

Comment on lines 84 to 86
var applicationDateTime = app.ApplicationDate.ToDateTime(TimeOnly.MinValue);
var decisionDateTime = faker.Date.Between(applicationDateTime, DateTime.Today);
app.DecisionDate = DateOnly.FromDateTime(decisionDateTime);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Есть BetweenDateOnly

{
_logger.LogInformation("Credit application {Id} found in cache", id);
var cachedApplication = JsonSerializer.Deserialize<CreditApplicationModel>(cachedData);
return cachedApplication!;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Согласен с копилотом, теоретически может быть ситуация, что в кэш запишется null и лучше проверять здесь, если не null, возвращаем, если null идем дальше и генерируем новый объект

private readonly IDistributedCache _cache = cache;
private readonly ILogger<CreditApplicationService> _logger = logger;

private static readonly TimeSpan _cacheExpiration = TimeSpan.FromMinutes(5);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

5 лучше вынести в appsettings.json

Comment on lines 14 to 22
builder.Services.AddCors(options =>
{
options.AddDefaultPolicy(policy =>
{
policy.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
});
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Здесь копилот тоже прав, но в принципе пока можно так оставить

Comment on lines 12 to 14
<PackageReference Include="Aspire.Hosting" Version="8.2.2" />
<PackageReference Include="Aspire.Hosting.AppHost" Version="8.2.2" />
<PackageReference Include="Aspire.Hosting.Redis" Version="8.2.2" />
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Лучше апнуть aspire до последней версии доступной на .net 8 - 9.5.2

потому что сейчас у меня не запускается на 8.2.2

вот как примерно будет выглядеть этот файл после:

<Project Sdk="Microsoft.NET.Sdk">

  <Sdk Name="Aspire.AppHost.Sdk" Version="9.5.2" />

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Aspire.Hosting" Version="9.5.2" />
    <PackageReference Include="Aspire.Hosting.AppHost" Version="9.5.2" />
    <PackageReference Include="Aspire.Hosting.Redis" Version="9.5.2" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\CreditApplication.Generator\CreditApplication.Generator.csproj" />
    <ProjectReference Include="..\Client.Wasm\Client.Wasm.csproj" />
  </ItemGroup>

</Project>

@@ -14,7 +14,7 @@
"dotnetRunMessages": true,
"launchBrowser": true,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Возможно стоит поднастроить настройки запуска клиента, чтобы не открывался отдельно браузер с клиентом


private static readonly string[] _terminalStatuses = ["Одобрена", "Отклонена"];

private readonly ILogger<CreditApplicationGenerator> _logger = logger;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Можно эту строчку удалить и везде использовать logger

Comment on lines 15 to 17
private readonly CreditApplicationGenerator _generator = generator;
private readonly IDistributedCache _cache = cache;
private readonly ILogger<CreditApplicationService> _logger = logger;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Аналогично

Comment on lines 53 to 56
.FinishWith((f, app) =>
{
SetStatusDependentFields(f, app);
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Здесь можно немного попроще:

.FinishWith(SetStatusDependentFields);

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 20 out of 20 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 39 to 46
var cachedApplication = JsonSerializer.Deserialize<CreditApplicationModel>(cachedData);

if (cachedApplication is not null)
{
return cachedApplication;
}

_logger.LogWarning("Cached data for credit application {Id} deserialized to null, regenerating", id);
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JsonSerializer.Deserialize<CreditApplicationModel>(cachedData) can throw (e.g., corrupted/partial cache entry). Right now this will bubble up and turn the request into a 500 instead of regenerating. Consider catching JsonException, logging it, deleting the bad cache key, and then proceeding to generate/cache a fresh value.

Suggested change
var cachedApplication = JsonSerializer.Deserialize<CreditApplicationModel>(cachedData);
if (cachedApplication is not null)
{
return cachedApplication;
}
_logger.LogWarning("Cached data for credit application {Id} deserialized to null, regenerating", id);
try
{
var cachedApplication = JsonSerializer.Deserialize<CreditApplicationModel>(cachedData);
if (cachedApplication is not null)
{
return cachedApplication;
}
_logger.LogWarning("Cached data for credit application {Id} deserialized to null, regenerating", id);
}
catch (JsonException ex)
{
_logger.LogWarning(ex,
"Failed to deserialize cached credit application {Id}. Removing corrupted cache entry and regenerating.",
id);
try
{
await _cache.RemoveAsync(cacheKey, cancellationToken);
}
catch (System.Exception removeEx)
{
_logger.LogError(removeEx,
"Failed to remove corrupted cache entry for credit application {Id}",
id);
}
}

Copilot uses AI. Check for mistakes.
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Http.Resilience" Version="9.0.0" />
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Microsoft.Extensions.* package versions are inconsistent here (Microsoft.Extensions.Http.Resilience is 9.0.0 while Microsoft.Extensions.ServiceDiscovery is 9.5.2). These packages commonly share dependencies, and mismatched major/minor versions can lead to restore/runtime conflicts. Align them to the same version line (or introduce central package management) to avoid binding issues.

Suggested change
<PackageReference Include="Microsoft.Extensions.Http.Resilience" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Http.Resilience" Version="9.5.2" />

Copilot uses AI. Check for mistakes.
<UnorderedListItem><Link To="https://puginarug.com/">Ссылка на форк</Link></UnorderedListItem>
<UnorderedListItem>Номер <Strong>№1 «Кэширование»</Strong></UnorderedListItem>
<UnorderedListItem>Вариант <Strong>№4 «Кредитная заявка»</Strong></UnorderedListItem>
<UnorderedListItem>Выполнена <Strong>Горшениным Дмитрием 6511</Strong> </UnorderedListItem>
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Grammatically this reads as feminine (“Выполнена”), while the sentence is about the work/assignment (“задание/лабораторная”) and is usually phrased as “Выполнено …”. Consider adjusting the wording to avoid the agreement error.

Suggested change
<UnorderedListItem>Выполнена <Strong>Горшениным Дмитрием 6511</Strong> </UnorderedListItem>
<UnorderedListItem>Выполнено <Strong>Горшениным Дмитрием 6511</Strong> </UnorderedListItem>

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

In progress Код в процессе проверки Lab 1 Лабораторная №1. Кэширование

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants