Skip to content

Launch readiness master tracker — every open issue banded pre-MVP / post-MVP / scale, grouped by subsystem #1072

Description

@teetangh

This is the live launch-readiness tracker. The two previous ones — #331 (MVP Launch Roadmap) and #328 (MVP Pending Items) — were both closed in March 2026, and nothing replaced them. Since then the backlog has grown to 107 open issues, of which 44 carry no label at all, so there has been no single place that answers "what is actually left before we can take money from strangers".

This issue does three things. It sorts every open issue into one of three launch bands, it groups those bands by subsystem, and it records the issues that are stale, wrong, duplicated or in the wrong band so they can be fixed rather than silently rot.

Everything below was checked against dev at 839d359c on 2026-08-01. Where a claim is a code-verified fact rather than a restatement of the issue text, it is marked [verified].


1. How the bands are defined

The three bands are not a priority ranking. They answer three different questions.

Pre-MVP — the platform is about to take real money from people who are not us. An issue belongs here if a launch-day user could lose money, lose data, be unable to finish a booking, or if the failure would happen without us finding out. Regulatory exposure that attaches on the first transaction also belongs here. This band is the launch gate.

Post-MVP — the first ninety days after launch. The platform works, but coverage, polish and operational maturity are thin. Nothing here stops us from opening the doors; all of it will start to hurt once real users are inside.

Scale — needed only when volume, enterprise demand, or a new revenue line forces the question. Building any of it before launch is speculative work against unvalidated demand.

2. Where we are, in one table

Band Open issues Label What it means
Pre-MVP 30 launch: pre-mvp The launch gate.
Post-MVP 48 launch: post-mvp First ninety days.
Scale 13 launch: scale Deliberately deferred.
Unbanded 13 Carry no band label at all — see the correction below.
Stale / needs triage 3 of 12 §6's list, mostly worked through.

Counts refreshed 2026-08-13 (103 open, down from 107). Live queries: pre-MVP · post-MVP · scale.

Correction. This section used to claim every open issue carries exactly one band label. That was true when written and is not now: 13 open issues carry no band label#1076, #1078, #1084, #1085, #1086, #1089, #1115, #1117, #1120, #1124, #1127, #1128 and this tracker — and #1132 carries two (pre-mvp and scale). Almost all of the unbanded were filed after 2026-08-01, so the drift is new-issue intake rather than decay. The banding rule needs to run at filing time or it will keep drifting.

