db.Migrate() runs GORM AutoMigrate for all models followed by applyConstraints() which creates partial unique indexes that GORM cannot express as struct tags:
Index
Constraint
idx_one_owner_per_org
Exactly one owner per organisation
idx_unique_domain_per_org
Domain names unique within an org
Migrations run automatically on API startup — no migration CLI needed.
EncryptedString is a custom GORM type that transparently encrypts on write and decrypts on read using AES-256-GCM. Call db.SetEncryptionKey(key) before any DB operation — the key must be exactly 32 characters.
Fields using this type (registry credentials, storage keys, git tokens) are stored as base64-encoded ciphertext and are never readable as plaintext in the database.
db.RegisterMigration(fn) registers additional schema migrations that run after AutoMigrate and applyConstraints. Call it from any package’s init() to extend the schema without modifying packages/db directly.