Files
resolutionflow/.ai/HANDOFF.md
Michael Chihlas 3cea0f23ee
All checks were successful
Mirror to GitHub / mirror (push) Successful in 5s
CI / frontend (pull_request) Successful in 6m44s
CI / e2e (pull_request) Successful in 10m25s
CI / backend (pull_request) Successful in 11m25s
docs(handoff): record PR #166/#168 merges, dashboard CTA + welcome step-2 fixes, issues #171/#172
- HANDOFF.md: refreshed for 2026-05-14. PR #166 + #168 merged. Bug-pending-capture
  item from 2026-05-12 likely resolved by PR #168 (dashboard CTA dead-link +
  welcome step-2 PSA confusion); confirm with user next session. Stripe/EIN
  blocker carried forward. Issues #171 (WelcomeStep2 connect-now test coverage)
  and #172 (gitignore core dumps + agent .remember/ state) noted.
- CURRENT_TASK.md: added entries for PR #166, #167, #168 to "Recently shipped"
  with full narrative of the three bundled threads on #168 (session expiration,
  dashboard CTA fix, welcome step-2 reshape).
- SESSION_LOG.md: appended detailed 2026-05-14 entry covering the bug-fix design
  conversation, the FOCUS_START_SESSION_EVENT pattern, the welcome step-2
  Connect-now-bug catch (link never persisted primary_psa), CI gating on PR #168,
  and the two filed issues.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-14 00:57:46 -04:00

9.4 KiB

HANDOFF.md

Last updated: 2026-05-14

Active task: Phase O cutover for self-serve signup. All code blockers remain closed on main. Still blocked on Stripe live-mode activation — root cause is EIN, not code. User does not yet have an EIN for ResolutionFlow, LLC; Stripe requires a tax ID for live-mode activation. EIN application via IRS.gov was scheduled for 2026-05-13 — confirm status at next session start. Mailing-address decision (carried forward from 2026-05-12): user enters home address into Stripe's private business profile temporarily so live-mode isn't blocked on the P.O. Box; public ContactPage/PoliciesPage mailing-address TODOs stay "available on request" until the P.O. Box is purchased. Stripe accepts an address update later without re-verification. Apex DNS at Namecheap is still missing (separate user-side issue, only matters once Stripe runs site-verification). Nothing on the code side blocks live-mode flip.

