From b4d8bd8de23cab6535ae6981ede1c99be44935f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89mile=20R=C3=A9?= Date: Thu, 7 May 2026 14:05:52 +0400 Subject: [PATCH] Add country code to consent records MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Store the visitor's resolved country code alongside regulation in cookie_consent_records so downstream surfaces can expose it. Signed-off-by: Émile Ré --- pkg/cookiebanner/service.go | 2 ++ pkg/coredata/cookie_consent_record.go | 7 +++++++ pkg/coredata/migrations/20260507T131200Z.sql | 19 +++++++++++++++++++ pkg/server/api/cookiebanner/v1/handler.go | 17 ++++++++--------- 4 files changed, 36 insertions(+), 9 deletions(-) create mode 100644 pkg/coredata/migrations/20260507T131200Z.sql diff --git a/pkg/cookiebanner/service.go b/pkg/cookiebanner/service.go index 26cd93803..8b11ef51a 100644 --- a/pkg/cookiebanner/service.go +++ b/pkg/cookiebanner/service.go @@ -104,6 +104,7 @@ type ( Action coredata.CookieConsentAction SdkVersion string Regulation Regulation + CountryCode coredata.CountryCode } DetectedCookie struct { @@ -1842,6 +1843,7 @@ func (s *Service) RecordConsent( Action: req.Action, SdkVersion: req.SdkVersion, Regulation: req.Regulation, + CountryCode: req.CountryCode, CreatedAt: time.Now(), } diff --git a/pkg/coredata/cookie_consent_record.go b/pkg/coredata/cookie_consent_record.go index 5de68d586..a3b74f58b 100644 --- a/pkg/coredata/cookie_consent_record.go +++ b/pkg/coredata/cookie_consent_record.go @@ -41,6 +41,7 @@ type ( Action CookieConsentAction `db:"action"` SdkVersion string `db:"sdk_version"` Regulation Regulation `db:"regulation"` + CountryCode CountryCode `db:"country_code"` CreatedAt time.Time `db:"created_at"` } @@ -92,6 +93,7 @@ SELECT action, sdk_version, regulation, + country_code, created_at FROM cookie_consent_records @@ -177,6 +179,7 @@ INSERT INTO cookie_consent_records ( action, sdk_version, regulation, + country_code, created_at ) VALUES ( @id, @@ -191,6 +194,7 @@ INSERT INTO cookie_consent_records ( @action, @sdk_version, @regulation, + @country_code, @created_at ) ` @@ -208,6 +212,7 @@ INSERT INTO cookie_consent_records ( "action": r.Action, "sdk_version": r.SdkVersion, "regulation": r.Regulation, + "country_code": r.CountryCode, "created_at": r.CreatedAt, } @@ -238,6 +243,7 @@ SELECT action, sdk_version, regulation, + country_code, created_at FROM cookie_consent_records @@ -290,6 +296,7 @@ SELECT action, sdk_version, regulation, + country_code, created_at FROM cookie_consent_records diff --git a/pkg/coredata/migrations/20260507T131200Z.sql b/pkg/coredata/migrations/20260507T131200Z.sql new file mode 100644 index 000000000..db84cd874 --- /dev/null +++ b/pkg/coredata/migrations/20260507T131200Z.sql @@ -0,0 +1,19 @@ +-- Copyright (c) 2026 Probo Inc . +-- +-- Permission to use, copy, modify, and/or distribute this software for any +-- purpose with or without fee is hereby granted, provided that the above +-- copyright notice and this permission notice appear in all copies. +-- +-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +-- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +-- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +-- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +-- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +-- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +-- PERFORMANCE OF THIS SOFTWARE. + +ALTER TABLE cookie_consent_records + ADD COLUMN country_code TEXT NOT NULL DEFAULT ''; + +ALTER TABLE cookie_consent_records + ALTER COLUMN country_code DROP DEFAULT; diff --git a/pkg/server/api/cookiebanner/v1/handler.go b/pkg/server/api/cookiebanner/v1/handler.go index cf37ec2fb..fac8b3086 100644 --- a/pkg/server/api/cookiebanner/v1/handler.go +++ b/pkg/server/api/cookiebanner/v1/handler.go @@ -71,7 +71,8 @@ func (h *Handler) handleGetConfig(w http.ResponseWriter, r *http.Request) { } lang := r.URL.Query().Get("lang") - regulation := h.resolveRegulation(r) + cc := h.resolveCountryCode(r) + regulation := cookiebanner.RegulationForCountry(cc) config, err := h.cookieBannerSvc.GetActiveBannerConfig(r.Context(), bannerID, lang, regulation) if err != nil { @@ -91,20 +92,16 @@ func (h *Handler) handleGetConfig(w http.ResponseWriter, r *http.Request) { httpserver.RenderJSON(w, http.StatusOK, config) } -func (h *Handler) resolveRegulation(r *http.Request) cookiebanner.Regulation { +func (h *Handler) resolveCountryCode(r *http.Request) coredata.CountryCode { ip := clientip.Extract(r) cc, err := h.geolocSvc.LookupCountry(r.Context(), ip) if err != nil { h.logger.ErrorCtx(r.Context(), "cannot resolve country for IP", log.Error(err)) - return cookiebanner.RegulationNone + return "" } - if cc == "" { - return cookiebanner.RegulationNone - } - - return cookiebanner.RegulationForCountry(cc) + return cc } func (h *Handler) handleGetConsent(w http.ResponseWriter, r *http.Request) { @@ -170,6 +167,7 @@ func (h *Handler) handlePostConsent(w http.ResponseWriter, r *http.Request) { ip := clientip.Extract(r) ua := r.UserAgent() sdkVersion := r.Header.Get("X-SDK-Version") + cc := h.resolveCountryCode(r) req := cookiebanner.RecordConsentRequest{ Version: body.Version, @@ -179,7 +177,8 @@ func (h *Handler) handlePostConsent(w http.ResponseWriter, r *http.Request) { ConsentData: body.ConsentData, Action: body.Action, SdkVersion: sdkVersion, - Regulation: h.resolveRegulation(r), + Regulation: cookiebanner.RegulationForCountry(cc), + CountryCode: cc, } record, err := h.cookieBannerSvc.RecordConsent(r.Context(), bannerID, req)