[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:
Benjamin Admin
2026-04-27 00:09:30 +02:00
parent 5ef039a6bc
commit 92c86ec6ba
162 changed files with 23853 additions and 23034 deletions

View File

@@ -0,0 +1,244 @@
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 - Consent
// ========================================
// CreateConsent creates a new user consent
func (h *Handler) CreateConsent(c *gin.Context) {
var req models.CreateConsentRequest
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
}
versionID, err := uuid.Parse(req.VersionID)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid version ID"})
return
}
ctx := context.Background()
ipAddress := middleware.GetClientIP(c)
userAgent := middleware.GetUserAgent(c)
// Upsert consent
var consentID uuid.UUID
err = h.db.Pool.QueryRow(ctx, `
INSERT INTO user_consents (user_id, document_version_id, consented, ip_address, user_agent)
VALUES ($1, $2, $3, $4, $5)
ON CONFLICT (user_id, document_version_id)
DO UPDATE SET consented = $3, consented_at = NOW(), withdrawn_at = NULL
RETURNING id
`, userID, versionID, req.Consented, ipAddress, userAgent).Scan(&consentID)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to save consent"})
return
}
// Log to audit trail
h.logAudit(ctx, &userID, "consent_given", "document_version", &versionID, nil, ipAddress, userAgent)
c.JSON(http.StatusCreated, gin.H{
"message": "Consent saved successfully",
"consent_id": consentID,
})
}
// GetMyConsents returns all consents for the current user
func (h *Handler) GetMyConsents(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 uc.id, uc.consented, uc.consented_at, uc.withdrawn_at,
ld.id, ld.type, ld.name, ld.is_mandatory,
dv.id, dv.version, dv.language, dv.title
FROM user_consents uc
JOIN document_versions dv ON uc.document_version_id = dv.id
JOIN legal_documents ld ON dv.document_id = ld.id
WHERE uc.user_id = $1
ORDER BY uc.consented_at DESC
`, userID)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch consents"})
return
}
defer rows.Close()
var consents []map[string]interface{}
for rows.Next() {
var (
consentID uuid.UUID
consented bool
consentedAt time.Time
withdrawnAt *time.Time
docID uuid.UUID
docType string
docName string
isMandatory bool
versionID uuid.UUID
version string
language string
title string
)
if err := rows.Scan(&consentID, &consented, &consentedAt, &withdrawnAt,
&docID, &docType, &docName, &isMandatory,
&versionID, &version, &language, &title); err != nil {
continue
}
consents = append(consents, map[string]interface{}{
"consent_id": consentID,
"consented": consented,
"consented_at": consentedAt,
"withdrawn_at": withdrawnAt,
"document": map[string]interface{}{
"id": docID,
"type": docType,
"name": docName,
"is_mandatory": isMandatory,
},
"version": map[string]interface{}{
"id": versionID,
"version": version,
"language": language,
"title": title,
},
})
}
c.JSON(http.StatusOK, gin.H{"consents": consents})
}
// CheckConsent checks if the user has consented to a document
func (h *Handler) CheckConsent(c *gin.Context) {
docType := c.Param("documentType")
language := c.DefaultQuery("language", "de")
userID, err := middleware.GetUserID(c)
if err != nil || userID == uuid.Nil {
c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid user"})
return
}
ctx := context.Background()
// Get latest published version
var latestVersionID uuid.UUID
var latestVersion string
err = h.db.Pool.QueryRow(ctx, `
SELECT dv.id, dv.version
FROM document_versions dv
JOIN legal_documents ld ON dv.document_id = ld.id
WHERE ld.type = $1 AND dv.language = $2 AND dv.status = 'published'
ORDER BY dv.published_at DESC
LIMIT 1
`, docType, language).Scan(&latestVersionID, &latestVersion)
if err != nil {
c.JSON(http.StatusOK, models.ConsentCheckResponse{
HasConsent: false,
NeedsUpdate: false,
})
return
}
// Check if user has consented to this version
var consentedVersionID uuid.UUID
var consentedVersion string
var consentedAt time.Time
err = h.db.Pool.QueryRow(ctx, `
SELECT dv.id, dv.version, uc.consented_at
FROM user_consents uc
JOIN document_versions dv ON uc.document_version_id = dv.id
JOIN legal_documents ld ON dv.document_id = ld.id
WHERE uc.user_id = $1 AND ld.type = $2 AND uc.consented = true AND uc.withdrawn_at IS NULL
ORDER BY uc.consented_at DESC
LIMIT 1
`, userID, docType).Scan(&consentedVersionID, &consentedVersion, &consentedAt)
if err != nil {
// No consent found
latestIDStr := latestVersionID.String()
c.JSON(http.StatusOK, models.ConsentCheckResponse{
HasConsent: false,
CurrentVersionID: &latestIDStr,
NeedsUpdate: true,
})
return
}
// Check if consent is for latest version
needsUpdate := consentedVersionID != latestVersionID
latestIDStr := latestVersionID.String()
consentedVerStr := consentedVersion
c.JSON(http.StatusOK, models.ConsentCheckResponse{
HasConsent: true,
CurrentVersionID: &latestIDStr,
ConsentedVersion: &consentedVerStr,
NeedsUpdate: needsUpdate,
ConsentedAt: &consentedAt,
})
}
// WithdrawConsent withdraws a consent
func (h *Handler) WithdrawConsent(c *gin.Context) {
consentID, err := uuid.Parse(c.Param("id"))
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid consent ID"})
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)
// Update consent
result, err := h.db.Pool.Exec(ctx, `
UPDATE user_consents
SET withdrawn_at = NOW(), consented = false
WHERE id = $1 AND user_id = $2
`, consentID, userID)
if err != nil || result.RowsAffected() == 0 {
c.JSON(http.StatusNotFound, gin.H{"error": "Consent not found"})
return
}
// Log to audit trail
h.logAudit(ctx, &userID, "consent_withdrawn", "consent", &consentID, nil, ipAddress, userAgent)
c.JSON(http.StatusOK, gin.H{"message": "Consent withdrawn successfully"})
}