feat: scope articles by brand

This commit is contained in:
2026-05-20 15:37:25 +08:00
parent 5fb9d0b0dd
commit dd082e2ed1
72 changed files with 3213 additions and 432 deletions
+18 -7
View File
@@ -221,6 +221,10 @@ type SaveDraftResponse struct {
func (s *TemplateService) SaveDraft(ctx context.Context, templateID int64, req SaveDraftRequest) (*SaveDraftResponse, error) {
actor := auth.MustActor(ctx)
brandID, err := requireCurrentBrandID(ctx)
if err != nil {
return nil, err
}
if _, err := s.templates.GetTemplateByID(ctx, templateID, actor.TenantID); err != nil {
return nil, mapTemplateLookupError(err)
@@ -234,10 +238,10 @@ func (s *TemplateService) SaveDraft(ctx context.Context, templateID int64, req S
if req.ArticleID == nil {
var articleID int64
err = s.pool.QueryRow(ctx, `
INSERT INTO articles (tenant_id, source_type, template_id, generate_status, publish_status, wizard_state_json)
VALUES ($1, 'template', $2, 'draft', 'unpublished', $3)
INSERT INTO articles (tenant_id, brand_id, source_type, template_id, generate_status, publish_status, wizard_state_json)
VALUES ($1, $2, 'template', $3, 'draft', 'unpublished', $4)
RETURNING id
`, actor.TenantID, templateID, stateJSON).Scan(&articleID)
`, actor.TenantID, brandID, templateID, stateJSON).Scan(&articleID)
if err != nil {
return nil, response.ErrInternal(50012, "draft_create_failed", "failed to create article draft")
}
@@ -254,12 +258,13 @@ func (s *TemplateService) SaveDraft(ctx context.Context, templateID int64, req S
updated_at = NOW()
WHERE id = $2
AND tenant_id = $3
AND template_id = $4
AND brand_id = $4
AND template_id = $5
AND source_type = 'template'
AND deleted_at IS NULL
AND generate_status = 'draft'
RETURNING id
`, stateJSON, *req.ArticleID, actor.TenantID, templateID).Scan(&articleID)
`, stateJSON, *req.ArticleID, actor.TenantID, brandID, templateID).Scan(&articleID)
if err != nil {
return nil, response.ErrConflict(40913, "draft_not_editable", "draft is not editable")
}
@@ -270,6 +275,10 @@ func (s *TemplateService) SaveDraft(ctx context.Context, templateID int64, req S
func (s *TemplateService) Generate(ctx context.Context, templateID int64, req GenerateRequest) (*GenerateResponse, error) {
actor := auth.MustActor(ctx)
brandID, err := requireCurrentBrandID(ctx)
if err != nil {
return nil, err
}
templateRecord, err := s.templates.GetTemplateByID(ctx, templateID, actor.TenantID)
if err != nil {
@@ -346,12 +355,13 @@ func (s *TemplateService) Generate(ctx context.Context, templateID int64, req Ge
FROM articles
WHERE id = $1
AND tenant_id = $2
AND template_id = $3
AND brand_id = $3
AND template_id = $4
AND source_type = 'template'
AND deleted_at IS NULL
AND generate_status IN ('draft', 'failed')
FOR UPDATE
`, *req.ArticleID, actor.TenantID, templateID).Scan(&articleID)
`, *req.ArticleID, actor.TenantID, brandID, templateID).Scan(&articleID)
if err != nil {
return nil, response.ErrConflict(40913, "article_not_regeneratable", "article cannot be regenerated in its current state")
}
@@ -361,6 +371,7 @@ func (s *TemplateService) Generate(ctx context.Context, templateID int64, req Ge
} else {
articleID, err = articleTx.CreateArticle(ctx, repository.CreateArticleInput{
TenantID: actor.TenantID,
BrandID: brandID,
SourceType: "template",
TemplateID: &templateID,
})