Skip to main content
There is no FirstFlow server to harden, so production readiness is mostly about your Supabase project and key handling. Work through this list before you go live.

Database

1

All migrations applied

Confirm every file through 0008 has run, in order. A partially-migrated project fails silently for example the intent classifier computes a result but can’t persist it if 0007 is missing. See Set up Supabase.
2

RLS enabled and scoped

Verify rowsecurity is true on every firstflow_* table and the policies match your auth model. The browser’s anon key is public RLS is the only guard. See Row Level Security.
3

Backups configured

Enable Supabase automated backups (and point-in-time recovery if your plan offers it). FirstFlow data lives only in your project.

Secrets

1

Service-role key is server-only

SUPABASE_SERVICE_ROLE_KEY bypasses RLS. It must never carry a NEXT_PUBLIC_ prefix, never appear in client code, and never be committed. Only @firstflow/runtime-server uses it.
2

AI keys are server-only

ANTHROPIC_API_KEY / OPENAI_API_KEY / LLM_API_KEY live in backend environment only.
3

Rotate anything that leaked

If a service-role or AI key was ever pasted into a log, chat, or shared file, rotate it in the provider dashboard.

Identity

1

Real user ids in production

Pass an authenticated user.id for signed-in users so caps, resume, and persistence attribute correctly. Anonymous fallback is for pre-sign-in visitors. See Identity & auth.
2

captureContent is intentional

captureContent: true stores prompt and completion text in firstflow_conversation_messages. Enable it deliberately and make sure your RLS and retention match your privacy posture.

Smoke test

After deploying, confirm the full path in production:
  1. An experience fires and renders in the widget.
  2. firstflow_flow_runs gains a row (in-progress → completed/dismissed) and survives a reload (resume works).
  3. If you wrap an LLM client, firstflow_llm_calls gains a row with tokens and cost.
  4. If you use the classifier, firstflow_conversations.state / .intent updates.
If 1–2 pass but 3–4 don’t, re-check the service-role key and that migration 0007 is applied.

Versioning

Pin the @firstflow/* package versions and take upgrades deliberately. When you bump @firstflow/config-schema, check for new migrations and apply them before deploying the new runtime.

Next

Review what you own, or set up a local dev loop in Contributing.