retention

package
v1.2.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 6, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package retention provides data lifecycle and retention policy management for NornicDB.

This package implements compliance-driven data retention following major regulatory frameworks:

  • GDPR Art.5(1)(e): Storage limitation principle
  • GDPR Art.17: Right to erasure ("right to be forgotten")
  • HIPAA §164.530(j): Record retention (6 years minimum)
  • FISMA AU-11: Audit Record Retention
  • SOC2 CC7.4: Records retention requirements
  • SOX: Financial records (7 years)

Key Features:

  • Configurable retention policies per data category
  • Automatic data expiration and cleanup
  • Legal hold support (prevents deletion during litigation)
  • GDPR Art.17 erasure requests ("right to be forgotten")
  • Archive-before-delete option for compliance
  • Policy persistence (save/load from JSON)

Example Usage:

// Create retention manager
manager := retention.NewManager()

// Add default compliance policies
for _, policy := range retention.DefaultPolicies() {
	manager.AddPolicy(policy)
}

// Set callbacks
manager.SetDeleteCallback(func(record *retention.DataRecord) error {
	return database.Delete(record.ID)
})
manager.SetArchiveCallback(func(record *retention.DataRecord, path string) error {
	return archiveSystem.Store(record, path)
})

// Process records according to policies
record := &retention.DataRecord{
	ID:        "record-123",
	SubjectID: "user-456",
	Category:  retention.CategoryPII,
	CreatedAt: time.Now().Add(-4 * 365 * 24 * time.Hour), // 4 years old
}

if err := manager.ProcessRecord(ctx, record); err != nil {
	log.Fatal(err) // May be deleted if beyond retention period
}

// Handle GDPR erasure request
req, err := manager.CreateErasureRequest("user-456", "user@example.com")
if err != nil {
	log.Fatal(err)
}

// Find all user's data
records := findAllUserData("user-456")

// Process erasure (respects legal holds)
if err := manager.ProcessErasure(ctx, req.ID, records); err != nil {
	log.Fatal(err)
}

fmt.Printf("Erased %d records, retained %d (legal hold)\n",
	req.ItemsErased, req.ItemsRetained)

Compliance Notes:

GDPR Requirements:

  • Art.5(1)(e): Data minimization - don't keep data longer than necessary
  • Art.17: Right to erasure - users can request deletion of their data
  • Art.30: Records of processing - audit trail of what was deleted
  • 30-day deadline: Must respond to erasure requests within 30 days

HIPAA Requirements:

  • §164.530(j)(2): Retain PHI for 6 years from creation or last use
  • §164.308(a)(1)(ii)(D): Information system activity review (audit logs)
  • Must document retention policies and procedures

SOX Requirements:

  • §802: Retain financial records for 7 years
  • §1102: Criminal penalties for document destruction

ELI12 (Explain Like I'm 12):

Think of data retention like your school locker:

1. Some things you need to keep all year (textbooks = SYSTEM data) 2. Some things you can throw away after the semester (old homework = ANALYTICS) 3. Some things have rules about how long to keep them (report cards = AUDIT logs) 4. Sometimes the principal says "don't throw away ANYTHING!" (legal hold) 5. If you want your stuff deleted, you can ask and they have to do it (GDPR erasure)

The retention manager is like a locker monitor who makes sure old stuff gets thrown away at the right time, important stuff is archived first, and nobody throws away things they're not supposed to!

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrPolicyNotFound    = errors.New("retention: policy not found")
	ErrLegalHold         = errors.New("retention: data under legal hold cannot be deleted")
	ErrInvalidPolicy     = errors.New("retention: invalid policy configuration")
	ErrAlreadyExists     = errors.New("retention: policy already exists")
	ErrErasureInProgress = errors.New("retention: erasure already in progress")
)

Errors

Functions

This section is empty.

Types

type DataCategory

type DataCategory string

DataCategory represents a category of data for retention purposes.

const (
	// Standard categories
	CategorySystem    DataCategory = "SYSTEM"    // System/infrastructure data
	CategoryAudit     DataCategory = "AUDIT"     // Audit logs
	CategoryUser      DataCategory = "USER"      // User-created data
	CategoryAnalytics DataCategory = "ANALYTICS" // Analytics/metrics data
	CategoryBackup    DataCategory = "BACKUP"    // Backup data
	CategoryArchive   DataCategory = "ARCHIVE"   // Archived data

	// Compliance-specific categories
	CategoryPHI       DataCategory = "PHI"       // Protected Health Information (HIPAA)
	CategoryPII       DataCategory = "PII"       // Personally Identifiable Information (GDPR)
	CategoryFinancial DataCategory = "FINANCIAL" // Financial records (SOX)
	CategoryLegal     DataCategory = "LEGAL"     // Legal documents
)

