Post-letter follow-through: lite send, one-tap outcome capture, live unfrozen count#8
Post-letter follow-through: lite send, one-tap outcome capture, live unfrozen count#8thribhuvan003 wants to merge 7 commits into
Conversation
…rriding sm:hidden
…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.
✅ Deploy Preview for unholdd ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Review limit reached
Next review available in: 27 seconds Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the 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 configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (11)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
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-litesent+sent_at+response_due_at(reminders work) without a proof photo.approvedletters qualify (review-before-send holds);sent_proof_evidence_idstays 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.MarkSentFormgets a secondary action: "I sent it — I'll add proof later" (en + hi).2. Outcome capture
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 existingpublic_stats_opt_inconsent type, action-logged.OutcomeCaptureCardon the case page once a letter exists: one-tap ✅ Unfrozen / 🔓 Partially / 📩 Responded / ⏳ Still frozen, testimonial ask only on a good outcome. Fires theoutcome_loggedfunnel event.3. /impact completes
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(
/impactdegrades gracefully to 0 if the table is missing, but the outcome API would 500 — apply first, then merge.)Not in this PR