diff --git a/contrib/claude/coredata.md b/contrib/claude/coredata.md index 54492fc75..c58a66fe4 100644 --- a/contrib/claude/coredata.md +++ b/contrib/claude/coredata.md @@ -75,6 +75,22 @@ maps.Copy(args, cursor.SQLArguments()) **All SQL must be static** after `fmt.Sprintf()` injection — no conditional string building. Use `CASE WHEN` in SQL for optional filter logic. +**Use Go enum constants as named parameters** — never hardcode string literals like `'ACTIVE'` or `'PUBLISHED'` in SQL. Use a named parameter (`@state`) and pass the Go constant via `pgx.StrictNamedArgs`: + +```go +// Good — Go constant as named parameter +q := `SELECT ... FROM cookie_banners WHERE id = @id AND state = @state;` +args := pgx.StrictNamedArgs{ + "id": bannerID, + "state": CookieBannerStateActive, +} + +// Bad — hardcoded string literal in SQL +q := `SELECT ... FROM cookie_banners WHERE id = @id AND state = 'ACTIVE';` +``` + +This ensures the compiler catches renamed or removed enum values instead of silently producing wrong results at runtime. + ## Standard method signatures diff --git a/pkg/server/api/cookiebanner/v1/handler.go b/pkg/server/api/cookiebanner/v1/handler.go index f72d34736..7a6593b54 100644 --- a/pkg/server/api/cookiebanner/v1/handler.go +++ b/pkg/server/api/cookiebanner/v1/handler.go @@ -167,10 +167,14 @@ func (h *Handler) handlePostConsent(w http.ResponseWriter, r *http.Request) { return } - httpserver.RenderJSON(w, http.StatusCreated, postConsentResponse{ - ID: record.ID.String(), - VisitorID: record.VisitorID, - Action: string(record.Action), - CreatedAt: record.CreatedAt, - }) + httpserver.RenderJSON( + w, + http.StatusCreated, + postConsentResponse{ + ID: record.ID.String(), + VisitorID: record.VisitorID, + Action: string(record.Action), + CreatedAt: record.CreatedAt, + }, + ) }