type DataRecord

type DataRecord struct {
	// Unique record ID
	ID string `json:"id"`

	// Subject ID (owner/user)
	SubjectID string `json:"subject_id,omitempty"`

	// Data category
	Category DataCategory `json:"category"`

	// When record was created
	CreatedAt time.Time `json:"created_at"`

	// When record was last accessed
	LastAccessedAt time.Time `json:"last_accessed_at,omitempty"`

	// Record metadata
	Metadata map[string]string `json:"metadata,omitempty"`
}

DataRecord represents a record that may be subject to retention.

type ErasureRequest

type ErasureRequest struct {
	// Unique request ID
	ID string `json:"id"`

	// Subject ID (user) requesting erasure
	SubjectID string `json:"subject_id"`

	// Email/identifier for verification
	SubjectEmail string `json:"subject_email,omitempty"`

	// When request was received
	RequestedAt time.Time `json:"requested_at"`

	// Deadline for completion (GDPR: 30 days)
	Deadline time.Time `json:"deadline"`

	// Current status
	Status ErasureStatus `json:"status"`

	// Items found for erasure
	ItemsFound int `json:"items_found"`

	// Items erased
	ItemsErased int `json:"items_erased"`

	// Items retained (with reason)
	ItemsRetained int `json:"items_retained"`

	// Reason for any retained items
	RetainedReason string `json:"retained_reason,omitempty"`

	// When processing started
	StartedAt time.Time `json:"started_at,omitempty"`

	// When processing completed
	CompletedAt time.Time `json:"completed_at,omitempty"`

	// Error message if failed
	Error string `json:"error,omitempty"`

	// Whether subject was notified of completion
	SubjectNotified bool `json:"subject_notified"`
}

ErasureRequest represents a data subject erasure request (GDPR Art.17).

type ErasureStatus

type ErasureStatus string

ErasureStatus represents the status of an erasure request.

const (
	ErasureStatusPending    ErasureStatus = "PENDING"
	ErasureStatusInProgress ErasureStatus = "IN_PROGRESS"
	ErasureStatusCompleted  ErasureStatus = "COMPLETED"
	ErasureStatusFailed     ErasureStatus = "FAILED"
	ErasureStatusPartial    ErasureStatus = "PARTIAL" // Some items retained
)

type LegalHold

type LegalHold struct {
	// Unique identifier
	ID string `json:"id"`

	// Description of the hold
	Description string `json:"description"`

	// Matter/case reference
	Matter string `json:"matter,omitempty"`

	// Who placed the hold
	PlacedBy string `json:"placed_by"`

	// When the hold was placed
	PlacedAt time.Time `json:"placed_at"`

	// When the hold expires (zero = indefinite)
	ExpiresAt time.Time `json:"expires_at,omitempty"`

	// Data subject IDs under hold
	SubjectIDs []string `json:"subject_ids,omitempty"`

	// Data categories under hold
	Categories []DataCategory `json:"categories,omitempty"`

	// Whether hold is active
	Active bool `json:"active"`
}

LegalHold represents a legal hold on data.

func (*LegalHold) CoversData

func (h *LegalHold) CoversData(subjectID string, category DataCategory) bool

CoversData returns true if the hold covers the given subject and category.

func (*LegalHold) IsActive

func (h *LegalHold) IsActive() bool

IsActive returns true if the legal hold is currently active.

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

Manager manages retention policies and data lifecycle.

func NewManager

func NewManager() *Manager

NewManager creates a new retention manager with empty policies and holds.

The manager starts with no policies, legal holds, or erasure requests. Use AddPolicy() or load DefaultPolicies() to configure retention rules.

Example:

manager := retention.NewManager()

// Add default compliance policies
for _, policy := range retention.DefaultPolicies() {
	if err := manager.AddPolicy(policy); err != nil {
		log.Fatal(err)
	}
}

// Set deletion callback
manager.SetDeleteCallback(func(record *retention.DataRecord) error {
	return db.Delete(record.ID)
})

