feat(catalog): class template editing

Templates were delete-and-recreate only. Adds PUT
/v1/catalog/class-templates/{id} across repository, service (sharing
the create-time validation), route, spec, and client; the classes tab
gets a pencil action that loads the row into the form with a
save/cancel affordance.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
Tomas DvorakandDevin committed 2026-09-18 13:13:37 +02:00
1 parent 3892e9ce8c
commit 5884203e9d
11 files changed
+249 -21

No files matched your search

@@ -640,3 +640,43 @@ func TestCancelBookingPromotesWaitlist(t *testing.T) {
t.Fatalf("expected second waiter promoted, got %q", booking.Status)
}
}
func TestUpdateClassTemplate(t *testing.T) {
repo := db.NewMemoryRepository()
svc := newCatalogService(repo)
ctx := context.Background()
created, err := svc.CreateClassTemplate(ctx, owner, domain.UpsertClassTemplateRequest{
Title: "Yin Yoga", DurationMinutes: 75, Capacity: 10,
})
if err != nil {
t.Fatalf("create template: %v", err)
}
updated, err := svc.UpdateClassTemplate(ctx, owner, created.ID, domain.UpsertClassTemplateRequest{
Title: "Yin Yoga (večer)", DurationMinutes: 90, Capacity: 12,
})
if err != nil {
t.Fatalf("update template: %v", err)
}
if updated.Title != "Yin Yoga (večer)" || updated.DurationMinutes != 90 || updated.Capacity != 12 {
t.Fatalf("unexpected updated template: %+v", updated)
}
if _, err := svc.UpdateClassTemplate(ctx, owner, created.ID, domain.UpsertClassTemplateRequest{
Title: "", DurationMinutes: 90, Capacity: 12,
}); !errors.Is(err, ErrInvalidInput) {
t.Fatalf("expected ErrInvalidInput, got %v", err)
}
stranger := domain.Principal{Subject: "someone-else", Role: "staff"}
if _, err := svc.UpdateClassTemplate(ctx, stranger, created.ID, domain.UpsertClassTemplateRequest{
Title: "X", DurationMinutes: 60, Capacity: 5,
}); !errors.Is(err, ErrTenantMembership) {
t.Fatalf("expected ErrTenantMembership, got %v", err)
}
if _, err := svc.UpdateClassTemplate(ctx, owner, "00000000-0000-0000-0000-000000000099", domain.UpsertClassTemplateRequest{
Title: "X", DurationMinutes: 60, Capacity: 5,
}); !errors.Is(err, ErrClassTemplateNotFound) {
t.Fatalf("expected ErrClassTemplateNotFound, got %v", err)
}
}