import { Body,Controller,Get,Param,Post,Req,UseGuards } from '@nestjs/common';
import { AuthGuard } from '../../../common/auth/auth.guard';
import { OrganizationContextGuard,type TenantScopedRequest } from '../../../common/auth/organization-context.guard';
import { PermissionGuard } from '../../../common/auth/permission.guard';
import { RequirePermissions } from '../../../common/auth/permissions.decorator';
import { RequireStepUp } from '../../../common/auth/step-up.decorator';
import { StepUpGuard } from '../../../common/auth/step-up.guard';
import { PlanAdminService } from '../application/plan-admin.service';
import { EntitlementProjectionService } from '../application/entitlement-projection.service';
import { ZodValidationPipe } from '../../../common/validation/zod-validation.pipe';
import { commercialPlanCreateSchema,commercialPlanVersionSchema,entitlementOverrideSchema } from '../../../common/validation/critical-write.schemas';
import type { z } from 'zod';
@Controller('/commercial/admin')
@UseGuards(AuthGuard,OrganizationContextGuard,PermissionGuard)
export class CommercialAdminController {
constructor(
private readonly plans:PlanAdminService,
private readonly projections:EntitlementProjectionService,
) {}
@Get('/plans')
@RequirePermissions('platform.plans.manage')
list(){return this.plans.list();}
@Post('/plans')
@RequirePermissions('platform.plans.manage')
create(@Body(new ZodValidationPipe(commercialPlanCreateSchema)) body:z.infer<typeof commercialPlanCreateSchema>){return this.plans.createPlan(body);}
@Post('/plans/:id/versions')
@RequirePermissions('platform.plans.manage')
version(@Param('id') planId:string,@Body(new ZodValidationPipe(commercialPlanVersionSchema)) body:z.infer<typeof commercialPlanVersionSchema>){
return this.plans.createVersion({planId,...body});
}
@Post('/plan-versions/:id/validate')
@RequirePermissions('platform.plans.manage')
validate(@Param('id') id:string){return this.plans.validateVersion(id);}
@Post('/plan-versions/:id/activate')
@RequirePermissions('platform.plans.manage')
activate(@Param('id') id:string){return this.plans.activateVersion(id);}
@Post('/entitlement-overrides')
@RequirePermissions('platform.entitlements.override')
@RequireStepUp('commercial.entitlement_override')
@UseGuards(StepUpGuard)
async override(@Req() req:TenantScopedRequest,@Body(new ZodValidationPipe(entitlementOverrideSchema)) body:z.infer<typeof entitlementOverrideSchema>){
const result=await this.plans.override({
organizationId:req.organizationId!,userId:req.auth?.userId,...body,
});
await this.projections.rebuild(req.organizationId!);
return result;
}
@Post('/entitlement-overrides/:id/revoke')
@RequirePermissions('platform.entitlements.override')
@RequireStepUp('commercial.entitlement_override')
@UseGuards(StepUpGuard)
async revoke(@Req() req:TenantScopedRequest,@Param('id') id:string){
const result=await this.plans.revokeOverride({organizationId:req.organizationId!,overrideId:id});
await this.projections.rebuild(req.organizationId!);
return result;
}
}
