9119e2383e
- Introduced a new `config.yaml` file for managing server, database, cache, queue, AI, scraping, logging, and rate limiting configurations. - Updated `docker-compose.yml` to reflect the new server port (8081) and adjusted health check endpoints accordingly. - Modified `Dockerfile` to expose the new server port. - Updated `README.md` to reflect changes in server configuration and added documentation for the new configuration structure. - Added test scripts for server and Swagger documentation testing. - Refactored customer domain structure to align with new configuration settings and improve maintainability.
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
{
"_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_idstatusgendercreated_at(descending)- Text index on
full_name,email,mobile,username
API Endpoints
Public Endpoints (No Authentication Required)
1. Register Customer
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:
{
"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
POST /api/customers/login
Content-Type: application/json
{
"email_or_mobile": "john@example.com",
"password": "securepassword123"
}
Response:
{
"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
POST /api/customers/refresh-token
Content-Type: application/json
{
"refresh_token": "refresh_token_here"
}
Protected Endpoints (Authentication Required)
4. Get Profile
GET /api/customers/profile
Authorization: Bearer <access_token>
X-Customer-ID: <customer_uuid>
5. Update Profile
PUT /api/customers/profile
Authorization: Bearer <access_token>
X-Customer-ID: <customer_uuid>
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
PUT /api/customers/change-password
Authorization: Bearer <access_token>
X-Customer-ID: <customer_uuid>
Content-Type: application/json
{
"old_password": "currentpassword",
"new_password": "newsecurepassword123"
}
7. Add Device Token
POST /api/customers/device-token
Authorization: Bearer <access_token>
X-Customer-ID: <customer_uuid>
Content-Type: application/json
{
"device_token": "fcm_token_here",
"device_type": "android"
}
8. Remove Device Token
DELETE /api/customers/device-token
Authorization: Bearer <access_token>
X-Customer-ID: <customer_uuid>
Content-Type: application/json
{
"device_token": "fcm_token_here"
}
9. Logout
POST /api/customers/logout
Authorization: Bearer <access_token>
X-Customer-ID: <customer_uuid>
Content-Type: application/json
{
"device_token": "fcm_token_here"
}
Admin Endpoints (Admin Authentication Required)
10. List Customers
GET /api/admin/customers?search=john&status=active&gender=male&limit=20&offset=0&sort_by=created_at&sort_order=desc
Authorization: Bearer <admin_access_token>
Response:
{
"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
GET /api/admin/customers/{customer_id}
Authorization: Bearer <admin_access_token>
12. Update Customer Status
PUT /api/admin/customers/{customer_id}/status
Authorization: Bearer <admin_access_token>
Content-Type: application/json
{
"status": "inactive"
}
13. Get All Device Tokens
GET /api/admin/customers/device-tokens
Authorization: Bearer <admin_access_token>
Response:
{
"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 charactersusername: Required, alphanumeric, 3-30 characters, uniqueemail: Required, valid email format, uniquemobile: Required, 10-15 characters, uniquepassword: Required, 8-128 charactersnational_id: Optional, 5-20 charactersgender: Optional, must be "male", "female", or "other"birthdate: Optional, valid Unix timestampprofile_image: Optional, valid URLcompany_id: Optional, valid UUID
Login Form
email_or_mobile: Requiredpassword: 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 charactersdevice_type: Required, must be "android" or "ios"
List Customers Form
search: Optional, text searchstatus: Optional, must be "active" or "inactive"gender: Optional, must be "male", "female", or "other"company_id: Optional, valid UUIDlimit: Optional, 1-100offset: Optional, minimum 0sort_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
{
"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 parametersVALIDATION_ERROR: Input validation failedUNAUTHORIZED: Authentication required or failedFORBIDDEN: Insufficient permissionsNOT_FOUND: Resource not foundCONFLICT: Resource already existsINTERNAL_SERVER_ERROR: Server error
HTTP Status Codes
200 OK: Success201 Created: Resource created successfully400 Bad Request: Invalid request401 Unauthorized: Authentication required403 Forbidden: Insufficient permissions404 Not Found: Resource not found409 Conflict: Resource conflict422 Unprocessable Entity: Validation error500 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)
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
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
curl -X PUT http://localhost:8081/api/customers/profile \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <access_token>" \
-H "X-Customer-ID: <customer_uuid>" \
-d '{
"full_name": "John Updated Doe",
"email": "john.updated@example.com"
}'
List Customers (Admin)
curl -X GET "http://localhost:8081/api/admin/customers?search=john&status=active&limit=10" \
-H "Authorization: Bearer <admin_access_token>"
Future Enhancements
Planned Features
- JWT Implementation: Proper JWT token generation and validation
- Email Verification: Email verification system
- Password Reset: Forgot password functionality
- Role-Based Access Control: User roles and permissions
- Rate Limiting: API rate limiting implementation
- Audit Logging: Comprehensive audit trail
- Bulk Operations: Bulk user import/export
- Advanced Search: Full-text search with filters
- File Upload: Profile picture upload handling
- Two-Factor Authentication: 2FA support
Technical Improvements
- Caching: Redis caching for frequently accessed data
- Background Jobs: Async processing for heavy operations
- Monitoring: Health checks and metrics
- Testing: Comprehensive unit and integration tests
- Documentation: OpenAPI/Swagger documentation
- Performance: Query optimization and indexing
- Security: Additional security measures
- Scalability: Horizontal scaling support
Dependencies
Required Packages
github.com/google/uuid: UUID generationgithub.com/labstack/echo/v4: HTTP frameworkgithub.com/asaskevich/govalidator: Input validationgolang.org/x/crypto/bcrypt: Password hashinggo.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:
- Follow the existing code structure and patterns
- Add comprehensive validation for new fields
- Include proper error handling and logging
- Write unit tests for new functionality
- Update documentation for new endpoints
- Follow security best practices
- Use Unix timestamps for all time fields
- Implement proper pagination for list endpoints
- Add appropriate indexes for new fields
- Follow the flat domain structure pattern