Files
tm_back/internal/customer/README.md
T
n.nakhostin 9119e2383e Add configuration file and update server settings
- 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.
2025-08-02 12:37:04 +03:30

15 KiB

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_id
  • status
  • gender
  • created_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 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

{
  "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)

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

  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