Skip to content

NotBrianZach/bza

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

381 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

bza — AI Reading Companion

Upload a book. Get AI-powered character tracking, page discussions, concept analysis, and generated illustrations. Billed at cost.


What it does

  • Book reader — paginated reading view (CSS columns layout) with arrow-key navigation, reading progress, and bookmarks
  • Character panel — automatic extraction, relationship mapping, summary history timeline, image generation
  • Structure panel — concepts, themes, and plot structure tracked across pages
  • Chat — ask questions about any page with full context
  • Image generation — generate illustrations for characters, scenes, or concepts; toggle inline in reader
  • Billing — usage-based Stripe metered billing at 2× API cost, reported weekly

Stack

Layer Technology
Frontend Next.js 14, Tailwind CSS, Supabase Auth
Backend API Flask (Python)
Database PostgreSQL via Supabase
Edge Functions Supabase (Deno)
Storage Supabase Storage
Billing Stripe metered billing
Secrets TempleDB (age-key encrypted)
Deploy TempleDB deploy hooks

Getting started

Prerequisites

  • TempleDB installed and on PATH
  • Node.js 18+, Python 3.11+
  • A Supabase project

1. Store secrets in TempleDB

# Supabase
templedb secret set bza NEXT_PUBLIC_SUPABASE_URL         https://<ref>.supabase.co  --keys age-key
templedb secret set bza NEXT_PUBLIC_SUPABASE_ANON_KEY    <anon-key>                 --keys age-key
templedb secret set bza SUPABASE_URL                     https://<ref>.supabase.co  --keys age-key
templedb secret set bza SUPABASE_ANON_KEY                <anon-key>                 --keys age-key
templedb secret set bza SUPABASE_SERVICE_ROLE_KEY        <service-role-key>         --keys age-key
templedb secret set bza SUPABASE_DB_PASSWORD             <db-password>              --keys age-key
templedb secret set bza SUPABASE_DB_HOST                 aws-1-us-east-1.pooler.supabase.com --keys age-key

# AI
templedb secret set bza OPENAI_API_KEY                   sk-...                     --keys age-key

# Stripe (use placeholders until ready; run setup-stripe.sh to populate)
templedb secret set bza STRIPE_SECRET_KEY                sk_live_...                --keys age-key
templedb secret set bza NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY  pk_live_...            --keys age-key

# App
templedb secret set bza SITE_URL                         https://yourdomain.com     --keys age-key

2. Run database migrations

./scripts/db-migrate.sh        # runs all migrations in supabase/setup/ in order
./scripts/db-migrate.sh --list # list migration files
./scripts/db-migrate.sh 08     # run a specific migration by partial name

3. Set up Stripe (one-time)

./scripts/setup-stripe.sh

Creates the product, meter, price, and webhook endpoint in Stripe. Stores all resulting IDs back in TempleDB automatically.

4. Deploy

templedb deploy run bza                    # full stack (local target)
templedb deploy run bza --target production

The deploy hook (deploy_bza_web.sh) injects secrets, deploys edge functions, starts the Next.js frontend, then starts the Flask backend.


Development

# Frontend only
cd frontend && npm run dev

# Frontend + Supabase edge functions served locally
cd frontend && npm run dev:all

# Update a secret and redeploy
templedb secret set bza STRIPE_SECRET_KEY sk_live_... --keys age-key
templedb deploy run bza

Project layout

bza/
├── frontend/               Next.js SaaS frontend
│   ├── app/                Pages (dashboard, billing, reader, auth)
│   ├── components/         BookReader, CharacterPanel, StructurePanel, ImagePanel, …
│   └── lib/                supabase-queries.ts, localStorage.ts
├── backend/                Flask API (book processing, analysis queue)
├── supabase/
│   ├── functions/          Edge functions (analyze-characters, chat-with-book, …)
│   ├── setup/              SQL migrations — run via scripts/db-migrate.sh
│   └── .env.template       Documents required edge function env vars (no real values)
└── scripts/
    ├── db-migrate.sh        Run SQL migrations against production DB
    ├── setup-stripe.sh      One-time Stripe object creation
    └── report-usage.sh      Weekly usage reporting to Stripe meter

Billing model

API costs are recorded per request in api_usage. Every Sunday a cron job sums each customer's raw cost, multiplies by 2, converts to cents, and sends a Stripe meter event (ai_usage_cents). Stripe invoices at $0.01/unit on a daily interval.

# Add to crontab
0 0 * * 0 /tmp/bza/scripts/report-usage.sh >> /tmp/bza/logs/usage.log 2>&1

# Dry run (prints without sending to Stripe)
./scripts/report-usage.sh --dry-run

Secrets

All secrets live in TempleDB encrypted with age-key. No .env files with real values are committed. The files below are generated at deploy/dev time and gitignored:

  • frontend/.env.local — Next.js environment variables
  • supabase/.env — edge function environment variables
templedb secret list bza                              # list all
templedb secret get bza KEY                           # read one
templedb secret set bza KEY value --keys age-key      # set one
templedb secret export bza --format dotenv            # export all

About

turn books, articles, plaintext or webpages into interactive read eval print loops, manage bookmarks in your own local database

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors