- Add modules: ai, audit, billing-usage, biometrics, branches, dashboard, feature-flags, invoices, mcp, mobile, notifications, partners, payment-terminals, products, profiles, purchases, reports, sales, storage, warehouses, webhooks, whatsapp - Add controllers, DTOs, entities, and services for each module - Add shared services and utilities Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
169 lines
4.5 KiB
TypeScript
169 lines
4.5 KiB
TypeScript
/**
|
|
* 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<void> {
|
|
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<void> {
|
|
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<void> {
|
|
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<void> {
|
|
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<void> {
|
|
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<void> {
|
|
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<void> {
|
|
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<void> {
|
|
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<void> {
|
|
try {
|
|
const comparison = await this.service.comparePlans(req.params.id, req.params.otherId);
|
|
res.json({ data: comparison });
|
|
} catch (error) {
|
|
next(error);
|
|
}
|
|
}
|
|
}
|