Continuing BookifAI (AI KDP book SaaS on Sondra's own stack). This session (1) designed and LOCKED the entitlement model, book-size cap, and the research/demand-feed features into the PRD, then (2) built the billing spine on top of the already-deployed money-spine backend. Everything is TEST mode; app has 0 real users. Prior context: c:\Users\srver\AIOS-Workspace\aios-starter-kit\PROJECTS\Bookify AI Studio\handoffs\billing-money-spine-2026-07-05.md.
book_credits). Slot spent at book creation so text-only books can't run up (rejected Option B / charge-at-first-action for the text leak). Inside a slotted book the user is uncapped except the 15/40 image cap. Free first book = try-before-buy. No separate research-credit currency (YAGNI). Spec in PRD.md Β§7.8.PRD.md Β§7.8.search (Amazon direct scrape is BLOCKED β proven live) + cheap Sonnet 5 structuring. Cost measured: Firecrawl flat plan (1,000 credits/cycle), scrape=1 credit, search=~2; weekly generic feed ~30-40 credits/mo = effectively $0. In PRD.md Β§7.8.anthropic/claude-sonnet-5 (OpenRouter) for writing + structuring; not Opus.Landing.jsx two-row marquee (lb-marquee), each chip links to signup ?idea=... β prefills Feature A. Spec in Β§7.8.claim_book_slot(uuid) (freeβcreditβunpaid, ownership-checked, EXECUTE authenticated), meter_image(user,project,kind) + refund_image(...) (service_role only). Local file: ...\app\supabase\migrations\20260706000000_billing_slot_metering.sql.meter_image before generation, auto-refund on failure. Closes the prior unauth/unmetered security hole. ...\app\supabase\functions\generate-illustration\index.ts....\app\supabase\functions\generate-chapter\index.ts.CreateBook.tsx); projectId+kind:"page" passed to illustration + 402 lock messaging (BookPreview.tsx readLockReason); projectId added to chapter body (ChapterGenerator.tsx); download page locked behind paid with "Unlock this book β $29" button (ExportOptions.tsx); Account "Plan & Credits" card with book/image credit counts + Buy Author Pack $79 / Buy Image Credits $9 buttons + purchase-return handling (Account.tsx). Regenerated src/integrations/supabase/types.ts.c:\Users\srver\AIOS-Workspace\aios-starter-kit\PROJECTS\Bookify AI Studio\PRD.md β read Β§7.7 then Β§7.8 (locked billing + research/feed spec).c:\Users\srver\AIOS-Workspace\aios-starter-kit\PROJECTS\Bookify AI Studio\app\supabase\migrations\20260706000000_billing_slot_metering.sqlc:\Users\srver\AIOS-Workspace\aios-starter-kit\PROJECTS\Bookify AI Studio\app\supabase\functions\generate-illustration\index.tsc:\Users\srver\AIOS-Workspace\aios-starter-kit\PROJECTS\Bookify AI Studio\app\supabase\functions\generate-chapter\index.tsc:\Users\srver\AIOS-Workspace\aios-starter-kit\PROJECTS\Bookify AI Studio\app\src\components\create-book\ExportOptions.tsx (paywall + $29 unlock)c:\Users\srver\AIOS-Workspace\aios-starter-kit\PROJECTS\Bookify AI Studio\app\src\pages\Account.tsx (buy buttons)c:\Users\srver\AIOS-Workspace\aios-starter-kit\PROJECTS\Bookify AI Studio\stripe-test-products.json (price IDs)cd "PROJECTS/Bookify AI Studio/app" && npm run dev -> localhost:8080.generate-illustration no-auth -> 401, anon -> 401; generate-chapter unslotted book -> 402 no_slot. Re-run: curl -s -o /dev/null -w "%{http_code}" -X POST https://umnlokuehteqwrheoyai.supabase.co/functions/v1/generate-illustration -H "Content-Type: application/json" -d '{"scenePrompt":"x","projectId":"0"}' -> 401.cd "PROJECTS/Bookify AI Studio/app" && npx tsc --noEmit -> exit 0.TOKEN=$(python -c "import re,pathlib;print(re.findall(r'sbp_[A-Za-z0-9]+',pathlib.Path.home().joinpath('.claude.json').read_text(encoding='utf-8'))[0])"); CLI ~/AppData/Local/Programs/cli-bin/supabase.exe; SUPABASE_ACCESS_TOKEN=$TOKEN supabase.exe functions deploy <name> --project-ref umnlokuehteqwrheoyai.gen types typescript --project-id umnlokuehteqwrheoyai > src/integrations/supabase/types.ts.npm run dev -> localhost:8080; (2) sign up/log in, make a book, reach the download page -> Unlock $29; (3) Stripe TEST card 4242 4242 4242 4242, any future date, any CVC; (4) confirm it returns to Account and downloads unlock. Author Pack ($79) / Image Credits ($9) buttons test the same way from Account.meter_image but the cover screen (CoverGenerator.tsx) was NOT confirmed to route through generate-illustration with kind:"cover" β wire + verify that next./app-safety-check before any real launch. Live key STRIPE_API_KEY_MAIN in master .env; create live products + live webhook + reset secrets.generate-chapter checks entitlement by projectId via service role; it does not re-verify per-user ownership on the text call (ownership is enforced at claim_book_slot, which is auth'd). A user passing a stranger's paid projectId could generate text billed to us β text is cheap, no data written. Tighten later if desired.Sondra runs the live 4242 test-card round-trip; if it grants access cleanly, next agent wires cover-generation metering (CoverGenerator.tsx -> generate-illustration kind:"cover"), then starts Feature A (Research My Idea) per PRD Β§7.8.
Generated for the CEO Dashboard · source: PROJECTS/Bookify AI Studio/handoffs/billing-spine-build-2026-07-06.md π€