diff --git a/server/cmd/dev-seed/main.go b/server/cmd/dev-seed/main.go index 5401191..e1a8ae5 100644 --- a/server/cmd/dev-seed/main.go +++ b/server/cmd/dev-seed/main.go @@ -707,17 +707,19 @@ func clearMonitoringData(ctx context.Context, tx pgx.Tx, state *seedState) error singles := []string{ `DELETE FROM monitoring_platform_access_snapshots WHERE tenant_id = $1`, `DELETE FROM monitoring_article_url_aliases WHERE tenant_id = $1`, - `DELETE FROM site_domain_mappings WHERE tenant_id = $1`, } for _, query := range singles { if _, err := tx.Exec(ctx, query, state.TenantID); err != nil { return wrapSeedErr("clear monitoring data", err) } } + if _, err := tx.Exec(ctx, `DELETE FROM site_domain_mappings`); err != nil { + return wrapSeedErr("clear site mappings", err) + } return nil } -func insertSiteMappings(ctx context.Context, tx pgx.Tx, tenantID int64) error { +func insertSiteMappings(ctx context.Context, tx pgx.Tx, _ int64) error { mappings := []struct { domain string siteKey string @@ -729,9 +731,14 @@ func insertSiteMappings(ctx context.Context, tx pgx.Tx, tenantID int64) error { } for _, item := range mappings { if _, err := tx.Exec(ctx, ` - INSERT INTO site_domain_mappings (tenant_id, registrable_domain, site_key, site_name, is_active) - VALUES ($1, $2, $3, $4, TRUE) - `, tenantID, item.domain, item.siteKey, item.siteName); err != nil { + INSERT INTO site_domain_mappings (registrable_domain, site_key, site_name, is_active) + VALUES ($1, $2, $3, TRUE) + ON CONFLICT (registrable_domain) DO UPDATE + SET site_key = EXCLUDED.site_key, + site_name = EXCLUDED.site_name, + is_active = EXCLUDED.is_active, + updated_at = NOW() + `, item.domain, item.siteKey, item.siteName); err != nil { return wrapSeedErr("insert site mapping", err) } } diff --git a/server/internal/ops/domain/types.go b/server/internal/ops/domain/types.go index 46fd74d..7af5bc3 100644 --- a/server/internal/ops/domain/types.go +++ b/server/internal/ops/domain/types.go @@ -63,3 +63,13 @@ type AuditLogFilter struct { Limit int Offset int } + +type SiteDomainMapping struct { + ID int64 + RegistrableDomain string + SiteKey string + SiteName string + IsActive bool + CreatedAt time.Time + UpdatedAt time.Time +} diff --git a/server/migrations_monitoring/20260410103000_create_monitoring_tables.up.sql b/server/migrations_monitoring/20260410103000_create_monitoring_tables.up.sql index c7487e4..96353c3 100644 --- a/server/migrations_monitoring/20260410103000_create_monitoring_tables.up.sql +++ b/server/migrations_monitoring/20260410103000_create_monitoring_tables.up.sql @@ -152,16 +152,22 @@ CREATE INDEX idx_citation_facts_run CREATE TABLE site_domain_mappings ( id BIGSERIAL PRIMARY KEY, - tenant_id BIGINT, registrable_domain VARCHAR(255) NOT NULL, site_key VARCHAR(255) NOT NULL, site_name VARCHAR(255) NOT NULL, is_active BOOLEAN NOT NULL DEFAULT true, - created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); -CREATE INDEX idx_site_domain_mappings_lookup - ON site_domain_mappings(tenant_id, registrable_domain, is_active); +CREATE UNIQUE INDEX uk_site_domain_mappings_domain + ON site_domain_mappings(registrable_domain); + +CREATE INDEX idx_site_domain_mappings_active_domain + ON site_domain_mappings(registrable_domain) WHERE is_active = TRUE; + +CREATE INDEX idx_site_domain_mappings_created + ON site_domain_mappings(created_at DESC, id DESC); CREATE TABLE monitoring_article_url_aliases ( id BIGSERIAL PRIMARY KEY, diff --git a/server/migrations_monitoring/20260429110000_globalize_site_domain_mappings.down.sql b/server/migrations_monitoring/20260429110000_globalize_site_domain_mappings.down.sql new file mode 100644 index 0000000..c211014 --- /dev/null +++ b/server/migrations_monitoring/20260429110000_globalize_site_domain_mappings.down.sql @@ -0,0 +1,10 @@ +DROP INDEX IF EXISTS idx_site_domain_mappings_created; +DROP INDEX IF EXISTS idx_site_domain_mappings_active_domain; +DROP INDEX IF EXISTS uk_site_domain_mappings_domain; + +ALTER TABLE site_domain_mappings + ADD COLUMN IF NOT EXISTS tenant_id BIGINT, + DROP COLUMN IF EXISTS updated_at; + +CREATE INDEX IF NOT EXISTS idx_site_domain_mappings_lookup + ON site_domain_mappings(tenant_id, registrable_domain, is_active); diff --git a/server/migrations_monitoring/20260429110000_globalize_site_domain_mappings.up.sql b/server/migrations_monitoring/20260429110000_globalize_site_domain_mappings.up.sql new file mode 100644 index 0000000..0ac702f --- /dev/null +++ b/server/migrations_monitoring/20260429110000_globalize_site_domain_mappings.up.sql @@ -0,0 +1,24 @@ +UPDATE site_domain_mappings +SET registrable_domain = LOWER(TRIM(registrable_domain)), + site_key = LOWER(TRIM(site_key)), + site_name = TRIM(site_name); + +DELETE FROM site_domain_mappings older +USING site_domain_mappings newer +WHERE older.registrable_domain = newer.registrable_domain + AND older.id < newer.id; + +DROP INDEX IF EXISTS idx_site_domain_mappings_lookup; + +ALTER TABLE site_domain_mappings + DROP COLUMN IF EXISTS tenant_id, + ADD COLUMN IF NOT EXISTS updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(); + +CREATE UNIQUE INDEX IF NOT EXISTS uk_site_domain_mappings_domain + ON site_domain_mappings(registrable_domain); + +CREATE INDEX IF NOT EXISTS idx_site_domain_mappings_active_domain + ON site_domain_mappings(registrable_domain) WHERE is_active = TRUE; + +CREATE INDEX IF NOT EXISTS idx_site_domain_mappings_created + ON site_domain_mappings(created_at DESC, id DESC);