Commit Graph

215 Commits

Author SHA1 Message Date
ي
ea0a7ec34e Implement deterministic quality evaluators for AI recommendations 2026-05-28 09:17:32 +05:30
ajaysi
96fa469fe8 fix: add metadata-based Stripe customer lookup in verify-checkout for reliable post-subscription plan detection (#538) 2026-05-26 15:25:05 +05:30
ajaysi
a1a1abb8fd fix: redact sensitive API key count from log in ai_refresh (#536) 2026-05-25 20:57:48 +05:30
ajaysi
c47b452943 fix: redact sensitive API key names from log in ai_refresh (#535) 2026-05-25 20:57:47 +05:30
ajaysi
d889e83d6a fix: harden podcast media path resolution and URL parsing (#530) 2026-05-25 20:31:08 +05:30
ي
d0f0c25cf3 Potential fix for code scanning alert no. 87: Clear-text logging of sensitive information
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-05-25 17:41:16 +05:30
ي
0c48e2e0bf Potential fix for code scanning alert no. 85: Clear-text logging of sensitive information
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-05-25 17:39:49 +05:30
ي
c6c118e7b8 Potential fix for code scanning alert no. 128: Uncontrolled data used in path expression
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-05-25 17:33:13 +05:30
ي
56b2f3afcf Potential fix for code scanning alert no. 134: Use of a broken or weak cryptographic hashing algorithm on sensitive data
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-05-25 17:29:39 +05:30
ajaysi
cb3666dd7b fix: multi-tenant isolation for asset serving, image-studio ownership check, ts compile error 2026-05-25 17:23:59 +05:30
ajaysi
9b3bec698b fix: credit tracking, voice clone TTL, avatar upload ui, asset serving fallback, OAuth encryption, free plan video renders, backlink outreach sprint 2026-05-25 17:07:35 +05:30
ajaysi
090d69761f feat: Sprint 1 - Deep discovery, lead persistence, and dashboard nav
- Add BacklinkOutreachScraper (Exa + DuckDuckGo deep scraping)
- Extend DB and Pydantic models for lead enrichment columns
- Add StorageService methods for lead CRUD with auto-migration
- Add backend endpoints: deep discover, campaign detail, lead management
- Extend frontend API client and store with discovery + lead actions
- Create BacklinkOutreachDashboard component with campaigns/discover/leads tabs
- Register route at /backlink-outreach under SEO feature flag
- Add nav entry under Enterprise & Advanced in tool categories
2026-05-23 17:07:33 +05:30
ajaysi
d1cd28d407 Merge branch 'recover-stash' 2026-05-23 13:13:18 +05:30
ajaysi
17b69708ca Merge branch 'pr-497' 2026-05-23 13:09:48 +05:30
ajaysi
8f116ef4d1 On main: session-work-2026-05-22 2026-05-23 13:09:41 +05:30
ajaysi
644e72d289 feat: Brainstorm Topics with GSC + Issue #518 fixes + Blog Editor enhancements
Issue #518 - Subscription not updating after checkout:
- Fix stale closure in SubscriptionContext checkout polling (use subscriptionRef)
- Move checkout success polling from InitialRouteHandler into SubscriptionContext
- Remove redundant polling code from InitialRouteHandler
- Fix plan label: 'Free' instead of 'No Plan', proper capitalization
- Add plan refresh button in UserBadge
- Add 'View Costing Details' to UserBadge dropdown
- Rename 'ALwrity Podcast Maker' to 'Podcast Creator' across UI
- Clean subscription=success URL param after verification

Blog Writer WYSIWYG Editor enhancements:
- Per-section preview toggle (view/edit icons)
- Enhanced hover-based toolbar
- Circular SVG progress stats bar with detailed tooltip
- Research tool chips in stats bar footer
- Per-section TTS with useTextToSpeech hook (browser native)
- Full blog preview modal with print/PDF support
- PlayAllTTSButton: sequential playback with progress bar
- OnThisPageNav: floating sidebar with scroll tracking
- Section data attributes for scroll anchoring

GSC Brainstorm Topics feature:
- Backend: gsc_brainstorm_service.py (rule-based + LLM recommendations)
- Backend: POST /gsc/brainstorm endpoint with 3-word minimum validation
- Frontend: gscBrainstorm.ts API client
- Frontend: useGSCBrainstormConnection hook (popup OAuth, no /onboarding redirect)
- Frontend: useGSCBrainstorm hook (connect check + brainstorm call)
- Frontend: GSCBrainstormModal (3-tab results: Opportunities, Gaps, AI Recs)
- Frontend: BrainstormButton (visible at 3+ words, GSC connect overlay)
- Wire BrainstormButton into ManualResearchForm and ResearchAction
- Add blog_writer to gsc_auth router features for ALWRITY_ENABLED_FEATURES
2026-05-20 22:44:15 +05:30
ي
68190dedb3 Implement real Wix token-backed routes and error mapping 2026-05-20 22:42:16 +05:30
ي
9afd0d322d # Harden Wix test routes behind admin+env gating 2026-05-20 22:38:36 +05:30
ي
11d83e6f86 Harden OAuth callback postMessage origin and payload encoding 2026-05-20 22:35:05 +05:30
ي
e8c190188f Unify workspace root resolution across services 2026-05-18 14:35:37 +05:30
ajaysi
928c2f20aa fix: WYSIWYG editor, content generation, and writing assistant bug fixes
- Fix text selection menu not showing: wire contentRef via inputRef on multiline TextField
- Fix blog title not truncating: add min-w-0 for flex item overflow
- Fix outline generation 500: escape curly braces in f-string prompt template
- Fix content generation 'NoneType not callable': replace SessionLocal() with get_session_for_user(), add db param to MediumBlogGenerator, fix signature mismatch in database_task_manager
- Fix writing assistant suggest 500: add auth + user_id to API endpoint and service, replace sync requests with httpx.AsyncClient
- Fix hallucination detector 404: explicitly include router in main.py and app.py
- Fix missing error_data in task failure responses
- Hide CopilotKit web inspector button
- Remove hardcoded fallback suggestions from SmartTypingAssist
- Fix stale closure refs in SmartTypingAssist handleTypingChange
- Add two-column editor layout, stats bar, section hover menu
- Various subscription, billing, and research module improvements
2026-05-14 09:11:51 +05:30
ajaysi
3f984e8d0c feat(podcast): add pre-estimate endpoint, enhance cost estimator with multi-model support, cleanup alpha pricing seeding
- Add POST /podcast/pre-estimate endpoint for cost estimation before analysis
- Enhance cost_estimator.py with multi-model support (gemini, audio, voice clone, image, video)
- Add detailed cost breakdown (llm, audio, media costs + per-phase breakdown)
- Remove redundant pricing seeding from init_alpha_subscription_tiers.py
- Add SSOT pricing via PricingService.initialize_default_pricing()
- Update TopicUrlInput tooltip to show estimate details
- Add debug logging for pricing seeding and pre-estimate
- Clean up verbose podcast mode debug logs in app.py
2026-05-06 15:29:12 +05:30
ajaysi
fc47445181 fix(voice-clone): persist clone info in localStorage, auto-merge into project knobs, fix clone ID detection in CreateModal
- Move voice clone cache from module-level memory to localStorage
  so it survives page refresh and works across browser tabs
- VoiceAvatarPlaceholder now syncs clone result to localStorage
  immediately after creation (both design and clone paths)
- usePodcastProjectState auto-merges voice clone cache into project
  knobs when loading a project (fills gap for projects created
  before voice clone or when voice clone was created after)
- CreateModal now detects voice clone IDs by prefix (vc_*) not
  just by VOICE_CLONE_ID constant, fixing the mismatch where
  VoiceSelector passes the actual clone ID but CreateModal
  expected the placeholder ID
- AudioRegenerateModal is intentionally per-scene override and
  does not write back to knobs (by design)
- trends.py handler added for podcast topic trend analysis
2026-04-24 20:36:35 +05:30
ajaysi
d518365c87 fix: add missing budget_cap argument to create_project in update_project handler 2026-04-24 15:47:42 +05:30
ajaysi
ba94ee30bc feat(phase-4): UI/UX improvements for Podcast Maker Write phase
Frontend Changes:
- Add scene numbering badge (1/N) next to scene titles
- Add inline status chips (Complete, Audio, Image, Voice, Why Script)
- Professional AI-like gradient styling for all chips with shadows
- Remove Script Editor header and 'Why This Script Format?' collapsible
- Move Voice and Why Script info to per-scene chips
- Make scene section mobile-responsive (responsive layout, button sizing)
- Rename 'B-Roll Charts' to 'Podcast Charts' with accordion (collapsed by default)
- Add sceneIndex prop to SceneEditor for scene numbering
- Enhanced accessibility with keyboard navigation and focus states

Backend Changes:
- Audio handler improvements
- B-roll handler enhancements
- Script handler updates
- B-roll composer and service improvements
- Removed temporary broll_temp files

Technical:
- Full mobile responsiveness for scene cards
- Gradient chip styling: vibrant colors with white text and shadows
- Non-breaking approval/generation flow preserved
- TypeScript compatibility maintained
2026-04-24 15:44:09 +05:30
ajaysi
8b79099b15 Fix preflight NameError, clean up debug logs, remove redundant voice button, fix Tooltip warning 2026-04-22 16:10:27 +05:30
ajaysi
3c4965462a Add debug logging to asset serving to see file content 2026-04-22 12:56:48 +05:30
ajaysi
26ccb2f609 Add debug logging for voice clone preview audio bytes 2026-04-22 12:41:11 +05:30
ajaysi
cbd68fa43f Fix voice clone NotSupportedError and improve subscription services 2026-04-22 12:27:51 +05:30
ajaysi
dd7f8515a4 debug: add logging for asset path resolution 2026-04-22 11:23:24 +05:30
ajaysi
5e205d52cd fix: add comprehensive logging for voice clone debugging
- Backend: change logger.info to logger.warning for production logs
- Frontend: add console logs in brandAssets.ts createVoiceClone
- Frontend: add token auth and audio error logs in VoiceAvatarPlaceholder
- Log token fetching, authenticated URL, audio duration
2026-04-22 09:58:20 +05:30
ajaysi
b9f2123ce9 debug: add more logging for voice clone audio format detection 2026-04-22 09:34:44 +05:30
ajaysi
efff72f4bd fix: create avatars subdirectory before saving avatar upload 2026-04-22 08:29:37 +05:30
ajaysi
913e59a0a8 fix: voice clone preview audio authentication + MIME type fixes
- Restore auth on assets_serving.py using get_current_user_with_query_token
  (supports ?token= query param for <audio> elements)
- Add proper MIME type detection on asset serving (fixes NotSupportedError)
- Use storage_paths for path resolution in assets_serving.py
- VoiceSelector: append auth token to preview URLs for /api/ endpoints
- VoiceAvatarPlaceholder: add authenticatedAudioUrl state with async token
  resolution so <audio> elements get ?token= query param
- TestPersonaModal: same auth token pattern for voice preview audio
2026-04-22 08:04:55 +05:30
ajaysi
02d13716f3 fix: voice clone preview audio not playing + avatar upload 500 + asset serving
- Fix voice clone preview saved as .wav regardless of actual format (MP3/WebM
  content from WaveSpeed was saved with .wav extension causing NotSupportedError)
- Add detect_audio_format() and ensure_audio_extension() to media_utils
- Fix assets_serving.py: use storage_paths for root resolution, add proper
  MIME types to FileResponse, add auth via query token for <audio> elements
- Fix assets_serving.py: add path traversal security check
- Fix step4_asset_routes.py: use get_user_workspace() instead of WORKSPACE_DIR,
  detect actual audio format before saving preview
- Fix get_db() in database.py: raise HTTPException(401) instead of raw Exception,
  catch engine creation failures with HTTPException(503)
- Fix avatar.py: add auth error handling, diagnostic logging for path resolution,
  graceful DB save degradation
2026-04-22 07:24:28 +05:30
ajaysi
c5d625945f fix: centralize ROOT_DIR resolution, fix workspace path on Render.com, cleanup legacy paths
- Upgrade utils/storage_paths.py with robust find_repo_root() (env var override + validation + fallback)
- Remove broken _find_root() from podcast/constants.py, import from storage_paths instead
- Fix ROOT_DIR resolving to backend/ instead of project root (caused avatar upload 500s on Render.com)
- Fix video_combination_service.py default output dir (was writing to data/media instead of workspace)
- Add deprecation comments to global data/media constants in media_utils.py
- Pass user_id through resolve_media_path for tenant-scoped podcast resolution
- Add ALWRITY_ROOT_DIR env var support for explicit production overrides
- Log warning when get_podcast_media_dir called without user_id
- Use OperationButton with cost display for scene action buttons
2026-04-22 06:28:45 +05:30
ajaysi
b1ca29f7f7 fix: workspace-aware media resolution + production-ready logging
- load_podcast_image_bytes now accepts user_id for workspace-aware resolution
- Video and avatar handlers pass user_id to image loading
- Strip JWT tokens from console logs (dev-only verbose logging)
- Guard debug logs behind NODE_ENV===development in SceneCard, useRenderQueue, SubscriptionContext, mediaCache
- Add devLogger utility
2026-04-21 21:19:40 +05:30
ajaysi
91b2f996fd feat: voice clone audio generation + podcast workspace architecture
- Voice clone integration: When user selects voice clone in Write phase,
  backend uses their uploaded voice sample + scene script text to generate
  audio via qwen3/minimax/cosyvoice voice clone APIs
- Multi-tenant workspace storage: All podcast assets (audio, video, images,
  charts) now use workspace-specific directories per user
- Chart preview improvements: Card-based B-Roll charts UI with thumbnails,
  takeaway text, and action buttons; public endpoint for image serving
- Voice clone caching: In-memory LRU cache for voice samples (avoids
  re-downloading per scene); frontend caches voice clone metadata
- Thread pool for voice clone: Audio generation uses ThreadPoolExecutor to
  avoid blocking the FastAPI event loop
- Auto-detect voice clone IDs (vc_*, MY_VOICE_CLONE) to route correctly
- DB fallback for voice sample URL: Fetches from ContentAsset if not passed
- Fixed API URL resolution for chart previews
- Fixed GlassyCard DOM warnings for motion props
- Fixed ScriptGenerationProgressView syntax error
- Fixed usePodcastWorkflow scriptData reference
2026-04-21 19:38:50 +05:30
ajaysi
7637babd7d Add detailed logging for project update debugging 2026-04-20 16:01:13 +05:30
ajaysi
afdbc78779 Add detailed logging for voice clone debugging in production 2026-04-20 15:46:11 +05:30
ajaysi
4a4b8c5a24 Fix voice clone preview URL not matching saved file
The save_file_safely function may add a UUID suffix to the filename if there's
a collision, but the preview URL was being constructed using the original
filename instead of the actual saved filename. Now uses saved_preview_path.name.
2026-04-20 14:08:43 +05:30
ajaysi
625dd550d3 Fix production issues: add matplotlib dep, fix get_db calls, resolve ESLint
- Add matplotlib>=3.7.0 to requirements-podcast.txt (B-roll requires it)
- Fix research.py and exa_provider.py using get_session_for_user() instead of broken Depends(get_db)
- Fix BrollInfoPanel.tsx: call useScriptEditor hook unconditionally
- Add debug logging to avatar endpoint for troubleshooting
2026-04-20 12:55:25 +05:30
ajaysi
7f7279f903 Merge remote-tracking branch 'origin/codex/task-title-3y5pbt' 2026-04-20 08:47:19 +05:30
ي
e68c289901 Harden audio-only script flow and mode propagation 2026-04-20 08:44:46 +05:30
ajaysi
f748c081c2 Merge remote-tracking branch 'origin/codex/task-title' 2026-04-20 08:40:16 +05:30
ي
cf70261658 Implement async B-roll scene rendering with media path resolution 2026-04-20 08:32:42 +05:30
ajaysi
7aead3ae7d Merge remote-tracking branch 'origin/codex/refactor-preview-generation-flow' 2026-04-20 08:28:16 +05:30
ي
6db378beff Refactor chart preview IDs to use one deterministic identifier 2026-04-20 08:22:58 +05:30
ي
17c046c51e Add broll router to podcast API registrations 2026-04-20 08:19:55 +05:30
ajaysi
ba9ddbf368 Fix: Avatar/media path resolution and voice clone dependencies
- Remove nltk dependency from step4_assets by inlining _extract_user_id
- Add graceful error handling for step4_assets in podcast-only mode
- Fix media_utils.py to use tenant-aware get_podcast_media_read_dirs()
- Resolves avatar image 404 during scene image generation
2026-04-20 08:01:45 +05:30