Test results, bug inventory & fix roadmap — Generated 2026-02-22 — NotebookLM Reimagined
| Project | notebooklm-frontend |
| Status | Next.js builds succeed, but production domain serves old Vite SPA |
| API Routes | Working (chat, sources, study, audio, video, studio) |
| Issue | notebooklm-frontend.vercel.app still shows "NotebookLM Clone" (legacy) |
| URL | notebooklm-api.vercel.app |
| Health | 200 OK — healthy |
| READ ops | Working (list notebooks, list keys) |
| WRITE ops | All return 500 (stale env vars) |
Tested against production Vercel deployments on 2026-02-22.
| Test | Endpoint | Result | Status |
|---|---|---|---|
| Health check | GET /health | 200 — {"status":"healthy"} | Pass |
| Root info | GET / | 200 — name, version, docs link | Pass |
| OpenAPI spec | GET /openapi.json | 200 — 66 operations across 45 paths | Pass |
| Swagger docs | GET /docs | 200 — Interactive Swagger UI | Pass |
| Auth required | GET /api/v1/notebooks (no auth) | 401 — proper error message | Pass |
| List notebooks | GET /api/v1/notebooks (auth) | 200 — empty array (correct) | Pass |
| List API keys | GET /api/v1/api-keys (auth) | 200 — empty array (correct) | Pass |
| Create notebook | POST /api/v1/notebooks (auth) | 500 — Internal server error | Fail |
| Get profile | GET /api/v1/profile (auth) | 500 — Internal server error | Fail |
| Invalid method | DELETE /health | 405 — Method Not Allowed | Pass |
| Invalid route | GET /api/v1/nonexistent | 404 — Not Found | Pass |
| Test | Result | Status |
|---|---|---|
| Homepage loads | 200 — But production domain shows old Vite SPA, not Next.js | Warn |
| Preview deploys | Build succeeds, but 401 (Vercel SSO protection) | Warn |
| API routes exist | 14 route files found (chat, sources, study, studio, audio, video, etc.) | Pass |
| Supabase reachable | kdupqjswwohqslmczgra.supabase.co responding | Pass |
| Category | Count | Description | Status |
|---|---|---|---|
| API Keys | 7 | CRUD + rotate + usage tracking | Read only |
| Sources | 7 | Upload, text, URL (with fetching), YouTube + CRUD | Frontend OK |
| Studio | 7 | Reports, slide decks, infographics, data tables | Frontend OK |
| Audio | 6 | TTS audio generation + CRUD + download | Frontend OK |
| Video | 6 | Video generation via AtlasCloud + CRUD | Frontend OK |
| Notes | 6 | User notes + save-from-response | Frontend OK |
| Notebooks | 5 | CRUD for notebooks | Read only |
| Chat | 5 | RAG chat with citations + sessions | Frontend OK |
| Research | 5 | Deep research tasks | Frontend OK |
| Study | 4 | Flashcards, quiz, study guide, FAQ, mind map | Frontend OK |
| Global Chat | 2 | Cross-notebook queries | Read only |
| Export | 2 | JSON + ZIP export | Frontend OK |
| Profile | 2 | Get + update user profile | 500 error |
Ordered by severity. Issues marked Fixed were resolved in today's session.
| # | Bug | Impact | Status |
|---|---|---|---|
| 1 | Backend WRITE operations fail with 500 All INSERT/UPDATE operations on deployed backend return 500. SELECTs work. Likely stale Supabase env vars on Vercel. |
Backend API unusable for creating notebooks, sources, chats | Open |
| 2 | Production domain serves old Vite SPAnotebooklm-frontend.vercel.app shows "NotebookLM Clone" with <div id="root">. Current Next.js app only on preview deploys. |
Users visiting production URL see non-functional legacy app | Open |
| 3 | JWT signature verification disabled Backend auth.py has verify_signature: False. Any crafted JWT with valid sub claim is accepted. |
Authentication bypass — anyone can impersonate any user | Open |
| # | Bug | Impact | Status |
|---|---|---|---|
| 4 | URL source content ignored by all endpoints 12 files checked type === 'text' for metadata.content, excluding URL sources. Chat only saw "URL: https://...". |
URL sources were useless — fetched content never used | Fixed |
| 5 | CORS allows all originsallow_origins=["*"] in main.py. Confirmed: evil-site.com gets Access-Control-Allow-Origin. |
Cross-origin attacks possible against authenticated users | Open |
| 6 | Backend 500 errors return null details Error handler returns "details": null instead of exception info. Makes debugging impossible. |
Cannot diagnose backend failures without server logs | Open |
| 7 | Frontend NEXT_PUBLIC_API_URL points to localhost.env.local has http://localhost:8000. Frontend API routes work directly but backend API is unreachable from frontend code that uses API_BASE. |
Frontend-to-backend API proxy broken in production | Open |
| 8 | "now()" string stored as timestamps Backend uses Python string "now()" in insert payloads instead of actual timestamps or SQL now(). |
Timestamp fields contain literal string "now()" instead of dates | Open |
| # | Bug | Impact | Status |
|---|---|---|---|
| 9 | YouTube sources have no transcript extraction YouTube sources are created with status: 'ready' but only store the URL and video_id. No transcript fetching. |
YouTube sources provide zero content to chat/study | Open |
| 10 | PDF sources not text-extracted PDFs uploaded to storage but not parsed for text. Chat route downloads and sends as base64 to Gemini (works for chat only, not study/audio/etc). |
PDF content only available in chat, not study/studio/audio/video | Open |
| 11 | No rate limiting on any endpoint No middleware or decorator for rate limiting. Gemini API calls are unbounded per user. |
Cost exposure — single user could run up API bill | Open |
| 12 | Video download from AtlasCloud may fail silently Falls back to AtlasCloud URL if Supabase upload fails. CORS issues may prevent playback. |
Videos may not play in browser due to CORS | Open |
| 13 | Source count increment/decrement RPCs may not exist Backend calls increment_source_count and decrement_source_count RPCs that may not be defined in Supabase. |
Notebook source counts may be wrong | Open |
| # | Bug | Impact | Status |
|---|---|---|---|
| 14 | Hardcoded Supabase URL in sources router Backend sources.py had a hardcoded Supabase URL for storage. |
Would break if Supabase project changes | Open |
| 15 | No input validation on content size Text sources truncate to 100K chars but no enforcement on request size. |
Large payloads could cause OOM or slow responses | Open |
| 16 | Audio TTS limited to 3000 chars Script truncated to 3000 chars for TTS. Long scripts lose most content. |
Audio overviews miss most of the generated script | Open |
| 17 | Cache-Control headers overridden by Vercel Backend middleware sets cache headers but Vercel replaces them. |
Cache policy not applied as intended | Open |
type === 'text' → type in ('text', 'url') across chat, studio, study, audio, video, export, and global_chat routes in both frontend and backend. Commit 7ee6ba1.metadata.content. Both Next.js API route and FastAPI backend. Commit fc7f100.resize-none to max-h-[200px] overflow-y-auto with [field-sizing:fixed]. Commit fc7f100.gemini-2.0-flash to gemini-2.5-flash. Commit 72fe0fa.Goal: Get both frontend and backend fully operational on Vercel.
| Task | Bug # | Effort |
|---|---|---|
| Update Vercel backend env vars (SUPABASE_SERVICE_ROLE_KEY, etc.) | 1 | 5 min |
| Fix production domain to serve Next.js app (redeploy or reconfigure root directory) | 2 | 10 min |
Set NEXT_PUBLIC_API_URL on Vercel frontend to https://notebooklm-api.vercel.app | 7 | 5 min |
Fix "now()" string timestamps — remove or use datetime.utcnow().isoformat() | 8 | 15 min |
| Fix 500 error details returning null | 6 | 10 min |
Goal: Close security gaps before any real users.
| Task | Bug # | Effort |
|---|---|---|
| Enable JWT signature verification in backend auth | 3 | 30 min |
| Restrict CORS to specific allowed origins | 5 | 10 min |
| Add rate limiting middleware (per-user, per-endpoint) | 11 | 1 hr |
| Add request size limits for source content | 15 | 15 min |
Goal: Fill content gaps so all source types are fully functional.
| Task | Bug # | Effort |
|---|---|---|
| Add YouTube transcript extraction (youtube-transcript-api or similar) | 9 | 2 hr |
| Add PDF text extraction (PyPDF2 or pdfplumber) for study/audio/video routes | 10 | 2 hr |
| Implement audio TTS chunking for long scripts | 16 | 1 hr |
| Fix video download CORS fallback | 12 | 30 min |
| Verify/create source count RPCs in Supabase | 13 | 15 min |
| Remove hardcoded Supabase URL | 14 | 5 min |
For Forge or other agents consuming the MasteryBook API:
| Pattern | Endpoint | Use Case |
|---|---|---|
| Create notebook + add sources | POST /api/v1/notebooks → POST .../sources/text | Agent builds knowledge base from research |
| RAG query across notebooks | POST /api/v1/chat/global | Agent searches all knowledge for answers |
| Generate study materials | POST .../study | Agent creates flashcards/quizzes for training |
| Generate reports | POST .../studio | Agent produces briefing docs from sources |
| Export knowledge | GET .../export | Agent extracts structured data from notebooks |
Auth: Use X-API-Key: nb_live_... header. Create keys via POST /api/v1/api-keys. Backend currently needs env var fix before write operations work.