Skip to content

Commit c82b233

Browse files
author
Victoria Ivanova
committed
Merge branch 'main' of github.com:atidev/bugget into optimizations
2 parents af981f2 + 0c0a458 commit c82b233

File tree

87 files changed

+1514
-210
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

87 files changed

+1514
-210
lines changed

.cursor/rules/backend.mdc

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
description:
3+
globs:
4+
alwaysApply: false
5+
---
6+
---
7+
description:
8+
globs:
9+
alwaysApply: true
10+
---
11+
description: Архитектура и стандарты backend .NET
12+
globs: backend/**/*.cs
13+
14+
# Your rule content
15+
16+
- Bugget.Entities — DTO, BO, DbModels, Views
17+
- Bugget.DA — доступ к данным (PostgreSQL, Files, HttpClients)
18+
- Bugget.BO — бизнес-логика
19+
- Bugget.Features — сквозные фичи (например, уведомления)
20+
- Bugget — Web API, Hubs, Controllers
21+
- Старайся использовать уже существующие сущности, структуры, паттерны
22+
- Ищи подходящие маппинги, DTO, типы, прежде чем создавать новые
23+
- Sql код пиши тут devops/migrator/sql/*.sql
24+
- Sql добавляется только вперед, то есть НЕ ПРАВЬ существующие файлы, создавай новые

backend/Bugget.BO/Bugget.BO.csproj

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
</PropertyGroup>
88

99
<ItemGroup>
10-
<ProjectReference Include="..\Bugget.Features\Bugget.Features.csproj" />
10+
<ProjectReference Include="..\Bugget.ExternalClients\Bugget.ExternalClients.csproj" />
11+
<ProjectReference Include="..\Monade\Monade.csproj" />
12+
<ProjectReference Include="..\TaskQueue\TaskQueue.csproj" />
1113
</ItemGroup>
1214

1315
</Project>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using Monade.Errors;
2+
3+
namespace Bugget.BO.Errors;
4+
5+
public static class BoErrors
6+
{
7+
public static readonly NotFoundError BugNotFoundError = new NotFoundError("bug_not_found", "Баг не найден");
8+
public static readonly NotFoundError NotFoundError = new NotFoundError("not_found", "Объект не найден");
9+
public static readonly NotFoundError ReportNotFoundError = new NotFoundError("report_not_found", "Репорт не найден");
10+
public static readonly InternalServerError InternalServerError = new InternalServerError("internal_server_error", "Внутреняя ошибка сервера");
11+
}

backend/Bugget.BO/Mappers/BugMapper.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public static BugUpdateDbModel ToBugUpdateDbModel(this BugUpdate bug)
4848
};
4949
}
5050

51-
public static BugView ToView(this BugDbModel bug, IReadOnlyDictionary<string, Employee> employeesDict)
51+
public static BugView ToView(this BugDbModel bug, IReadOnlyDictionary<string, EmployeeObsolete> employeesDict)
5252
{
5353
return new BugView
5454
{

backend/Bugget.BO/Mappers/CommentMapper.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public static Comment ToComment(this CommentDto comment, int bugId, int reportId
3131
};
3232
}
3333

34-
public static CommentView ToCommentView(this CommentDbModel comment, IReadOnlyDictionary<string, Employee> employeesDict)
34+
public static CommentView ToCommentView(this CommentDbModel comment, IReadOnlyDictionary<string, EmployeeObsolete> employeesDict)
3535
{
3636
return new CommentView
3737
{

backend/Bugget.BO/Mappers/ReportMapper.cs

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@
66
using Bugget.Entities.DbModels.Bug;
77
using Bugget.Entities.DbModels.Report;
88
using Bugget.Entities.DTO.Report;
9+
using Bugget.Entities.SocketViews;
910
using Bugget.Entities.Views;
1011

1112
namespace Bugget.BO.Mappers;
1213

1314
public static class ReportMapper
1415
{
15-
public static ReportView ToView(this ReportDbModel report, IReadOnlyDictionary<string, Employee> employeesDict)
16+
public static ReportView ToView(this ReportObsoleteDbModel report, IReadOnlyDictionary<string, EmployeeObsolete> employeesDict)
1617
{
1718
return new ReportView
1819
{
@@ -35,7 +36,7 @@ public static ReportView ToView(this ReportDbModel report, IReadOnlyDictionary<s
3536
};
3637
}
3738

38-
public static SearchReportsView ToView(this SearchReportsDbModel search, IReadOnlyDictionary<string, Employee> employeesDict)
39+
public static SearchReportsView ToView(this SearchReportsDbModel search, IReadOnlyDictionary<string, EmployeeObsolete> employeesDict)
3940
{
4041
return new SearchReportsView
4142
{
@@ -52,17 +53,17 @@ public static Report ToReport(this ReportCreateDto report, string userId)
5253
ResponsibleUserId = report.ResponsibleId,
5354
CreatorUserId = userId,
5455
Bugs = report.Bugs.Select(b => new Bug
55-
{
56-
Receive = b.Receive,
57-
Expect = b.Expect,
58-
CreatorUserId = userId,
59-
})
56+
{
57+
Receive = b.Receive,
58+
Expect = b.Expect,
59+
CreatorUserId = userId,
60+
})
6061
.ToArray(),
6162
ParticipantsUserIds = new string[] { userId, report.ResponsibleId }.Distinct().ToArray()
6263
};
6364
}
6465

65-
public static ReportUpdate ToReportUpdate(this ReportUpdateDto report, int reportId, string userId)
66+
public static ReportUpdate ToReportUpdate(this ReportPatchDto report, int reportId, string userId)
6667
{
6768
return new ReportUpdate
6869
{
@@ -113,7 +114,7 @@ public static SearchReports ToSearchReports(
113114
string? sort,
114115
uint skip,
115116
uint take,
116-
IReadOnlyDictionary<string, IReadOnlyCollection<Employee>> employeesByTeam)
117+
IReadOnlyDictionary<string, IReadOnlyCollection<EmployeeObsolete>> employeesByTeam)
117118
{
118119
List<string> resultUserIds = [];
119120
if (!string.IsNullOrEmpty(teamId))
@@ -139,4 +140,15 @@ public static SearchReports ToSearchReports(
139140
Sort = SortOption.Parse(sort)
140141
};
141142
}
143+
144+
public static PatchReportSocketView ToSocketView(this ReportPatchDto patchDto, ReportPatchResultDbModel? result)
145+
{
146+
return new PatchReportSocketView
147+
{
148+
Title = patchDto.Title,
149+
Status = patchDto.Status,
150+
ResponsibleUserId = patchDto.ResponsibleUserId,
151+
PastResponsibleUserId = patchDto.ResponsibleUserId == null ? null : result?.PastResponsibleUserId
152+
};
153+
}
142154
}

backend/Bugget.BO/Services/EmployeesService.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
using Bugget.DA.Files;
2+
using Bugget.DA.Interfaces;
23
using Bugget.Entities.Adapters;
34
using Bugget.Entities.BO;
45
using Bugget.Entities.Constants;
56
using Bugget.Entities.Views;
7+
using Bugget.Entities.Views.Users;
68

79
namespace Bugget.BO.Services;
810

9-
public class EmployeesService(EmployeesDataAccess employeesDataAccess)
11+
public class EmployeesService(EmployeesDataAccess employeesDataAccess, IEmployeesClient employeesClient)
1012
{
1113
public (IEnumerable<EmployeeView>, int) AutocompleteEmployees(
1214
string userId,
@@ -53,8 +55,14 @@ public class EmployeesService(EmployeesDataAccess employeesDataAccess)
5355
return (foundedTeams.Skip(skip).Take(take), foundedTeams.Length);
5456
}
5557

56-
public IReadOnlyDictionary<string, Employee> DictEmployees()
58+
public IReadOnlyDictionary<string, EmployeeObsolete> DictEmployees()
5759
{
5860
return employeesDataAccess.DictEmployees();
5961
}
62+
63+
public async Task<IEnumerable<UserView>> GetUserViewsAsync(IEnumerable<string> userIds, string? organizationId)
64+
{
65+
var employees = await employeesClient.GetEmployeesAsync(userIds, organizationId);
66+
return employees.Select(e => new UserView { Id = e.Id, Name = e.Name, PhotoUrl = e.PhotoUrl });
67+
}
6068
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using Bugget.BO.WebSockets;
2+
using Bugget.DA.Postgres;
3+
4+
namespace Bugget.BO.Services
5+
{
6+
public class ParticipantsService(ParticipantsDbClient participantsDbClient, IReportPageHubClient reportPageHubClient)
7+
{
8+
public async Task AddParticipantIfNotExistAsync(int reportId, string userId)
9+
{
10+
var participants = await participantsDbClient.AddParticipantIfNotExistAsync(reportId, userId);
11+
12+
if (participants != null)
13+
{
14+
await reportPageHubClient.SendReportParticipantsAsync(reportId, participants);
15+
}
16+
}
17+
}
18+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using Bugget.BO.WebSockets;
2+
using Bugget.DA.Postgres;
3+
using Bugget.Entities.BO.ReportBo;
4+
using Bugget.Entities.DbModels.Report;
5+
using Bugget.Entities.DTO.Report;
6+
using Bugget.Entities.SocketViews;
7+
8+
namespace Bugget.BO.Services
9+
{
10+
public class ReportAutoStatusService(ReportsDbClient reportsDbClient, IReportPageHubClient reportPageHubClient)
11+
{
12+
public async Task CalculateStatusAsync(int reportId, ReportPatchDto patchDto, ReportPatchResultDbModel result)
13+
{
14+
// если статус backlog и меняется ответственный, то меняем статус на in progress
15+
if (result.Status == (int)ReportStatus.Backlog && patchDto.ResponsibleUserId != null)
16+
{
17+
await reportsDbClient.ChangeStatusAsync(reportId, (int)ReportStatus.InProgress);
18+
await reportPageHubClient.SendReportPatchAsync(reportId, new PatchReportSocketView
19+
{
20+
Status = (int)ReportStatus.InProgress,
21+
});
22+
}
23+
}
24+
}
25+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using Bugget.BO.Mappers;
2+
using Bugget.BO.WebSockets;
3+
using Bugget.Entities.DbModels.Report;
4+
using Bugget.Entities.DTO.Report;
5+
using Bugget.ExternalClients;
6+
using Bugget.ExternalClients.Context;
7+
8+
namespace Bugget.BO.Services
9+
{
10+
public class ReportEventsService(
11+
IReportPageHubClient reportPageHubClient,
12+
ExternalClientsActionService externalClientsActionService,
13+
ParticipantsService participantsService,
14+
ReportAutoStatusService autoStatusService)
15+
{
16+
public async Task HandlePatchReportEventAsync(int reportId, string userId, ReportPatchDto patchDto, ReportPatchResultDbModel result)
17+
{
18+
await Task.WhenAll(
19+
reportPageHubClient.SendReportPatchAsync(reportId, patchDto.ToSocketView(result)),
20+
externalClientsActionService.ExecuteReportPatchPostActions(new ReportPatchContext(userId, patchDto, result)),
21+
participantsService.AddParticipantIfNotExistAsync(reportId, userId),
22+
patchDto.ResponsibleUserId != null ? participantsService.AddParticipantIfNotExistAsync(reportId, patchDto.ResponsibleUserId) : Task.CompletedTask,
23+
autoStatusService.CalculateStatusAsync(reportId, patchDto, result)
24+
);
25+
}
26+
}
27+
}

0 commit comments

Comments
 (0)