fix(billing): return default free-plan stub when no subscription exists

Previously GET /api/v1/billing/subscription threw 404 for tenants with no
subscription, causing React Query error state on the Plans and Overview pages.
Now returns a graceful default response so the UI renders without errors.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
hailin 2026-03-07 06:09:32 -08:00
parent b5d1f11104
commit 2773b6265c
1 changed files with 16 additions and 2 deletions

View File

@ -1,5 +1,5 @@
import {
Controller, Get, Post, Body, Headers, HttpCode, HttpStatus, NotFoundException,
Controller, Get, Post, Body, Headers, HttpCode, HttpStatus,
} from '@nestjs/common';
import { SubscriptionRepository } from '../../../infrastructure/repositories/subscription.repository';
import { PlanRepository } from '../../../infrastructure/repositories/plan.repository';
@ -21,7 +21,21 @@ export class SubscriptionController {
@Get('subscription')
async getSubscription(@Headers('x-tenant-id') tenantId: string) {
const sub = await this.subscriptionRepo.findByTenantId(tenantId);
if (!sub) throw new NotFoundException('No active subscription');
if (!sub) {
// No subscription yet — return a default free-plan stub so the UI renders gracefully
const freePlan = await this.planRepo.findByName('free');
return {
id: null,
status: 'none',
plan: freePlan ? { name: freePlan.name, displayName: freePlan.displayName } : { name: 'free', displayName: 'Free' },
nextPlan: null,
currentPeriodStart: null,
currentPeriodEnd: null,
trialEndsAt: null,
cancelAtPeriodEnd: false,
cancelledAt: null,
};
}
const plan = await this.planRepo.findById(sub.planId);
const nextPlan = sub.nextPlanId ? await this.planRepo.findById(sub.nextPlanId) : null;