feat: aggregate account and transaction activity logs on space activity page

This commit is contained in:
juancwu 2026-05-03 23:56:06 +00:00
commit 9826068208
7 changed files with 135 additions and 38 deletions

View file

@ -25,7 +25,7 @@ func NewAccountActivityService(spaceAudit *SpaceAuditLogService, txAudit *Transa
// Rather than a SQL UNION across two heterogeneous tables, we fetch up to (offset+limit)
// from each side and merge in Go. Audit volume per account is low, so the simplicity
// outweighs the slight overfetch.
func (s *AccountActivityService) List(accountID string, limit, offset int) ([]model.AccountActivityRow, error) {
func (s *AccountActivityService) List(accountID string, limit, offset int) ([]model.ActivityRow, error) {
if limit <= 0 {
limit = 25
}
@ -43,12 +43,12 @@ func (s *AccountActivityService) List(accountID string, limit, offset int) ([]mo
return nil, fmt.Errorf("failed to list transaction events: %w", err)
}
rows := make([]model.AccountActivityRow, 0, len(spaceLogs)+len(txLogs))
rows := make([]model.ActivityRow, 0, len(spaceLogs)+len(txLogs))
for _, l := range spaceLogs {
rows = append(rows, model.AccountActivityRow{SpaceLog: l})
rows = append(rows, model.ActivityRow{SpaceLog: l})
}
for _, l := range txLogs {
rows = append(rows, model.AccountActivityRow{TxLog: l})
rows = append(rows, model.ActivityRow{TxLog: l})
}
sort.Slice(rows, func(i, j int) bool {
return rows[i].Timestamp().After(rows[j].Timestamp())
@ -75,3 +75,57 @@ func (s *AccountActivityService) Count(accountID string) (int, error) {
}
return spaceCount + txCount, nil
}
// ListSpace returns a merged feed of every audit entry scoped to the space — its own
// space_audit_logs (rename, members, account events) plus every transaction event for
// transactions whose account belongs to this space. Same in-memory merge as List.
func (s *AccountActivityService) ListSpace(spaceID string, limit, offset int) ([]model.ActivityRow, error) {
if limit <= 0 {
limit = 25
}
if offset < 0 {
offset = 0
}
fetchN := offset + limit
spaceLogs, err := s.spaceAudit.repo.ListBySpace(spaceID, fetchN, 0)
if err != nil {
return nil, fmt.Errorf("failed to list space events: %w", err)
}
txLogs, err := s.txAudit.repo.ListBySpace(spaceID, fetchN, 0)
if err != nil {
return nil, fmt.Errorf("failed to list transaction events: %w", err)
}
rows := make([]model.ActivityRow, 0, len(spaceLogs)+len(txLogs))
for _, l := range spaceLogs {
rows = append(rows, model.ActivityRow{SpaceLog: l})
}
for _, l := range txLogs {
rows = append(rows, model.ActivityRow{TxLog: l})
}
sort.Slice(rows, func(i, j int) bool {
return rows[i].Timestamp().After(rows[j].Timestamp())
})
if offset >= len(rows) {
return nil, nil
}
end := offset + limit
if end > len(rows) {
end = len(rows)
}
return rows[offset:end], nil
}
func (s *AccountActivityService) CountSpace(spaceID string) (int, error) {
spaceCount, err := s.spaceAudit.repo.CountBySpace(spaceID)
if err != nil {
return 0, fmt.Errorf("failed to count space events: %w", err)
}
txCount, err := s.txAudit.repo.CountBySpace(spaceID)
if err != nil {
return 0, fmt.Errorf("failed to count transaction events: %w", err)
}
return spaceCount + txCount, nil
}

View file

@ -248,7 +248,11 @@ func (s *TransactionService) UpdateBill(input UpdateBillInput) (*model.Transacti
TransactionID: input.TransactionID,
ActorID: input.ActorID,
Action: model.TransactionAuditActionEdited,
Metadata: map[string]any{"changes": changes},
Metadata: map[string]any{
"account_id": existing.AccountID,
"transaction_type": string(existing.Type),
"changes": changes,
},
})
}
return existing, nil
@ -314,7 +318,11 @@ func (s *TransactionService) UpdateDeposit(input UpdateDepositInput) (*model.Tra
TransactionID: input.TransactionID,
ActorID: input.ActorID,
Action: model.TransactionAuditActionEdited,
Metadata: map[string]any{"changes": changes},
Metadata: map[string]any{
"account_id": existing.AccountID,
"transaction_type": string(existing.Type),
"changes": changes,
},
})
}
return existing, nil