Skip to content

feat: Add ability to purchase provider coding plans#3521

Open
jeanduplessis wants to merge 9 commits into
mainfrom
coding-plans
Open

feat: Add ability to purchase provider coding plans#3521
jeanduplessis wants to merge 9 commits into
mainfrom
coding-plans

Conversation

@jeanduplessis
Copy link
Copy Markdown
Contributor

@jeanduplessis jeanduplessis commented May 27, 2026

Summary

Adds managed MiniMax Token Plan Plus subscriptions funded by Kilo Credits and surfaced through Subscription Center and admin operations.

Why this change is needed

Kilo needs a first Coding Plans offering that can sell provider-plan access without redirecting subscribers to an upstream checkout or exposing managed provider credentials. The pilot also needs explicit billing, cleanup, and manual-revocation rules because ordinary MiniMax BYOK controls routing while Kilo remains responsible for subscription lifecycle and issued credentials.

How this is addressed

  • Defines Coding Plans and Subscription Center contracts for managed credentials, credit billing, sold-out notification intents, BYOK behavior, and operator revocation workflow.
  • Adds persistent inventory, subscription, charged-term, and availability-intent records for MiniMax Token Plan Plus.
  • Activates subscriptions atomically by charging credits, claiming encrypted inventory, and installing an ordinary personal MiniMax BYOK configuration; renewal, grace-period termination, cancellation, and account deletion preserve cleanup and revocation invariants.
  • Adds customer purchase, status, billing history, cancellation, sold-out notification, and BYOK warning surfaces within Subscription Center.
  • Adds admin inventory upload, credential validation, manual revocation operations, and scheduled billing lifecycle processing.
  • Gates the customer-facing Coding Plans UI on /subscriptions behind the CODING_PLANS_PURCHASE_ENABLED server flag (hidden by default) so the feature can ship dark; backend routers, billing lifecycle cron, and admin operations remain active regardless of the flag.

Human Verification

  • Extensive end-to-end testing and validation done locally to confirm user and admin flows and confirm MiniMax credential integration works.

Reviewer Notes

Human Reviewer Flags

  • Introduces .specs/coding-plans.md and extends Subscription Center contract for first managed provider-plan pilot.
  • Uses ordinary personal MiniMax BYOK configuration for traffic while separating routing actions from Coding Plans billing and credential revocation ownership.
  • Chooses manual MiniMax credential revocation for initial release; admin workflow may reveal credential only for pending or failed revocation work.
  • Customer-facing purchase UI ships dark: the Coding Plans tab is hidden unless CODING_PLANS_PURCHASE_ENABLED=true, so merging does not expose Coding Plans to users until the flag is enabled in the target environment.

Code Reviewer Agent

Code Reviewer Notes
  • Review atomic purchase and renewal paths carefully: credit debit, inventory assignment, installed BYOK entry, subscription state, and term recording must remain all-or-nothing.
  • Review lifecycle cleanup boundaries: user-modified/replaced BYOK credentials must survive cancellation, failed renewal, administrative termination, and soft deletion.
  • Review sensitive-data handling around encrypted inventory, validation failures, admin credential reveal, and sanitized revocation failures.
  • Review new database migration and hourly billing cron together with tRPC ownership/admin authorization boundaries.

@jeanduplessis jeanduplessis marked this pull request as ready for review May 28, 2026 13:06
Comment thread apps/web/src/lib/coding-plans/index.ts Outdated
Comment thread apps/web/src/lib/coding-plans/billing-lifecycle-cron.ts
@kilo-code-bot
Copy link
Copy Markdown
Contributor

kilo-code-bot Bot commented May 28, 2026

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Executive Summary

Full review of all 60 files. All previously flagged issues are resolved. No new issues found in the updated diff (incremental history unavailable due to force-push; full diff reviewed against gh pr diff).

