feat(auth,prompt-rule): add password change with session revocation and scope prompt rules by brand
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:
@@ -26,6 +26,11 @@ type ClaimedGenerationTask struct {
|
||||
|
||||
const generationCleanupTimeout = 30 * time.Second
|
||||
|
||||
type promptRuleTaskContext struct {
|
||||
PromptRuleID int64
|
||||
BrandID int64
|
||||
}
|
||||
|
||||
func newGenerationCleanupContext() (context.Context, context.CancelFunc) {
|
||||
return context.WithTimeout(context.Background(), generationCleanupTimeout)
|
||||
}
|
||||
@@ -215,13 +220,20 @@ func (s *PromptRuleGenerationService) ProcessQueuedTask(ctx context.Context, tas
|
||||
}
|
||||
|
||||
rule := extractPromptRuleSnapshot(inputParams)
|
||||
if rule == nil {
|
||||
promptRuleID, err := s.resolvePromptRuleIDForTask(ctx, task)
|
||||
if rule == nil || int64(extractInt(inputParams, "prompt_rule_id")) <= 0 || int64(extractInt(inputParams, "brand_id")) <= 0 {
|
||||
taskContext, err := s.resolvePromptRuleTaskContext(ctx, task)
|
||||
if err != nil {
|
||||
s.failGeneration(context.Background(), job, initialTitle, "task_load", err)
|
||||
return
|
||||
}
|
||||
rule, err = s.loadPromptRule(ctx, task.TenantID, promptRuleID)
|
||||
inputParams["prompt_rule_id"] = taskContext.PromptRuleID
|
||||
inputParams["brand_id"] = taskContext.BrandID
|
||||
}
|
||||
if rule == nil {
|
||||
promptRuleID := int64(extractInt(inputParams, "prompt_rule_id"))
|
||||
brandID := int64(extractInt(inputParams, "brand_id"))
|
||||
var err error
|
||||
rule, err = s.loadPromptRule(ctx, task.TenantID, brandID, promptRuleID)
|
||||
if err != nil {
|
||||
s.failGeneration(context.Background(), job, initialTitle, "task_load", err)
|
||||
return
|
||||
@@ -254,6 +266,47 @@ func (s *PromptRuleGenerationService) ProcessQueuedTask(ctx context.Context, tas
|
||||
s.executeGeneration(ctx, job)
|
||||
}
|
||||
|
||||
func (s *PromptRuleGenerationService) resolvePromptRuleTaskContext(ctx context.Context, task ClaimedGenerationTask) (promptRuleTaskContext, error) {
|
||||
resolved := promptRuleTaskContext{
|
||||
PromptRuleID: int64(extractInt(task.InputParams, "prompt_rule_id")),
|
||||
BrandID: int64(extractInt(task.InputParams, "brand_id")),
|
||||
}
|
||||
if resolved.PromptRuleID > 0 && resolved.BrandID > 0 {
|
||||
return resolved, nil
|
||||
}
|
||||
|
||||
if task.ArticleID <= 0 {
|
||||
return resolved, fmt.Errorf("article context missing for prompt rule task")
|
||||
}
|
||||
|
||||
var articlePromptRuleID int64
|
||||
var articleBrandID int64
|
||||
if err := s.pool.QueryRow(ctx, `
|
||||
SELECT COALESCE(prompt_rule_id, 0), brand_id
|
||||
FROM articles
|
||||
WHERE id = $1
|
||||
AND tenant_id = $2
|
||||
AND source_type = 'custom_generation'
|
||||
AND deleted_at IS NULL
|
||||
`, task.ArticleID, task.TenantID).Scan(&articlePromptRuleID, &articleBrandID); err != nil {
|
||||
return resolved, fmt.Errorf("load task prompt rule context: %w", err)
|
||||
}
|
||||
|
||||
if resolved.PromptRuleID <= 0 {
|
||||
resolved.PromptRuleID = articlePromptRuleID
|
||||
}
|
||||
if resolved.BrandID <= 0 {
|
||||
resolved.BrandID = articleBrandID
|
||||
}
|
||||
if resolved.PromptRuleID <= 0 {
|
||||
return resolved, fmt.Errorf("prompt rule context missing for prompt rule task")
|
||||
}
|
||||
if resolved.BrandID <= 0 {
|
||||
return resolved, fmt.Errorf("brand context missing for prompt rule task")
|
||||
}
|
||||
return resolved, nil
|
||||
}
|
||||
|
||||
func (s *PromptRuleGenerationService) resolvePromptRuleIDForTask(ctx context.Context, task ClaimedGenerationTask) (int64, error) {
|
||||
if promptRuleID := int64(extractInt(task.InputParams, "prompt_rule_id")); promptRuleID > 0 {
|
||||
return promptRuleID, nil
|
||||
|
||||
Reference in New Issue
Block a user