Backend:
- Add batch_id column to Post model (UUID, groups posts from same generation)
- Set batch_id in /generate endpoint for all posts in same request
Frontend:
- ContentArchive: group posts by batch_id into single cards with platform tabs
- Character name at top, platform tabs below, status badge, text preview
- Click platform tab to switch between variants of same content
- ConfirmModal: render via React portal to document.body for true fullscreen overlay
- Add box-shadow and higher z-index for better visual separation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Backend:
- /generate now returns array of posts (one per platform selected)
- Each post generated with platform-specific LLM prompt and char limits
- Monthly counter incremented by number of platforms
Frontend:
- ConfirmModal: reusable Editorial Fresh modal replaces ugly browser confirm()
- ContentPage: platform tabs when multiple posts, switch between variants
- ContentPage: generatedPosts array state replaces single generated
- ContentArchive: uses ConfirmModal for delete confirmation
- Platform chips filtered by plan (Freemium: IG/FB only)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Hashtag auto-save: debounced 500ms save on add/remove/edit, no manual button
- Platform chips: Freemium sees only Instagram/Facebook, Pro sees all 4
- Platform badge: changed from tab-like to informative "per instagram" label
- Add "Archivio →" link in content page header
- Rewrite ContentArchive: show text_content preview (was showing only hashtags),
add edit button, use Editorial Fresh design system, fix post.text → post.text_content
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add explicit instruction to LLM: never write framework labels (PROBLEMA,
AGITAZIONE, SOLUZIONE, etc.) — use them as invisible narrative structure only
- Replace static hashtag chips with HashtagEditor component:
- Click hashtag to edit inline
- Click X to remove
- Input field to add new hashtags
- Save button to persist changes to DB
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Opus 4.6 first, then Sonnet 4.6, Haiku 4.5
- Add legacy 4.5 Sonnet/Haiku, remove obsolete 3.5 versions
- Fix OpenRouter Claude labels to match
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add curated model catalogs for Claude, OpenAI, Gemini, OpenRouter
- ModelSelector component: dropdown with known models + "Personalizzato" option
- Custom input fallback for unknown providers or manual model IDs
- Auto-switch between dropdown/custom based on provider change
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Change default activeSection from 'piano' to 'profilo'
- Support ?tab= query param to deep-link into settings sections
- Update missing API key banner to link to /settings?tab=ai
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add 'brief' field to GenerateContentRequest schema
- Pass brief from router to generate_post_text service
- Inject brief as mandatory instructions in LLM prompt with highest priority
- Return structured error when LLM provider/API key not configured
- Show dedicated warning banner with link to Settings when API key missing
Fixes: content ignoring editorial brief, unhelpful API key error messages
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Left panel: dark ink (#1A1A1A) bg with decorative blobs, testimonial quote,
avatar, copyright — NOT coral
- Right panel: cream bg, no card/shadow, form directly on page
- editorial-tag (red uppercase label) + Fraunces heading per page
- Google button: outline style (white bg + border)
- Inputs: full border h-11, white bg, focus:border-ink, no border-radius
- Submit CTA: black full-width h-12 → hover accent
- Login/Register as separate form components (not tab toggle)
- Responsive: left panel hidden on mobile
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Redesign Settings: Testi, Immagini, Video, Voiceover — sezioni separate
- Ogni sezione ha dropdown provider + API key + campo opzionale modello
- Opzione "Personalizzato" con campo Base URL libero per qualsiasi servizio
- LLM: aggiunto OpenRouter + provider custom OpenAI-compatible
- Backend: OpenAICompatibleProvider unifica OpenAI/OpenRouter/custom
- Router content: passa llm_base_url a get_llm_provider
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>