Resolved since previous review
  • billing-lifecycle-cron.ts:175 — Unbounded sweep query now bounded with BILLING_LIFECYCLE_SWEEP_LIMIT = 1_000 and stable orderBy. Resolved.
  • billing-lifecycle-cron.ts:249auto_top_up_triggered counter semantics documented with explicit comment. Resolved.
  • billing-lifecycle-cron.ts:263 — Added explainer comment for renewal orchestration logic. Resolved.
  • coding-plans/index.ts — Sequential live-API validation before DB insert replaced with pLimit(10)-bounded Promise.all. Resolved.
Other Observations (not blocking)

terminateCodingPlanImmediately TOCTOU on status: The subscription is read outside the transaction (filtering status IN ('active','past_due')), but the UPDATE inside the transaction has no status guard. In the narrow race where the cron cancels the subscription between the outer SELECT and the transaction, the admin UPDATE will overwrite cancellation_reason on an already-canceled record with 'administrative_termination'. BYOK cleanup is safe (deletion is guarded by management_source = 'coding_plan'). Low severity admin edge case.

Offset-based pagination: getBillingHistory uses an integer offset as cursor. Works at current scale; may produce inconsistent pages if rows are inserted between paginated requests.

Sweep backlog: If more than 1 000 rows become due simultaneously (e.g. after an outage), both sweeps will process at most 1 000 per cron run and the remainder will be picked up on the next invocation. This is correct and safe behavior, but may be worth noting in operational runbooks.

Migration trailing newline: packages/db/src/migrations/0153_perpetual_bromley.sql ends without a trailing newline. Cosmetically inconsistent with other migration files; not blocking.

Files Reviewed (60 files)
  • .specs/coding-plans.md
  • .specs/subscription-center.md
  • apps/web/public/logos/minimax.svg
  • apps/web/src/app/(app)/components/PersonalAppSidebar.tsx
  • apps/web/src/app/(app)/subscriptions/coding-plans/[subscriptionId]/page.tsx
  • apps/web/src/app/(app)/subscriptions/page.tsx
  • apps/web/src/app/admin/coding-plans/CodingPlansOperationsContent.tsx
  • apps/web/src/app/admin/coding-plans/page.tsx
  • apps/web/src/app/admin/components/AppSidebar.tsx
  • apps/web/src/app/api/cron/coding-plans-billing/route.ts
  • apps/web/src/components/organizations/byok/BYOKKeysManager.tsx
  • apps/web/src/components/profile/kilo-pass/KiloPassSubscribeCard.tsx
  • apps/web/src/components/profile/kilo-pass/KiloPassTierCard.tsx
  • apps/web/src/components/subscriptions/AvailableProductCard.tsx
  • apps/web/src/components/subscriptions/BillingHistoryTable.tsx
  • apps/web/src/components/subscriptions/DetailPageHeader.tsx
  • apps/web/src/components/subscriptions/PersonalSubscriptions.tsx
  • apps/web/src/components/subscriptions/SubscriptionCard.tsx
  • apps/web/src/components/subscriptions/SubscriptionGroup.tsx
  • apps/web/src/components/subscriptions/SubscriptionStatusBadge.tsx
  • apps/web/src/components/subscriptions/TerminalToggle.tsx
  • apps/web/src/components/subscriptions/coding-plans/CodingPlanDetail.tsx
  • apps/web/src/components/subscriptions/coding-plans/CodingPlansGroup.tsx
  • apps/web/src/components/subscriptions/coding-plans/MiniMaxPlanIcon.tsx
  • apps/web/src/components/subscriptions/helpers.test.ts
  • apps/web/src/components/subscriptions/helpers.ts
  • apps/web/src/components/subscriptions/kilo-pass/KiloPassDetail.tsx
  • apps/web/src/components/subscriptions/kilo-pass/KiloPassGroup.tsx
  • apps/web/src/components/subscriptions/kiloclaw/KiloClawDetail.tsx
  • apps/web/src/components/subscriptions/kiloclaw/KiloClawGroup.tsx
  • apps/web/src/components/subscriptions/kiloclaw/KiloClawSubscribeCard.tsx
  • apps/web/src/components/ui/alert.tsx
  • apps/web/src/lib/ai-gateway/byok/coding-plan-entitlement.test.ts
  • apps/web/src/lib/ai-gateway/byok/index.ts
  • apps/web/src/lib/ai-gateway/byok/types.ts
  • apps/web/src/lib/coding-plans/billing-lifecycle-cron.test.ts
  • apps/web/src/lib/coding-plans/billing-lifecycle-cron.ts — bounded sweep limit, clarified auto_top_up_triggered semantics, renewal orchestration comment
  • apps/web/src/lib/coding-plans/index.ts — p-limit bounded validation, atomic purchase/lifecycle flows
  • apps/web/src/lib/coding-plans/index.test.ts
  • apps/web/src/lib/coding-plans/inventory-validation.ts
  • apps/web/src/lib/coding-plans/inventory-validation.test.ts
  • apps/web/src/lib/coding-plans/pricing.ts
  • apps/web/src/lib/coding-plans/revocation.ts
  • apps/web/src/lib/config.server.ts
  • apps/web/src/lib/constants.ts
  • apps/web/src/lib/user/index.test.ts
  • apps/web/src/lib/user/index.ts — GDPR soft-delete for coding plan data
  • apps/web/src/routers/byok-router.test.ts
  • apps/web/src/routers/byok-router.ts
  • apps/web/src/routers/coding-plans-router.test.ts
  • apps/web/src/routers/coding-plans-router.ts
  • apps/web/src/routers/root-router.ts
  • apps/web/vercel.json
  • dev/seed/coding-plans/available-credentials.ts
  • dev/seed/coding-plans/occupied-minimax-byok.ts
  • packages/db/src/migrations/0153_perpetual_bromley.sql
  • packages/db/src/migrations/meta/0153_snapshot.json
  • packages/db/src/migrations/meta/_journal.json
  • packages/db/src/schema-types.ts
  • packages/db/src/schema.ts

Reviewed by claude-4.6-sonnet-20260217 · 5,964,659 tokens

Review guidance: REVIEW.md from base branch main

Comment thread apps/web/src/lib/coding-plans/index.ts Outdated
Comment thread apps/web/src/lib/coding-plans/billing-lifecycle-cron.ts
Comment thread apps/web/src/lib/coding-plans/billing-lifecycle-cron.ts
- Add upstream_plan_id to the coding plan key inventory (migration 0148)
  and parse managed MiniMax credentials in <api key>::<plan id> format.
- Clear encrypted_api_key when a credential enters revocation_pending,
  including on GDPR soft-delete, so revoked keys are not retained.
- Gate the Coding Plans tab on /subscriptions behind
  CODING_PLANS_PURCHASE_ENABLED; hidden by default for a dark launch.
- Update billing lifecycle, revocation, inventory validation, the
  coding-plans router, and admin operations surfaces accordingly.
The counter intentionally measures triggered auto-top-up attempts (not
successful charges), matching spec rule 5.5. Document that a best-effort
maybePerformAutoTopUp failure still counts as a triggered attempt.
Replace the serial validation loop in uploadKeysToInventory with a
p-limit(10) fan-out so large inventory uploads finish well within the
request budget without firing one unbounded burst at the MiniMax API.
Behavior is unchanged: malformed entries fail before validation, any
invalid credential aborts the upload, and nothing is inserted on failure.
PLAN.md was a development planning artifact and does not belong in the
repo root (the designated location for plans is .plans/). Drop it so it
is not part of this PR's changes.
This duplicated glob with a doubled dev/dev segment was auto-written into
tsconfig.json by the Next dev server and committed by mistake. It points
at a nonexistent directory and duplicates the existing .next/dev/types
entry, so removing it restores tsconfig to match main.
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.

3 participants