DadsBot is a Next.js 14 app that captures long-form oral histories with warm, biographer-style prompts. This README consolidates the scattered docs across the repo so you can bootstrap, deploy, and debug without hunting for context.
- Purpose: capture long-form oral histories with the Interview Guide tone.
- Session flow: one-button capture, automatic speech-to-text, assistant reply synthesis, and optional email summaries.
- Continuity tools: per-user memory primers, session manifests, fallbacks pulled from structured copy, and diagnostics surfaces for operators.
- Interface highlights: compact account selector with active-handle badge, inline status + debug log, and footer commit stamp linking to the deployed build.
- Pick an account (or create a new handle) from the badge dropdown — history, settings, diagnostics, and primers scope to that handle.
- Start recording from the hero button. The recorder calibrates noise, captures the user turn, and posts it to
/api/ask-audio. - Ask pipeline:
- Session memory (history, asked questions, primer) is fetched via
lib/data.ts. - Google Gemini is prompted with the interview guide, primer snapshot, and recent turns. If it fails, curated fallbacks from
docs/fallback-texts.mdkeep the interview moving. - The assistant reply plays through the recorder when available, otherwise falls back to browser SpeechSynthesis.
- Session memory (history, asked questions, primer) is fetched via
- Finalize session:
/api/finalize-sessionrenders transcripts, emails the recap when configured, archives manifests, and rewrites the per-user memory primer. - Review + iterate:
/history,/settings, and/diagnosticsexpose transcripts, account preferences, recent API errors, and locally cached debug payloads. Session manifests (the "Memory Log" view of each recording) are persisted under thesessions/blob prefix for download or inspection.
- Reference hosting: Netlify + Blobs/Functions was the previous target; Vercel + Supabase is now the reference deployment for Next.js 14 with App Router.
- Netlify migration status: Prior checklists referenced
docs/netlify-migration-guide.md, but that file is absent. Use the hosting comparison below and the Supabase checklist to configure storage and diagnostics. - Platform comparison:
- Vercel + Supabase (recommended): zero-config Next.js deploys with Supabase storage. Set
SUPABASE_URL,SUPABASE_SERVICE_ROLE_KEY, andSUPABASE_STORAGE_BUCKETin every environment. - Cloudflare Pages + Workers + R2: replace
lib/blob.tswith an R2 helper and supply R2 credentials explicitly. - Render + S3-compatible storage: wire
lib/blob.tsto S3/B2/R2; preview deploys are manual. - AWS Amplify Hosting + S3: update
lib/blob.tsfor S3 and configure IAM roles explicitly. - Fly.io + S3-compatible storage: bring your own CI/CD; ensure storage env vars exist before boot.
- Vercel + Supabase (recommended): zero-config Next.js deploys with Supabase storage. Set
- Supabase storage:
SUPABASE_URL,SUPABASE_SERVICE_ROLE_KEY,SUPABASE_STORAGE_BUCKET(validated inutils/blob-env.ts). - Supabase tables:
SUPABASE_TURNS_TABLE(optional but recommended),SUPABASE_SESSIONS_TABLE(required). Client diagnostics expectNEXT_PUBLIC_SUPABASE_URL,NEXT_PUBLIC_SUPABASE_STORAGE_BUCKET, andNEXT_PUBLIC_SUPABASE_TURNS_TABLE. - Email:
DEFAULT_NOTIFY_EMAILmust be a real inbox; validated on server bootstrap. - Providers:
OPENAI_API_KEY,GOOGLE_API_KEY,SENDGRID_API_KEYas applicable. No defaults are assumed.GOOGLE_MODELmust be set wherever Google calls are used. - Platform context: diagnostics log
VERCEL,VERCEL_ENV, andNODE_ENVfor traceability.
- Bucket readiness: service role must be allowed to list/create buckets and objects;
lib/blob.tswill attempt bucket creation (public: false). Storage policies must allow service-role uploads/list/deletes. - Sessions table: use
docs/supabase-schema.sqlto create/alignpublic.sessionswithid,created_at,email_to,status,duration_ms,total_turns, andartifactscolumns (UUIDidis required). - Turns table: ensure columns
session_id,turn, andtranscriptexist alongside optionalassistant_reply,provider,manifest_url,user_audio_url,assistant_audio_url,duration_ms, andassistant_duration_ms. Run the schema script to add indexes and uniqueness constraints. - RLS policies: enable RLS on
public.conversation_turnsand add per-user or per-tenant policies (templates indocs/conversation-turns-rls.md). Keep service role access unless you adjust the code paths. - Network/domain:
SUPABASE_URLmust end with.supabase.coor.supabase.net; allow outbound access from the hosting platform.
- A primer is maintained per user handle under
memory/primers/{normalized-handle}.md(unassigned sessions usememory/primers/unassigned.md). Legacy single-primer blobs atmemory/MemoryPrimer.txtare still cleaned up for backwards compatibility. - After each finalize:
- Key sentences from the latest user turns are categorised by Interview Guide stage.
- All sessions for that handle are re-analysed, newest notes flagged as “Latest”, and a biography-style cheat sheet is rewritten.
- The markdown snapshot is uploaded to blob storage and cached in-memory for fast reuse.
- Inspect or download primers via the Netlify CLI:
netlify blobs:list --site $NETLIFY_BLOBS_SITE_ID --store memory --prefix primers/andnetlify blobs:get --site $NETLIFY_BLOBS_SITE_ID --store memory --key primers/<HANDLE>.md. Session manifests remain undersessions/{id}/alongside transcripts.
- Interview scaffolding:
docs/interview-guide.mdandlib/interview-guide.tsload the guide at runtime. - Fallback copy system: edit
docs/fallback-texts.md, then runpnpm fallback:syncto refreshlib/fallback-texts.tsandlib/fallback-texts.generated.ts. Placeholders like{DETAIL}or{DATE}are replaced at runtime. - Memory primer engine:
lib/data.tsmanages manifests, blob storage, and the per-handle biography builder. - UI copy & styling:
app/page.tsx,app/globals.css, andapp/layout.tsx(footer shows commit + timestamp). - Automation scripts:
scripts/extract-fallback-copy.mjsand other helpers underscripts/for blob inspection.
- Diagnostics dashboard:
/diagnosticsshows health checks, provider failures, and links to localStorage payloads (DIAGNOSTIC_TRANSCRIPT_STORAGE_KEY,DIAGNOSTIC_PROVIDER_ERROR_STORAGE_KEY). The home panel mirrors recent state transitions; browser storage keeps a rolling log per handle. - Blob helpers:
app/api/blob/[...path]surfaces inline blob contents using the site’s Netlify credentials. Usenetlify blobs:list/netlify blobs:getto inspectsessions/andmemory/primers/prefixes. - OpenAI diagnostics:
/api/diagnostics/openainow refuses to run unless bothOPENAI_API_KEYandOPENAI_DIAGNOSTICS_MODELare set; it logs hypotheses and fails fast withmissing_openai_api_key/missing_openai_modelerrors when env vars are absent. - Google usage audit:
- Real Google calls occur in
app/api/ask-audio/route.tsandapp/api/session/[id]/intro/route.ts(REST) plusapp/api/diagnostics/google/route.ts(SDK). All requireGOOGLE_API_KEYandGOOGLE_MODEL. lib/google.tsresolvesGOOGLE_MODELbut ultimately calls OpenAI chat completions.- Removing Google: replace REST calls in
ask-audioand session intro, remove diagnostics route, and drop Google env vars/dependency. Reintroducing Google should centralize client creation and add env validation.
- Real Google calls occur in
- Diagnostics log platform context and env summaries so deploys fail fast when secrets are missing. Ensure
[diagnostic]logs remain prefixed and include timestamps in any new tooling. - Historical branch sync notes (see
docs/branch-sync-report.md) showed onlymainexisted at that time; recreate the branch locally if you need to mirror that baseline.
Active backlog lives in ToDoLater.txt. Key themes still open:
- Flow resilience: restore the richer multi-turn interview cadence, add heartbeat/timeout safeguards, and surface state-change logging for stuck turns.
- Realtime polish: integrate robust blob storage + authenticated email delivery, add audio playback diagnostics, and wire streaming/OpenAI voice providers with interruption handling.
- Product extensions: expand the history UI (per-turn media + playback), resume sessions with recaps, expose provider switches, and build end-to-end tests for the first-turn/finalize pipeline.
- Fallback sync:
pnpm fallback:syncafter editing fallback copy. - Supabase schema: run statements in
docs/supabase-schema.sqlto align tables and indexes. - Netlify blobs inspection:
netlify blobs:list --site $NETLIFY_BLOBS_SITE_ID --store memory --prefix sessions/andnetlify blobs:get --site $NETLIFY_BLOBS_SITE_ID --store memory --key sessions/<SESSION_ID>/session.json.