feat(monitoring/site-mappings): globalize site_domain_mappings

Drop tenant scoping on site_domain_mappings now that the citation query
resolves mappings without tenant filtering. Add a unique index on
registrable_domain plus an updated_at column, and switch the dev-seed
upsert to use ON CONFLICT (registrable_domain). Adds a SiteDomainMapping
type to ops/domain for the upcoming console management UI.
This commit is contained in:
2026-04-29 16:00:13 +08:00
parent 01b289ba0b
commit 674709c86b
5 changed files with 66 additions and 9 deletions
+12 -5
View File
@@ -707,17 +707,19 @@ func clearMonitoringData(ctx context.Context, tx pgx.Tx, state *seedState) error
singles := []string{ singles := []string{
`DELETE FROM monitoring_platform_access_snapshots WHERE tenant_id = $1`, `DELETE FROM monitoring_platform_access_snapshots WHERE tenant_id = $1`,
`DELETE FROM monitoring_article_url_aliases 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 { for _, query := range singles {
if _, err := tx.Exec(ctx, query, state.TenantID); err != nil { if _, err := tx.Exec(ctx, query, state.TenantID); err != nil {
return wrapSeedErr("clear monitoring data", err) 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 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 { mappings := []struct {
domain string domain string
siteKey string siteKey string
@@ -729,9 +731,14 @@ func insertSiteMappings(ctx context.Context, tx pgx.Tx, tenantID int64) error {
} }
for _, item := range mappings { for _, item := range mappings {
if _, err := tx.Exec(ctx, ` if _, err := tx.Exec(ctx, `
INSERT INTO site_domain_mappings (tenant_id, registrable_domain, site_key, site_name, is_active) INSERT INTO site_domain_mappings (registrable_domain, site_key, site_name, is_active)
VALUES ($1, $2, $3, $4, TRUE) VALUES ($1, $2, $3, TRUE)
`, tenantID, item.domain, item.siteKey, item.siteName); err != nil { 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) return wrapSeedErr("insert site mapping", err)
} }
} }
+10
View File
@@ -63,3 +63,13 @@ type AuditLogFilter struct {
Limit int Limit int
Offset int Offset int
} }
type SiteDomainMapping struct {
ID int64
RegistrableDomain string
SiteKey string
SiteName string
IsActive bool
CreatedAt time.Time
UpdatedAt time.Time
}
@@ -152,16 +152,22 @@ CREATE INDEX idx_citation_facts_run
CREATE TABLE site_domain_mappings ( CREATE TABLE site_domain_mappings (
id BIGSERIAL PRIMARY KEY, id BIGSERIAL PRIMARY KEY,
tenant_id BIGINT,
registrable_domain VARCHAR(255) NOT NULL, registrable_domain VARCHAR(255) NOT NULL,
site_key VARCHAR(255) NOT NULL, site_key VARCHAR(255) NOT NULL,
site_name VARCHAR(255) NOT NULL, site_name VARCHAR(255) NOT NULL,
is_active BOOLEAN NOT NULL DEFAULT true, 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 CREATE UNIQUE INDEX uk_site_domain_mappings_domain
ON site_domain_mappings(tenant_id, registrable_domain, is_active); 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 ( CREATE TABLE monitoring_article_url_aliases (
id BIGSERIAL PRIMARY KEY, id BIGSERIAL PRIMARY KEY,
@@ -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);
@@ -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);