feat: Complete Z.CRM system with all 6 modules
✨ Features: - Complete authentication system with JWT - Dashboard with all 6 modules visible - Contact Management module (Salesforce-style) - CRM & Sales Pipeline module (Pipedrive-style) - Inventory & Assets module (SAP-style) - Tasks & Projects module (Jira/Asana-style) - HR Management module (BambooHR-style) - Marketing Management module (HubSpot-style) - Admin Panel with user management and role matrix - World-class UI/UX with RTL Arabic support - Cairo font (headings) + Readex Pro font (body) - Sample data for all modules - Protected routes and authentication flow - Backend API with Prisma + PostgreSQL - Comprehensive documentation 🎨 Design: - Color-coded modules - Professional data tables - Stats cards with metrics - Progress bars and status badges - Search and filters - Responsive layout 📊 Tech Stack: - Frontend: Next.js 14, TypeScript, Tailwind CSS - Backend: Node.js, Express, Prisma - Database: PostgreSQL - Auth: JWT with bcrypt 🚀 Production-ready frontend with all features accessible
This commit is contained in:
157
backend/src/modules/crm/crm.routes.ts
Normal file
157
backend/src/modules/crm/crm.routes.ts
Normal file
@@ -0,0 +1,157 @@
|
||||
import { Router } from 'express';
|
||||
import { body, param } from 'express-validator';
|
||||
import { dealsController, quotesController } from './crm.controller';
|
||||
import { authenticate, authorize } from '../../shared/middleware/auth';
|
||||
import { validate } from '../../shared/middleware/validation';
|
||||
|
||||
const router = Router();
|
||||
|
||||
// All routes require authentication
|
||||
router.use(authenticate);
|
||||
|
||||
// ============= DEALS =============
|
||||
|
||||
// Get all deals
|
||||
router.get(
|
||||
'/deals',
|
||||
authorize('crm', 'deals', 'read'),
|
||||
dealsController.findAll
|
||||
);
|
||||
|
||||
// Get deal by ID
|
||||
router.get(
|
||||
'/deals/:id',
|
||||
authorize('crm', 'deals', 'read'),
|
||||
param('id').isUUID(),
|
||||
validate,
|
||||
dealsController.findById
|
||||
);
|
||||
|
||||
// Get deal history
|
||||
router.get(
|
||||
'/deals/:id/history',
|
||||
authorize('crm', 'deals', 'read'),
|
||||
param('id').isUUID(),
|
||||
validate,
|
||||
dealsController.getHistory
|
||||
);
|
||||
|
||||
// Create deal
|
||||
router.post(
|
||||
'/deals',
|
||||
authorize('crm', 'deals', 'create'),
|
||||
[
|
||||
body('name').notEmpty().trim(),
|
||||
body('contactId').isUUID(),
|
||||
body('structure').isIn(['B2B', 'B2C', 'B2G', 'PARTNERSHIP']),
|
||||
body('pipelineId').isUUID(),
|
||||
body('stage').notEmpty(),
|
||||
body('estimatedValue').isNumeric(),
|
||||
validate,
|
||||
],
|
||||
dealsController.create
|
||||
);
|
||||
|
||||
// Update deal
|
||||
router.put(
|
||||
'/deals/:id',
|
||||
authorize('crm', 'deals', 'update'),
|
||||
param('id').isUUID(),
|
||||
validate,
|
||||
dealsController.update
|
||||
);
|
||||
|
||||
// Update deal stage
|
||||
router.patch(
|
||||
'/deals/:id/stage',
|
||||
authorize('crm', 'deals', 'update'),
|
||||
[
|
||||
param('id').isUUID(),
|
||||
body('stage').notEmpty(),
|
||||
validate,
|
||||
],
|
||||
dealsController.updateStage
|
||||
);
|
||||
|
||||
// Mark deal as won
|
||||
router.post(
|
||||
'/deals/:id/win',
|
||||
authorize('crm', 'deals', 'update'),
|
||||
[
|
||||
param('id').isUUID(),
|
||||
body('actualValue').isNumeric(),
|
||||
body('wonReason').notEmpty(),
|
||||
validate,
|
||||
],
|
||||
dealsController.win
|
||||
);
|
||||
|
||||
// Mark deal as lost
|
||||
router.post(
|
||||
'/deals/:id/lose',
|
||||
authorize('crm', 'deals', 'update'),
|
||||
[
|
||||
param('id').isUUID(),
|
||||
body('lostReason').notEmpty(),
|
||||
validate,
|
||||
],
|
||||
dealsController.lose
|
||||
);
|
||||
|
||||
// ============= QUOTES =============
|
||||
|
||||
// Get quotes for a deal
|
||||
router.get(
|
||||
'/deals/:dealId/quotes',
|
||||
authorize('crm', 'quotes', 'read'),
|
||||
param('dealId').isUUID(),
|
||||
validate,
|
||||
quotesController.findByDeal
|
||||
);
|
||||
|
||||
// Get quote by ID
|
||||
router.get(
|
||||
'/quotes/:id',
|
||||
authorize('crm', 'quotes', 'read'),
|
||||
param('id').isUUID(),
|
||||
validate,
|
||||
quotesController.findById
|
||||
);
|
||||
|
||||
// Create quote
|
||||
router.post(
|
||||
'/quotes',
|
||||
authorize('crm', 'quotes', 'create'),
|
||||
[
|
||||
body('dealId').isUUID(),
|
||||
body('items').isArray(),
|
||||
body('subtotal').isNumeric(),
|
||||
body('taxRate').isNumeric(),
|
||||
body('taxAmount').isNumeric(),
|
||||
body('total').isNumeric(),
|
||||
body('validUntil').isISO8601(),
|
||||
validate,
|
||||
],
|
||||
quotesController.create
|
||||
);
|
||||
|
||||
// Approve quote
|
||||
router.post(
|
||||
'/quotes/:id/approve',
|
||||
authorize('crm', 'quotes', 'approve'),
|
||||
param('id').isUUID(),
|
||||
validate,
|
||||
quotesController.approve
|
||||
);
|
||||
|
||||
// Send quote
|
||||
router.post(
|
||||
'/quotes/:id/send',
|
||||
authorize('crm', 'quotes', 'update'),
|
||||
param('id').isUUID(),
|
||||
validate,
|
||||
quotesController.send
|
||||
);
|
||||
|
||||
export default router;
|
||||
|
||||
Reference in New Issue
Block a user