A full‑stack app that creates AI‑generated ad scripts and avatar videos.
Frontend (Next.js + Clerk) lets users configure topics and avatars; backend (FastAPI + Inngest) orchestrates LLM script generation and HeyGen video creation via durable async workflows.
backend/
├── main.py # FastAPI app, router registration, Inngest mount
├── requirements.txt # Python dependencies
├── .env # Environment variables (not committed)
├── .gitignore
├── readMe.md # Detailed backend README
├── inngest_functions.py # Inngest client and async workflow steps
└── app/
├── core/
│ └── settings.py # Environment loading and Settings dataclass
├── data/
│ └── tables.py # Supabase table constants
├── logger/
│ ├── __init__.py
│ └── setup.py # Logging configuration (console + file)
├── utils/
│ └── supabase_client.py # Supabase client initialization
├── exceptions/
│ ├── __init__.py
│ ├── errors.py # Custom AppError types
│ └── handlers.py # FastAPI exception handler registration
├── api/
│ └── routes/
│ └── v1/
│ ├── generate_script_router.py
│ ├── save_video_script_router.py
│ ├── get_video_script_router.py
│ ├── generate_avatar_vdo_and_fetch_url_router.py
│ ├── generate_avatar_vdo_and_fetch_url_Inngest_router.py
│ ├── get_avatar_list_router.py
│ ├── get_voice_list_router.py
│ ├── upload_imagekit_router.py
│ └── user_details_router.py
└── services/
├── generate_video_script.py # LangChain + OpenRouter script generation
├── save_video_script.py # Persist to Supabase video_data
├── get_video_script.py # Fetch by UUID
├── generate_avatar_vdo_and_fetch_url.py # HeyGen sync generate + poll
├── generate_avatar_vdo.py # HeyGen generate API
├── get_video_url.py # HeyGen status fetch
├── get_avatar_list.py # HeyGen avatars
├── get_voice_list.py # HeyGen voices
├── upload_imagekit.py # ImageKit upload
└── user_details.py # Supabase user CRUD and credits
frontend/
├── package.json # Dependencies and scripts
├── next.config.ts
├── tailwind.config.ts
├── tsconfig.json
├── .env.local # Clerk keys (not committed)
├── .gitignore
├── README.md # Detailed frontend README
└── src/
├── proxy.ts # Clerk middleware (route protection)
├── app/
│ ├── layout.tsx # Root layout (ClerkProvider + Header/Footer)
│ ├── page.tsx # Landing page
│ ├── globals.css
│ ├── _components/ # Landing page components
│ │ ├── Header.tsx
│ │ ├── Footer.tsx
│ │ ├── HeroSection.tsx
│ │ └── FeaturesSection.tsx
│ ├── (auth)/
│ │ ├── sign-in/[[...sign-in]]/page.tsx
│ │ └── sign-up/[[...sign-up]]/page.tsx
│ └── dashboard/
│ ├── layout.tsx # Dashboard layout (sidebar + main)
│ ├── page.tsx # Dashboard home
│ ├── _components/
│ │ ├── DashboardSidebar.tsx
│ │ ├── CreateAd.tsx
│ │ ├── VideoList.tsx
│ │ └── HeroSection.tsx
│ └── createAd/
│ ├── page.tsx # Topic input + script generation + save
│ └── [videoId]/
│ ├── page.tsx # Configure avatar/voice/background + trigger
│ └── _components/
│ ├── VideoScript.tsx
│ ├── AvaterList.tsx
│ ├── VoiceList.tsx
│ └── BackgroundImageUploader.tsx
└── store/
└── userStore.ts # Zustand store for backend user records
- Backend:
cd backend && pip install -r requirements.txt && uvicorn main:app --reload - Frontend:
cd frontend && npm install && npm run dev - Inngest (for async video gen): In backend folder, run
npx inngest-cli@latest dev -u http://127.0.0.1:8000/api/inngest --no-discoverywithINNGEST_DEV=1.
See backend/readMe.md and `frontend/README.md for detailed setup and API docs.