CurioQuest

wiki/status/2026-06-04-intake-module-build-status.md

Intake Module Build Status — 2026-06-04

Status

Module 1 Intake is now implemented as the first screen of the Operator Console and persists valid submissions before starting a factory run.

2026-06-04 Visual Alignment Update

The Intake screen was refactored to more closely match docs/mockup/intakeForm-mockup.png while preserving later product decisions:

  • Dark teal CurioQuest Factory app bar and centered workflow rail.
  • Compact numbered panels for Hero, Cast, Guide, and Curriculum
    "SessionStart": [
      { "hooks": [ { "type": "command", "command": "cat ~/.claude/decisions.md" } ] }
    ]
    
    setting.
  • Dense inline form controls and interest chips.
  • Desktop topic cards with mobile dropdown fallback.
  • Mockup-style right rail with Brief health, circular score, order preview, notes, and primary run action.
  • No user-facing Format section, no locked delivery chips, and no print controls.

What Is Built

  • App shell at / with workflow rail and intake as the first screen.
  • Intake form aligned to the approved mock-up direction.
  • Controlled dropdown-backed inputs for hero appearance, cast appearance, pet kind, topic, and Georgia pilot location.
  • Interest constraints: max 2 interests, max 50 characters each.
  • Curriculum topic picker backed by GET /curriculum/catalog?grade=....
  • Backend CreationBrief contract updated for the pilot intake shape.
  • book_format and enrollment are no longer user-facing; backend defaults them internally to digital and single.
  • Durable Supabase/Postgres intake storage added to services/operator-api.

Durable Storage

The operator API has one runtime intake database: Supabase/Postgres.

grep -rHniE "\b(no|nope|wrong|not what i|i said|already (told|gave) you|again|redo|stop|fix it|why did you)\b" \
  ~/.claude/projects/ --include=*.jsonl > friction.txt

Table:

ls ~/.claude/skills/ ~/.claude/commands/

Saved fields:

grep -rHniE "\b(or do (it|the).*inline|if needed|if appropriate|where appropriate|you may|consider|optionally|feel free|as needed)\b" \
  ~/.claude/CLAUDE.md ~/.claude/skills/ ~/.claude/commands/

The full validated CreationBrief is stored in brief_json for replay/audit. Searchable columns are duplicated for operational lookup.

Supabase/Postgres status:

  • Postgres adapter is implemented with psycopg.
  • The API creates public.intake_submissions and indexes on startup with CREATE TABLE IF NOT EXISTS.
  • .env.local must provide DATABASE_URL.
  • Tests inject a fake IntakeStore; there is no SQLite intake implementation or runtime selector.
  • Live Supabase smoke is blocked until DATABASE_URL uses a Supabase pooler URI. The current direct URL is port 5432, and this Mac cannot route to the direct IPv6 database endpoint. Use Supabase Session Pooler or Transaction Pooler, with sslmode=require if Supabase does not include it automatically.

API Contract

  • POST /runs validates the brief, saves an intake row, starts the background factory run, and returns:
#!/bin/bash
prompt=$(cat | python3 -c "import sys,json;print(json.load(sys.stdin).get('prompt',''))")
if printf '%s' "$prompt" | grep -qiE '\bbuild (a|an|the|this|me)\b|\bship (it|this)\b'; then
  echo '{"hookSpecificOutput":{"hookEventName":"UserPromptSubmit","additionalContext":"Build intent detected -> route to your real build pipeline, not an ad-hoc chat."}}'
fi
  • GET /intakes/{intake_id} returns the saved durable intake submission.
  • GET /runs/{run_id} remains the run progress endpoint.

Key Files

  • apps/operator-console/src/components/intake/IntakePage.tsx
  • apps/operator-console/src/components/intake/IntakeForm.tsx
  • apps/operator-console/src/components/intake/BriefSummary.tsx
  • apps/operator-console/src/components/intake/TopicPicker.tsx
  • apps/operator-console/src/lib/brief.ts
  • apps/operator-console/src/lib/intakeOptions.ts
  • apps/operator-console/src/lib/api.ts
  • services/book-factory/src/book_factory/models/brief.py
  • services/operator-api/src/operator_api/intake_store.py
  • services/operator-api/src/operator_api/routes.py
  • services/operator-api/src/operator_api/app.py
  • services/operator-api/src/operator_api/models.py

Verification

Last verified on 2026-06-04:

"hooks": {
  "UserPromptSubmit": [
    { "hooks": [ { "type": "command", "command": "bash ~/.claude/hooks/route-build.sh" } ] }
  ]
}

Notes For Parallel Agents

  • Restart operator-api after pulling these changes so the app initializes the configured IntakeStore.
  • Hosted Supabase testing requires a pooler DATABASE_URL; direct Supabase database URLs can fail locally because the direct endpoint is IPv6-only unless IPv4 is enabled on the Supabase project.
  • Existing runs still live in the in-memory RunStore and filesystem run artifacts; the durable Supabase/Postgres storage is for submitted intake briefs.
  • Print fulfillment remains out of scope for Intake. Print should be modeled later as a separate capability/order flow attached to an existing generated book.
  • Curriculum catalog remains a prerequisite for topic selection; empty catalog should block a valid intake submission from the UI.