# Royal Enfield Dealership Onboarding System - Backend Documentation ## ๐Ÿ“‹ Overview This is a comprehensive Node.js + Express backend for the Royal Enfield Dealership Onboarding System. It handles a multi-stage workflow with 13 different user roles, managing dealer applications, resignations, constitutional changes, relocations, and full F&F settlement processes. ## ๐Ÿ—๏ธ Architecture **Tech Stack:** - **Runtime:** Node.js (v18+) - **Framework:** Express.js - **Database:** PostgreSQL (with Sequelize ORM) - **Authentication:** JWT (JSON Web Tokens) - **File Storage:** Multer + Local/Cloud storage - **Email:** Nodemailer - **Validation:** express-validator - **Security:** bcryptjs, helmet, cors ## ๐Ÿ“ Project Structure ``` backend/ โ”œโ”€โ”€ back.md # This comprehensive documentation file โ”œโ”€โ”€ package.json # Dependencies and scripts โ”œโ”€โ”€ .env.example # Environment variables template โ”œโ”€โ”€ server.js # Main entry point โ”œโ”€โ”€ config/ โ”‚ โ”œโ”€โ”€ database.js # Database configuration โ”‚ โ”œโ”€โ”€ email.js # Email service configuration โ”‚ โ””โ”€โ”€ constants.js # System constants (roles, statuses, stages) โ”œโ”€โ”€ models/ โ”‚ โ”œโ”€โ”€ index.js # Sequelize model loader โ”‚ โ”œโ”€โ”€ User.js # User model โ”‚ โ”œโ”€โ”€ Application.js # Dealer application model โ”‚ โ”œโ”€โ”€ Resignation.js # Resignation request model โ”‚ โ”œโ”€โ”€ ConstitutionalChange.js # Constitutional change model โ”‚ โ”œโ”€โ”€ RelocationRequest.js # Relocation request model โ”‚ โ”œโ”€โ”€ Outlet.js # Dealership/Studio outlet model โ”‚ โ”œโ”€โ”€ Worknote.js # Discussion worknotes model โ”‚ โ”œโ”€โ”€ Document.js # Document uploads model โ”‚ โ”œโ”€โ”€ AuditLog.js # Audit trail model โ”‚ โ”œโ”€โ”€ FinancePayment.js # Finance payment tracking โ”‚ โ”œโ”€โ”€ FnF.js # Full & Final settlement โ”‚ โ”œโ”€โ”€ Region.js # Regional hierarchy model โ”‚ โ””โ”€โ”€ Zone.js # Zone model โ”œโ”€โ”€ controllers/ โ”‚ โ”œโ”€โ”€ authController.js # Login, logout, token refresh โ”‚ โ”œโ”€โ”€ userController.js # User management โ”‚ โ”œโ”€โ”€ applicationController.js # Dealer applications โ”‚ โ”œโ”€โ”€ resignationController.js # Resignation workflow โ”‚ โ”œโ”€โ”€ constitutionalController.js # Constitutional changes โ”‚ โ”œโ”€โ”€ relocationController.js # Relocation requests โ”‚ โ”œโ”€โ”€ outletController.js # Outlet management โ”‚ โ”œโ”€โ”€ worknoteController.js # Discussion platform โ”‚ โ”œโ”€โ”€ financeController.js # Finance operations โ”‚ โ”œโ”€โ”€ masterController.js # Master configuration โ”‚ โ””โ”€โ”€ dashboardController.js # Dashboard statistics โ”œโ”€โ”€ routes/ โ”‚ โ”œโ”€โ”€ auth.js # Authentication routes โ”‚ โ”œโ”€โ”€ users.js # User routes โ”‚ โ”œโ”€โ”€ applications.js # Application routes โ”‚ โ”œโ”€โ”€ resignations.js # Resignation routes โ”‚ โ”œโ”€โ”€ constitutional.js # Constitutional change routes โ”‚ โ”œโ”€โ”€ relocations.js # Relocation routes โ”‚ โ”œโ”€โ”€ outlets.js # Outlet routes โ”‚ โ”œโ”€โ”€ worknotes.js # Worknote routes โ”‚ โ”œโ”€โ”€ finance.js # Finance routes โ”‚ โ”œโ”€โ”€ master.js # Master configuration routes โ”‚ โ””โ”€โ”€ dashboard.js # Dashboard routes โ”œโ”€โ”€ middleware/ โ”‚ โ”œโ”€โ”€ auth.js # JWT verification middleware โ”‚ โ”œโ”€โ”€ roleCheck.js # Role-based access control โ”‚ โ”œโ”€โ”€ upload.js # File upload middleware โ”‚ โ”œโ”€โ”€ validation.js # Input validation โ”‚ โ””โ”€โ”€ errorHandler.js # Global error handler โ”œโ”€โ”€ utils/ โ”‚ โ”œโ”€โ”€ emailTemplates.js # Email HTML templates โ”‚ โ”œโ”€โ”€ emailService.js # Email sending utilities โ”‚ โ”œโ”€โ”€ logger.js # Winston logger โ”‚ โ””โ”€โ”€ helpers.js # Helper functions โ””โ”€โ”€ migrations/ # Database migrations โ””โ”€โ”€ initial-setup.js # Initial database schema ``` ## ๐Ÿ‘ฅ User Roles & Permissions The system supports 13 distinct roles with hierarchical permissions: 1. **DD (Dealer Development)** - Creates applications, initial review 2. **DD-ZM (DD Zone Manager)** - Zone-level approvals 3. **RBM (Regional Business Manager)** - Regional approvals 4. **ZBH (Zonal Business Head)** - Zonal head approvals 5. **DD Lead** - Organization-wide DD leadership (singular position) 6. **DD Head** - Head of DD department (singular position) 7. **NBH (National Business Head)** - National head (singular position) 8. **DD Admin** - Administrative operations 9. **Legal Admin** - Legal clearance and document verification 10. **Super Admin** - Full system access 11. **DD AM (Area Manager)** - Area-level management 12. **Finance** - Payment tracking and financial approvals 13. **Dealer** - Dealer portal access (resignation, relocation, constitutional changes) ## ๐Ÿ—„๏ธ Database Schema ### Key Tables: #### 1. **users** ```sql - id (UUID, PK) - email (STRING, UNIQUE) - password (STRING, hashed) - role (ENUM: DD, DD-ZM, RBM, ZBH, DD Lead, DD Head, NBH, DD Admin, Legal Admin, Super Admin, DD AM, Finance, Dealer) - name (STRING) - region (STRING) - East, West, North, South, Central - zone (STRING) - status (ENUM: active, inactive) - createdAt, updatedAt ``` #### 2. **applications** ```sql - id (UUID, PK) - applicationId (STRING, UNIQUE) - e.g., APP-2026-001 - applicantName (STRING) - email (STRING) - phone (STRING) - businessType (ENUM: Dealership, Studio) - proposedLocation (TEXT) - city, state, pincode - currentStage (ENUM: DD, DD-ZM, RBM, ZBH, DD Lead, DD Head, NBH, Legal, Finance, Approved, Rejected) - status (ENUM: Pending, In Review, Approved, Rejected) - ranking (INTEGER) - DD ranking system - submittedBy (UUID, FK -> users) - submittedAt (DATE) - progressPercentage (INTEGER) - documents (JSON) - Array of document references - createdAt, updatedAt ``` #### 3. **outlets** ```sql - id (UUID, PK) - code (STRING, UNIQUE) - e.g., DL-MH-001, ST-MH-002 - name (STRING) - type (ENUM: Dealership, Studio) - address (TEXT) - city (STRING) - state (STRING) - pincode (STRING) - latitude (DECIMAL) - longitude (DECIMAL) - status (ENUM: Active, Pending Resignation, Closed) - establishedDate (DATE) - dealerId (UUID, FK -> users) - region (STRING) - zone (STRING) - createdAt, updatedAt ``` #### 4. **resignations** ```sql - id (UUID, PK) - resignationId (STRING, UNIQUE) - e.g., RES-001 - outletId (UUID, FK -> outlets) - dealerId (UUID, FK -> users) - resignationType (ENUM: Voluntary, Retirement, Health Issues, Business Closure, Other) - lastOperationalDateSales (DATE) - lastOperationalDateServices (DATE) - reason (TEXT) - additionalInfo (TEXT) - currentStage (ENUM: ASM, RBM, ZBH, NBH, DD Admin, Legal, Finance, Completed, Rejected) - status (STRING) - progressPercentage (INTEGER) - submittedOn (DATE) - documents (JSON) - createdAt, updatedAt ``` #### 5. **constitutional_changes** ```sql - id (UUID, PK) - requestId (STRING, UNIQUE) - e.g., CC-001 - outletId (UUID, FK -> outlets) - dealerId (UUID, FK -> users) - changeType (ENUM: Ownership Transfer, Partnership Change, LLP Conversion, Company Formation, Director Change) - currentStructure (STRING) - proposedStructure (STRING) - reason (TEXT) - effectiveDate (DATE) - currentStage (ENUM: DD Admin Review, Legal Review, NBH Approval, Finance Clearance, Completed, Rejected) - status (STRING) - progressPercentage (INTEGER) - submittedOn (DATE) - documents (JSON) - createdAt, updatedAt ``` #### 6. **relocation_requests** ```sql - id (UUID, PK) - requestId (STRING, UNIQUE) - e.g., REL-001 - outletId (UUID, FK -> outlets) - dealerId (UUID, FK -> users) - relocationType (ENUM: Within City, Intercity, Interstate) - currentAddress (TEXT) - currentLatitude (DECIMAL) - currentLongitude (DECIMAL) - proposedAddress (TEXT) - proposedLatitude (DECIMAL) - proposedLongitude (DECIMAL) - proposedCity (STRING) - proposedState (STRING) - proposedPincode (STRING) - distance (DECIMAL) - in kilometers - reason (TEXT) - effectiveDate (DATE) - currentStage (ENUM: DD Admin Review, RBM Review, NBH Approval, Legal Clearance, Completed, Rejected) - status (STRING) - progressPercentage (INTEGER) - submittedOn (DATE) - documents (JSON) - createdAt, updatedAt ``` #### 7. **worknotes** ```sql - id (UUID, PK) - requestId (UUID) - Generic reference to any request - requestType (ENUM: application, resignation, constitutional, relocation) - userId (UUID, FK -> users) - userName (STRING) - userRole (STRING) - message (TEXT) - attachments (JSON) - timestamp (DATE) - createdAt, updatedAt ``` #### 8. **documents** ```sql - id (UUID, PK) - filename (STRING) - originalName (STRING) - mimeType (STRING) - size (INTEGER) - path (STRING) - uploadedBy (UUID, FK -> users) - relatedTo (STRING) - application/resignation/etc - relatedId (UUID) - documentType (STRING) - GST, PAN, Aadhaar, etc - uploadedAt (DATE) - createdAt, updatedAt ``` #### 9. **audit_logs** ```sql - id (UUID, PK) - userId (UUID, FK -> users) - userName (STRING) - userRole (STRING) - action (STRING) - CREATED, UPDATED, APPROVED, REJECTED, etc - entityType (STRING) - application, resignation, etc - entityId (UUID) - changes (JSON) - Before/after values - ipAddress (STRING) - timestamp (DATE) - createdAt, updatedAt ``` #### 10. **finance_payments** ```sql - id (UUID, PK) - applicationId (UUID, FK -> applications) - outletId (UUID, FK -> outlets) - dealerId (UUID, FK -> users) - paymentType (ENUM: Security Deposit, License Fee, Setup Fee, Other) - amount (DECIMAL) - dueDate (DATE) - paidDate (DATE) - status (ENUM: Pending, Paid, Overdue, Waived) - transactionId (STRING) - paymentMode (STRING) - remarks (TEXT) - createdAt, updatedAt ``` #### 11. **fnf_settlements** ```sql - id (UUID, PK) - fnfId (STRING, UNIQUE) - e.g., FNF-001 - resignationId (UUID, FK -> resignations) - outletId (UUID, FK -> outlets) - dealerId (UUID, FK -> users) - totalDues (DECIMAL) - securityDepositRefund (DECIMAL) - otherCharges (DECIMAL) - netSettlement (DECIMAL) - status (ENUM: Initiated, DD Clearance, Legal Clearance, Finance Approval, Completed) - settledDate (DATE) - progressPercentage (INTEGER) - createdAt, updatedAt ``` #### 12. **regions** ```sql - id (UUID, PK) - name (STRING, UNIQUE) - East, West, North, South, Central - code (STRING) - headName (STRING) - headEmail (STRING) - isActive (BOOLEAN) - createdAt, updatedAt ``` #### 13. **zones** ```sql - id (UUID, PK) - name (STRING) - code (STRING) - regionId (UUID, FK -> regions) - managerName (STRING) - managerEmail (STRING) - states (JSON) - Array of states covered - isActive (BOOLEAN) - createdAt, updatedAt ``` ## ๐Ÿ”Œ API Endpoints ### Authentication #### `POST /api/auth/login` ```json Request: { "email": "user@example.com", "password": "password123" } Response: { "success": true, "token": "jwt_token_here", "user": { "id": "uuid", "email": "user@example.com", "name": "John Doe", "role": "DD" } } ``` #### `POST /api/auth/logout` ```json Headers: { Authorization: "Bearer jwt_token" } Response: { "success": true, "message": "Logged out successfully" } ``` #### `GET /api/auth/me` ```json Headers: { Authorization: "Bearer jwt_token" } Response: { "success": true, "user": { "id": "uuid", "email": "user@example.com", "name": "John Doe", "role": "DD", "region": "West", "zone": "Mumbai" } } ``` ### Outlets #### `GET /api/outlets/my-outlets` Get all outlets for logged-in dealer ```json Headers: { Authorization: "Bearer dealer_token" } Response: { "success": true, "outlets": [ { "id": "uuid", "code": "DL-MH-001", "name": "Royal Enfield Mumbai", "type": "Dealership", "address": "Bandra West, Mumbai", "status": "Active", "hasActiveResignation": false } ] } ``` ### Resignations #### `POST /api/resignations/create` Create resignation request (Dealer only) ```json Headers: { Authorization: "Bearer dealer_token" } Request: { "outletId": "uuid", "resignationType": "Voluntary", "lastOperationalDateSales": "2026-02-28", "lastOperationalDateServices": "2026-02-28", "reason": "Personal health issues", "additionalInfo": "Optional details" } Response: { "success": true, "resignationId": "RES-001", "message": "Resignation request submitted successfully" } ``` #### `GET /api/resignations/list` Get resignations (role-based filtering) ```json Headers: { Authorization: "Bearer jwt_token" } Response: { "success": true, "resignations": [ { "resignationId": "RES-001", "outlet": { "code": "DL-MH-001", "name": "..." }, "resignationType": "Voluntary", "currentStage": "ASM Review", "status": "Pending", "progressPercentage": 15 } ] } ``` #### `GET /api/resignations/:id` Get resignation details ```json Headers: { Authorization: "Bearer jwt_token" } Response: { "success": true, "resignation": { "resignationId": "RES-001", "outlet": {...}, "resignationType": "Voluntary", "reason": "...", "timeline": [...], "worknotes": [...] } } ``` #### `POST /api/resignations/:id/approve` Approve resignation at current stage ```json Headers: { Authorization: "Bearer jwt_token" } Request: { "remarks": "Approved by ASM" } Response: { "success": true, "message": "Resignation approved and moved to next stage" } ``` #### `POST /api/resignations/:id/reject` Reject resignation ```json Headers: { Authorization: "Bearer jwt_token" } Request: { "reason": "Incomplete documentation" } Response: { "success": true, "message": "Resignation rejected" } ``` ### Constitutional Changes #### `POST /api/constitutional/create` Create constitutional change request (Dealer only) ```json Headers: { Authorization: "Bearer dealer_token" } Request: { "outletId": "uuid", "changeType": "Partnership Change", "currentStructure": "Sole Proprietorship", "proposedStructure": "Partnership Firm", "reason": "Business expansion", "effectiveDate": "2026-03-01" } Response: { "success": true, "requestId": "CC-001" } ``` #### `GET /api/constitutional/list` Get constitutional change requests ```json Headers: { Authorization: "Bearer jwt_token" } Response: { "success": true, "requests": [...] } ``` ### Relocation Requests #### `POST /api/relocations/create` Create relocation request (Dealer only) ```json Headers: { Authorization: "Bearer dealer_token" } Request: { "outletId": "uuid", "relocationType": "Within City", "proposedAddress": "New location address", "proposedLatitude": 19.0760, "proposedLongitude": 72.8777, "proposedCity": "Mumbai", "proposedState": "Maharashtra", "proposedPincode": "400050", "reason": "Better footfall location", "effectiveDate": "2026-04-01" } Response: { "success": true, "requestId": "REL-001" } ``` #### `GET /api/relocations/calculate-distance` Calculate distance between two locations ```json Headers: { Authorization: "Bearer jwt_token" } Query: ?fromLat=19.0760&fromLng=72.8777&toLat=19.1196&toLng=72.9046 Response: { "success": true, "distance": 5.2, "unit": "km" } ``` ### Worknotes #### `POST /api/worknotes/create` Add worknote to any request ```json Headers: { Authorization: "Bearer jwt_token" } Request: { "requestId": "uuid", "requestType": "resignation", "message": "Please provide updated documents" } Response: { "success": true, "worknote": {...} } ``` #### `GET /api/worknotes/:requestId/:requestType` Get all worknotes for a request ```json Headers: { Authorization: "Bearer jwt_token" } Response: { "success": true, "worknotes": [ { "id": "uuid", "userName": "John Doe", "userRole": "DD Admin", "message": "...", "timestamp": "2026-01-13T10:30:00Z" } ] } ``` ### Applications #### `POST /api/applications/create` Create new dealer application (public endpoint) ```json Request: { "applicantName": "Rajesh Kumar", "email": "rajesh@example.com", "phone": "+91-9876543210", "businessType": "Dealership", "proposedLocation": "Full address", "city": "Mumbai", "state": "Maharashtra", "pincode": "400001" } Response: { "success": true, "applicationId": "APP-2026-001" } ``` #### `GET /api/applications/list` Get applications (role-based filtering) ```json Headers: { Authorization: "Bearer jwt_token" } Query: ?status=Pending®ion=West&page=1&limit=10 Response: { "success": true, "applications": [...], "total": 50, "page": 1, "pages": 5 } ``` #### `POST /api/applications/:id/assign-ranking` DD assigns ranking (1-5) ```json Headers: { Authorization: "Bearer dd_token" } Request: { "ranking": 4 } Response: { "success": true, "message": "Ranking assigned" } ``` #### `POST /api/applications/:id/move-stage` Move application to next stage ```json Headers: { Authorization: "Bearer jwt_token" } Request: { "action": "approve", // or "reject" "remarks": "All documents verified" } Response: { "success": true, "nextStage": "DD-ZM" } ``` ### Finance #### `GET /api/finance/onboarding-payments` Get all pending onboarding payments ```json Headers: { Authorization: "Bearer finance_token" } Response: { "success": true, "payments": [...] } ``` #### `POST /api/finance/payment/:id/mark-paid` Mark payment as received ```json Headers: { Authorization: "Bearer finance_token" } Request: { "transactionId": "TXN123456", "paidDate": "2026-01-13", "paymentMode": "NEFT" } Response: { "success": true, "message": "Payment marked as paid" } ``` #### `GET /api/finance/fnf-list` Get F&F settlement requests ```json Headers: { Authorization: "Bearer finance_token" } Response: { "success": true, "fnfRequests": [...] } ``` ### Dashboard #### `GET /api/dashboard/stats` Get dashboard statistics (role-based) ```json Headers: { Authorization: "Bearer jwt_token" } Response: { "success": true, "stats": { "totalApplications": 150, "pendingApplications": 45, "approvedApplications": 95, "rejectedApplications": 10, "pendingResignations": 5, "pendingRelocations": 3 } } ``` ### Master Configuration #### `GET /api/master/regions` Get all regions ```json Headers: { Authorization: "Bearer jwt_token" } Response: { "success": true, "regions": [ { "id": "uuid", "name": "East", "code": "EAST", "zones": [...] } ] } ``` #### `POST /api/master/regions/create` Create region (Super Admin only) ```json Headers: { Authorization: "Bearer admin_token" } Request: { "name": "East", "code": "EAST", "headName": "Amit Kumar", "headEmail": "amit@example.com" } Response: { "success": true, "region": {...} } ``` ### File Upload #### `POST /api/upload/document` Upload document ```json Headers: { Authorization: "Bearer jwt_token", Content-Type: "multipart/form-data" } FormData: - file: (binary) - relatedTo: "resignation" - relatedId: "uuid" - documentType: "GST Certificate" Response: { "success": true, "document": { "id": "uuid", "filename": "unique-filename.pdf", "originalName": "gst-certificate.pdf", "url": "/uploads/documents/unique-filename.pdf" } } ``` ## ๐Ÿ” Authentication & Authorization ### JWT Authentication Flow: 1. **Login:** User sends credentials โ†’ Server validates โ†’ Returns JWT token 2. **Protected Routes:** Client sends token in Authorization header 3. **Token Verification:** Middleware validates token before processing request 4. **Token Expiry:** 24 hours (configurable) ### Role-Based Access Control (RBAC): Middleware checks user role against route permissions: ```javascript // Example: Only DD Lead can access opportunity requests router.get('/opportunity-requests', auth, roleCheck(['DD Lead']), getOpportunityRequests ); // Example: Multiple roles can approve resignations router.post('/resignations/:id/approve', auth, roleCheck(['DD Admin', 'RBM', 'ZBH', 'NBH', 'Legal Admin']), approveResignation ); ``` ### Permission Matrix: | Feature | DD | DD-ZM | RBM | ZBH | DD Lead | DD Head | NBH | DD Admin | Legal | Finance | Dealer | |---------|----|----|-----|-----|---------|---------|-----|----------|-------|---------|--------| | Create Application | โœ… | โŒ | โŒ | โŒ | โœ… | โœ… | โŒ | โŒ | โŒ | โŒ | โŒ | | View All Applications | โœ… | โœ… | โœ… | โœ… | โœ… | โœ… | โœ… | โœ… | โœ… | โœ… | โŒ | | Approve Application Stage | โœ… | โœ… | โœ… | โœ… | โœ… | โœ… | โœ… | โŒ | โœ… | โœ… | โŒ | | Create Resignation | โŒ | โŒ | โŒ | โŒ | โŒ | โŒ | โŒ | โŒ | โŒ | โŒ | โœ… | | Approve Resignation | โŒ | โŒ | โœ… | โœ… | โŒ | โŒ | โœ… | โœ… | โœ… | โœ… | โŒ | | Constitutional Change | โŒ | โŒ | โŒ | โŒ | โŒ | โŒ | โœ… | โœ… | โœ… | โœ… | โœ… | | Relocation Request | โŒ | โŒ | โœ… | โŒ | โŒ | โŒ | โœ… | โœ… | โœ… | โŒ | โœ… | | Master Configuration | โŒ | โŒ | โŒ | โŒ | โœ… | โŒ | โŒ | โœ… | โŒ | โŒ | โŒ | ## ๐Ÿ“ง Email Notifications ### Email Triggers: 1. **Application Submitted** โ†’ Notify assigned DD 2. **Application Approved/Rejected** โ†’ Notify applicant 3. **Stage Changed** โ†’ Notify next approver 4. **Deadline Approaching** โ†’ Reminder email (3 days, 1 day before) 5. **Resignation Submitted** โ†’ Notify DD Admin 6. **Constitutional Change** โ†’ Notify Legal team 7. **Relocation Request** โ†’ Notify RBM 8. **Payment Due** โ†’ Notify dealer 9. **F&F Initiated** โ†’ Notify Finance team ### Email Templates: Located in `utils/emailTemplates.js`: - Application confirmation - Approval notification - Rejection notification - Stage progression - Deadline reminder - Password reset ## ๐Ÿš€ Setup Instructions ### 1. Prerequisites Install the following on your system: - Node.js v18+ (https://nodejs.org) - PostgreSQL 14+ (https://www.postgresql.org) - Git (optional) ### 2. Install Dependencies ```bash cd backend npm install ``` ### 3. Database Setup Create PostgreSQL database: ```sql CREATE DATABASE royal_enfield_onboarding; CREATE USER re_admin WITH PASSWORD 'your_password'; GRANT ALL PRIVILEGES ON DATABASE royal_enfield_onboarding TO re_admin; ``` ### 4. Environment Configuration Copy `.env.example` to `.env` and configure: ```env # Server NODE_ENV=development PORT=5000 # Database DB_HOST=localhost DB_PORT=5432 DB_NAME=royal_enfield_onboarding DB_USER=re_admin DB_PASSWORD=your_password # JWT JWT_SECRET=your_super_secret_jwt_key_here_make_it_long_and_random JWT_EXPIRES_IN=24h # Email (Gmail example) EMAIL_HOST=smtp.gmail.com EMAIL_PORT=587 EMAIL_USER=your-email@gmail.com EMAIL_PASSWORD=your-app-specific-password EMAIL_FROM=Royal Enfield # File Upload UPLOAD_PATH=./uploads MAX_FILE_SIZE=10485760 # Frontend URL (for CORS) FRONTEND_URL=http://localhost:5173 # Admin Default Password (for initial setup) ADMIN_DEFAULT_PASSWORD=Admin@123 ``` ### 5. Run Migrations ```bash npm run migrate ``` This creates all tables and seeds initial data: - Super Admin user - 5 Regions (East, West, North, South, Central) - Sample zones - Sample users for each role ### 6. Start Server **Development:** ```bash npm run dev ``` **Production:** ```bash npm start ``` Server runs on: `http://localhost:5000` ### 7. Test API Use Postman/Thunder Client: ```bash # Login as Super Admin POST http://localhost:5000/api/auth/login Body: { "email": "admin@royalenfield.com", "password": "Admin@123" } # Get dashboard stats GET http://localhost:5000/api/dashboard/stats Headers: Authorization: Bearer ``` ## ๐Ÿ”— Frontend Integration ### Update Frontend API Calls In your frontend, update API base URL: **Create `/src/lib/api.ts`:** ```typescript const API_BASE_URL = process.env.NODE_ENV === 'production' ? 'https://your-backend-domain.com/api' : 'http://localhost:5000/api'; export const api = { async login(email: string, password: string) { const response = await fetch(`${API_BASE_URL}/auth/login`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email, password }) }); return response.json(); }, async getMyOutlets(token: string) { const response = await fetch(`${API_BASE_URL}/outlets/my-outlets`, { headers: { 'Authorization': `Bearer ${token}` } }); return response.json(); }, async createResignation(token: string, data: any) { const response = await fetch(`${API_BASE_URL}/resignations/create`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, body: JSON.stringify(data) }); return response.json(); } }; ``` ### Replace Mock Data **Before (Mock):** ```typescript const mockOutlets = [...]; // Hardcoded data ``` **After (Real API):** ```typescript useEffect(() => { const fetchOutlets = async () => { const token = localStorage.getItem('token'); const result = await api.getMyOutlets(token); setOutlets(result.outlets); }; fetchOutlets(); }, []); ``` ## ๐Ÿ“Š Workflow State Machines ### Application Workflow: ``` Initial โ†’ DD Review โ†’ DD-ZM Review โ†’ RBM Review โ†’ ZBH Review โ†’ DD Lead Review โ†’ DD Head Review โ†’ NBH Approval โ†’ Legal Clearance โ†’ Finance Payment โ†’ Approved โœ… ``` ### Resignation Workflow: ``` Submitted โ†’ ASM Review โ†’ RBM Review โ†’ ZBH Review โ†’ NBH Approval โ†’ DD Admin Clearance โ†’ Legal Clearance โ†’ F&F Initiation โ†’ Finance Settlement โ†’ Completed โœ… ``` ### Constitutional Change Workflow: ``` Submitted โ†’ DD Admin Review โ†’ Legal Verification โ†’ NBH Approval โ†’ Finance Clearance โ†’ Completed โœ… ``` ### Relocation Workflow: ``` Submitted โ†’ DD Admin Review โ†’ RBM Assessment โ†’ NBH Approval โ†’ Legal Clearance โ†’ Completed โœ… ``` ## ๐Ÿ›ก๏ธ Security Features 1. **Password Hashing:** bcryptjs with salt rounds 2. **JWT Tokens:** Secure token-based authentication 3. **CORS:** Configured for frontend domain only 4. **Helmet:** Security headers 5. **Rate Limiting:** Prevent brute force attacks 6. **Input Validation:** express-validator on all inputs 7. **SQL Injection Prevention:** Sequelize ORM parameterized queries 8. **File Upload Validation:** Type and size restrictions 9. **Audit Logging:** All actions logged with user/timestamp ## ๐Ÿ“ Logging Winston logger with multiple transports: - **Console:** Development logging - **File:** `logs/error.log` - Error logs - **File:** `logs/combined.log` - All logs ## ๐Ÿงช Testing ```bash # Run tests npm test # Run with coverage npm run test:coverage ``` ## ๐Ÿšข Deployment ### Option 1: Railway (Recommended) 1. Create account on railway.app 2. Connect GitHub repository 3. Add PostgreSQL plugin 4. Set environment variables 5. Deploy automatically ### Option 2: Render 1. Create account on render.com 2. Create Web Service 3. Connect repository 4. Add PostgreSQL database 5. Set environment variables 6. Deploy ### Option 3: AWS/DigitalOcean 1. Set up EC2/Droplet 2. Install Node.js, PostgreSQL 3. Clone repository 4. Configure environment 5. Use PM2 for process management 6. Set up Nginx reverse proxy ### Environment Variables for Production: ```env NODE_ENV=production DB_HOST= DB_NAME= DB_USER= DB_PASSWORD= JWT_SECRET= EMAIL_HOST= EMAIL_USER= EMAIL_PASSWORD= FRONTEND_URL=https://your-frontend-domain.com ``` ## ๐Ÿ“ฆ Dependencies **Core:** - express: Web framework - sequelize: ORM - pg, pg-hstore: PostgreSQL driver - jsonwebtoken: JWT authentication - bcryptjs: Password hashing **Middleware:** - cors: Cross-origin resource sharing - helmet: Security headers - express-validator: Input validation - multer: File uploads **Utilities:** - nodemailer: Email sending - winston: Logging - dotenv: Environment variables - uuid: Unique IDs **Dev Dependencies:** - nodemon: Auto-restart on changes - jest: Testing framework ## ๐Ÿ”ง Maintenance ### Database Backup: ```bash pg_dump -U re_admin royal_enfield_onboarding > backup.sql ``` ### Restore Database: ```bash psql -U re_admin royal_enfield_onboarding < backup.sql ``` ### Clear Logs: ```bash npm run clear-logs ``` ## ๐Ÿ“ž Support & Troubleshooting ### Common Issues: **1. Database Connection Error:** - Check PostgreSQL is running: `sudo service postgresql status` - Verify credentials in `.env` - Check database exists: `psql -l` **2. Port Already in Use:** - Change PORT in `.env` - Kill process: `lsof -ti:5000 | xargs kill` **3. JWT Token Invalid:** - Check JWT_SECRET is same across restarts - Verify token expiry time - Clear old tokens from frontend **4. File Upload Failing:** - Check UPLOAD_PATH directory exists and is writable - Verify MAX_FILE_SIZE setting - Check disk space **5. Email Not Sending:** - Verify SMTP credentials - Check firewall/port 587 access - Enable "Less secure apps" for Gmail or use App Password ## ๐ŸŽฏ Next Steps for AI Assistant (Cursor/Windsurf/etc) When you provide this backend to your AI IDE, it will understand: 1. โœ… Complete architecture and file structure 2. โœ… Database schema and relationships 3. โœ… All API endpoints and their contracts 4. โœ… Authentication and authorization flow 5. โœ… Environment setup requirements 6. โœ… Deployment options 7. โœ… Integration points with frontend **The AI can then:** - Help you set up the database - Debug any issues - Add new features - Optimize queries - Handle deployment - Write tests - Generate documentation ## ๐Ÿ“„ License Proprietary - Royal Enfield Dealership Onboarding System --- **Created:** January 2026 **Version:** 1.0.0 **Last Updated:** January 13, 2026 For questions or support, refer to this documentation first, then consult with your development team.