Implement Phase 5: reconciliation, SignalR notifications, payees, splits & plugins
Add full frontend UI for five backend features: bank reconciliation (3-step stepper workflow), payee management (CRUD with alias chips), transaction splits (expandable rows + split editor), plugins (card grid), and real-time SignalR notifications (bell dropdown with badge). Fix backend PayeeResponse to expose alias IDs for deletion. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -22,7 +22,7 @@ public class PayeeService : IPayeeService
|
||||
.Include(p => p.Aliases).Include(p => p.DefaultCategory)
|
||||
.Where(p => p.UserId == userId)
|
||||
.OrderBy(p => p.Name)
|
||||
.Select(p => new PayeeResponse(p.Id, p.Name, p.DefaultCategoryId, p.DefaultCategory != null ? p.DefaultCategory.Name : null, p.IsActive, p.Aliases.Select(a => a.Alias).ToList()))
|
||||
.Select(p => new PayeeResponse(p.Id, p.Name, p.DefaultCategoryId, p.DefaultCategory != null ? p.DefaultCategory.Name : null, p.IsActive, p.Aliases.Select(a => new PayeeAliasResponse(a.Id, a.Alias)).ToList()))
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ public class PayeeService : IPayeeService
|
||||
{
|
||||
var p = await _db.Payees.Include(p => p.Aliases).Include(p => p.DefaultCategory)
|
||||
.FirstOrDefaultAsync(p => p.Id == payeeId && p.UserId == userId);
|
||||
return p == null ? null : new PayeeResponse(p.Id, p.Name, p.DefaultCategoryId, p.DefaultCategory?.Name, p.IsActive, p.Aliases.Select(a => a.Alias).ToList());
|
||||
return p == null ? null : new PayeeResponse(p.Id, p.Name, p.DefaultCategoryId, p.DefaultCategory?.Name, p.IsActive, p.Aliases.Select(a => new PayeeAliasResponse(a.Id, a.Alias)).ToList());
|
||||
}
|
||||
|
||||
public async Task<PayeeResponse> CreateAsync(Guid userId, CreatePayeeRequest request)
|
||||
@@ -51,7 +51,7 @@ public class PayeeService : IPayeeService
|
||||
|
||||
_db.Payees.Add(payee);
|
||||
await _db.SaveChangesAsync();
|
||||
return new PayeeResponse(payee.Id, payee.Name, payee.DefaultCategoryId, null, true, request.Aliases ?? new());
|
||||
return new PayeeResponse(payee.Id, payee.Name, payee.DefaultCategoryId, null, true, payee.Aliases.Select(a => new PayeeAliasResponse(a.Id, a.Alias)).ToList());
|
||||
}
|
||||
|
||||
public async Task<PayeeResponse> UpdateAsync(Guid userId, Guid payeeId, UpdatePayeeRequest request)
|
||||
@@ -65,7 +65,7 @@ public class PayeeService : IPayeeService
|
||||
payee.IsActive = request.IsActive;
|
||||
await _db.SaveChangesAsync();
|
||||
|
||||
return new PayeeResponse(payee.Id, payee.Name, payee.DefaultCategoryId, null, payee.IsActive, payee.Aliases.Select(a => a.Alias).ToList());
|
||||
return new PayeeResponse(payee.Id, payee.Name, payee.DefaultCategoryId, null, payee.IsActive, payee.Aliases.Select(a => new PayeeAliasResponse(a.Id, a.Alias)).ToList());
|
||||
}
|
||||
|
||||
public async Task DeleteAsync(Guid userId, Guid payeeId)
|
||||
|
||||
@@ -3,13 +3,15 @@ namespace Purrse.Core.DTOs;
|
||||
public record CreatePayeeRequest(string Name, Guid? DefaultCategoryId, List<string>? Aliases);
|
||||
public record UpdatePayeeRequest(string Name, Guid? DefaultCategoryId, bool IsActive);
|
||||
|
||||
public record PayeeAliasResponse(Guid Id, string Alias);
|
||||
|
||||
public record PayeeResponse(
|
||||
Guid Id,
|
||||
string Name,
|
||||
Guid? DefaultCategoryId,
|
||||
string? DefaultCategoryName,
|
||||
bool IsActive,
|
||||
List<string> Aliases
|
||||
List<PayeeAliasResponse> Aliases
|
||||
);
|
||||
|
||||
public record CreatePayeeAliasRequest(string Alias);
|
||||
|
||||
Reference in New Issue
Block a user