The honest summary is that the Pre-MVP band is dominated by five subsystem audit trackers that have never been fully worked through (#676 booking, #677 payments, #688 schema, #690 auth — #689 Stream was closed as superseded by #1134) plus the booking-lifecycle findings from the 2026-07-17 audit (#1003#1013). The money paths themselves have had three hardening waves and are in good shape; what has not had a hardening wave is cancellation, refund and rejection of anything that is not a 1:1 consultation.


3. Pre-MVP — the launch gate

Booking

Issue Why it gates launch
#676 Booking production-readiness master tracker. Self-assessed at ~75% readiness; the remaining 25% is not enumerated anywhere else.
#1071 Rescheduling a webinar longer than 30 minutes moves only its first slot, leaving one appointment holding sessions on two different days. Silent data corruption.
#1012 A stale second tab can delete and recreate an allocation the first tab already completed. Data loss with no error surfaced.
#1005 Consultees are shown Reschedule and Cancel buttons on group events and trials that the server always rejects, and the trial path reports a false success toast. Every launch-day group booking hits this.
#997 GET /api/bookings/subscriptions?status=PENDING sat unresolved for 30–40s in production. Consultants cannot triage requests.
#1003 Cancelling a whole webinar or class refunds nobody and notifies nobody, and deletion is blocked on "cancel or refund first" — which no in-app path can satisfy. Circular, and it holds other people's money.
#837 The B2C state-machine and payments hardening umbrella. Its launch-blocker checklist is the parent of most of the remaining B2C money work.
#834 Waitlist slot assignment outside the checkout transaction, plus partial multi-session enrolment. Sits under #837 but its premise file no longer exists — see §6.11.

Finance

Issue Why it gates launch
#677 Payments production-readiness master tracker.
#1009 Escalated — see §6.1. Trial cancellation hard-deletes the appointment, and Payment.appointment is onDelete: Cascade [verified: prisma/schema.prisma, Payment.appointment line 39 of the model; tx.appointment.delete at app/api/trials/[trialId]/route.ts:586,795]. Paid trials shipped in PR #1046, so this is no longer a future risk — cancelling a paid trial destroys the payment record today.
#1004 A consultant rejecting a paid request triggers no refund. The word "refund" does not appear in the status-PATCH handlers. Money stays captured until somebody notices manually.
#738 B2C tax and compliance: refund/chargeback tax adjustments, multi-attendee webinar treatment, non-resident flows. Attaches on the first transaction.
#481 Billing guardrails across Netlify, Supabase, Stream and Razorpay. A launch-day traffic spike with no spend ceiling is an unbounded liability.
#863 Enterprise launch-residuals register, including the one go-live gate: the ENABLE_LIVE_PAYOUTS flip [verified: lib/feature-flags.ts:63].

Stream (video · recordings)

Issue Why it gates launch
#1134 Stream subsystem audit v2. The webhook pipeline had never processed a single event in production, and any signed-in user could join any consultation from devtools. Eight PRs (#1136#1143) are open against it, all green. Two operator steps have ordering that can cause an outage — see the issue.

Refreshed 2026-08-13. #689, #899 and #1061 all previously sat here and are all closed: #689 and #899 as superseded by #1134, #1061 by PR #1067. The tail #1134's PR train does not close is tracked in #1144 (post-MVP).

Notifications

Issue Why it gates launch
#691 Notifications production-readiness audit. NTF-1: 23 fire-and-forget void notify*() calls — on a Novu or Resend outage during checkout the payment captures and the user is told nothing. NTF-2: zero unsubscribe links, which is a CAN-SPAM/DPDP exposure.
#1055 The ADR 23 org preference switches save and read back correctly but do not gate delivery until the Novu console carries the category and routing conditions. A member who turns billing alerts off still receives them.
#536 Notification copy leaks raw templates and empty date placeholders to users. Cheap to fix, and it is the first thing every user sees.

Auth · onboarding · abuse

Issue Why it gates launch
#690 Auth production-readiness audit. AUTH-1: User.emailVerified exists in the schema and is enforced nowhere [verified: no reference in lib/auth-guard.ts, lib/auth-helpers.ts or middleware.ts]. AUTH-2: OAuth tokens at rest.
#698 Onboarding audit across all three roles. OB-2 — setOnboardingRoleAction() writes User.role = ORG_ADMIN to the database without the session following — is a live authorization split-brain.
#405 Account creation, deletion and recreation. Spam-account and abuse vectors that get exercised the day the platform is public.
#695 Admin/staff dashboard code audit. ADM-1: POST /api/user/staff accepts a password, stores it nowhere, and never calls BetterAuth — every staff account created through it cannot sign in.
#407 Layered rate limiting. Banded pre-MVP because the remaining layers are launch-relevant, but the issue text is out of date — the core is already shipped, see §6.5.

Trust · documents · moderation

Issue Why it gates launch
#693 Moderation audit. MOD-1 was a literal TODO: staff "ban"/"suspend" wrote a row and did nothing. PR #974 shipped the real side-effects but linked as Part of, not Closesneeds verification and closure, not more work (§6.2).
#694 Document subsystem audit. DOC-1: a consultee whose appointment is cancelled or refunded keeps reading documents through a cached signed URL. DOC-2: no upload rate limiting.
#692 Referrals and credits anti-fraud. The self-referral check is the only guard; duplicate accounts, IP/device velocity and circular referrals are unguarded, against an ₹500 default reward. This is a launch-day arbitrage.

Enterprise

Issue Why it gates launch
#688 Prisma schema master tracker. Schema freeze is the launch gate — deferred implementation is fine, deferred schema is not.
#705 Pre-MVP infrastructure and schema freeze: Redis gaps, Postgres extensions, queue strategy.
#840 Org invitees have no first-class onboarding path; the role picker forces an unwanted profile or heavy verification. Gates the first enterprise customer, not B2C.

Infrastructure · observability

Issue Why it gates launch
#1066 58 cron job files call Sentry.captureException into an SDK that was never initialised in those processes. Every scheduled-job error in production is currently dropped. PR #1068 is open.
#866 / #1010 The every-minute webhook dispatcher actually fires about once every 2.5 hours under GitHub Actions throttling. #866 holds the decision; #1010 is the QStash execution. Reminders and webhook delivery are both on this path.
#932 Cross-region Netlify (us-east-2) ↔ Supabase (ap-south-1) latency causes pooler connection timeouts in production today.
#697 Infra audit. INF-1: maintenance mode is written to Redis with no TTL, so an OFFLINE state that loses its owner keeps the platform down indefinitely.
#480 The original production-readiness audit. Needs a status pass (§6.5) but its showstopper section is still the reference list.
#874 Capacity and load-test go/no-go. This is the explicit launch capacity artifact and it has not been executed.
#867 Dashboard semantic correctness — 71 findings across six dashboards on state machines, editability and race conditions.

4. Post-MVP — the first ninety days

Booking#448 (reschedule notifications, audit trail, staff/admin blind spots), #1065 (preference-scored auto-allocation, PR #1069 open), #1006 (subscription refund proration for partially-consumed plans), #1058 (no archive path for booked consultant plans), #309 (slot availability caching), #1013 (booking docs 07/08 stale against the code), #472 (session overrun detection).

Finance#770 (contract and BillingSubscription amend/renew/reconcile, 8 gaps), #1020 (dispute/earnings edge cases; dormant until host orgs launch).

Stream · chat#1070 (adopt Stream's scheduled-call model: starts_at, members/roles, backstage join windows), #473 (circuit breaker and graceful degradation), #535 (hard-delete soft-deleted Stream users after the 30-day grace), #341 (Send Inquiry replacing open DMs), #639 (Stream SDK at 771KB on every page).

Notifications#399 (Novu webhook receiver for delivery tracking), #337 (reschedule emails — fold into #448, §6.4).

Auth · onboarding#725 (BetterAuth Tier 1: 2FA, captcha, HIBP, admin/RBAC migration), #884 (risk-based phone step-up plus India DLT/DPDP), #494 (onboarding UX phases 2 and 3), #469 (Google One Tap), #724 (collapse the half-onboarded ORG_ADMIN state).

Enterprise#1021 (org-scoped support, feedback and quality signal), #701 (org lifecycle, HRIS, SSO runtime, governance), #684 (org plans gap audit — verify first, §6.6), #746 (the additions and integrations roadmap; individual tiers will split across bands).

Referrals · growth · discovery#880 (referral reward model and cross-role weighting — the policy should be locked pre-launch even though the build is post), #696 (search and discovery audit; SCH-1, the sitemap listing only five static routes, is worth pulling forward because SEO takes weeks to compound), #334 / #767 / #312 (newsletter and CMS — all three have stale premises, §6.3), #381 (granular cookie consent).

Dashboards · UX#868 (consultant and consultee dashboard redesign), #487 (consultant dashboard PM audit, 122 findings), #486 (consultee dashboard PM audit), #485 (price on cards, chronological grouping), #1054 (UrlTabs still uses router.replace, forcing a full tree re-render per tab switch).

Performance#734 (systemic frontend performance), #906 (/api/appointments at ~2.3s), #450 (landing/explore/detail; partly shipped via #938/#940), #920 (make build-time-DB pages dynamic), #937 (Prisma Accelerate evaluation), #383 (query performance system).

Observability · platform#900 (Sentry follow-ups), #378 (PostHog only now — the Sentry half shipped in PR #901, §6.7), #531 (structured logging; winston is not installed [verified]), #409 (Aikido — reconsider, we already run SonarCloud and CodeRabbit), #1030 (145 Sonar code smells), #654 (zod is still pinned at ^3.25.67 [verified: package.json:127]), #308 (seed data realism), #377 (Intercom).

5. Scale — deliberately deferred

#872 (DST / IANA TZID — the platform is pinned to Asia/Kolkata per ADR 17, so this unblocks only the first non-IST consultant), #367 and #366 (recording library and recording monetization — overlapping, merge them, §6.8), #342 (Stream Chat feature roadmap), #371 (AI semantic mentor search), #702 (affiliate program — the issue's own need assessment says the signal is weak), #663 (enterprise analytics charts), #739 (agentic customer support), #875 (agentic detect→remediate — not currently an actionable issue, §6.9), #348 (realtime document updates), #869 · #733 · #274 · #842 (four overlapping refactor issues — consolidate, §6.10), #640 (tseslint.configs.strict), #270 (payments service factory).


6. Issues that are stale, wrong, or in the wrong place

This is the part of the triage that changes what we do next, so each item carries its evidence.

Status 2026-08-13 — nine of the twelve are resolved. Closed since: #1009 (§6.1), #693 (§6.2), #337 (§6.4), #407 (§6.5), #684 (§6.6), #636 (§6.8), #613 and #875 (§6.9), #733/#274/#842 (§6.10), #834 (§6.11). Of §6.3, #334 is now closed as superseded by PR #1035 — the newsletter shipped on the reworked Waitlist, ConvertKit never adopted — while #767 and #312 stay open carrying the CMS decision, which is genuinely unmade. §6.7 (#378) stays open: Sentry shipped via #901 with #900 as its tracker, PostHog is still absent from package.json. §6.12's coverage gaps (collaborators, trials) are still gaps.

Each of the above was re-verified against dev before acting; this list was written against dev@839d359c on 2026-08-01 and several premises had moved.

6.1 #1009 has already come true — escalate to Pre-MVP, highest severity

The issue is titled "must precede #969" and reads as a future risk. It is not. PR #969 was closed unmerged, but PR #1046 wired paid trials through the approval-payment flow and merged. TrialSession.paymentId is live in the schema, Payment.appointment is onDelete: Cascade, and app/api/trials/[trialId]/route.ts still calls tx.appointment.delete at lines 586 and 795 [all verified]. Cancelling a paid trial today deletes the appointment, which cascade-deletes the Payment row; TrialSession.payment is SetNull, so the trial survives holding a dangling reference and the money record is simply gone. Retitle, drop the "#969" framing, label priority: critical, and treat it as the top Pre-MVP finance item.

6.2 #693 is probably done — verify and close

PR #974 shipped real moderation side-effects and merged, but its body says Part of #693 rather than Closes #693, so nothing auto-closed. Given the convention of never closing issues by hand, the cleanest resolution is a verification pass and then a Closes #693 on the next PR that touches moderation.

6.3 #334, #767 and #312 all rest on premises that no longer hold

PR #1035 ("retire the event queue, rebuild Waitlist as the newsletter") merged, and lib/newsletter/ no longer exists [verified]. #767's central claim — that lib/newsletter/convertkit.ts is a four-function stub awaiting a vendor decision — is now false, and the newsletter ships on the reworked Waitlist double-opt-in instead. convertkit and directus are absent from package.json [verified], while app/api/webhooks/directus/ still exists as a skeleton. All three need rewriting against reality, and #334 in particular may be closeable outright.

6.4 #337 is a subset of #448

An APPOINTMENT_RESCHEDULED Novu workflow now exists [verified: lib/novu/workflows.ts:15], and #448 covers the same notification gaps plus the audit trail and staff/admin blind spots. Fold #337 into #448.

6.5 #407 describes a state that no longer exists

The issue opens with "there is currently zero rate limiting on any route". Rate limiting is wired: middleware.ts imports Ratelimit, lib/rate-limit.ts is a full implementation, and ADR 07 documents the posture [all verified]. Either narrow the issue to the layers still missing, or close it.

6.6 #684 was written against a branch we no longer have

It is scoped to feature/enterprise-arch4 post-Checkpoint-9h and claims the org plans page is non-functional end-to-end. The org catalog and unified offering editor shipped since, in #1050, #1053, #1057 and #1060. Re-verify before any work is planned against it.

6.7 #378 is half shipped

Sentry landed in PR #901 with its own follow-up tracker in #900. #378 should be retitled to cover PostHog product analytics only, with the Sentry half pointing at #900. posthog is absent from package.json [verified], so the remaining half is genuinely unstarted.

6.8 #636 is superseded by its own successor

#639 states in its own body that it supersedes #636 with measured build data. Close #636 as superseded.

6.9 Two issues are not issues

#613 is a March 2026 point-in-time audit snapshot whose scores have been overtaken by every audit since; it is a document, not work. #875 is a pasted conversation about agentic remediation with no scoped deliverable. Both should either be rewritten into something actionable or closed.

6.10 Four overlapping refactor issues

#869 (codebase reorganization), #733 (lib/utils boundary erosion), #274 (shared dashboard components) and #842 (de-export pass) all describe the same structural debt from different angles. #869 has the most complete migration plan; the other three should become checklist items inside it.

6.11 #834 needs re-verification

Its premise file, lib/waitlist/slot-handler.ts, no longer exists — lib/waitlist/ now contains only service.ts and tokens.ts [verified] after the #1035 rework. The underlying concern (slot assignment outside the checkout transaction, no unique constraint on the SlotOfAppointmentUser join) may or may not have survived the rewrite. Confirm against the current code before leaving it in the #837 umbrella.

6.12 Coverage gaps — subsystems with no open issue

Collaborators has no open issue of its own, even though the collaborator settlement model and the personal-vs-org collaborator reorganisation were both explicitly deferred as follow-ups. Trials has exactly one (#1009), which is a bug rather than a readiness review, and paid trials shipped without one. Both are blind spots rather than clean bills of health.


7. Labelling

Forty-four of the 107 open issues carry no label at all, and the label vocabulary has no way to express a launch band or most subsystems. The production label is applied to 22 issues and does not distinguish "blocks launch" from "matters in production eventually".

New labels to create:

Bands — launch: pre-mvp, launch: post-mvp, launch: scale.

Subsystems — booking (or rename the existing appointments), finance, chat, auth, onboarding, referrals, trials, collaborators, moderation, documents, search, dashboard, compliance, tech-debt.

Done. All twenty labels above were created and applied on 2026-08-01. Every one of the 107 open issues now carries exactly one band label and at least one subsystem label; the count of issues with no label at all went from 44 to 0. The narrower appointments label was folded into booking.

Existing labels still worth retiring: production (22 uses) becomes ambiguous now that the bands exist and no longer distinguishes "blocks launch" from "matters in production eventually". Maintenance check (3 uses) and critical (1 use, redundant with priority: critical) are also candidates. These have been left in place for now.


8. Standing rules for this tracker

New issues should get a band label and a subsystem label at filing time, otherwise this tracker decays back into the state that made it necessary. When an issue moves band — because something shipped, or because a risk came true the way #1009 did — change the label rather than only the prose, since the band queries are what people will actually read.

Activity

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

Metadata

Metadata

Assignees

Labels

documentationImprovements or additions to documentationproductionProduction deployment and readiness

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions