apps/recallassess/recallassess-api/src/api/admin/subscription/subscription.controller.ts
api/admin/subscription
Methods |
|
| Async add |
add()
|
Decorators :
@Post()
|
|
Returns :
Promise<never>
|
| delete |
delete()
|
Decorators :
@Delete(':id')
|
|
Returns :
never
|
| Private normalizeNextBillingDate | ||||||
normalizeNextBillingDate(input: unknown)
|
||||||
|
Parameters :
Returns :
string
|
| Async save |
save()
|
Decorators :
@Put(':id')
|
|
Returns :
Promise<never>
|
| Async syncStripeLive | ||||||
syncStripeLive(id: number)
|
||||||
Decorators :
@Post(':id/sync-stripe-live')
|
||||||
|
TEST ONLY: Allow toggling subscription expired/active from admin UI in non-production. Admin edit is otherwise blocked (PUT is METHOD_NOT_ALLOWED).
Parameters :
Returns :
unknown
|
| Async updateAutoRenew | |||||||||
updateAutoRenew(id: number, body: literal type)
|
|||||||||
Decorators :
@Post(':id/auto-renew')
|
|||||||||
|
Parameters :
Returns :
unknown
|
| Async updateNextBillingDate | |||||||||
updateNextBillingDate(id: number, body: literal type)
|
|||||||||
Decorators :
@Post(':id/next-billing-date')
|
|||||||||
|
Parameters :
Returns :
Promise<literal type>
|
import { BaseController } from "@bish-nest/core/controller/base.controller";
import {
BadRequestException,
Body,
Controller,
Delete,
HttpCode,
HttpStatus,
MethodNotAllowedException,
Param,
ParseIntPipe,
Post,
Put,
} from "@nestjs/common";
import { SubscriptionService } from "./subscription.service";
@Controller("api/admin/subscription")
export class SubscriptionController extends BaseController<SubscriptionService> {
private normalizeNextBillingDate(input: unknown): string {
if (input instanceof Date && !Number.isNaN(input.getTime())) {
return input.toISOString();
}
if (typeof input === "string") {
const v = input.trim();
if (v.length === 0) {
throw new BadRequestException("next_billing_date is required");
}
if (/^\d{4}-\d{2}-\d{2}$/.test(v)) {
return `${v}T00:00:00.000Z`;
}
const parsed = new Date(v);
if (!Number.isNaN(parsed.getTime())) {
return parsed.toISOString();
}
}
throw new BadRequestException("next_billing_date must be a valid date or datetime");
}
constructor(subscriptionService: SubscriptionService) {
super(subscriptionService);
}
/**
* TEST ONLY: Allow toggling subscription expired/active from admin UI in non-production.
* Admin edit is otherwise blocked (PUT is METHOD_NOT_ALLOWED).
*/
@Post(":id/sync-stripe-live")
async syncStripeLive(@Param("id", ParseIntPipe) id: number) {
return this.entityService.syncStripeSubscriptionFieldsFromLive(id);
}
@Post(":id/next-billing-date")
@HttpCode(HttpStatus.OK)
async updateNextBillingDate(
@Param("id", ParseIntPipe) id: number,
@Body() body: { next_billing_date?: unknown },
): Promise<{ success: boolean; message: string; next_billing_date: string }> {
const nextBillingDate = this.normalizeNextBillingDate(body?.next_billing_date);
return this.entityService.updateNextBillingDateFromAdmin(id, nextBillingDate);
}
@Post(":id/auto-renew")
@HttpCode(HttpStatus.OK)
async updateAutoRenew(
@Param("id", ParseIntPipe) id: number,
@Body() body: { enabled?: unknown },
) {
if (typeof body?.enabled !== "boolean") {
throw new BadRequestException("enabled must be a boolean");
}
return this.entityService.updateAutoRenewFromAdmin(id, body.enabled);
}
// Override add method - subscriptions are read-only in admin panel
@Post()
@HttpCode(HttpStatus.METHOD_NOT_ALLOWED)
async add(): Promise<never> {
throw new MethodNotAllowedException("Subscription creation is not allowed through the admin panel");
}
// Override save method - subscriptions are read-only in admin panel
@Put(":id")
@HttpCode(HttpStatus.METHOD_NOT_ALLOWED)
async save(): Promise<never> {
throw new MethodNotAllowedException("Subscription editing is not allowed through the admin panel");
}
// Override delete method - subscriptions are read-only in admin panel
@Delete(":id")
@HttpCode(HttpStatus.METHOD_NOT_ALLOWED)
delete(): never {
throw new MethodNotAllowedException("Subscription deletion is not allowed through the admin panel");
}
}