mirror of
https://github.com/Dvorinka/Bookra.git
synced 2026-10-29 07:54:44 +00:00
feat(activity): per-tenant audit feed in notification dropdown
activity_events records booking lifecycle transitions with the actor behind each change — staff (dashboard), customer (self-service), or system (auto-promotion). The notification dropdown leads with the real feed instead of derived recent-booking guesses. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
e5cb9bd543
commit
d86cba61e3
18 files changed
+634
-28
No files matched your search
@@ -0,0 +1,92 @@
|
||||
package bookings
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"bookra/apps/backend/internal/db"
|
||||
)
|
||||
|
||||
const activityTenantID = "5d6b3551-0a3e-4b86-bdf0-e9df20a47148"
|
||||
|
||||
var activitySessionID = "4bf74c12-44dd-45ca-86bb-b104f16f2435"
|
||||
|
||||
func seedSessionBooking(t *testing.T, repo *db.MemoryRepository, name, status string) db.BookingRecord {
|
||||
t.Helper()
|
||||
created, err := repo.CreateBooking(context.Background(), db.CreateBookingParams{
|
||||
TenantID: activityTenantID,
|
||||
ClassSessionID: &activitySessionID,
|
||||
CustomerName: name,
|
||||
CustomerEmail: name + "@example.com",
|
||||
Status: status,
|
||||
Reference: "BK-" + name,
|
||||
ManageToken: "tok-" + name,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("seed booking: %v", err)
|
||||
}
|
||||
booking, err := repo.GetBookingByReference(context.Background(), created.Reference)
|
||||
if err != nil {
|
||||
t.Fatalf("get booking: %v", err)
|
||||
}
|
||||
return booking
|
||||
}
|
||||
|
||||
func TestCustomerCancelWritesActivityEvent(t *testing.T) {
|
||||
repo := db.NewMemoryRepository()
|
||||
booking := newBookingFixture(t, repo)
|
||||
svc := NewCustomerService(repo, nil, "http://localhost:3000")
|
||||
|
||||
if err := svc.CancelBooking(context.Background(), booking.Reference, "secret-manage-token"); err != nil {
|
||||
t.Fatalf("cancel booking: %v", err)
|
||||
}
|
||||
|
||||
events, err := repo.ListActivityEvents(context.Background(), activityTenantID, 1)
|
||||
if err != nil {
|
||||
t.Fatalf("list activity: %v", err)
|
||||
}
|
||||
if len(events) != 1 {
|
||||
t.Fatalf("expected 1 event, got %d", len(events))
|
||||
}
|
||||
event := events[0]
|
||||
if event.Action != "booking.cancelled" {
|
||||
t.Fatalf("expected booking.cancelled, got %s", event.Action)
|
||||
}
|
||||
if event.ActorKind != "customer" || event.ActorName != "Test Customer" {
|
||||
t.Fatalf("expected customer actor Test Customer, got %s %q", event.ActorKind, event.ActorName)
|
||||
}
|
||||
if event.EntityID == nil || *event.EntityID != booking.ID {
|
||||
t.Fatalf("expected entity id %s, got %v", booking.ID, event.EntityID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPromoteWaitlistWritesSystemEvent(t *testing.T) {
|
||||
repo := db.NewMemoryRepository()
|
||||
// Demo session capacity is 4 — three confirmed leaves exactly one seat.
|
||||
for _, name := range []string{"fill-a", "fill-b", "fill-c"} {
|
||||
seedSessionBooking(t, repo, name, "confirmed")
|
||||
}
|
||||
waiting := seedSessionBooking(t, repo, "queued", "waitlisted")
|
||||
|
||||
promoted, err := PromoteWaitlist(context.Background(), repo, activityTenantID, activitySessionID)
|
||||
if err != nil {
|
||||
t.Fatalf("promote waitlist: %v", err)
|
||||
}
|
||||
if len(promoted) != 1 || promoted[0].ID != waiting.ID {
|
||||
t.Fatalf("expected queued booking promoted, got %v", promoted)
|
||||
}
|
||||
|
||||
events, err := repo.ListActivityEvents(context.Background(), activityTenantID, 10)
|
||||
if err != nil {
|
||||
t.Fatalf("list activity: %v", err)
|
||||
}
|
||||
for _, event := range events {
|
||||
if event.Action == "booking.promoted" && event.ActorKind == "system" {
|
||||
if event.EntityID == nil || *event.EntityID != waiting.ID {
|
||||
t.Fatalf("expected entity id %s, got %v", waiting.ID, event.EntityID)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
t.Fatal("expected system booking.promoted event")
|
||||
}
|
||||
Reference in new issue
Block a user