apps/recallassess/recallassess-api/src/api/admin/company/company.controller.ts
api/admin/company
Methods |
|
| Async add |
add()
|
Decorators :
@Post()
|
|
Returns :
Promise<never>
|
| getStripeConnection |
getStripeConnection()
|
Decorators :
@Get('stripe-connection')
|
|
Static route must be registered before
Returns :
CompanyStripeConnectionDto
|
| Async getStripeSubscription | ||||||
getStripeSubscription(id: number)
|
||||||
Decorators :
@Get(':id/stripe-subscription')
|
||||||
|
Parameters :
Returns :
Promise<CompanyStripeSubscriptionDto>
|
| Private normalizeFromDate | ||||||
normalizeFromDate(input: unknown)
|
||||||
|
Parameters :
Returns :
string
|
| Private normalizeNextBillingDate | ||||||
normalizeNextBillingDate(input: unknown)
|
||||||
|
Parameters :
Returns :
string
|
| Async postStripeCreateSubscription | ||||||
postStripeCreateSubscription(id: number)
|
||||||
Decorators :
@Post(':id/stripe-create-subscription')
|
||||||
|
Parameters :
Returns :
Promise<literal type>
|
| Async postStripeNextBillingDate | |||||||||
postStripeNextBillingDate(id: number, body: CompanyNextBillingDateDto | literal type)
|
|||||||||
Decorators :
@Post(':id/stripe-next-billing-date')
|
|||||||||
|
Parameters :
Returns :
Promise<literal type>
|
| Async postStripeReactivateSubscription | |||||||||
postStripeReactivateSubscription(id: number, body: CompanyReactivateSubscriptionDto | literal type)
|
|||||||||
Decorators :
@Post(':id/stripe-reactivate-subscription')
|
|||||||||
|
Parameters :
Returns :
Promise<literal type>
|
| Async postStripeReactivateSubscriptionPreview | |||||||||
postStripeReactivateSubscriptionPreview(id: number, body: CompanyReactivateSubscriptionDto | literal type)
|
|||||||||
Decorators :
@Post(':id/stripe-reactivate-subscription-preview')
|
|||||||||
|
Parameters :
Returns :
Promise<literal type>
|
| Async postStripeSyncInvoices | ||||||
postStripeSyncInvoices(id: number)
|
||||||
Decorators :
@Post(':id/stripe-sync-invoices')
|
||||||
|
Parameters :
Returns :
Promise<literal type>
|
import { BaseController } from "@bish-nest/core/controller/base.controller";
import {
Body,
BadRequestException,
Controller,
Get,
HttpCode,
HttpStatus,
MethodNotAllowedException,
Param,
ParseIntPipe,
Post,
} from "@nestjs/common";
import { CompanyReactivateSubscriptionDto } from "./dto/company-reactivate-subscription.dto";
import { CompanyNextBillingDateDto } from "./dto/company-next-billing-date.dto";
import { CompanyStripeConnectionDto } from "./dto/company-stripe-connection.dto";
import { CompanyStripeSubscriptionDto } from "./dto/company-stripe-subscription.dto";
import { CompanyService } from "./services/company.service";
@Controller("api/admin/company")
export class CompanyController extends BaseController<CompanyService> {
private normalizeFromDate(input: unknown): string {
if (input instanceof Date && !Number.isNaN(input.getTime())) {
return input.toISOString().slice(0, 10);
}
if (typeof input === "string") {
const v = input.trim();
if (v.length === 0) {
throw new BadRequestException("from_date is required");
}
if (/^\d{4}-\d{2}-\d{2}$/.test(v)) {
return v;
}
const parsed = new Date(v);
if (!Number.isNaN(parsed.getTime())) {
return parsed.toISOString().slice(0, 10);
}
}
throw new BadRequestException("from_date must be in YYYY-MM-DD format");
}
private normalizeNextBillingDate(input: unknown): string {
if (input instanceof Date && !Number.isNaN(input.getTime())) {
return input.toISOString().slice(0, 10);
}
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;
}
const parsed = new Date(v);
if (!Number.isNaN(parsed.getTime())) {
return parsed.toISOString().slice(0, 10);
}
}
throw new BadRequestException("next_billing_date must be in YYYY-MM-DD format");
}
constructor(private readonly companyService: CompanyService) {
super(companyService);
}
/** Static route must be registered before `:id/...` so "stripe-connection" is not parsed as an id. */
@Get("stripe-connection")
getStripeConnection(): CompanyStripeConnectionDto {
return this.companyService.getStripeConnectionDiagnostics();
}
@Get(":id/stripe-subscription")
async getStripeSubscription(
@Param("id", ParseIntPipe) id: number,
): Promise<CompanyStripeSubscriptionDto> {
return this.companyService.getStripeSubscriptionSnapshot(id);
}
@Post(":id/stripe-create-subscription")
@HttpCode(HttpStatus.OK)
async postStripeCreateSubscription(
@Param("id", ParseIntPipe) id: number,
): Promise<{ success: boolean; message: string }> {
return this.companyService.runAdminCreateStripeSubscription(id);
}
@Post(":id/stripe-reactivate-subscription")
@HttpCode(HttpStatus.OK)
async postStripeReactivateSubscription(
@Param("id", ParseIntPipe) id: number,
@Body() body: CompanyReactivateSubscriptionDto | { from_date?: unknown },
): Promise<{ success: boolean; message: string }> {
const fromDate = this.normalizeFromDate((body as { from_date?: unknown })?.from_date);
return this.companyService.runAdminReactivateStripeSubscription(id, fromDate);
}
@Post(":id/stripe-reactivate-subscription-preview")
@HttpCode(HttpStatus.OK)
async postStripeReactivateSubscriptionPreview(
@Param("id", ParseIntPipe) id: number,
@Body() body: CompanyReactivateSubscriptionDto | { from_date?: unknown },
): Promise<{
currency: "USD";
base_amount: number;
processing_fee: number;
vat_fee: number;
immediate_charge_amount: number;
next_recurring_charge_amount: number;
vip_offer_applied: boolean;
vip_offer_summary: string | null;
billing_cycle: "QUARTERLY" | "HALF_YEARLY" | "ANNUAL";
from_date: string;
end_date: string;
next_stripe_billing_date: string;
}> {
const fromDate = this.normalizeFromDate((body as { from_date?: unknown })?.from_date);
return this.companyService.previewAdminReactivateStripeSubscription(id, fromDate);
}
@Post(":id/stripe-next-billing-date")
@HttpCode(HttpStatus.OK)
async postStripeNextBillingDate(
@Param("id", ParseIntPipe) id: number,
@Body() body: CompanyNextBillingDateDto | { next_billing_date?: unknown },
): Promise<{ success: boolean; message: string; next_billing_date: string }> {
const nextBillingDate = this.normalizeNextBillingDate(
(body as { next_billing_date?: unknown })?.next_billing_date,
);
return this.companyService.updateAdminStripeNextBillingDate(id, nextBillingDate);
}
@Post(":id/stripe-sync-invoices")
@HttpCode(HttpStatus.OK)
async postStripeSyncInvoices(
@Param("id", ParseIntPipe) id: number,
): Promise<{ success: boolean; message: string; invoices_created: number; refunds_created: number }> {
return this.companyService.syncStripeInvoicesAndRefunds(id);
}
// Override add method - companies are created via signup, not through admin panel
@Post()
@HttpCode(HttpStatus.METHOD_NOT_ALLOWED)
async add(): Promise<never> {
throw new MethodNotAllowedException("Company creation is not allowed through the admin panel. Companies are created via the signup process.");
}
}