feat: rich character profiles — brand voice, target, rules, hashtag profiles

Backend:
- Character model: add brand_voice, target_audience, business_goals,
  products_services, content_rules (JSON do/dont), hashtag_profiles (JSON)
- Content generation: inject full character context into LLM system prompt
  (voice, audience, goals, products, rules)
- Hashtag generation: merge always-on tags from profile with AI-generated tags
- Schema: update CharacterBase and CharacterUpdate with new fields

Frontend:
- CharacterForm: new sections "Identità e Voce", "Regole Contenuti",
  "Profili Hashtag" with dedicated editors
- RulesEditor: do/don't list with add/remove
- HashtagProfileEditor: per-platform tabs, fixed hashtags + max generated count
- All fields loaded on edit, saved on submit

DB migration: 6 new columns added to characters table

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Michele
2026-04-04 16:34:25 +02:00
parent 8629d145a8
commit befa8b4adc
5 changed files with 290 additions and 14 deletions

View File

@@ -111,6 +111,12 @@ def generate_content(
"niche": character.niche,
"topics": character.topics or [],
"tone": character.tone or "professional",
"brand_voice": character.brand_voice,
"target_audience": character.target_audience,
"business_goals": character.business_goals,
"products_services": character.products_services,
"content_rules": character.content_rules or {},
"hashtag_profiles": character.hashtag_profiles or {},
}
base_url = _get_setting(db, "llm_base_url", current_user.id)
@@ -145,7 +151,19 @@ def generate_content(
brief=request.brief,
)
hashtags = generate_hashtags(text, llm, platform)
# Hashtag generation with profile support
ht_profile = char_dict.get("hashtag_profiles", {}).get(platform, {})
always_tags = ht_profile.get("always", [])
max_generated = ht_profile.get("max_generated", 12)
hashtags_generated = generate_hashtags(text, llm, platform, count=max_generated)
# Merge: always tags first, then generated (no duplicates)
seen = set()
hashtags = []
for tag in always_tags + hashtags_generated:
normalized = tag.lower()
if normalized not in seen:
seen.add(normalized)
hashtags.append(tag)
affiliate_links_used: list[dict] = []
if affiliate_link_dicts: