feat(auth,prompt-rule): add password change with session revocation and scope prompt rules by brand
Frontend CI / Frontend (push) Successful in 3m8s
Backend CI / Backend (push) Successful in 14m48s

Add self-service password change that re-hashes the credential and bumps a
per-user session version so all existing access/refresh tokens are rejected.
Session version is tracked in Redis with an in-memory fallback and enforced in
middleware and refresh.

Scope prompt rules and rule groups to a brand: new brand_id column (migrated to
a "未归属" fallback brand for existing rows), brand-filtered queries/indexes, and
brand-aware admin-web tabs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-20 18:09:53 +08:00
parent 9f9e4f8e19
commit e045e00fbf
41 changed files with 1135 additions and 167 deletions
@@ -0,0 +1,25 @@
DROP INDEX IF EXISTS idx_prompt_rule_tenant_brand_status;
DROP INDEX IF EXISTS idx_prompt_rule_tenant_brand_created;
DROP INDEX IF EXISTS idx_prompt_rule_group_tenant_brand;
CREATE INDEX IF NOT EXISTS idx_prompt_rule_group_tenant
ON prompt_rule_groups(tenant_id, sort_order);
CREATE INDEX IF NOT EXISTS idx_prompt_rule_tenant
ON prompt_rules(tenant_id, created_at DESC);
CREATE INDEX IF NOT EXISTS idx_prompt_rule_tenant_status
ON prompt_rules(tenant_id, status)
WHERE deleted_at IS NULL;
ALTER TABLE prompt_rules
ALTER COLUMN brand_id DROP NOT NULL;
ALTER TABLE prompt_rule_groups
ALTER COLUMN brand_id DROP NOT NULL;
ALTER TABLE prompt_rules
DROP COLUMN IF EXISTS brand_id;
ALTER TABLE prompt_rule_groups
DROP COLUMN IF EXISTS brand_id;
@@ -0,0 +1,60 @@
ALTER TABLE prompt_rule_groups
ADD COLUMN IF NOT EXISTS brand_id BIGINT REFERENCES brands(id);
ALTER TABLE prompt_rules
ADD COLUMN IF NOT EXISTS brand_id BIGINT REFERENCES brands(id);
INSERT INTO brands (tenant_id, name, description, status)
SELECT tenant_id, '未归属', '系统迁移生成,用于存放未归属公司的历史 Prompt 规则。', 'active'
FROM (
SELECT tenant_id FROM prompt_rule_groups WHERE brand_id IS NULL
UNION
SELECT tenant_id FROM prompt_rules WHERE brand_id IS NULL
) tenants_with_prompt_rules
WHERE NOT EXISTS (
SELECT 1
FROM brands b
WHERE b.tenant_id = tenants_with_prompt_rules.tenant_id
AND b.name = '未归属'
AND b.deleted_at IS NULL
);
UPDATE prompt_rule_groups prg
SET brand_id = b.id,
updated_at = NOW()
FROM brands b
WHERE b.tenant_id = prg.tenant_id
AND b.name = '未归属'
AND b.deleted_at IS NULL
AND prg.brand_id IS NULL;
UPDATE prompt_rules pr
SET brand_id = b.id,
updated_at = NOW()
FROM brands b
WHERE b.tenant_id = pr.tenant_id
AND b.name = '未归属'
AND b.deleted_at IS NULL
AND pr.brand_id IS NULL;
ALTER TABLE prompt_rule_groups
ALTER COLUMN brand_id SET NOT NULL;
ALTER TABLE prompt_rules
ALTER COLUMN brand_id SET NOT NULL;
DROP INDEX IF EXISTS idx_prompt_rule_group_tenant;
DROP INDEX IF EXISTS idx_prompt_rule_tenant;
DROP INDEX IF EXISTS idx_prompt_rule_tenant_status;
CREATE INDEX IF NOT EXISTS idx_prompt_rule_group_tenant_brand
ON prompt_rule_groups(tenant_id, brand_id, sort_order, created_at)
WHERE deleted_at IS NULL;
CREATE INDEX IF NOT EXISTS idx_prompt_rule_tenant_brand_created
ON prompt_rules(tenant_id, brand_id, created_at DESC)
WHERE deleted_at IS NULL;
CREATE INDEX IF NOT EXISTS idx_prompt_rule_tenant_brand_status
ON prompt_rules(tenant_id, brand_id, status)
WHERE deleted_at IS NULL;