Bug-pending-capture item (2026-05-12) — likely resolved: Prior session noted "user reported finding a bug, will send screenshot next session." This session surfaced two concrete UX bugs that were fixed and merged (PR #168): the dashboard "Start a session" CTA was a dead link, and welcome step-2's PSA setup had a near-invisible "Connect now →" link that didn't even persist primary_psa. Confirm with user at next session start whether the screenshot bug was one of these or something else still pending.

Where this session ended

Two PRs merged into main:

  • PR #166 (fe0e692) — docs/handoff doc updates from prior session. Squash-merged 2026-05-14.
  • PR #168 (3a35121) — session expiration policy + dashboard NextStep CTA fix + welcome step-2 PSA CTA reshape. Merge-committed 2026-05-14. Three notable additions:
    • feat(dashboard) 8d79dd9 — The "Start a session" CTAs on NextStepCard and SetupChecklist used to Link-navigate to /, leaving the user on the same page (the StartSessionInput lives on the dashboard) with no visible response. Replaced with a FOCUS_START_SESSION_EVENT window event the StartSessionInput listens for: scrolls input to viewport top (scrollIntoView({block:'start'})), focuses the textarea (with preventScroll:true so it doesn't fight the smooth scroll), pulses a rgba(96,165,250,…) ring for 900ms. NextStepCard hides itself via local locallyHidden state on click so the user isn't double-prompted while typing. SetupChecklist gets the same event-dispatch treatment for its ran_session row.
    • feat(welcome) dc88797 — Welcome step-2 PSA CTA reshaped. Selecting a real PSA now swaps the single Continue + tiny "Connect now →" link for an explicit two-button choice: Connect <PSA> now (primary, blue — saves primary_psa then routes to /account/integrations) and Connect later (secondary outlined — saves primary_psa then continues to step 3). Important pre-existing bug fixed: the old subtle Link never actually persisted primary_psa before navigating away. Both new buttons do. "No PSA yet" and no-selection states still show the original single Continue. Skip-this-step and Skip-the-rest unchanged. Existing tests pass without edits (testids welcome-step-2-connect-now and welcome-step-2-continue reused).
    • docs: e5b2624 — added docs/plans/2026-05-13-public-landing-routing-refactor.md, docs/architecture/ reports (god-node map + report 2026-05-06, workflows.json/html, workflows-analysis.html), docs/tutorials/build-a-page.md, and abc-feat-self-serve-signup-phase-2-design-20260507-112020.md at repo root.

tsc --project tsconfig.app.json --noEmit clean across all changes. Local vitest blocked by root-owned node_modules/.vite-temp (same env issue noted in prior handoffs); CI ran the suite green.

Two issues filed for session leftovers:

  • Issue #171 — Test coverage for the new welcome step-2 "Connect now" path (existing tests still pass but don't exercise the new button's save + redirect-to-integrations behavior).
  • Issue #172 — Repo hygiene: gitignore core.[0-9]* + **/.remember/, and delete the existing 20MB core dumps (core.144926, core.145678, docs/architecture/core.1392564) and docs/architecture/.remember/. Carried forward across multiple sessions.

Working tree clean except those persistent untracked items (intentionally left for issue #172).

Single alembic head: 4ce3e594cb87 (no schema changes this session).

Resume point

First thing next session:

  1. Confirm with user whether the "bug-pending-capture" screenshot bug from 2026-05-12 was one of the two PR #168 fixes or something else still pending.
  2. Check EIN application status (filed 2026-05-13 via IRS.gov). If granted, unblocks the Phase O Stripe live-mode setup chain.

After that — Phase O manual ops, all user-side, all gated on EIN landing first:

  1. EIN application status check (user, applied 2026-05-13).
  2. Stripe Dashboard live-mode (once EIN is in hand):
    • 3 Products (Starter, Pro, Enterprise). Monthly Prices for Starter ($19.99) + Pro ($29.99). No Prices on Enterprise (sales-led).
    • Customer Portal with plan-switching disabled.
    • Webhook at https://api.resolutionflow.com/api/v1/webhooks/stripe with 5 events. Save live signing secret.
    • Business profile fields: Customer service URL https://resolutionflow.com/contact. Refund/cancellation policy URL https://resolutionflow.com/policies. Terms https://resolutionflow.com/terms. Privacy https://resolutionflow.com/privacy. Phone (470) 949-4131. Mailing address = user's home address temporarily (private Stripe field; swap to P.O. Box later without re-verification). EIN = the newly-issued tax ID.
  3. Apex DNS fix at Namecheap (re-add @ ALIAS → c9g7uku8.up.railway.app, or re-add apex as a Railway custom domain). Becomes the next blocker once Stripe runs site-verification.
  4. Railway prod env: STRIPE_SECRET_KEY=sk_live_..., STRIPE_WEBHOOK_SECRET, STRIPE_PUBLISHABLE_KEY + VITE_STRIPE_PUBLISHABLE_KEY (frontend redeploy required — Vite bake-at-build, Lesson 60), OAUTH_REDIRECT_BASE=https://resolutionflow.com, SELF_SERVE_ENABLED=false (still false at this point), INTERNAL_TESTER_EMAILS=<allowlist>, prod Google + Microsoft OAuth credentials.
  5. Bootstrap prod super-admin via create_site_admin.py (PR #167) — already done end-to-end on prod per 2026-05-12 user confirmation. Re-runnable if needed.
  6. Sync Stripe → DB: railway run python -m scripts.sync_stripe_plan_ids (or via railway ssh). Verify plan_billing rows have sk_live_* price IDs.
  7. Internal validation (Phase O Task 46): 9 scenarios with internal testers whose emails match INTERNAL_TESTER_EMAILS.
  8. Flag flip (Task 47): email pilots, set SELF_SERVE_ENABLED=true + VITE_SELF_SERVE_ENABLED=true (frontend redeploy). PostHog signup-funnel dashboard + Sentry alert at >1/hour Stripe webhook errors.

Open issues from prior session (non-code, user-side)

  • Apex DNS missing. resolutionflow.com (apex) returns no A/CNAME at the authoritative DNS (Namecheap). When www was reconfigured in Railway, the apex record got dropped from the zone. www works (cert provisioned 2026-05-08 01:40 UTC). User to re-add apex record at Namecheap (ALIAS @c9g7uku8.up.railway.app) or re-add the apex as a Railway custom domain. Railway path is more durable.
  • Edge HSTS sticky state on user's machine. Browser remembers the earlier broken-cert visit. Fix: edge://net-internals/#hsts (delete resolutionflow.com and www.resolutionflow.com) + #dns clear host cache + #sockets flush.

Carry-forward

  • Annual pricing intentionally NOT implemented — user wants exit flexibility. Schema columns preserved as nullable. sync_stripe_plan_ids.py leaves annual fields NULL.
  • INTERNAL_TESTER_EMAILS parsed comma-separated → normalized lowercase list. Anonymous callers always see the global flag — allowlist never leaks via unauthenticated request content (regression test enforces).
  • Office-hours design doc now at docs/ root (abc-feat-self-serve-signup-phase-2-design-20260507-112020.md) as of this session. NOT yet adopted as roadmap — gated on 3 cold calls with external Directors of Onboarding.
  • Mailing address fill-in: search for TODO: replace with full mailing address in frontend/src/pages/ContactPage.tsx and frontend/src/pages/PoliciesPage.tsx (one each) once P.O. Box is purchased.
  • backend/scripts/create_site_admin.py is the durable site-admin bootstrap tool — idempotent. Three modes: --send-reset, --print-reset, --promote-only. Run from inside the deployed backend container via railway ssh.
  • Bot-crawlability of legal pages: still SPA-rendered. Stripe didn't enforce content scraping last time (issue was DNS). If a future vendor review flags it, pre-render with vite-plugin-prerender-spa (~half day).
  • Frontend env additions for cutover: VITE_SELF_SERVE_ENABLED, VITE_GOOGLE_CLIENT_ID, VITE_MS_CLIENT_ID, VITE_OAUTH_REDIRECT_BASE, VITE_CALENDLY_URL, VITE_STRIPE_PUBLISHABLE_KEY.
  • Branch hygiene note (process learning): PR #168 ended up bundling unrelated work — session expiration policy (the original scope of feat/session-expiration-policy) plus dashboard CTA fixes plus welcome step-2 reshape. The mixed scope was deliberate (user wanted it on the same PR), but worth flagging for future PRs: if onboarding-UX work continues, branch it separately from auth/session work.