Returns a new Manager ready for policy configuration.

Example 1 - GDPR Compliance Setup:

manager := retention.NewManager()

// Add GDPR-compliant policies
for _, policy := range retention.DefaultPolicies() {
	manager.AddPolicy(policy)
}

// Set callbacks for data operations
manager.SetDeleteCallback(func(record *retention.DataRecord) error {
	log.Printf("Deleting record: %s (age: %v)", record.ID, time.Since(record.CreatedAt))
	return database.Delete(record.ID)
})

manager.SetArchiveCallback(func(record *retention.DataRecord, path string) error {
	log.Printf("Archiving to: %s", path)
	return archiveSystem.Store(record, path)
})

Example 2 - HIPAA Healthcare Application:

manager := retention.NewManager()

// PHI retention: 6 years minimum
phiPolicy := &retention.Policy{
	ID:       "phi-6y",
	Name:     "PHI Retention",
	Category: retention.CategoryPHI,
	RetentionPeriod: retention.RetentionPeriod{
		Duration: 6 * 365 * 24 * time.Hour,
	},
	ArchiveBeforeDelete:  true,
	ArchivePath:          "/secure-archive/phi",
	ComplianceFrameworks: []string{"HIPAA"},
	Active:               true,
}
manager.AddPolicy(phiPolicy)

// Audit logs: 7 years
auditPolicy := &retention.Policy{
	ID:       "audit-7y",
	Category: retention.CategoryAudit,
	RetentionPeriod: retention.RetentionPeriod{
		Duration: 7 * 365 * 24 * time.Hour,
	},
	ArchiveBeforeDelete: true,
}
manager.AddPolicy(auditPolicy)

Example 3 - With Legal Holds:

manager := retention.NewManager()
manager.AddPolicy(retention.DefaultPolicies()[0])

// Create legal hold for litigation
hold, err := manager.CreateLegalHold(
	"litigation-2024-001",
	"Smith v. Company - Employment Case",
	[]string{"legal", "hr"},
)
if err != nil {
	log.Fatal(err)
}

// Records matching these tags won't be deleted
record := &retention.DataRecord{
	ID:       "email-123",
	Category: retention.CategoryUser,
	Tags:     []string{"hr", "employment"},
	CreatedAt: time.Now().Add(-5 * 365 * 24 * time.Hour),
}

// Won't delete - protected by legal hold
err = manager.ProcessRecord(ctx, record)

Example 4 - GDPR Right to Erasure:

manager := retention.NewManager()

// User requests data deletion
erasureReq, err := manager.CreateErasureRequest(
	"user-456",
	"user@example.com",
)
if err != nil {
	log.Fatal(err)
}

// Find all user's data across systems
records := []*retention.DataRecord{
	{ID: "profile-456", SubjectID: "user-456"},
	{ID: "orders-456", SubjectID: "user-456"},
	{ID: "analytics-456", SubjectID: "user-456"},
}

// Process erasure (30-day GDPR deadline)
err = manager.ProcessErasure(ctx, erasureReq.ID, records)
if err != nil {
	log.Fatal(err)
}

fmt.Printf("Erased: %d, Retained: %d (legal hold)\n",
	erasureReq.ItemsErased, erasureReq.ItemsRetained)

ELI12:

NewManager is like hiring a librarian for your school:

  • The librarian keeps track of rules: "Throw away old magazines after 3 months"
  • They archive important stuff before throwing it away
  • They handle requests: "I want my book reports deleted" (GDPR erasure)
  • They respect "DO NOT THROW AWAY" signs (legal holds)

Why do we need this?

  • GDPR: European law says "delete old data you don't need"
  • HIPAA: US health law says "keep medical records for 6 years"
  • SOX: Financial law says "keep money records for 7 years"
  • Storage costs: Old data costs money to store

How it works:

  1. Set up policies: "Keep PHI for 6 years, analytics for 90 days"
  2. Manager checks records: "Is this record too old?"
  3. If yes: Archive first (if policy says so), then delete
  4. If legal hold: "Can't delete this, it's in a lawsuit!"

Real-world Use:

  • Healthcare: Manage patient records (HIPAA compliance)
  • SaaS: Handle user data deletion requests (GDPR)
  • Finance: Retain transaction records (SOX compliance)
  • E-commerce: Clean up old analytics data

