/** * Subscription Plans Controller * * REST API endpoints for subscription plan management */ import { Router, Request, Response, NextFunction } from 'express'; import { DataSource } from 'typeorm'; import { SubscriptionPlansService } from '../services'; import { CreateSubscriptionPlanDto, UpdateSubscriptionPlanDto } from '../dto'; export class SubscriptionPlansController { public router: Router; private service: SubscriptionPlansService; constructor(dataSource: DataSource) { this.router = Router(); this.service = new SubscriptionPlansService(dataSource); this.initializeRoutes(); } private initializeRoutes(): void { // Public routes this.router.get('/public', this.getPublicPlans.bind(this)); this.router.get('/:id/compare/:otherId', this.comparePlans.bind(this)); // Protected routes (require admin) this.router.get('/', this.getAll.bind(this)); this.router.get('/:id', this.getById.bind(this)); this.router.post('/', this.create.bind(this)); this.router.put('/:id', this.update.bind(this)); this.router.delete('/:id', this.delete.bind(this)); this.router.patch('/:id/activate', this.activate.bind(this)); this.router.patch('/:id/deactivate', this.deactivate.bind(this)); } /** * GET /subscription-plans/public * Get public plans for pricing page */ private async getPublicPlans(req: Request, res: Response, next: NextFunction): Promise { try { const plans = await this.service.findPublicPlans(); res.json({ data: plans }); } catch (error) { next(error); } } /** * GET /subscription-plans * Get all plans (admin only) */ private async getAll(req: Request, res: Response, next: NextFunction): Promise { try { const { isActive, isPublic, planType } = req.query; const plans = await this.service.findAll({ isActive: isActive !== undefined ? isActive === 'true' : undefined, isPublic: isPublic !== undefined ? isPublic === 'true' : undefined, planType: planType as any, }); res.json({ data: plans }); } catch (error) { next(error); } } /** * GET /subscription-plans/:id * Get plan by ID */ private async getById(req: Request, res: Response, next: NextFunction): Promise { try { const plan = await this.service.findById(req.params.id); if (!plan) { res.status(404).json({ error: 'Plan not found' }); return; } res.json({ data: plan }); } catch (error) { next(error); } } /** * POST /subscription-plans * Create new plan */ private async create(req: Request, res: Response, next: NextFunction): Promise { try { const dto: CreateSubscriptionPlanDto = req.body; const plan = await this.service.create(dto); res.status(201).json({ data: plan }); } catch (error) { next(error); } } /** * PUT /subscription-plans/:id * Update plan */ private async update(req: Request, res: Response, next: NextFunction): Promise { try { const dto: UpdateSubscriptionPlanDto = req.body; const plan = await this.service.update(req.params.id, dto); res.json({ data: plan }); } catch (error) { next(error); } } /** * DELETE /subscription-plans/:id * Delete plan (soft delete) */ private async delete(req: Request, res: Response, next: NextFunction): Promise { try { await this.service.delete(req.params.id); res.status(204).send(); } catch (error) { next(error); } } /** * PATCH /subscription-plans/:id/activate * Activate plan */ private async activate(req: Request, res: Response, next: NextFunction): Promise { try { const plan = await this.service.setActive(req.params.id, true); res.json({ data: plan }); } catch (error) { next(error); } } /** * PATCH /subscription-plans/:id/deactivate * Deactivate plan */ private async deactivate(req: Request, res: Response, next: NextFunction): Promise { try { const plan = await this.service.setActive(req.params.id, false); res.json({ data: plan }); } catch (error) { next(error); } } /** * GET /subscription-plans/:id/compare/:otherId * Compare two plans */ private async comparePlans(req: Request, res: Response, next: NextFunction): Promise { try { const comparison = await this.service.comparePlans(req.params.id, req.params.otherId); res.json({ data: comparison }); } catch (error) { next(error); } } }