Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 2.70.0 #89

Open
wants to merge 24 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Inc.TeamAssistant.sln
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Inc.TeamAssistant.CheckIn.G
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Inc.TeamAssistant.Stories", "src\Inc.TeamAssistant.Stories\Inc.TeamAssistant.Stories.csproj", "{DA961B87-B9F3-4A4E-8C2B-F91101FB07CB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Inc.TeamAssistant.Connector.ApplicationTests", "tests\Inc.TeamAssistant.Connector.ApplicationTests\Inc.TeamAssistant.Connector.ApplicationTests.csproj", "{DC8CE5DD-1854-4760-99E0-D35F221ABF21}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -262,6 +264,10 @@ Global
{DA961B87-B9F3-4A4E-8C2B-F91101FB07CB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DA961B87-B9F3-4A4E-8C2B-F91101FB07CB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DA961B87-B9F3-4A4E-8C2B-F91101FB07CB}.Release|Any CPU.Build.0 = Release|Any CPU
{DC8CE5DD-1854-4760-99E0-D35F221ABF21}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DC8CE5DD-1854-4760-99E0-D35F221ABF21}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DC8CE5DD-1854-4760-99E0-D35F221ABF21}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DC8CE5DD-1854-4760-99E0-D35F221ABF21}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{B9C88CA2-123E-4D55-A931-91B0CFA08447} = {BF819FCA-A383-4283-B680-4B80B7B5CA32}
Expand Down Expand Up @@ -311,5 +317,6 @@ Global
{504EF63F-2C47-44FC-BB22-F199C7DF7251} = {1943C11E-7A4A-4300-BDC1-DA333BD3EBED}
{41B5195D-3C81-4501-9278-57FA95F973FD} = {15DCF7E1-1D36-4C21-A623-35A1D037A4DA}
{DA961B87-B9F3-4A4E-8C2B-F91101FB07CB} = {8285EFA4-C244-455D-94D1-86994A904BFF}
{DC8CE5DD-1854-4760-99E0-D35F221ABF21} = {1943C11E-7A4A-4300-BDC1-DA333BD3EBED}
EndGlobalSection
EndGlobal
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ Collect a random coffee meetings 💬.

- Create a bot for team
- Creating teams to work together
- Estimate of tasks. SP or t-shirts
- Select a reviewer for the code. Round-robin or random selection
- Estimate of tasks. SP, power of two, t-shirts
- Select a reviewer for the code. Round-robin, random selection, specific target, retargeting
- Notification of the review of the code and code owners
- Show teammates on world map
- Organize random coffee meetings
- Show teammates stats on world map

## Technology

Expand Down Expand Up @@ -94,6 +94,7 @@ The community looks forward to your contributions.
- [X] Integrate with Jira/Trello (estimate tasks)
- [X] Add a feature for use world map
- [X] Redesign UI/UX
- [X] Add story book for UI
- [ ] Integrate with GitLab (code review)
- [ ] Split the monolith into separate services

Expand Down
Binary file modified docs/features_map.xmind
Binary file not shown.
54 changes: 54 additions & 0 deletions docs/test_db.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
-- connector
UPDATE connector.bots
SET
name = 'inc_teamassistant_test_bot',
token = ''
WHERE id = '8eace573-343b-4af7-b255-40c152d6832a';

DELETE FROM connector.activated_features
WHERE bot_id != '8eace573-343b-4af7-b255-40c152d6832a';

DELETE FROM connector.dashboard_settings
WHERE bot_id != '8eace573-343b-4af7-b255-40c152d6832a';

UPDATE connector.teams
SET
bot_id = '8eace573-343b-4af7-b255-40c152d6832a',
chat_id = -1001685108427;

DELETE FROM connector.bots
WHERE id != '8eace573-343b-4af7-b255-40c152d6832a';

-- appraiser
UPDATE appraiser.stories
SET
bot_id = '8eace573-343b-4af7-b255-40c152d6832a',
chat_id = -1001685108427;

