# Customer Management Module This module implements a complete User Management system for the Tender Management System, allowing administrators to register users who can later access the mobile application. ## Features ### 1. User Registration (by Admin) - **Fields**: Full name, username, email, mobile number, password (hashed), national ID (optional), gender (enum), birthdate (optional), profile image (optional), user status (active/inactive), registration date - **Uniqueness**: Ensures uniqueness for email, mobile, and username - **Validation**: Comprehensive input validation using govalidator ### 2. Authentication for Mobile Users - **Login**: Secure login via email or mobile number + password - **JWT Tokens**: Access and refresh token generation - **Password Security**: bcrypt hashing for secure password storage ### 3. Device Token Management - **Storage**: Saves device_token and device_type (Android/iOS) when user logs in - **Updates**: Updates token if user logs in from new device or re-installs app - **Cleanup**: Endpoint to delete token on logout ### 4. User Profile Management - **View/Edit**: Personal info (name, email, mobile, etc.) - **Password Change**: Secure password change endpoint - **Profile Picture**: Upload/update profile picture support ### 5. Push Notification Ready - **Multiple Tokens**: Stores multiple device tokens per user - **User Association**: Tokens tied to correct user ID - **Admin Access**: API to get all active device tokens for admin push campaigns ### 6. Admin Panel APIs - **List/Search/Filter**: Users by name, mobile, email, registration date, and status - **Status Management**: Activate/deactivate users - **Role Support**: Framework for role assignment (user, moderator, etc.) ### 7. Security & Best Practices - **Input Validation**: Comprehensive validation and sanitization - **Rate Limiting**: Framework for authentication endpoint rate limiting - **Password Security**: bcrypt hashing with configurable cost - **HTTP Status Codes**: Proper status codes and error messages - **Activity Logging**: User activities (login, logout, profile update) ## Architecture ### Clean Architecture Implementation - **Domain Layer**: Business entities, aggregates, interfaces, and core business rules - **Service Layer**: Business logic and use cases - **Handler Layer**: HTTP controllers and request/response handling - **Repository Layer**: Data access implementations - **Infrastructure Layer**: External dependencies (DB, cache, queues, config) ### File Structure ``` internal/customer/ ├── entity.go # Core domain entities and types ├── form.go # Request/response forms with validation ├── repository.go # Repository interface and implementation ├── service.go # Business logic and use cases ├── handler.go # HTTP controllers and request/response handling ├── validation.go # Custom validation rules └── README.md # This documentation ``` ## Database Schema ### Customer Collection ```javascript { "_id": "uuid", "full_name": "string", "username": "string (unique)", "email": "string (unique)", "mobile": "string (unique)", "password": "string (hashed)", "national_id": "string (optional)", "gender": "enum (male|female|other) (optional)", "birthdate": "int64 (unix timestamp) (optional)", "profile_image": "string (url) (optional)", "status": "enum (active|inactive)", "company_id": "uuid (optional)", "is_verified": "boolean", "device_tokens": [ { "token": "string", "device_type": "enum (android|ios)", "created_at": "int64 (unix timestamp)", "updated_at": "int64 (unix timestamp)" } ], "last_login_at": "int64 (unix timestamp) (optional)", "created_at": "int64 (unix timestamp)", "updated_at": "int64 (unix timestamp)" } ``` ### Indexes - `email` (unique) - `username` (unique) - `mobile` (unique) - `company_id` - `status` - `gender` - `created_at` (descending) - Text index on `full_name`, `email`, `mobile`, `username` ## API Endpoints ### Public Endpoints (No Authentication Required) #### 1. Register Customer ```http POST /api/customers/register Content-Type: application/json { "full_name": "John Doe", "username": "johndoe", "email": "john@example.com", "mobile": "+1234567890", "password": "securepassword123", "national_id": "123456789", "gender": "male", "birthdate": 631152000, "profile_image": "https://example.com/avatar.jpg", "company_id": "uuid-optional" } ``` **Response:** ```json { "success": true, "message": "Customer registered successfully", "data": { "id": "uuid", "full_name": "John Doe", "username": "johndoe", "email": "john@example.com", "mobile": "+1234567890", "national_id": "123456789", "gender": "male", "birthdate": 631152000, "profile_image": "https://example.com/avatar.jpg", "status": "active", "company_id": "uuid", "is_verified": false, "device_tokens": [], "created_at": 1703123456, "updated_at": 1703123456 } } ``` #### 2. Login ```http POST /api/customers/login Content-Type: application/json { "email_or_mobile": "john@example.com", "password": "securepassword123" } ``` **Response:** ```json { "success": true, "message": "Login successful", "data": { "customer": { "id": "uuid", "full_name": "John Doe", "username": "johndoe", "email": "john@example.com", "mobile": "+1234567890", "status": "active", "is_verified": false, "device_tokens": [], "last_login_at": 1703123456, "created_at": 1703123456, "updated_at": 1703123456 }, "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "refresh_token": "refresh_token_here", "expires_at": 1703127056 } } ``` #### 3. Refresh Token ```http POST /api/customers/refresh-token Content-Type: application/json { "refresh_token": "refresh_token_here" } ``` ### Protected Endpoints (Authentication Required) #### 4. Get Profile ```http GET /api/customers/profile Authorization: Bearer X-Customer-ID: ``` #### 5. Update Profile ```http PUT /api/customers/profile Authorization: Bearer X-Customer-ID: Content-Type: application/json { "full_name": "John Updated Doe", "email": "john.updated@example.com", "mobile": "+1234567891", "gender": "male", "birthdate": 631152000, "profile_image": "https://example.com/new-avatar.jpg" } ``` #### 6. Change Password ```http PUT /api/customers/change-password Authorization: Bearer X-Customer-ID: Content-Type: application/json { "old_password": "currentpassword", "new_password": "newsecurepassword123" } ``` #### 7. Add Device Token ```http POST /api/customers/device-token Authorization: Bearer X-Customer-ID: Content-Type: application/json { "device_token": "fcm_token_here", "device_type": "android" } ``` #### 8. Remove Device Token ```http DELETE /api/customers/device-token Authorization: Bearer X-Customer-ID: Content-Type: application/json { "device_token": "fcm_token_here" } ``` #### 9. Logout ```http POST /api/customers/logout Authorization: Bearer X-Customer-ID: Content-Type: application/json { "device_token": "fcm_token_here" } ``` ### Admin Endpoints (Admin Authentication Required) #### 10. List Customers ```http GET /api/admin/customers?search=john&status=active&gender=male&limit=20&offset=0&sort_by=created_at&sort_order=desc Authorization: Bearer ``` **Response:** ```json { "success": true, "message": "Customers retrieved successfully", "data": [ { "id": "uuid", "full_name": "John Doe", "username": "johndoe", "email": "john@example.com", "mobile": "+1234567890", "status": "active", "is_verified": false, "device_tokens": [], "last_login_at": 1703123456, "created_at": 1703123456, "updated_at": 1703123456 } ], "meta": { "total": 100, "limit": 20, "offset": 0, "page": 1, "pages": 5 } } ``` #### 11. Get Customer by ID ```http GET /api/admin/customers/{customer_id} Authorization: Bearer ``` #### 12. Update Customer Status ```http PUT /api/admin/customers/{customer_id}/status Authorization: Bearer Content-Type: application/json { "status": "inactive" } ``` #### 13. Get All Device Tokens ```http GET /api/admin/customers/device-tokens Authorization: Bearer ``` **Response:** ```json { "success": true, "message": "Device tokens retrieved successfully", "data": [ { "token": "fcm_token_1", "device_type": "android", "created_at": 1703123456, "updated_at": 1703123456 }, { "token": "fcm_token_2", "device_type": "ios", "created_at": 1703123457, "updated_at": 1703123457 } ] } ``` ## Validation Rules ### Registration Form - `full_name`: Required, 2-100 characters - `username`: Required, alphanumeric, 3-30 characters, unique - `email`: Required, valid email format, unique - `mobile`: Required, 10-15 characters, unique - `password`: Required, 8-128 characters - `national_id`: Optional, 5-20 characters - `gender`: Optional, must be "male", "female", or "other" - `birthdate`: Optional, valid Unix timestamp - `profile_image`: Optional, valid URL - `company_id`: Optional, valid UUID ### Login Form - `email_or_mobile`: Required - `password`: Required ### Update Form - All fields optional with same validation rules as registration - Uniqueness checks only if field is being updated ### Device Token Form - `device_token`: Required, 32-255 characters - `device_type`: Required, must be "android" or "ios" ### List Customers Form - `search`: Optional, text search - `status`: Optional, must be "active" or "inactive" - `gender`: Optional, must be "male", "female", or "other" - `company_id`: Optional, valid UUID - `limit`: Optional, 1-100 - `offset`: Optional, minimum 0 - `sort_by`: Optional, must be "full_name", "email", "mobile", "created_at", or "last_login_at" - `sort_order`: Optional, must be "asc" or "desc" ## Error Handling ### Standard Error Response Format ```json { "success": false, "message": "Error message", "error": { "code": "ERROR_CODE", "message": "Detailed error message", "details": "Additional error details" } } ``` ### Common Error Codes - `BAD_REQUEST`: Invalid request format or parameters - `VALIDATION_ERROR`: Input validation failed - `UNAUTHORIZED`: Authentication required or failed - `FORBIDDEN`: Insufficient permissions - `NOT_FOUND`: Resource not found - `CONFLICT`: Resource already exists - `INTERNAL_SERVER_ERROR`: Server error ### HTTP Status Codes - `200 OK`: Success - `201 Created`: Resource created successfully - `400 Bad Request`: Invalid request - `401 Unauthorized`: Authentication required - `403 Forbidden`: Insufficient permissions - `404 Not Found`: Resource not found - `409 Conflict`: Resource conflict - `422 Unprocessable Entity`: Validation error - `500 Internal Server Error`: Server error ## Security Features ### Password Security - bcrypt hashing with configurable cost - Minimum 8 characters required - Maximum 128 characters allowed ### Input Validation - Comprehensive validation using govalidator - Custom validators for Unix timestamps - SQL injection prevention through parameterized queries - XSS prevention through input sanitization ### Authentication - JWT-based token system - Access and refresh token separation - Token expiration handling - Secure token generation ### Data Protection - Passwords never serialized in responses - Sensitive data logging prevention - Input sanitization and validation ## Usage Examples ### Register a New Customer (Admin) ```bash curl -X POST http://localhost:8081/api/customers/register \ -H "Content-Type: application/json" \ -d '{ "full_name": "John Doe", "username": "johndoe", "email": "john@example.com", "mobile": "+1234567890", "password": "securepassword123", "gender": "male", "birthdate": 631152000 }' ``` ### Login as Customer ```bash curl -X POST http://localhost:8081/api/customers/login \ -H "Content-Type: application/json" \ -d '{ "email_or_mobile": "john@example.com", "password": "securepassword123" }' ``` ### Update Profile ```bash curl -X PUT http://localhost:8081/api/customers/profile \ -H "Content-Type: application/json" \ -H "Authorization: Bearer " \ -H "X-Customer-ID: " \ -d '{ "full_name": "John Updated Doe", "email": "john.updated@example.com" }' ``` ### List Customers (Admin) ```bash curl -X GET "http://localhost:8081/api/admin/customers?search=john&status=active&limit=10" \ -H "Authorization: Bearer " ``` ## Future Enhancements ### Planned Features 1. **JWT Implementation**: Proper JWT token generation and validation 2. **Email Verification**: Email verification system 3. **Password Reset**: Forgot password functionality 4. **Role-Based Access Control**: User roles and permissions 5. **Rate Limiting**: API rate limiting implementation 6. **Audit Logging**: Comprehensive audit trail 7. **Bulk Operations**: Bulk user import/export 8. **Advanced Search**: Full-text search with filters 9. **File Upload**: Profile picture upload handling 10. **Two-Factor Authentication**: 2FA support ### Technical Improvements 1. **Caching**: Redis caching for frequently accessed data 2. **Background Jobs**: Async processing for heavy operations 3. **Monitoring**: Health checks and metrics 4. **Testing**: Comprehensive unit and integration tests 5. **Documentation**: OpenAPI/Swagger documentation 6. **Performance**: Query optimization and indexing 7. **Security**: Additional security measures 8. **Scalability**: Horizontal scaling support ## Dependencies ### Required Packages - `github.com/google/uuid`: UUID generation - `github.com/labstack/echo/v4`: HTTP framework - `github.com/asaskevich/govalidator`: Input validation - `golang.org/x/crypto/bcrypt`: Password hashing - `go.mongodb.org/mongo-driver`: MongoDB driver ### Configuration - MongoDB connection string - JWT secret key - Password hashing cost - Token expiration times - Rate limiting settings ## Contributing When contributing to this module: 1. Follow the existing code structure and patterns 2. Add comprehensive validation for new fields 3. Include proper error handling and logging 4. Write unit tests for new functionality 5. Update documentation for new endpoints 6. Follow security best practices 7. Use Unix timestamps for all time fields 8. Implement proper pagination for list endpoints 9. Add appropriate indexes for new fields 10. Follow the flat domain structure pattern