From 3eca390089c4c76e5358ead7390495036a9e2ce4 Mon Sep 17 00:00:00 2001 From: Autumn-27 <53844290+Autumn-27@users.noreply.github.com> Date: Mon, 24 Aug 2026 08:55:55 -0400 Subject: [PATCH] =?UTF-8?q?style(db):=20=E5=AF=B9=E9=BD=90=20ICP=20?= =?UTF-8?q?=E8=8C=83=E5=9B=B4=E5=8C=B9=E9=85=8D=20SQL=20=E7=BC=A9=E8=BF=9B?= =?UTF-8?q?,=E5=B9=B6=E6=B3=A8=E6=98=8E=E6=89=8B=E5=B7=A5=E6=8C=82?= =?UTF-8?q?=E8=BD=BD=E8=B5=84=E4=BA=A7=E7=9A=84=E8=AF=AD=E5=8F=A5=E9=A1=BA?= =?UTF-8?q?=E5=BA=8F=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #53 引入 icp 范围匹配时,三处覆盖度 CTE 里新增的 OR 分支混进了 tab 缩进, 与同一 JOIN 条件内其它分支(纯空格)不一致。统一改回空格,SQL 语义未变 (git diff -w 无差异)。 AttachAssetsToTask 里 UPDATE assets 会先触发 trg_assets_task_links 写入 source='system',随后的显式 INSERT 才把来源改成 'manual'。加注释说明这层 顺序依赖,避免后续调换两条语句导致人工挂载的来源静默退化成 system。 --- db/task_assets.go | 4 ++++ db/task_assets_context.go | 24 ++++++++++++------------ db/task_scope.go | 14 +++++++------- 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/db/task_assets.go b/db/task_assets.go index db87fef..cd8823c 100644 --- a/db/task_assets.go +++ b/db/task_assets.go @@ -288,6 +288,10 @@ FROM assets WHERE id=ANY($2::bigint[])`, taskID, assetIDs).Scan(&found, &existin if found != len(assetIDs) { return mutation, ErrTaskAssetAssetNotFound } + // Order matters: this UPDATE fires trg_assets_task_links, which creates the + // link rows with the generic source='system'. The INSERT below must stay + // after it so the operator-authored 'manual' provenance wins; swapping the + // two statements silently degrades every manual attach back to 'system'. if _, err := tx.Exec(` UPDATE assets SET task_ids=CASE WHEN $1=ANY(task_ids) THEN task_ids ELSE array_append(task_ids,$1) END diff --git a/db/task_assets_context.go b/db/task_assets_context.go index b14c79a..7b08c0d 100644 --- a/db/task_assets_context.go +++ b/db/task_assets_context.go @@ -29,12 +29,12 @@ target AS ( JOIN task_scope ts ON ( (ts.kind='company' AND a.company_id = ts.company_id) OR (ts.kind='root_domain' AND a.root_domain = ts.domain) - OR (ts.kind='subdomain' AND a.domain = ts.domain) - OR (ts.kind IN ('ip','cidr') AND a.ip IS NOT NULL AND a.ip !~ '[^0-9a-fA-F:.]' AND ts.net >>= a.ip::inet) - OR (ts.kind='icp' AND ( - lower(regexp_replace(COALESCE(a.icp,''), '[[:space:]]+', '', 'g')) = ts.value - OR lower(regexp_replace(COALESCE(a.app_icp,''), '[[:space:]]+', '', 'g')) = ts.value - )) + OR (ts.kind='subdomain' AND a.domain = ts.domain) + OR (ts.kind IN ('ip','cidr') AND a.ip IS NOT NULL AND a.ip !~ '[^0-9a-fA-F:.]' AND ts.net >>= a.ip::inet) + OR (ts.kind='icp' AND ( + lower(regexp_replace(COALESCE(a.icp,''), '[[:space:]]+', '', 'g')) = ts.value + OR lower(regexp_replace(COALESCE(a.app_icp,''), '[[:space:]]+', '', 'g')) = ts.value + )) ) JOIN context_tasks ctx ON ctx.task_id=ts.task_id UNION @@ -179,12 +179,12 @@ context_assets AS ( JOIN task_scope ts ON ( (ts.kind='company' AND a.company_id=ts.company_id) OR (ts.kind='root_domain' AND a.root_domain=ts.domain) - OR (ts.kind='subdomain' AND a.domain=ts.domain) - OR (ts.kind IN ('ip','cidr') AND a.ip IS NOT NULL AND a.ip !~ '[^0-9a-fA-F:.]' AND ts.net >>= a.ip::inet) - OR (ts.kind='icp' AND ( - lower(regexp_replace(COALESCE(a.icp,''), '[[:space:]]+', '', 'g')) = ts.value - OR lower(regexp_replace(COALESCE(a.app_icp,''), '[[:space:]]+', '', 'g')) = ts.value - )) + OR (ts.kind='subdomain' AND a.domain=ts.domain) + OR (ts.kind IN ('ip','cidr') AND a.ip IS NOT NULL AND a.ip !~ '[^0-9a-fA-F:.]' AND ts.net >>= a.ip::inet) + OR (ts.kind='icp' AND ( + lower(regexp_replace(COALESCE(a.icp,''), '[[:space:]]+', '', 'g')) = ts.value + OR lower(regexp_replace(COALESCE(a.app_icp,''), '[[:space:]]+', '', 'g')) = ts.value + )) ) JOIN context_tasks ctx ON ctx.task_id=ts.task_id ) diff --git a/db/task_scope.go b/db/task_scope.go index f584b5d..f3907f5 100644 --- a/db/task_scope.go +++ b/db/task_scope.go @@ -308,13 +308,13 @@ target AS ( JOIN task_scope ts ON ts.task_id = $1 AND ( (ts.kind='company' AND a.company_id = ts.company_id) OR (ts.kind='root_domain' AND a.root_domain = ts.domain) - OR (ts.kind='subdomain' AND a.domain = ts.domain) - OR (ts.kind IN ('ip','cidr') AND a.ip IS NOT NULL AND a.ip !~ '[^0-9a-fA-F:.]' AND ts.net >>= a.ip::inet) - OR (ts.kind='icp' AND ( - lower(regexp_replace(COALESCE(a.icp,''), '[[:space:]]+', '', 'g')) = ts.value - OR lower(regexp_replace(COALESCE(a.app_icp,''), '[[:space:]]+', '', 'g')) = ts.value - )) - ) + OR (ts.kind='subdomain' AND a.domain = ts.domain) + OR (ts.kind IN ('ip','cidr') AND a.ip IS NOT NULL AND a.ip !~ '[^0-9a-fA-F:.]' AND ts.net >>= a.ip::inet) + OR (ts.kind='icp' AND ( + lower(regexp_replace(COALESCE(a.icp,''), '[[:space:]]+', '', 'g')) = ts.value + OR lower(regexp_replace(COALESCE(a.app_icp,''), '[[:space:]]+', '', 'g')) = ts.value + )) + ) ), tested AS ( SELECT DISTINCT ea.asset_id