-- maps
UPDATE maps.maps
SET
bot_id = '8eace573-343b-4af7-b255-40c152d6832a',
chat_id = -1001685108427;


-- random_coffee
UPDATE random_coffee.entries
SET
bot_id = '8eace573-343b-4af7-b255-40c152d6832a',
chat_id = -1001685108427;

-- review
UPDATE review.task_for_reviews
SET
bot_id = '8eace573-343b-4af7-b255-40c152d6832a',
chat_id = -1001685108427;

UPDATE review.task_for_reviews
SET
state = 4,
accept_date = now()
WHERE state in (1, 2, 3);

UPDATE review.draft_task_for_reviews
SET chat_id = -1001685108427;
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
using FluentValidation;
using Inc.TeamAssistant.Appraiser.Model.Commands.AddStory;
using Inc.TeamAssistant.Primitives.Extensions;
using Inc.TeamAssistant.Primitives.Languages;

namespace Inc.TeamAssistant.Appraiser.Application.CommandHandlers.AddStory.Validators;

internal sealed class AddStoryCommandValidator : AbstractValidator<AddStoryCommand>
{
private readonly IMessageBuilder _messageBuilder;

public AddStoryCommandValidator(IMessageBuilder messageBuilder)
{
_messageBuilder = messageBuilder ?? throw new ArgumentNullException(nameof(messageBuilder));
Expand All @@ -19,7 +21,7 @@ public AddStoryCommandValidator(IMessageBuilder messageBuilder)

RuleFor(e => e.Title)
.NotEmpty()
.Must(e => !e.StartsWith("/"))
.Must(e => !e.HasCommand())
.WithMessage("'{PropertyName}' please enter text value.");

RuleFor(e => e.Links)
Expand All @@ -39,8 +41,10 @@ private async Task CheckLinks(

if (links.Count > 1)
{
var errorMessage = await _messageBuilder.Build(Messages.Appraiser_MultipleLinkError,
var errorMessage = await _messageBuilder.Build(
Messages.Appraiser_MultipleLinkError,
context.InstanceToValidate.MessageContext.LanguageId);

context.AddFailure(nameof(AddStoryCommand.Links), errorMessage);
}
else
Expand All @@ -49,8 +53,10 @@ private async Task CheckLinks(

if (!string.IsNullOrWhiteSpace(link) && link.Length > 2000)
{
var errorMessage = await _messageBuilder.Build(Messages.Appraiser_LinkLengthError,
var errorMessage = await _messageBuilder.Build(
Messages.Appraiser_LinkLengthError,
context.InstanceToValidate.MessageContext.LanguageId);

context.AddFailure(nameof(AddStoryCommand.Links), errorMessage);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public async Task<IReadOnlyDictionary<long, int>> GetStats(
"""
SELECT
sfe.participant_id AS personid,
count(*) AS eventscount
COUNT(*) AS eventscount
FROM appraiser.story_for_estimates AS sfe
JOIN appraiser.stories AS s ON sfe.story_id = s.id
WHERE s.created > @from AND sfe.participant_id = ANY(@person_ids) AND sfe.value > 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
using Inc.TeamAssistant.Appraiser.Domain;
using Npgsql;

namespace Inc.TeamAssistant.Appraiser.DataAccess.Internal;
namespace Inc.TeamAssistant.Appraiser.DataAccess;

internal static class GetStoryQuery
internal static class StoryProvider
{
public static async Task<IReadOnlyCollection<Story>> Get(
NpgsqlConnection connection,
Expand Down
9 changes: 4 additions & 5 deletions src/Inc.TeamAssistant.Appraiser.DataAccess/StoryReader.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using Dapper;
using Inc.TeamAssistant.Appraiser.Application.Contracts;
using Inc.TeamAssistant.Appraiser.DataAccess.Internal;
using Inc.TeamAssistant.Appraiser.Domain;
using Inc.TeamAssistant.Primitives.DataAccess;

Expand Down Expand Up @@ -37,7 +36,7 @@ public async Task<IReadOnlyCollection<Story>> GetStories(
s.rounds_count AS roundscount,
s.url AS url
FROM appraiser.stories AS s
WHERE s.team_id = @team_id AND s.created <= @before AND (@from is null OR s.created >= @from);",
WHERE s.team_id = @team_id AND s.created <= @before AND (@from IS NULL OR s.created >= @from);",
new
{
team_id = teamId,
Expand Down Expand Up @@ -74,7 +73,7 @@ FROM appraiser.stories AS s
await using var connection = _connectionFactory.Create();

var storyIds = await connection.QueryAsync<Guid>(command);
var stories = await GetStoryQuery.Get(connection, storyIds.ToArray(), token);
var stories = await StoryProvider.Get(connection, storyIds.ToArray(), token);
var results = stories.OrderBy(p => p.Created).ToArray();

return results;
Expand All @@ -86,7 +85,7 @@ FROM appraiser.stories AS s
SELECT
s.id AS id
FROM appraiser.stories AS s
WHERE s.team_id = @team_id AND total_value is null
WHERE s.team_id = @team_id AND total_value IS NULL
ORDER BY s.created
OFFSET 0
LIMIT 1;",
Expand All @@ -100,7 +99,7 @@ OFFSET 0
if (!storyId.HasValue)
return null;

var stories = await GetStoryQuery.Get(connection, new[] { storyId.Value }, token);
var stories = await StoryProvider.Get(connection, new[] { storyId.Value }, token);
return stories.SingleOrDefault();
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
using System.Text.Json;
using Dapper;
using Inc.TeamAssistant.Appraiser.Application.Contracts;
using Inc.TeamAssistant.Appraiser.DataAccess.Internal;
using Inc.TeamAssistant.Appraiser.Domain;
using Inc.TeamAssistant.Primitives.DataAccess;

Expand All @@ -20,7 +18,7 @@ public StoryRepository(IConnectionFactory connectionFactory)
{
await using var connection = _connectionFactory.Create();

var stories = await GetStoryQuery.Get(connection, new[] { storyId }, token);
var stories = await StoryProvider.Get(connection, new[] { storyId }, token);

return stories.SingleOrDefault();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
using Inc.TeamAssistant.Appraiser.Model.Common;
using Inc.TeamAssistant.Primitives;

namespace Inc.TeamAssistant.Appraiser.Model.Queries.GetActiveStory;

public sealed record GetActiveStoryResult(string TeamName, string CodeForConnect, StoryDto? Story);
public sealed record GetActiveStoryResult(string TeamName, string CodeForConnect, StoryDto? Story)
: IWithEmpty<GetActiveStoryResult>
{
public static GetActiveStoryResult Empty { get; } = new(string.Empty, string.Empty, Story: null);
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
using Inc.TeamAssistant.Primitives;

namespace Inc.TeamAssistant.Appraiser.Model.Queries.GetAssessmentHistory;

public sealed record GetAssessmentHistoryResult(IReadOnlyCollection<AssessmentHistoryDto> Items);
public sealed record GetAssessmentHistoryResult(IReadOnlyCollection<AssessmentHistoryDto> Items)
: IWithEmpty<GetAssessmentHistoryResult>
{
public static GetAssessmentHistoryResult Empty { get; } = new(Array.Empty<AssessmentHistoryDto>());
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
using Inc.TeamAssistant.Appraiser.Model.Common;
using Inc.TeamAssistant.Primitives;

namespace Inc.TeamAssistant.Appraiser.Model.Queries.GetStories;

public sealed record GetStoriesResult(IReadOnlyCollection<StoryDto> Items);
public sealed record GetStoriesResult(IReadOnlyCollection<StoryDto> Items)
: IWithEmpty<GetStoriesResult>
{
public static GetStoriesResult Empty { get; } = new(Array.Empty<StoryDto>());
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
using Inc.TeamAssistant.Primitives;

namespace Inc.TeamAssistant.CheckIn.Model.Queries.GetMaps;

public sealed record GetMapsResult(IReadOnlyCollection<MapDto> Items);
public sealed record GetMapsResult(IReadOnlyCollection<MapDto> Items)
: IWithEmpty<GetMapsResult>
{
public static GetMapsResult Empty { get; } = new(Array.Empty<MapDto>());
}
18 changes: 18 additions & 0 deletions src/Inc.TeamAssistant.Connector.Application/Alias/AliasFinder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System.Reflection;

namespace Inc.TeamAssistant.Connector.Application.Alias;

public static class AliasFinder
{
public static IEnumerable<AliasValue> Find()
{
var fields = Assembly.GetExecutingAssembly()
.GetTypes()
.SelectMany(t => t.GetFields());

foreach (var field in fields)
foreach (var attribute in field.GetCustomAttributes())
if (attribute is CommandAlias commandAlias)
yield return new AliasValue(commandAlias.Value, (string)field.GetValue(null)!);
}
}
30 changes: 30 additions & 0 deletions src/Inc.TeamAssistant.Connector.Application/Alias/AliasService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using Inc.TeamAssistant.Primitives.Extensions;

namespace Inc.TeamAssistant.Connector.Application.Alias;

internal sealed class AliasService
{
private readonly IReadOnlyDictionary<string, string> _aliasMap;

public AliasService(IEnumerable<AliasValue> aliasMap)
{
ArgumentNullException.ThrowIfNull(aliasMap);

_aliasMap = aliasMap.ToDictionary(i => i.Alias, i => i.Command, StringComparer.InvariantCultureIgnoreCase);
}

public string OverrideCommand(string text)
{
ArgumentNullException.ThrowIfNull(text);

if (!text.HasCommand())
return text;

var alias = text.Split(' ').First();
var result = _aliasMap.TryGetValue(alias, out var command)
? text.Replace(alias, command)
: text;

return result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
namespace Inc.TeamAssistant.Connector.Application.Alias;

public sealed record AliasValue(string Alias, string Command);
14 changes: 14 additions & 0 deletions src/Inc.TeamAssistant.Connector.Application/Alias/CommandAlias.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace Inc.TeamAssistant.Connector.Application.Alias;

[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
public sealed class CommandAlias : Attribute
{
public string Value { get; }

public CommandAlias(string value)
{
ArgumentException.ThrowIfNullOrWhiteSpace(value);

Value = value;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,14 @@ public async Task<CommandResult> Handle(ChangeTeamPropertyCommand command, Cance
throw new TeamAssistantUserException(Messages.Connector_TeamNotFound, command.TeamId);

team.ChangeProperty(new PropertyKey(command.Name), command.Value);

await _teamRepository.Upsert(team, token);

var message = await _messageBuilder.Build(
Messages.Connector_ChangedPropertySuccess,
command.MessageContext.LanguageId,
team.Name);

return CommandResult.Build(NotificationMessage.Create(command.MessageContext.ChatMessage.ChatId, message));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,13 @@ public async Task<CommandResult> Handle(CreateTeamCommand command, CancellationT
command.MessageContext.Bot.Properties);

await _teamRepository.Upsert(team, token);


var linkForConnect = _teamLinkBuilder.BuildLinkForConnect(command.BotName, team.Id);
var message = await _messageBuilder.Build(
Messages.Connector_JoinToTeam,
command.MessageContext.LanguageId,
team.Name,
_teamLinkBuilder.BuildLinkForConnect(command.BotName, team.Id));
linkForConnect);
var notification = NotificationMessage.Create(command.MessageContext.ChatMessage.ChatId, message, pinned: true);

return CommandResult.Build(notification);
Expand Down
Loading