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

@@ -24,6 +24,12 @@ class CharacterBase(BaseModel):
niche: str
topics: list[str] = []
tone: Optional[str] = None
brand_voice: Optional[str] = None
target_audience: Optional[str] = None
business_goals: Optional[str] = None
products_services: Optional[str] = None
content_rules: dict = {} # {"do": [...], "dont": [...]}
hashtag_profiles: dict = {} # per-platform: {"instagram": {"always": [], "pool": [], ...}}
visual_style: dict = {}
social_accounts: dict = {}
affiliate_links: list[dict] = []
@@ -40,6 +46,12 @@ class CharacterUpdate(BaseModel):
niche: Optional[str] = None
topics: Optional[list[str]] = None
tone: Optional[str] = None
brand_voice: Optional[str] = None
target_audience: Optional[str] = None
business_goals: Optional[str] = None
products_services: Optional[str] = None
content_rules: Optional[dict] = None
hashtag_profiles: Optional[dict] = None
visual_style: Optional[dict] = None
social_accounts: Optional[dict] = None
affiliate_links: Optional[list[dict]] = None