Skip to content

Add cookie banner versioning with JSONB snapshots#1028

Merged
codenem merged 4 commits intomainfrom
cookie-banner-versioning
Apr 13, 2026
Merged

Add cookie banner versioning with JSONB snapshots#1028
codenem merged 4 commits intomainfrom
cookie-banner-versioning

Conversation

@codenem
Copy link
Copy Markdown
Contributor

@codenem codenem commented Apr 13, 2026

Closes ENG-274

Introduce append-only cookie_banner_versions table with a JSONB snapshot of consent-relevant configuration (privacy policy URL, consent mode, expiry, categories and their cookies). Each version has its own state (DRAFT/PUBLISHED) separate from the banner lifecycle.

Replace the banner state enum (DRAFT/PUBLISHED/DISABLED) with a simpler ACTIVE/INACTIVE toggle. Link consent records to the specific published version the visitor accepted.


Summary by cubic

Adds append-only cookie banner versioning with JSONB snapshots and links each consent to the exact published version accepted. Auto-creates a draft version on banner creation and denormalizes organization_id onto versions, categories, and consent records to avoid JOINs in auth.

  • New Features

    • cookie_banner_versions with per-version DRAFT/PUBLISHED and a JSONB snapshot (policy URL, consent mode, expiry, categories/cookies).
    • Service APIs: PublishCookieBannerVersion, GetCookieBannerVersion, ListCookieBannerVersionsForBanner, CountCookieBannerVersionsForBanner (publishing promotes the latest draft and fails if none).
    • Draft snapshots are auto-provisioned on banner creation and updated on consent field changes and category create/update/delete.
    • Consent records include cookie_banner_version_id; CreateCookieConsentRecord requires version and validates it is PUBLISHED.
    • New errors: ErrVersionNotFound, ErrVersionNotPublished, ErrBannerAlreadyActive, ErrBannerAlreadyInactive, ErrNoDraftVersion.
  • Migration

    • DB: replace cookie_banner_state enum with ACTIVE/INACTIVE; add cookie_banner_versions; add NOT NULL cookie_banner_version_id FK on cookie_consent_records; unique (cookie_banner_id, version); add NOT NULL organization_id on cookie_banner_versions, cookie_categories, and cookie_consent_records.
    • API: replace PublishCookieBanner/DisableCookieBanner with ActivateCookieBanner/DeactivateCookieBanner; use LoadActiveByID (was LoadPublishedByID); pass version when creating consent; new banners start as ACTIVE.
    • Ops: publish a version via PublishCookieBannerVersion before recording consent.

Written for commit d2937c5. Summary will update on new commits.

Copy link
Copy Markdown
Contributor

@gearnode gearnode left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@codenem codenem force-pushed the cookie-banner-models branch from 9f2e756 to a153427 Compare April 13, 2026 10:50
codenem added 3 commits April 13, 2026 14:52
Introduce append-only cookie_banner_versions table with a JSONB
snapshot of consent-relevant configuration (privacy policy URL,
consent mode, expiry, categories and their cookies). Each version
has its own state (DRAFT/PUBLISHED) separate from the banner
lifecycle.

Replace the banner state enum (DRAFT/PUBLISHED/DISABLED) with a
simpler ACTIVE/INACTIVE toggle. Link consent records to the
specific published version the visitor accepted.

Signed-off-by: Émile Ré <emile@getprobo.com>
Signed-off-by: Émile Ré <emile@getprobo.com>
Add organization_id to cookie_banner_versions, cookie_categories,
and cookie_consent_records so AuthorizationAttributes can return
it directly without JOINing back to cookie_banners. Document the
pattern in contrib/claude/coredata.md.

Signed-off-by: Émile Ré <emile@getprobo.com>
@codenem codenem force-pushed the cookie-banner-versioning branch from 605c9cc to 61cd324 Compare April 13, 2026 10:52
Base automatically changed from cookie-banner-models to main April 13, 2026 10:56
@codenem codenem marked this pull request as ready for review April 13, 2026 11:17
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 12 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="pkg/cookiebanner/service.go">

<violation number="1" location="pkg/cookiebanner/service.go:254">
P1: No initial draft version is created when a new banner is created. The banner starts as `ACTIVE` with consent-relevant config and default categories, but `ensureDraftVersion` is never called in this transaction. As a result, `PublishCookieBannerVersion` will fail with `ErrNoDraftVersion` and no consent can be recorded until the user makes a separate update to trigger draft creation.

After inserting the default categories, load them back and call `ensureDraftVersion` (matching the pattern used in `CreateCookieCategory`, `UpdateCookieBanner`, etc.).</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Signed-off-by: Émile Ré <emile@getprobo.com>
@codenem codenem merged commit d2937c5 into main Apr 13, 2026
17 checks passed
@codenem codenem deleted the cookie-banner-versioning branch April 13, 2026 12:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants