Store cookie durations as max_age_seconds

Replace the free-form duration TEXT column with a nullable
max_age_seconds INTEGER on both cookies and cookie_patterns
tables. The SDK detector now sends raw seconds instead of
humanized strings, eliminating locale-dependent comparisons
in the pattern merge worker. Humanization happens at display
time in the widget and console UI.

Signed-off-by: Émile Ré <emile@getprobo.com>
This commit is contained in:
Émile Ré
2026-04-29 18:54:36 +04:00
parent b8ff3c66e1
commit 5cdaddf8b1
21 changed files with 308 additions and 151 deletions

View File

@@ -224,9 +224,9 @@ func (r *cookieBannerVersionResolver) Categories(ctx context.Context, obj *types
cookies := make([]*types.CookieBannerVersionCookie, len(cat.Cookies))
for j, c := range cat.Cookies {
cookies[j] = &types.CookieBannerVersionCookie{
Name: c.Name,
Duration: c.Duration,
Description: c.Description,
Name: c.Name,
MaxAgeSeconds: c.MaxAgeSeconds,
Description: c.Description,
}
}
@@ -754,7 +754,7 @@ func (r *mutationResolver) CreateCookiePattern(ctx context.Context, input types.
Pattern: input.Pattern,
MatchType: input.MatchType,
DisplayName: input.DisplayName,
Duration: input.Duration,
MaxAgeSeconds: input.MaxAgeSeconds,
Description: input.Description,
},
)
@@ -799,7 +799,7 @@ func (r *mutationResolver) UpdateCookiePattern(ctx context.Context, input types.
cookiebanner.UpdateCookiePatternRequest{
CookiePatternID: input.CookiePatternID,
DisplayName: input.DisplayName,
Duration: input.Duration,
MaxAgeSeconds: gqlutils.UnwrapOmittable(input.MaxAgeSeconds),
Description: input.Description,
},
)

View File

@@ -200,7 +200,7 @@ type CookiePattern implements Node {
pattern: String!
matchType: CookiePatternMatchType!
displayName: String!
duration: String!
maxAgeSeconds: Int
description: String!
source: CookieSource!
cookieCount: Int! @goField(forceResolver: true)
@@ -243,7 +243,7 @@ type CookieBannerVersionCategory {
type CookieBannerVersionCookie {
name: String!
duration: String!
maxAgeSeconds: Int
description: String!
}
@@ -434,14 +434,14 @@ input CreateCookiePatternInput {
pattern: String!
matchType: CookiePatternMatchType!
displayName: String!
duration: String!
maxAgeSeconds: Int
description: String!
}
input UpdateCookiePatternInput {
cookiePatternId: ID!
displayName: String
duration: String
maxAgeSeconds: Int @goField(omittable: true)
description: String
}

View File

@@ -69,13 +69,13 @@ func NewCookiePattern(cp *coredata.CookiePattern) *CookiePattern {
ID: cp.CookieBannerID,
},
},
Pattern: cp.Pattern,
MatchType: cp.MatchType,
DisplayName: cp.DisplayName,
Duration: cp.Duration,
Description: cp.Description,
Source: cp.Source,
CreatedAt: cp.CreatedAt,
UpdatedAt: cp.UpdatedAt,
Pattern: cp.Pattern,
MatchType: cp.MatchType,
DisplayName: cp.DisplayName,
MaxAgeSeconds: cp.MaxAgeSeconds,
Description: cp.Description,
Source: cp.Source,
CreatedAt: cp.CreatedAt,
UpdatedAt: cp.UpdatedAt,
}
}

View File

@@ -187,9 +187,9 @@ func (h *Handler) handlePostConsent(w http.ResponseWriter, r *http.Request) {
}
type detectedCookieEntry struct {
Name string `json:"name"`
Duration string `json:"duration"`
Source string `json:"source"`
Name string `json:"name"`
MaxAgeSeconds *int `json:"max_age_seconds"`
Source string `json:"source"`
}
type reportDetectedCookiesBody struct {
@@ -239,9 +239,9 @@ func (h *Handler) handleReportDetectedCookies(w http.ResponseWriter, r *http.Req
detected = append(
detected,
cookiebanner.DetectedCookie{
Name: name,
Duration: strings.TrimSpace(c.Duration),
Source: source,
Name: name,
MaxAgeSeconds: c.MaxAgeSeconds,
Source: source,
},
)
}