Compliance Benefits:

  • GDPR Art.5(1)(e): Storage limitation ✓
  • GDPR Art.17: Right to erasure ✓
  • HIPAA §164.530(j): 6-year retention ✓
  • SOX: 7-year financial records ✓
  • Automatic audit trail of deletions ✓

Performance:

  • Policy lookup: O(1) hash map
  • Record processing: O(1) per record
  • Legal hold check: O(n) where n = number of holds (usually <10)
  • Erasure request: O(m) where m = records to erase

Thread Safety:

All methods are thread-safe for concurrent access.

func (*Manager) AddPolicy

func (m *Manager) AddPolicy(policy *Policy) error

AddPolicy adds a retention policy.

func (*Manager) CreateErasureRequest

func (m *Manager) CreateErasureRequest(subjectID, subjectEmail string) (*ErasureRequest, error)

CreateErasureRequest creates a GDPR Art.17 erasure request for a data subject.

This implements the "right to be forgotten" - EU citizens can request deletion of all their personal data.

The request is given a 30-day deadline per GDPR requirements. Processing the request will delete all data for the subject EXCEPT:

  • Data under legal hold
  • Data required by law to retain (e.g., financial records)

Parameters:

  • subjectID: Unique identifier for the data subject (user)
  • subjectEmail: Email for verification and notification

Returns:

  • ErasureRequest with PENDING status
  • ErrErasureInProgress if another erasure is already processing for this subject

Example:

// User requests data deletion
req, err := manager.CreateErasureRequest("user-123", "user@example.com")
if err != nil {
	return err
}

fmt.Printf("Erasure request %s created\n", req.ID)
fmt.Printf("Deadline: %s (30 days)\n", req.Deadline)

// Find all user's data
records := database.FindBySubject("user-123")

// Process the erasure
if err := manager.ProcessErasure(ctx, req.ID, records); err != nil {
	return err
}

// Notify user of completion
if req.Status == retention.ErasureStatusCompleted {
	notifyUser(req.SubjectEmail, "Your data has been deleted")
}

Compliance:

GDPR Art.17 requires processing within 30 days without undue delay.

func (*Manager) DeletePolicy

func (m *Manager) DeletePolicy(id string) error

DeletePolicy removes a policy.

func (*Manager) GetErasureRequest

func (m *Manager) GetErasureRequest(id string) (*ErasureRequest, error)

GetErasureRequest retrieves an erasure request by ID.

func (*Manager) GetLegalHold

func (m *Manager) GetLegalHold(id string) (*LegalHold, error)

GetLegalHold retrieves a legal hold by ID.

func (*Manager) GetPolicy

func (m *Manager) GetPolicy(id string) (*Policy, error)

GetPolicy retrieves a policy by ID.

func (*Manager) GetPolicyForCategory

func (m *Manager) GetPolicyForCategory(category DataCategory) (*Policy, error)

GetPolicyForCategory finds the policy for a data category.

func (*Manager) IsUnderLegalHold

func (m *Manager) IsUnderLegalHold(subjectID string, category DataCategory) bool

IsUnderLegalHold checks if data is under any active legal hold.

func (*Manager) ListErasureRequests

func (m *Manager) ListErasureRequests() []*ErasureRequest

ListErasureRequests returns all erasure requests.

func (*Manager) ListLegalHolds

func (m *Manager) ListLegalHolds() []*LegalHold

ListLegalHolds returns all legal holds.

func (*Manager) ListPolicies

func (m *Manager) ListPolicies() []*Policy

ListPolicies returns all policies.

func (*Manager) LoadPolicies

func (m *Manager) LoadPolicies(path string) error

LoadPolicies loads policies from a JSON file.

func (*Manager) PlaceLegalHold

func (m *Manager) PlaceLegalHold(hold *LegalHold) error

PlaceLegalHold places a legal hold to prevent data deletion during litigation.

Legal holds (also called "litigation holds") preserve data that may be relevant to pending or anticipated legal proceedings. Data under legal hold CANNOT be deleted, even if retention policies would normally require deletion.

The hold can target:

  • Specific data subjects (users)
  • Specific data categories (e.g., all emails)
  • All data (leave SubjectIDs and Categories empty)

Parameters:

  • hold: LegalHold configuration

Returns:

  • nil on success
  • Error if hold is invalid

Example:

// Litigation started - preserve all data for user-123
hold := &retention.LegalHold{
	ID:          "hold-2024-001",
	Description: "Smith v. Company lawsuit",
	Matter:      "Case #2024-CV-12345",
	PlacedBy:    "legal@company.com",
	SubjectIDs:  []string{"user-123"},
	// No expiration - hold until manually released
}

if err := manager.PlaceLegalHold(hold); err != nil {
	log.Fatal(err)
}

fmt.Println("Legal hold placed - data preserved")

// Later, when litigation ends...
manager.ReleaseLegalHold("hold-2024-001")

Warning:

Failure to preserve data under legal hold can result in sanctions,
adverse inference instructions, or case dismissal.

func (*Manager) ProcessErasure

func (m *Manager) ProcessErasure(ctx context.Context, requestID string, records []*DataRecord) error

ProcessErasure processes an erasure request with the given records.

func (*Manager) ProcessRecord

func (m *Manager) ProcessRecord(ctx context.Context, record *DataRecord) error

ProcessRecord processes a record according to retention policies.

func (*Manager) ReleaseLegalHold

func (m *Manager) ReleaseLegalHold(holdID string) error

ReleaseLegalHold releases a legal hold.

func (*Manager) SavePolicies

func (m *Manager) SavePolicies(path string) error

SavePolicies saves all policies to a JSON file.

func (*Manager) SetArchiveCallback

func (m *Manager) SetArchiveCallback(fn func(record *DataRecord, archivePath string) error)

SetArchiveCallback sets the function called when data should be archived.

func (*Manager) SetDefaultPolicy

func (m *Manager) SetDefaultPolicy(policy *Policy) error

SetDefaultPolicy sets the default policy for data without a specific policy.

func (*Manager) SetDeleteCallback

func (m *Manager) SetDeleteCallback(fn func(record *DataRecord) error)

SetDeleteCallback sets the function called when data should be deleted.

func (*Manager) ShouldDelete

func (m *Manager) ShouldDelete(record *DataRecord) (bool, string)

ShouldDelete determines if a record should be deleted based on policies and holds.

func (*Manager) UpdatePolicy

func (m *Manager) UpdatePolicy(policy *Policy) error

UpdatePolicy updates an existing policy.

type Policy

type Policy struct {
	// Unique policy identifier
	ID string `json:"id"`

	// Human-readable name
	Name string `json:"name"`

	// Data category this policy applies to
	Category DataCategory `json:"category"`

	// How long to retain data
	RetentionPeriod RetentionPeriod `json:"retention_period"`

	// Archive data before deletion
	ArchiveBeforeDelete bool `json:"archive_before_delete"`

	// Archive location path
	ArchivePath string `json:"archive_path,omitempty"`

	// Compliance frameworks this policy satisfies
	ComplianceFrameworks []string `json:"compliance_frameworks,omitempty"`

	// Whether policy is active
	Active bool `json:"active"`

	// When policy was created
	CreatedAt time.Time `json:"created_at"`

	// When policy was last modified
	UpdatedAt time.Time `json:"updated_at"`

	// Description/notes
	Description string `json:"description,omitempty"`
}

Policy defines a retention policy for a data category.

func DefaultPolicies

func DefaultPolicies() []*Policy

DefaultPolicies returns a set of pre-configured compliance-ready retention policies.

These policies satisfy common regulatory requirements:

  • Audit logs: 7 years (HIPAA, SOX, FISMA)
  • PHI: 6 years (HIPAA §164.530(j))
  • PII: 3 years (GDPR data minimization)
  • Financial: 7 years (SOX, IRS)
  • User data: 1 year (reasonable default)
  • Analytics: 90 days (short-term operational data)
  • System: Indefinite (configuration data)

Returns a slice of Policy objects ready to use with AddPolicy().

Example:

manager := retention.NewManager()

// Load all default policies
for _, policy := range retention.DefaultPolicies() {
	if err := manager.AddPolicy(policy); err != nil {
		log.Printf("Failed to add policy %s: %v", policy.Name, err)
	}
}

// Or selectively add policies
for _, policy := range retention.DefaultPolicies() {
	if policy.Category == retention.CategoryPHI {
		manager.AddPolicy(policy) // HIPAA compliance
	}
}

// Save policies for persistence
manager.SavePolicies("./config/retention-policies.json")

Customization:

These are starting points. Adjust retention periods based on your:
- Industry regulations
- Geographic requirements
- Business needs
- Legal counsel recommendations

