Skip to content

Post-letter follow-through: lite send, one-tap outcome capture, live unfrozen count#8

Open
thribhuvan003 wants to merge 7 commits into
mainfrom
feat/post-letter-follow-through
Open

Post-letter follow-through: lite send, one-tap outcome capture, live unfrozen count#8
thribhuvan003 wants to merge 7 commits into
mainfrom
feat/post-letter-follow-through

Conversation

@thribhuvan003

Copy link
Copy Markdown
Owner

Why: the live funnel shows 48 letters drafted and 0 ever marked sent — the proof-photo upload was gating the simple act of logging a send. This PR decouples "I sent it" from "proof uploaded" without weakening a single guarantee.

What's inside (one commit)

1. Lite send — POST .../escalations/[eid]/mark-sent-lite

  • Records status sent + sent_at + response_due_at (reminders work) without a proof photo.
  • Proof chain untouched: prior-level proof gates still run here; only approved letters qualify (review-before-send holds); sent_proof_evidence_id stays NULL, so the next letter remains locked until real proof goes through the existing full mark-sent flow. That route and its contract/smoke tests are untouched.
  • MarkSentForm gets a secondary action: "I sent it — I'll add proof later" (en + hi).

2. Outcome capture

  • Migration 20260717051500_case_outcomes.sql: insert-only log, unique per (case, outcome) so repeat taps are idempotent, 600-char testimonial cap, ON DELETE CASCADE (erasure-safe), RLS on with no anon/authenticated grants — same server-only boundary as every application table.
  • POST /api/v1/cases/[id]/outcome: owner-only, zod-validated, testimonial strictly opt-in under the existing public_stats_opt_in consent type, action-logged.
  • OutcomeCaptureCard on the case page once a letter exists: one-tap ✅ Unfrozen / 🔓 Partially / 📩 Responded / ⏳ Still frozen, testimonial ask only on a good outcome. Fires the outcome_logged funnel event.

3. /impact completes

  • "Accounts reported unfrozen" now shows the real count (labelled self-reported), replacing the coming-soon placeholder.

⚠️ Deploy order — migration FIRST

The code queries case_outcomes. Before merging, apply the migration to production Supabase:

supabase db push          # or run the SQL in the dashboard SQL editor

(/impact degrades gracefully to 0 if the table is missing, but the outcome API would 500 — apply first, then merge.)

Not in this PR

  • Contract tests for the two new routes (follow-up; existing suites unaffected)
  • Hindi strings for the new OutcomeCaptureCard (hardcoded EN v1, matching DraftLetterButton precedent; follow-up)

…re, live unfrozen count

The funnel showed 48 letters drafted and 0 ever marked sent: the proof-photo
upload gated the simple act of logging a send. This decouples them without
weakening any guarantee.

- mark-sent-lite API: record "I sent it" without a proof photo. Prior-level
  proof gates still apply, only approved letters qualify, and
  sent_proof_evidence_id stays NULL so the NEXT letter remains locked until
  real proof goes through the full mark-sent flow. Existing mark-sent route
  and its contracts are untouched.
- MarkSentForm: secondary "I sent it — I'll add proof later" action (en+hi).
- case_outcomes migration: insert-only, unique per (case, outcome), RLS on,
  no anon/authenticated grants (server-only boundary), 600-char testimonial
  cap, CASCADE on case erasure.
- outcome API: owner-only one-tap outcome report; testimonial strictly
  opt-in, recorded under the existing public_stats_opt_in consent type;
  action-logged.
- OutcomeCaptureCard on the case page once a letter exists; fires the
  outcome_logged funnel event.
- /impact: "Accounts reported unfrozen" now shows the real count
  (self-reported), replacing the coming-soon placeholder.
@netlify

netlify Bot commented Jul 17, 2026

Copy link
Copy Markdown

Deploy Preview for unholdd ready!

Name Link
🔨 Latest commit 1c8f6b4
🔍 Latest deploy log https://app.netlify.com/projects/unholdd/deploys/6a59bb8b575dbb00088d1b6c
😎 Deploy Preview https://deploy-preview-8--unholdd.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@vercel

vercel Bot commented Jul 17, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
unhold Ready Ready Preview, Comment Jul 17, 2026 5:20am

@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@thribhuvan003, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 27 seconds

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d64a7bde-be85-4977-b880-db4894cdabdf

📥 Commits

Reviewing files that changed from the base of the PR and between 3cc5cc7 and 1c8f6b4.

📒 Files selected for processing (11)
  • app/[locale]/cases/[id]/page.tsx
  • app/[locale]/impact/page.tsx
  • app/api/v1/cases/[id]/escalations/[eid]/mark-sent-lite/route.ts
  • app/api/v1/cases/[id]/outcome/route.ts
  • components/case/OutcomeCaptureCard.tsx
  • components/escalations/MarkSentForm.tsx
  • lib/metrics/public-stats.ts
  • messages/en.json
  • messages/hi.json
  • supabase/database.types.ts
  • supabase/migrations/20260717051500_case_outcomes.sql
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/post-letter-follow-through

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant