Soft Launch Plan

_Status_: active — 2025-10-22 _Scope_: Safely soft-launch Weldr with real users while preserving trust and telemetry.

This plan mirrors the “founder’s knife” cut: we only ship the safeguards that prevent data loss, privacy issues, or obvious trust gaps. Everything else waits until after we have production feedback.

---

Command Center

  • • Target soft launch window: next 24–48 hours.
  • • Demo loop we must personally validate 10× before inviting users:
  • 1. Sign up / login. 2. Run a prompt → wait for generation & preview. 3. Edit a field via Progressive Ownership. 4. Export to GitHub. 5. pnpm install && pnpm dev inside the export. 6. Make a manual code change, re-run preview/export. 7. Push to GitHub (verify history metadata).
  • • Record every run (screen capture + notes) so regressions are easy to spot.
  • ---

    1. Must Fix Before Soft Launch

    1.1 Persist Feedback Telemetry

  • Files: app/api/feedback/route.ts, lib/db/schema.ts, Supabase migrations.
  • Current gap: endpoint just logs and drops the event (// TODO: Store feedback in database at line 21); zero visibility into thumbs up/down usage.
  • Plan:
  • - [x] Add message_feedback table (chatId, messageId, userId, sentiment, optional note, createdAt). _Done 2025-10-22 via 0020_message_feedback migration._ - [x] Update the API route to insert rows via Drizzle, accepting optional comment text. _Drizzle upsert w/ tenant enforcement lands in app/api/feedback/route.ts._ - [x] Emit POST /api/feedback failures to Sentry/logs and return status to client. _Route now validates input + reuses structured error logging._ - [x] Add quick admin query (CLI or lib/feedback/service.ts) to review feedback during launch. _pnpm feedback:list --chatId= dumps recent entries from the new service helper._
  • Acceptance: Submit feedback in the UI → row appears in Supabase → runbook tells us how to filter by chat/user.
  • 1.2 Guard DSL Streaming (retry + fallback)

  • Files: app/(chat)/api/chat/route.ts around the sendEvent failure log (~line 538).
  • Current gap: if sendEvent returns false, the DSL delta is lost with no retries and the UI silently desyncs.
  • Plan:
  • - [x] Persist each DSL chunk to a buffer before acknowledging (new dsl_update_buffer table + helper in lib/dsl/dsl-update-buffer.ts). - [x] Implement at least one retry with exponential backoff (current server retries twice with 250ms backoff). - [x] On repeated failure, push a message-metadata event instructing the client to show “Preview sync failed — press Regenerate preview” + surface a button. - [x] Log failures with chatId/messageId so we can trace them later. _Now emitted alongside bufferId every time retries are exhausted._
  • Acceptance: Simulate a sendEvent failure (stub to return false) and confirm UI shows fallback + retry occurs; logs capture the incident.
  • 1.3 Scope Preview Regeneration by chatId

  • Files: lib/mcp/handlers/regenerate-preview.ts, /api/preview/worker-tick, preview job queue helpers.
  • Current gap: MCP handler drains the global queue, so one tenant can process another tenant’s preview work.
  • Plan:
  • - [x] Add chatId filtering to the worker tick path (queue query + drainPreviewJobs). _drainPreviewJobs now accepts chatId and only pulls jobs for that chat._ - [x] Expose /api/preview/regenerate?chatId=... that enqueues work for that chat only. _New API route processes a single chat’s queue and returns processed counts._ - [x] Update MCP handler to call the scoped endpoint and error out if the chat has no pending jobs. _weldr_regenerate_preview now reports when zero jobs were found._ - [x] Add integration test covering “chat A cannot drain chat B jobs”. _tests/integration/preview-regenerate-scope.test.ts seeds two chats and verifies cross-chat isolation._
  • Acceptance: Kick off two previews, call regenerate for chat A, verify chat B’s job remains untouched; no cross-tenant logs.
  • 1.4 Real User IDs in Export History

  • Files: lib/mcp/handlers/export.ts, app/api/export/{github,vercel}/route.ts, lib/export/export-history.ts.
  • Current gap: handler passes userId: 'mcp-user', so audit logs cannot identify who exported.
  • Plan:
  • - [x] Thread authenticated MCP identity (userId/email) through authPost requests. _Handler now forwards env/user-supplied IDs when triggering exports._ - [x] Update server routes to trust-and-verify the incoming userId (must map to session/tenant). _/api/export/{github,vercel} resolve actors via session, request body, or chat owner._
  • • [x] Show user metadata inside ExportHistoryService records (for /admin visibility). _History entries now store the resolved actor id._
  • • [ ] Add regression test ensuring exports fail if userId missing.
  • Acceptance: Run an export via CLI/agent, check history row contains the real user and surfaces in admin UI/support tooling.
  • 1.5 Enforce Production Safety Rails

  • Files: destructive scripts under scripts/ (e.g., cleanup helpers), docs/ops/runbooks.md (or addendum), and any ad-hoc SQL notebooks.
  • Current gap: Dev habits include occasional manual DELETE/TRUNCATE in prod because dev/prod share a Supabase project. One slip nukes customer data.
  • Plan:
  • - [ ] Update the internal runbook with “migrations only” guidance and explicitly forbid manual destructive SQL against shared tables. - [ ] Add dryRun flags + verbose logging to scripts that mutate tenant/app records so we can preview changes before hitting prod. - [ ] Gate dangerous scripts behind a CONFIRM_PROD=true env check sourced from .env.local so they cannot run accidentally. - [ ] Route destructive script logs into admin_audit_log (new helper or reuse existing logging infra) for after-the-fact review.
  • Acceptance: Attempt to run a cleanup script without the confirm env → it bails; logs show target rows on dry-run, and runbook documents the policy.
  • 1.6 Add Redundant Email Capture

  • Files: lib/db/auth-schema.ts (new important_contacts table + migration), signup handler (lib/auth/signup.ts or NextAuth callbacks), optional webhook client (Zapier/MailerLite).
  • Current gap: User email only lives in Supabase Auth/profile. Losing the DB or corrupting the table means no way to contact early users.
  • Plan:
  • - [x] Create important_contacts (id, email, source, created_at, notes jsonb) with NOT NULL email + uniqueness. _0022_important_contacts migration adds table + auth trigger._ - [x] On signup/profile create, insert into this table within the same transaction; log failures. _createUserProfile now records contacts via recordImportantContact (and fails fast on DB errors)._ - [x] Fire a secondary webhook (MailerLite/Mailchimp/Zapier/Google Sheet) with {email, userId, source} so we have an offsite copy. _recordImportantContact POSTs to CONTACT_BACKUP_WEBHOOK_URL when set and records lastSyncedAt._ - [x] Document a quick export command (pnpm contacts:export) that dumps the table to CSV. _New CLI script streams CSV to stdout._ - [x] Provide a one-off backfill script (pnpm contacts:backfill --dry-run) to mirror existing auth.users rows into the backup table without touching production flows.
  • Acceptance: Create a user → verify 1) new row in important_contacts, 2) webhook receives payload, 3) CLI export prints the email list (pnpm contacts:export --limit=1).
  • 1.7 Manual Backup & Weekly Automation

  • Files: scripts/db/export-critical-tables.ts (new), cron/GitHub Action config, docs/soft-launch-plan.md appendix for instructions.
  • Current gap: No recent backup of users, apps, dsl_snapshots, etc. Supabase free tier offers no retained backups.
  • Plan:
  • - [ ] Today: Use Supabase dashboard or pg_dump to export critical tables; store artifacts in a private, versioned location (Drive/S3/repo). - [ ] Script: pnpm tsx scripts/db/export-critical-tables.ts --dest=s3://... that selects the same tables and uploads to secure storage. - [ ] Schedule weekly automation (GitHub Action or cron on Fly/Render) with service-role creds to run the script and alert on failures. - [ ] Document restore instructions in the appendix.
  • Acceptance: Backup artifact exists with timestamp + checksum; weekly job is committed and dry-run tested with --dry-run option.
  • 1.8 “Preview / No Guarantees” Copy

  • Files: Marketing site (app/(marketing)/layout.tsx or components/Footer.tsx), workspace dashboard (app/(chat)/layout.tsx), localized strings.
  • Current gap: Users might assume production-grade durability; losing data without warning harms trust.
  • Plan:
  • - [x] Add a footer notice: “Early preview — data may be reset. Export important work.” _Marketing footer now shows a Preview badge + disclaimer linking to Launch FAQ._ - [x] Add an in-app banner on the dashboard with the same disclaimer + CTA to export. _PreviewEnvironmentBanner renders in the chat layout with export + FAQ links and can be dismissed per browser._ - [x] Add a small badge near the logo (“Preview”) for visual reinforcement. _Footer brand now renders a persistent Preview pill adjacent to the Weldr logo._
  • Acceptance: Visit marketing + dashboard pages; notice & banner render, copy reviewed for tone, and toggles exist to remove post-launch.
  • 1.9 Schema Health Check & Audit Log

  • Files: lib/db/schema.ts (ensure email columns are NOT NULL, review FK cascades), new event_log table + helper in lib/audit/event-log.ts.
  • Current gap: Potential cascading deletes on user tables and no canonical log of destructive actions (signups, exports, deletions).
  • Plan:
  • - [ ] Review FK definitions for unsafe ON DELETE CASCADE; replace with RESTRICT where user/app data is at risk. - [ ] Ensure email columns in auth/profile tables are NOT NULL and validated. - [ ] Add event_log (id, user_id, type, payload jsonb, created_at) and log signup, app creation, exports, admin scripts. - [ ] Provide a simple pnpm audit:recent --type=admin_action command for ops review.
  • Acceptance: Schema diff shows updated constraints; triggering signup/export writes an event log row queryable via CLI.
  • 1.10 Supabase Plan Decision

  • Files: none (operational). Document outcome in this plan + docs/ops/infra.md.
  • Current gap: Unclear whether we stay on free tier (manual backups only) or upgrade for automated backups/perf.
  • Plan:
  • - [ ] Evaluate expected load for soft launch (10–100 users) and budget. - [ ] If anxiety about limits/backups persists, upgrade to the first paid tier before launch. - [ ] Regardless of decision, note the rationale + next review date in this doc.
  • Acceptance: Decision recorded here with date, billing updated if upgrading, and follow-up reminder scheduled.
  • ---

    2. Should Fix within 72 Hours

    2.1 Remove or Flag Mock Vercel Deployments

  • • GenerationService returns https://${appId}.vercel.app without creating a deployment (lib/generation/generation-service.ts:167-196).
  • • Options:
  • - [ ] Hide the “Deploy to Vercel” CTA in the app/CLI until the real flow is wired. - or - [ ] Swap in the actual Vercel API (token + deployer).
  • • Acceptance: Users never see a fake success message.
  • 2.2 Run DB-dependent Tests Once

  • • Suites skipped by default:
  • - tests/custom-code/custom-store.test.ts (needs RUN_CUSTOM_STORE_TESTS=true + DB). - tests/db/tenant-rls.test.ts (needs POSTGRES_URL and non-CI env).
  • • Plan:
  • - [ ] Point both at staging Supabase, run locally, capture logs. - [ ] Document env vars + any manual prep in this plan’s appendix.

    2.3 Minimal Launch Asset Pack

  • • Deliverable: shareable folder containing
  • - [ ] Logo (SVG + PNG). - [ ] Single hero screenshot (chat → ownership → preview). - [ ] 20-second silent demo (MP4/WebM). - [ ] One-page feature list / differentiators bullet list.
  • • Source details live in business-docs/press-kit-checklist.md; this is the trimmed MVP.
  • ---

    3. Post-Launch / Nice to Have

  • • Full Vercel deployment integration and UI surfacing of deployment history.
  • • Expanded export history views, analytics dashboards, fancy telemetry.
  • • CRM setup, outreach automation, social sequencing, Product Hunt launch prep.
  • • Additional template polish, advanced test automation, ownership visualizations.
  • ---

    Appendix

  • Verification Log Template
  • - Date / Runner - Checklist (core loop, feedback submission, preview regen, export). - Issues discovered.
  • Env Requirements for DB Tests
  • - POSTGRES_URL= (non-pooler). - RUN_CUSTOM_STORE_TESTS=true. - Supabase service role key loaded in .env.local if tests touch auth claims.

    Keep this doc updated as tasks land. Mark each [ ] as [x] once complete and add short verification notes inline. When the “Must Fix” section is fully checked, we’re clear to soft-launch.* End Patch