[split-required] [guardrail-change] Enforce 500 LOC budget across all services
Install LOC guardrails (check-loc.sh, architecture.md, pre-commit hook) and split all 44 files exceeding 500 LOC into domain-focused modules: - consent-service (Go): models, handlers, services, database splits - backend-core (Python): security_api, rbac_api, pdf_service, auth splits - admin-core (TypeScript): 5 page.tsx + sidebar extractions - pitch-deck (TypeScript): 6 slides, 3 UI components, engine.ts splits - voice-service (Python): enhanced_task_orchestrator split Result: 0 violations, 36 exempted (pipeline, tests, pure-data files). Go build verified clean. No behavior changes — pure structural splits. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
158
consent-service/internal/handlers/cookies_public.go
Normal file
158
consent-service/internal/handlers/cookies_public.go
Normal file
@@ -0,0 +1,158 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/breakpilot/consent-service/internal/middleware"
|
||||
"github.com/breakpilot/consent-service/internal/models"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// ========================================
|
||||
// PUBLIC ENDPOINTS - Cookie Consent
|
||||
// ========================================
|
||||
|
||||
// GetCookieCategories returns all active cookie categories
|
||||
func (h *Handler) GetCookieCategories(c *gin.Context) {
|
||||
language := c.DefaultQuery("language", "de")
|
||||
ctx := context.Background()
|
||||
|
||||
rows, err := h.db.Pool.Query(ctx, `
|
||||
SELECT id, name, display_name_de, display_name_en, description_de, description_en,
|
||||
is_mandatory, sort_order
|
||||
FROM cookie_categories
|
||||
WHERE is_active = true
|
||||
ORDER BY sort_order ASC
|
||||
`)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch categories"})
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var categories []map[string]interface{}
|
||||
for rows.Next() {
|
||||
var cat models.CookieCategory
|
||||
if err := rows.Scan(&cat.ID, &cat.Name, &cat.DisplayNameDE, &cat.DisplayNameEN,
|
||||
&cat.DescriptionDE, &cat.DescriptionEN, &cat.IsMandatory, &cat.SortOrder); err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// Return localized data
|
||||
displayName := cat.DisplayNameDE
|
||||
description := cat.DescriptionDE
|
||||
if language == "en" && cat.DisplayNameEN != nil {
|
||||
displayName = *cat.DisplayNameEN
|
||||
if cat.DescriptionEN != nil {
|
||||
description = cat.DescriptionEN
|
||||
}
|
||||
}
|
||||
|
||||
categories = append(categories, map[string]interface{}{
|
||||
"id": cat.ID,
|
||||
"name": cat.Name,
|
||||
"display_name": displayName,
|
||||
"description": description,
|
||||
"is_mandatory": cat.IsMandatory,
|
||||
})
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"categories": categories})
|
||||
}
|
||||
|
||||
// SetCookieConsent sets cookie preferences for a user
|
||||
func (h *Handler) SetCookieConsent(c *gin.Context) {
|
||||
var req models.CookieConsentRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request body"})
|
||||
return
|
||||
}
|
||||
|
||||
userID, err := middleware.GetUserID(c)
|
||||
if err != nil || userID == uuid.Nil {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid user"})
|
||||
return
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
ipAddress := middleware.GetClientIP(c)
|
||||
userAgent := middleware.GetUserAgent(c)
|
||||
|
||||
// Process each category
|
||||
for _, cat := range req.Categories {
|
||||
categoryID, err := uuid.Parse(cat.CategoryID)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
_, err = h.db.Pool.Exec(ctx, `
|
||||
INSERT INTO cookie_consents (user_id, category_id, consented)
|
||||
VALUES ($1, $2, $3)
|
||||
ON CONFLICT (user_id, category_id)
|
||||
DO UPDATE SET consented = $3, updated_at = NOW()
|
||||
`, userID, categoryID, cat.Consented)
|
||||
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// Log to audit trail
|
||||
h.logAudit(ctx, &userID, "cookie_consent_updated", "cookie", nil, nil, ipAddress, userAgent)
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"message": "Cookie preferences saved"})
|
||||
}
|
||||
|
||||
// GetMyCookieConsent returns cookie preferences for the current user
|
||||
func (h *Handler) GetMyCookieConsent(c *gin.Context) {
|
||||
userID, err := middleware.GetUserID(c)
|
||||
if err != nil || userID == uuid.Nil {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid user"})
|
||||
return
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
rows, err := h.db.Pool.Query(ctx, `
|
||||
SELECT cc.category_id, cc.consented, cc.updated_at,
|
||||
cat.name, cat.display_name_de, cat.is_mandatory
|
||||
FROM cookie_consents cc
|
||||
JOIN cookie_categories cat ON cc.category_id = cat.id
|
||||
WHERE cc.user_id = $1
|
||||
`, userID)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch preferences"})
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var consents []map[string]interface{}
|
||||
for rows.Next() {
|
||||
var (
|
||||
categoryID uuid.UUID
|
||||
consented bool
|
||||
updatedAt time.Time
|
||||
name string
|
||||
displayName string
|
||||
isMandatory bool
|
||||
)
|
||||
|
||||
if err := rows.Scan(&categoryID, &consented, &updatedAt, &name, &displayName, &isMandatory); err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
consents = append(consents, map[string]interface{}{
|
||||
"category_id": categoryID,
|
||||
"name": name,
|
||||
"display_name": displayName,
|
||||
"consented": consented,
|
||||
"is_mandatory": isMandatory,
|
||||
"updated_at": updatedAt,
|
||||
})
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"cookie_consents": consents})
|
||||
}
|
||||
Reference in New Issue
Block a user