refactor(tags): remove tag entity and all references
Drops TagEntity, TagRepository, and tag wiring across data layer, worker, and UI. Adds RemoveTags migration to clean up schema. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -171,74 +171,6 @@ public sealed class TaskRepository
|
||||
|
||||
#endregion
|
||||
|
||||
#region Tags
|
||||
|
||||
public async Task AddTagAsync(string taskId, long tagId, CancellationToken ct = default)
|
||||
{
|
||||
var task = await _context.Tasks.Include(t => t.Tags).FirstOrDefaultAsync(t => t.Id == taskId, ct);
|
||||
if (task is null) return;
|
||||
var tag = await _context.Tags.FindAsync([tagId], ct);
|
||||
if (tag is not null && !task.Tags.Any(t => t.Id == tagId))
|
||||
{
|
||||
task.Tags.Add(tag);
|
||||
await _context.SaveChangesAsync(ct);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task RemoveTagAsync(string taskId, long tagId, CancellationToken ct = default)
|
||||
{
|
||||
var task = await _context.Tasks.Include(t => t.Tags).FirstOrDefaultAsync(t => t.Id == taskId, ct);
|
||||
if (task is null) return;
|
||||
var tag = task.Tags.FirstOrDefault(t => t.Id == tagId);
|
||||
if (tag is not null)
|
||||
{
|
||||
task.Tags.Remove(tag);
|
||||
await _context.SaveChangesAsync(ct);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task SetTagsAsync(string taskId, IReadOnlyList<string> tagNames, CancellationToken ct = default)
|
||||
{
|
||||
var task = await _context.Tasks.Include(t => t.Tags).FirstOrDefaultAsync(t => t.Id == taskId, ct);
|
||||
if (task is null) return;
|
||||
|
||||
task.Tags.Clear();
|
||||
|
||||
foreach (var name in tagNames.Where(n => !string.IsNullOrWhiteSpace(n)).Distinct(StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
var tag = await _context.Tags.FirstOrDefaultAsync(t => t.Name == name, ct);
|
||||
if (tag is null)
|
||||
{
|
||||
tag = new TagEntity { Name = name };
|
||||
_context.Tags.Add(tag);
|
||||
}
|
||||
task.Tags.Add(tag);
|
||||
}
|
||||
|
||||
await _context.SaveChangesAsync(ct);
|
||||
}
|
||||
|
||||
public async Task<List<TagEntity>> GetTagsAsync(string taskId, CancellationToken ct = default)
|
||||
{
|
||||
return await _context.Tasks
|
||||
.Where(t => t.Id == taskId)
|
||||
.SelectMany(t => t.Tags)
|
||||
.ToListAsync(ct);
|
||||
}
|
||||
|
||||
public async Task<List<TagEntity>> GetEffectiveTagsAsync(string taskId, CancellationToken ct = default)
|
||||
{
|
||||
var taskTags = _context.Tasks
|
||||
.Where(t => t.Id == taskId)
|
||||
.SelectMany(t => t.Tags);
|
||||
var listTags = _context.Tasks
|
||||
.Where(t => t.Id == taskId)
|
||||
.SelectMany(t => t.List.Tags);
|
||||
return await taskTags.Union(listTags).Distinct().ToListAsync(ct);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Planning
|
||||
|
||||
public async Task<List<TaskEntity>> GetChildrenAsync(string parentId, CancellationToken ct = default)
|
||||
@@ -254,7 +186,6 @@ public sealed class TaskRepository
|
||||
string parentId,
|
||||
string title,
|
||||
string? description,
|
||||
IReadOnlyList<string>? tagNames,
|
||||
string? commitType,
|
||||
CancellationToken ct = default)
|
||||
{
|
||||
@@ -286,22 +217,6 @@ public sealed class TaskRepository
|
||||
SortOrder = (maxSort ?? -1) + 1,
|
||||
};
|
||||
_context.Tasks.Add(child);
|
||||
|
||||
if (tagNames is not null && tagNames.Count > 0)
|
||||
{
|
||||
foreach (var tagName in tagNames.Distinct(StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
var tag = await _context.Tags.FirstOrDefaultAsync(t => t.Name == tagName, ct);
|
||||
if (tag is null)
|
||||
{
|
||||
tag = new TagEntity { Name = tagName };
|
||||
_context.Tags.Add(tag);
|
||||
await _context.SaveChangesAsync(ct);
|
||||
}
|
||||
child.Tags.Add(tag);
|
||||
}
|
||||
}
|
||||
|
||||
await _context.SaveChangesAsync(ct);
|
||||
return child;
|
||||
}
|
||||
@@ -311,11 +226,10 @@ public sealed class TaskRepository
|
||||
string? title,
|
||||
string? description,
|
||||
string? commitType,
|
||||
IReadOnlyList<string>? tagNames,
|
||||
TaskStatus? status,
|
||||
CancellationToken ct = default)
|
||||
{
|
||||
var task = await _context.Tasks.Include(t => t.Tags).FirstOrDefaultAsync(t => t.Id == taskId, ct)
|
||||
var task = await _context.Tasks.FirstOrDefaultAsync(t => t.Id == taskId, ct)
|
||||
?? throw new InvalidOperationException($"Task {taskId} not found.");
|
||||
|
||||
if (title is not null) task.Title = title;
|
||||
@@ -323,21 +237,6 @@ public sealed class TaskRepository
|
||||
if (commitType is not null) task.CommitType = commitType;
|
||||
if (status.HasValue) task.Status = status.Value;
|
||||
|
||||
if (tagNames is not null)
|
||||
{
|
||||
task.Tags.Clear();
|
||||
foreach (var name in tagNames.Where(n => !string.IsNullOrWhiteSpace(n)).Distinct(StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
var tag = await _context.Tags.FirstOrDefaultAsync(t => t.Name == name, ct);
|
||||
if (tag is null)
|
||||
{
|
||||
tag = new TagEntity { Name = name };
|
||||
_context.Tags.Add(tag);
|
||||
}
|
||||
task.Tags.Add(tag);
|
||||
}
|
||||
}
|
||||
|
||||
await _context.SaveChangesAsync(ct);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user