Example 1 - Use All Default Policies:

manager := retention.NewManager()

// Add all pre-configured compliance policies
for _, policy := range retention.DefaultPolicies() {
	if err := manager.AddPolicy(policy); err != nil {
		log.Printf("Failed to add policy %s: %v", policy.ID, err)
	}
}

// Now manager has HIPAA, GDPR, SOX policies configured

Example 2 - Selective Policy Usage:

policies := retention.DefaultPolicies()
manager := retention.NewManager()

// Only add policies relevant to your industry
for _, policy := range policies {
	// Healthcare app - need HIPAA policies
	if contains(policy.ComplianceFrameworks, "HIPAA") {
		manager.AddPolicy(policy)
	}

	// European app - need GDPR policies
	if contains(policy.ComplianceFrameworks, "GDPR") {
		manager.AddPolicy(policy)
	}
}

Example 3 - Customize Default Policies:

policies := retention.DefaultPolicies()
manager := retention.NewManager()

// Find and customize specific policy
for _, policy := range policies {
	if policy.Category == retention.CategoryPII {
		// Shorter retention for GDPR minimization
		policy.RetentionPeriod.Duration = 1 * 365 * 24 * time.Hour
		policy.Description = "Aggressive GDPR data minimization - 1 year"
	}
	manager.AddPolicy(policy)
}

Example 4 - Override with Custom Policies:

manager := retention.NewManager()

// Start with defaults
for _, policy := range retention.DefaultPolicies() {
	manager.AddPolicy(policy)
}

// Add industry-specific policy
customPolicy := &retention.Policy{
	ID:       "telemetry-30d",
	Name:     "Device Telemetry",
	Category: retention.CategoryAnalytics,
	RetentionPeriod: retention.RetentionPeriod{
		Duration: 30 * 24 * time.Hour,
	},
	Active:      true,
	Description: "IoT device telemetry - 30 days",
}
manager.AddPolicy(customPolicy)

ELI12:

DefaultPolicies is like getting a starter rulebook for your library:

"Here are the most common rules schools use:"

  • Keep report cards for 7 years (important!)
  • Keep homework for 1 year (useful)
  • Throw away scratch paper after 3 months (not important)
  • Keep textbooks forever (system data)

Instead of making up all the rules yourself, you get a proven set that follows the law!

Included Policies:

1. **Audit Logs (7 years)** - audit-7y

  • HIPAA §164.530(j), SOX §802, FISMA
  • Archives before deletion
  • Critical for compliance audits

2. **PHI/Health Data (6 years)** - phi-6y

  • HIPAA §164.530(j) requirement
  • Archives before deletion
  • Protected health information

3. **PII/Personal Data (3 years)** - pii-gdpr

  • GDPR Art.5(1)(e) minimization
  • No archival (privacy-focused)
  • Personally identifiable information

4. **Financial Records (7 years)** - financial-7y

  • SOX §802, IRS requirements
  • Archives before deletion
  • Tax and audit compliance

5. **User Data (1 year)** - user-1y

  • General user content
  • No archival by default
  • Configurable based on needs

6. **Analytics (90 days)** - analytics-90d

  • Short-term metrics
  • No archival
  • Quick cleanup

7. **System Data (indefinite)** - system-indefinite

  • Core configuration
  • Never deleted
  • Essential operations

When to Modify:

  • Your industry has stricter requirements
  • Operating in specific jurisdictions (EU, US, etc.)
  • Business needs longer/shorter retention
  • Legal counsel recommends changes

Compliance Coverage:

  • GDPR (EU): ✓ Data minimization, erasure rights
  • HIPAA (US Healthcare): ✓ 6-year PHI retention
  • SOX (US Finance): ✓ 7-year financial records
  • FISMA (US Federal): ✓ Audit log retention

Performance:

  • Returns static slice: O(1)
  • 7 pre-configured policies
  • No I/O or computation

Thread Safety:

Returns new policy instances - safe to modify.

func (*Policy) IsExpired

func (p *Policy) IsExpired(createdAt time.Time) bool

IsExpired returns true if data created at the given time should be deleted.

func (*Policy) Validate

func (p *Policy) Validate() error

Validate checks if the policy is valid.

type RetentionPeriod

type RetentionPeriod struct {
	Duration   time.Duration // How long to retain
	Indefinite bool          // Retain forever
}

RetentionPeriod defines a time-based retention period.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL