fix: resolve critical bugs and improve reliability across worker, data, UI

- Fix worker using wrong DB by defaulting to CurrentUser service account
  and expanding ~ to absolute paths at install time
- Fix DbContext disposed before fire-and-forget by passing taskId instead
  of TaskEntity into RunInSlotAsync, which creates its own context
- Fix ActiveTaskDto property casing mismatch between hub and client
- Move WAL mode PRAGMA before migrations to prevent concurrent lock issues
- Replace FirstAsync with FirstOrDefaultAsync + null guards in tag operations
- Add delete confirmation flow for lists
- Log fire-and-forget exceptions instead of swallowing them
- Broadcast RunCreated event from WorkerHub.RunNow
- Add IDisposable to MainWindowViewModel for event handler cleanup
- Preserve subtask CreatedAt on updates instead of overwriting
- Replace bare catch blocks with Debug.WriteLine logging

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
mika kuns
2026-04-16 13:12:59 +02:00
parent fca2bdb596
commit 3423919655
11 changed files with 154 additions and 61 deletions

View File

@@ -104,7 +104,8 @@ public sealed class TaskRepository
public async Task AddTagAsync(string taskId, long tagId, CancellationToken ct = default)
{
var task = await _context.Tasks.Include(t => t.Tags).FirstAsync(t => t.Id == taskId, ct);
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))
{
@@ -115,7 +116,8 @@ public sealed class TaskRepository
public async Task RemoveTagAsync(string taskId, long tagId, CancellationToken ct = default)
{
var task = await _context.Tasks.Include(t => t.Tags).FirstAsync(t => t.Id == taskId, ct);
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)
{