Files
breakpilot-core/consent-service/internal/models/consent.go
Benjamin Admin 92c86ec6ba [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>
2026-04-27 00:09:30 +02:00

238 lines
10 KiB
Go

package models
import (
"time"
"github.com/google/uuid"
)
// LegalDocument represents a type of legal document (e.g., Terms, Privacy Policy)
type LegalDocument struct {
ID uuid.UUID `json:"id" db:"id"`
Type string `json:"type" db:"type"` // 'terms', 'privacy', 'cookies', 'community'
Name string `json:"name" db:"name"`
Description *string `json:"description" db:"description"`
IsMandatory bool `json:"is_mandatory" db:"is_mandatory"`
IsActive bool `json:"is_active" db:"is_active"`
SortOrder int `json:"sort_order" db:"sort_order"`
CreatedAt time.Time `json:"created_at" db:"created_at"`
UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
}
// DocumentVersion represents a specific version of a legal document
type DocumentVersion struct {
ID uuid.UUID `json:"id" db:"id"`
DocumentID uuid.UUID `json:"document_id" db:"document_id"`
Version string `json:"version" db:"version"` // Semver: 1.0.0, 1.1.0
Language string `json:"language" db:"language"` // ISO 639-1: de, en
Title string `json:"title" db:"title"`
Content string `json:"content" db:"content"` // HTML or Markdown
Summary *string `json:"summary" db:"summary"` // Summary of changes
Status string `json:"status" db:"status"` // 'draft', 'review', 'approved', 'scheduled', 'published', 'archived'
PublishedAt *time.Time `json:"published_at" db:"published_at"`
ScheduledPublishAt *time.Time `json:"scheduled_publish_at" db:"scheduled_publish_at"`
CreatedBy *uuid.UUID `json:"created_by" db:"created_by"`
ApprovedBy *uuid.UUID `json:"approved_by" db:"approved_by"`
ApprovedAt *time.Time `json:"approved_at" db:"approved_at"`
CreatedAt time.Time `json:"created_at" db:"created_at"`
UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
}
// UserConsent represents a user's consent to a document version
type UserConsent struct {
ID uuid.UUID `json:"id" db:"id"`
UserID uuid.UUID `json:"user_id" db:"user_id"`
DocumentVersionID uuid.UUID `json:"document_version_id" db:"document_version_id"`
Consented bool `json:"consented" db:"consented"`
IPAddress *string `json:"ip_address" db:"ip_address"`
UserAgent *string `json:"user_agent" db:"user_agent"`
ConsentedAt time.Time `json:"consented_at" db:"consented_at"`
WithdrawnAt *time.Time `json:"withdrawn_at" db:"withdrawn_at"`
}
// AuditLog represents an audit trail entry for GDPR compliance
type AuditLog struct {
ID uuid.UUID `json:"id" db:"id"`
UserID *uuid.UUID `json:"user_id" db:"user_id"`
Action string `json:"action" db:"action"` // 'consent_given', 'consent_withdrawn', 'data_export', 'data_delete'
EntityType *string `json:"entity_type" db:"entity_type"` // 'document', 'cookie_category'
EntityID *uuid.UUID `json:"entity_id" db:"entity_id"`
Details *string `json:"details" db:"details"` // JSON string
IPAddress *string `json:"ip_address" db:"ip_address"`
UserAgent *string `json:"user_agent" db:"user_agent"`
CreatedAt time.Time `json:"created_at" db:"created_at"`
}
// DataExportRequest represents a user's request to export their data
type DataExportRequest struct {
ID uuid.UUID `json:"id" db:"id"`
UserID uuid.UUID `json:"user_id" db:"user_id"`
Status string `json:"status" db:"status"` // 'pending', 'processing', 'completed', 'failed'
DownloadURL *string `json:"download_url" db:"download_url"`
ExpiresAt *time.Time `json:"expires_at" db:"expires_at"`
CreatedAt time.Time `json:"created_at" db:"created_at"`
CompletedAt *time.Time `json:"completed_at" db:"completed_at"`
}
// DataDeletionRequest represents a user's request to delete their data
type DataDeletionRequest struct {
ID uuid.UUID `json:"id" db:"id"`
UserID uuid.UUID `json:"user_id" db:"user_id"`
Status string `json:"status" db:"status"` // 'pending', 'processing', 'completed', 'failed'
Reason *string `json:"reason" db:"reason"`
CreatedAt time.Time `json:"created_at" db:"created_at"`
ProcessedAt *time.Time `json:"processed_at" db:"processed_at"`
ProcessedBy *uuid.UUID `json:"processed_by" db:"processed_by"`
}
// VersionApproval tracks the approval workflow
type VersionApproval struct {
ID uuid.UUID `json:"id" db:"id"`
VersionID uuid.UUID `json:"version_id" db:"version_id"`
ApproverID uuid.UUID `json:"approver_id" db:"approver_id"`
Action string `json:"action" db:"action"` // 'submitted_for_review', 'approved', 'rejected', 'published'
Comment *string `json:"comment,omitempty" db:"comment"`
CreatedAt time.Time `json:"created_at" db:"created_at"`
}
// ConsentDeadline tracks consent deadlines per user
type ConsentDeadline struct {
ID uuid.UUID `json:"id" db:"id"`
UserID uuid.UUID `json:"user_id" db:"user_id"`
DocumentVersionID uuid.UUID `json:"document_version_id" db:"document_version_id"`
DeadlineAt time.Time `json:"deadline_at" db:"deadline_at"`
ReminderCount int `json:"reminder_count" db:"reminder_count"`
LastReminderAt *time.Time `json:"last_reminder_at,omitempty" db:"last_reminder_at"`
ConsentGivenAt *time.Time `json:"consent_given_at,omitempty" db:"consent_given_at"`
CreatedAt time.Time `json:"created_at" db:"created_at"`
}
// AccountSuspension tracks account suspensions
type AccountSuspension struct {
ID uuid.UUID `json:"id" db:"id"`
UserID uuid.UUID `json:"user_id" db:"user_id"`
Reason string `json:"reason" db:"reason"` // 'consent_deadline_exceeded'
Details *string `json:"details,omitempty" db:"details"` // JSON
SuspendedAt time.Time `json:"suspended_at" db:"suspended_at"`
LiftedAt *time.Time `json:"lifted_at,omitempty" db:"lifted_at"`
LiftedReason *string `json:"lifted_reason,omitempty" db:"lifted_reason"`
}
// ========================================
// Consent DTOs
// ========================================
// CreateConsentRequest is the request body for creating a consent
type CreateConsentRequest struct {
DocumentType string `json:"document_type" binding:"required"`
VersionID string `json:"version_id" binding:"required"`
Consented bool `json:"consented"`
}
// ConsentCheckResponse is the response for checking consent status
type ConsentCheckResponse struct {
HasConsent bool `json:"has_consent"`
CurrentVersionID *string `json:"current_version_id,omitempty"`
ConsentedVersion *string `json:"consented_version,omitempty"`
NeedsUpdate bool `json:"needs_update"`
ConsentedAt *time.Time `json:"consented_at,omitempty"`
}
// DocumentWithVersion combines document info with its latest published version
type DocumentWithVersion struct {
Document LegalDocument `json:"document"`
LatestVersion *DocumentVersion `json:"latest_version,omitempty"`
}
// ConsentHistory represents a user's consent history for a document
type ConsentHistory struct {
Document LegalDocument `json:"document"`
Version DocumentVersion `json:"version"`
Consent UserConsent `json:"consent"`
}
// ConsentStats represents statistics about consents
type ConsentStats struct {
TotalUsers int `json:"total_users"`
ConsentedUsers int `json:"consented_users"`
ConsentRate float64 `json:"consent_rate"`
RecentConsents int `json:"recent_consents"` // Last 7 days
RecentWithdrawals int `json:"recent_withdrawals"`
}
// MyDataResponse represents all data we have about a user
type MyDataResponse struct {
User User `json:"user"`
Consents []ConsentHistory `json:"consents"`
CookieConsents []CookieConsent `json:"cookie_consents"`
AuditLog []AuditLog `json:"audit_log"`
ExportedAt time.Time `json:"exported_at"`
}
// CreateDocumentRequest is the request body for creating a document
type CreateDocumentRequest struct {
Type string `json:"type" binding:"required"`
Name string `json:"name" binding:"required"`
Description *string `json:"description"`
IsMandatory bool `json:"is_mandatory"`
}
// CreateVersionRequest is the request body for creating a document version
type CreateVersionRequest struct {
DocumentID string `json:"document_id" binding:"required"`
Version string `json:"version" binding:"required"`
Language string `json:"language" binding:"required"`
Title string `json:"title" binding:"required"`
Content string `json:"content" binding:"required"`
Summary *string `json:"summary"`
}
// UpdateVersionRequest is the request body for updating a version
type UpdateVersionRequest struct {
Title *string `json:"title"`
Content *string `json:"content"`
Summary *string `json:"summary"`
Status *string `json:"status"`
}
// SubmitForReviewRequest for submitting a version for review
type SubmitForReviewRequest struct {
Comment *string `json:"comment"`
}
// ApproveVersionRequest for approving a version (DSB)
type ApproveVersionRequest struct {
Comment *string `json:"comment"`
ScheduledPublishAt *string `json:"scheduled_publish_at"` // ISO 8601 datetime for scheduled publishing
}
// RejectVersionRequest for rejecting a version
type RejectVersionRequest struct {
Comment string `json:"comment" binding:"required"`
}
// VersionCompareResponse for comparing versions
type VersionCompareResponse struct {
Published *DocumentVersion `json:"published,omitempty"`
Draft *DocumentVersion `json:"draft"`
Diff *string `json:"diff,omitempty"`
Approvals []VersionApproval `json:"approvals"`
}
// PendingConsentResponse for pending consents with deadline info
type PendingConsentResponse struct {
Document LegalDocument `json:"document"`
Version DocumentVersion `json:"version"`
DeadlineAt time.Time `json:"deadline_at"`
DaysLeft int `json:"days_left"`
IsOverdue bool `json:"is_overdue"`
}
// AccountStatusResponse for account status check
type AccountStatusResponse struct {
Status string `json:"status"` // 'active', 'suspended'
PendingConsents []PendingConsentResponse `json:"pending_consents,omitempty"`
SuspensionReason *string `json:"suspension_reason,omitempty"`
CanAccess bool `json:"can_access"`
}