Files
ALwrity/docs/PODCAST_PERSISTENCE_IMPLEMENTATION.md

6.1 KiB

Podcast Maker - Persistence & Asset Library Integration

Phase 1 Implementation Complete

1. Backend Changes

AssetSource Enum Update

  • Added PODCAST_MAKER = "podcast_maker" to backend/models/content_asset_models.py
  • Allows podcast episodes to be tracked in the unified asset library

Content Assets API Enhancement

  • Added POST /api/content-assets/ endpoint in backend/api/content_assets/router.py
  • Enables frontend to save audio files directly to asset library
  • Validates asset_type and source_module enums
  • Returns created asset with full metadata

2. Frontend Changes

Persistence Hook (usePodcastProjectState.ts)

  • Created comprehensive state management hook
  • Auto-saves to localStorage on every state change
  • Restores state on page load/refresh
  • Tracks all project data:
    • Project metadata (id, idea, duration, speakers)
    • Step results (analysis, queries, research, script)
    • Render jobs with status and progress
    • Settings (knobs, research provider, budget cap)
    • UI state (current step, visibility flags)
  • Handles Set serialization/deserialization for JSON storage
  • Provides helper functions: resetState, initializeProject

Podcast Dashboard Integration

  • Refactored PodcastDashboard.tsx to use persistence hook
  • All state now persists automatically
  • Resume alert shows when project is restored
  • "My Episodes" button navigates to Asset Library filtered by podcasts
  • Recent Episodes preview component shows latest 6 episodes

Render Queue Enhancement

  • Updated to use persisted render jobs
  • Auto-saves completed audio files to Asset Library
  • Includes metadata: project_id, scene_id, cost, provider, model
  • Proper initialization when moving to render phase

Script Editor Enhancement

  • Syncs script changes with persisted state
  • Prevents regeneration if script already exists
  • Scene approvals persist across refreshes

Asset Library Integration

  • Updated AssetLibrary.tsx to read URL search params
  • Supports filtering by source_module and asset_type from URL
  • Navigation: /asset-library?source_module=podcast_maker&asset_type=audio

3. API Service Updates

Podcast API (podcastApi.ts)

  • Added saveAudioToAssetLibrary() function
  • Saves audio files with proper metadata
  • Tags assets with project_id for easy filtering
  • Includes cost, provider, and model information

🔄 How It Works

LocalStorage Persistence Flow

  1. User creates project → State saved to localStorage with key podcast_project_state
  2. Each step completion → State automatically updated in localStorage
  3. Browser refresh → State restored from localStorage on mount
  4. Resume alert → Shows which step was in progress
  5. Audio generation → Completed files saved to Asset Library via API

Asset Library Integration Flow

  1. Audio render completessaveAudioToAssetLibrary() called
  2. Backend saves asset → Creates entry in content_assets table
  3. Asset appears in library → Filterable by source_module=podcast_maker
  4. User navigates → "My Episodes" button opens filtered Asset Library view
  5. Unified management → All podcast episodes visible alongside other content

📋 State Structure

interface PodcastProjectState {
  // Project metadata
  project: { id: string; idea: string; duration: number; speakers: number } | null;
  
  // Step results
  analysis: PodcastAnalysis | null;
  queries: Query[];
  selectedQueries: Set<string>;
  research: Research | null;
  rawResearch: BlogResearchResponse | null;
  estimate: PodcastEstimate | null;
  scriptData: Script | null;
  
  // Render jobs
  renderJobs: Job[];
  
  // Settings
  knobs: Knobs;
  researchProvider: ResearchProvider;
  budgetCap: number;
  
  // UI state
  showScriptEditor: boolean;
  showRenderQueue: boolean;
  currentStep: 'create' | 'analysis' | 'research' | 'script' | 'render' | null;
  
  // Timestamps
  createdAt?: string;
  updatedAt?: string;
}

🎯 User Experience

Resume After Refresh

  • User creates project → Works on analysis → Refreshes browser
  • Project state restored
  • Resume alert shows "Resuming from Analysis step"
  • User can continue where they left off

Resume After Restart

  • User completes research → Closes browser → Returns later
  • Project state restored from localStorage
  • All research data available
  • Can proceed to script generation

Asset Library Access

  • User completes episode → Audio saved to library
  • "My Episodes" button shows all podcast episodes
  • Filtered view: source_module=podcast_maker&asset_type=audio
  • Can download, share, favorite episodes
  • Unified with all other ALwrity content

🚀 Phase 2: Database Persistence (Future)

For long-term persistence across devices/browsers:

  1. Create podcast_projects table or use content_assets with project metadata
  2. Add endpoints:
    • POST /api/podcast/projects - Save project snapshot
    • GET /api/podcast/projects/{id} - Load project
    • GET /api/podcast/projects - List user's projects
  3. Sync strategy: Save to DB after each major step completion
  4. Resume UI: Show list of saved projects on dashboard

Testing Checklist

  • Project state persists after browser refresh
  • Resume alert shows correct step
  • Script doesn't regenerate if already exists
  • Render jobs persist and restore correctly
  • Audio files save to Asset Library
  • Asset Library filters by podcast_maker
  • Navigation to Asset Library works
  • Recent Episodes preview displays correctly
  • No console errors or warnings

📝 Notes

  • localStorage limit: ~5-10MB per domain. Podcast projects are typically <100KB, so safe.
  • Data loss risk: localStorage can be cleared by user. Phase 2 (DB persistence) will address this.
  • Cross-device: localStorage is browser-specific. Phase 2 will enable cross-device access.
  • Performance: Auto-save happens on every state change. Debouncing could be added if needed.