Files
akanealw eec8c28fb3
Go Benchmark / Performance Regression Check (push) Has been cancelled
Cerberus Integration / Cerberus Security Stack Integration (push) Has been cancelled
Upload Coverage to Codecov / Backend Codecov Upload (push) Has been cancelled
Upload Coverage to Codecov / Frontend Codecov Upload (push) Has been cancelled
CodeQL - Analyze / CodeQL analysis (go) (push) Has been cancelled
CodeQL - Analyze / CodeQL analysis (javascript-typescript) (push) Has been cancelled
CrowdSec Integration / CrowdSec Bouncer Integration (push) Has been cancelled
Docker Build, Publish & Test / build-and-push (push) Has been cancelled
Quality Checks / Auth Route Protection Contract (push) Has been cancelled
Quality Checks / Codecov Trigger/Comment Parity Guard (push) Has been cancelled
Quality Checks / Backend (Go) (push) Has been cancelled
Quality Checks / Frontend (React) (push) Has been cancelled
Rate Limit integration / Rate Limiting Integration (push) Has been cancelled
Security Scan (PR) / Trivy Binary Scan (push) Has been cancelled
Supply Chain Verification (PR) / Verify Supply Chain (push) Has been cancelled
WAF integration / Coraza WAF Integration (push) Has been cancelled
Docker Build, Publish & Test / Security Scan PR Image (push) Has been cancelled
Repo Health Check / Repo health (push) Has been cancelled
History Rewrite Dry-Run / Dry-run preview for history rewrite (push) Has been cancelled
Prune Renovate Branches / prune (push) Has been cancelled
Renovate / renovate (push) Has been cancelled
Nightly Build & Package / sync-development-to-nightly (push) Has been cancelled
Nightly Build & Package / Trigger Nightly Validation Workflows (push) Has been cancelled
Nightly Build & Package / build-and-push-nightly (push) Has been cancelled
Nightly Build & Package / test-nightly-image (push) Has been cancelled
Nightly Build & Package / verify-nightly-supply-chain (push) Has been cancelled
Update GeoLite2 Checksum / update-checksum (push) Has been cancelled
Container Registry Prune / prune-ghcr (push) Has been cancelled
Container Registry Prune / prune-dockerhub (push) Has been cancelled
Container Registry Prune / summarize (push) Has been cancelled
Supply Chain Verification / Verify SBOM (push) Has been cancelled
Supply Chain Verification / Verify Release Artifacts (push) Has been cancelled
Supply Chain Verification / Verify Docker Image Supply Chain (push) Has been cancelled
Monitor Caddy Major Release / check-caddy-major (push) Has been cancelled
Weekly Nightly to Main Promotion / Verify Nightly Branch Health (push) Has been cancelled
Weekly Nightly to Main Promotion / Create Promotion PR (push) Has been cancelled
Weekly Nightly to Main Promotion / Trigger Missing Required Checks (push) Has been cancelled
Weekly Nightly to Main Promotion / Notify on Failure (push) Has been cancelled
Weekly Nightly to Main Promotion / Workflow Summary (push) Has been cancelled
Weekly Security Rebuild / Security Rebuild & Scan (push) Has been cancelled
changed perms
2026-04-22 18:19:14 +00:00

4.1 KiB
Executable File

Database Migrations

This document tracks database schema changes and migration notes for the Charon project.

Migration Strategy

Charon uses GORM's AutoMigrate feature for database schema management. Migrations are automatically applied when the application starts. The migrations are defined in:

  • Main application: backend/cmd/api/main.go (security tables)
  • Route registration: backend/internal/api/routes/routes.go (all other tables)

Migration History

2024-12-XX: DNSProvider KeyVersion Field Addition

Purpose: Added encryption key rotation support for DNS provider credentials.

Changes:

  • Added KeyVersion field to DNSProvider model
    • Type: int
    • GORM tags: gorm:"default:1;index"
    • JSON tag: json:"key_version"
    • Purpose: Tracks which encryption key version was used for credentials

Backward Compatibility:

  • Existing records will automatically get key_version = 1 (GORM default)
  • No data migration required
  • The field is indexed for efficient queries during key rotation operations
  • Compatible with both basic encryption and rotation service

Migration Execution:

// Automatically handled by GORM AutoMigrate in routes.go:
db.AutoMigrate(&models.DNSProvider{})

Related Files:

  • backend/internal/models/dns_provider.go - Model definition
  • backend/internal/crypto/rotation_service.go - Key rotation logic
  • backend/internal/services/dns_provider_service.go - Service implementation

Testing:

  • All existing tests pass with the new field
  • Test database initialization updated to use shared cache mode
  • No breaking changes to existing functionality

Security Notes:

  • The KeyVersion field is essential for secure key rotation
  • It allows re-encrypting credentials with new keys while maintaining access to old data
  • The rotation service can decrypt using any registered key version
  • New records always use version 1 unless explicitly rotated

Best Practices for Future Migrations

Adding New Fields

  1. Always include GORM tags:

    FieldName string `json:"field_name" gorm:"default:value;index"`
    
  2. Set appropriate defaults to ensure backward compatibility

  3. Add indexes for fields used in queries or joins

  4. Document the migration in this README

Testing Migrations

  1. Test with clean database: Verify AutoMigrate creates tables correctly

  2. Test with existing database: Verify new fields are added without data loss

  3. Update test setup: Ensure test databases include all new tables/fields

Common Issues and Solutions

"no such table" Errors in Tests

Problem: Tests fail with "no such table: table_name" errors

Solutions:

  1. Ensure AutoMigrate is called in test setup:

    db.AutoMigrate(&models.YourModel{})
    
  2. For parallel tests, use shared cache mode:

    db, _ := gorm.Open(sqlite.Open(":memory:?cache=shared&mode=memory&_mutex=full"), &gorm.Config{})
    
  3. Verify table exists after migration:

    if !db.Migrator().HasTable(&models.YourModel{}) {
        t.Fatal("failed to create table")
    }
    

Migration Order Matters

Problem: Foreign key constraints fail during migration

Solution: Migrate parent tables before child tables:

db.AutoMigrate(
    &models.Parent{},
    &models.Child{},  // References Parent
)

Concurrent Test Access

Problem: Tests interfere with each other's database access

Solution: Configure connection pooling for SQLite:

sqlDB, _ := db.DB()
sqlDB.SetMaxOpenConns(1)
sqlDB.SetMaxIdleConns(1)

Rollback Strategy

Since Charon uses AutoMigrate, which only adds columns (never removes), rollback requires:

  1. Code rollback: Deploy previous version
  2. Manual cleanup (if needed): Drop added columns via SQL
  3. Data preservation: Old columns remain, data is safe

Note: Always test migrations in a development environment first.


See Also