refactor(db): use version string as primary key for ConfigVersion

-transition `of_config_versions` primary key from `id` to `version` string.
-add database migration files `202606270001_make_version_primary_key.sql` for PostgreSQL and SQLite.
-introduce AfterFind/AfterCreate GORM hooks to preserve JSON backward compatibility.
-refactor API controllers, logics, and front-end typescript definitions to receive `string` parameter.
This commit is contained in:
ryan
2026-06-27 13:46:55 +08:00
parent ac7b776378
commit 7b1fea8194
+9 -59
View File
@@ -18,7 +18,6 @@ import (
"unicode" "unicode"
"github.com/Rain-kl/Wavelet/internal/apps/openflare/routeidentity" "github.com/Rain-kl/Wavelet/internal/apps/openflare/routeidentity"
"github.com/Rain-kl/Wavelet/internal/db"
"github.com/Rain-kl/Wavelet/internal/model" "github.com/Rain-kl/Wavelet/internal/model"
"gorm.io/gorm" "gorm.io/gorm"
) )
@@ -40,34 +39,6 @@ const (
originURIPathQueryParts = 2 originURIPathQueryParts = 2
) )
type tlsCertificateRow struct {
ID uint `gorm:"column:id;primaryKey"`
CertPEM string `gorm:"column:cert_pem"`
}
func (tlsCertificateRow) TableName() string {
return "of_tls_certificates"
}
type tunnelNodeRow struct {
ID uint `gorm:"column:id;primaryKey"`
NodeType string `gorm:"column:node_type"`
}
func (tunnelNodeRow) TableName() string {
return "of_nodes"
}
type pagesProjectRow struct {
ID uint `gorm:"column:id;primaryKey"`
Enabled bool `gorm:"column:enabled"`
ActiveDeploymentID *uint `gorm:"column:active_deployment_id"`
}
func (pagesProjectRow) TableName() string {
return "of_pages_projects"
}
func uniqueStrings(items []string) []string { func uniqueStrings(items []string) []string {
if len(items) == 0 { if len(items) == 0 {
return items return items
@@ -243,37 +214,16 @@ func getOrCreateOriginByAddress(ctx context.Context, address string) (*model.Ori
return origin, nil return origin, nil
} }
func lookupTLSCertificateByID(ctx context.Context, id uint) (*tlsCertificateRow, error) { func lookupTLSCertificateByID(ctx context.Context, id uint) (*model.TLSCertificate, error) {
if !db.DB(ctx).Migrator().HasTable(&tlsCertificateRow{}) { return model.GetTLSCertificateByID(ctx, id)
return nil, gorm.ErrRecordNotFound
}
var certificate tlsCertificateRow
if err := db.DB(ctx).First(&certificate, id).Error; err != nil {
return nil, err
}
return &certificate, nil
} }
func lookupTunnelNodeByID(ctx context.Context, id uint) (*tunnelNodeRow, error) { func lookupTunnelNodeByID(ctx context.Context, id uint) (*model.OpenFlareNode, error) {
if !db.DB(ctx).Migrator().HasTable(&tunnelNodeRow{}) { return model.GetOpenFlareNodeByID(ctx, id)
return nil, gorm.ErrRecordNotFound
}
var node tunnelNodeRow
if err := db.DB(ctx).First(&node, id).Error; err != nil {
return nil, err
}
return &node, nil
} }
func lookupPagesProjectByID(ctx context.Context, id uint) (*pagesProjectRow, error) { func lookupPagesProjectByID(ctx context.Context, id uint) (*model.PagesProject, error) {
if !db.DB(ctx).Migrator().HasTable(&pagesProjectRow{}) { return model.GetPagesProjectByID(ctx, id)
return nil, gorm.ErrRecordNotFound
}
var project pagesProjectRow
if err := db.DB(ctx).First(&project, id).Error; err != nil {
return nil, err
}
return &project, nil
} }
func parseLeafCertificate(certPEM string) (*x509.Certificate, error) { func parseLeafCertificate(certPEM string) (*x509.Certificate, error) {
@@ -288,7 +238,7 @@ func parseLeafCertificate(certPEM string) (*x509.Certificate, error) {
return leaf, nil return leaf, nil
} }
func validateCertificateCoverage(certificate *tlsCertificateRow, domains []string) error { func validateCertificateCoverage(certificate *model.TLSCertificate, domains []string) error {
if certificate == nil { if certificate == nil {
return errors.New(errProxyRouteCertNotFound) return errors.New(errProxyRouteCertNotFound)
} }
@@ -304,8 +254,8 @@ func validateCertificateCoverage(certificate *tlsCertificateRow, domains []strin
return nil return nil
} }
func loadTLSCertificates(ctx context.Context, certIDs []uint) ([]*tlsCertificateRow, error) { func loadTLSCertificates(ctx context.Context, certIDs []uint) ([]*model.TLSCertificate, error) {
certificates := make([]*tlsCertificateRow, 0, len(certIDs)) certificates := make([]*model.TLSCertificate, 0, len(certIDs))
for _, certID := range certIDs { for _, certID := range certIDs {
certificate, err := lookupTLSCertificateByID(ctx, certID) certificate, err := lookupTLSCertificateByID(ctx, certID)
if err != nil { if err != nil {