Skip to main content

Development Workflow

Project Setup

  • Always run npm install after pulling latest changes
  • Ensure all required environment variables are configured
  • Run database migrations before starting development
  • Test API endpoints with Bruno collections after setup

Code Changes

  • Create feature branches for new development
  • Follow the established module pattern for new features
  • Run type checking and linting before committing
  • Test changes with relevant Bruno collections

Database Operations

  • Always filter by shop_id or merchant_id for multi-tenancy
  • Use database transactions for complex operations
  • Test queries with appropriate data isolation
  • Consider performance implications of new queries

Security Best Practices

Authentication & Authorization

  • Never bypass authentication middleware in production code
  • Always validate user permissions before sensitive operations
  • Use JWT tokens with appropriate expiration times
  • Store sensitive tokens in Redis, not in database

Data Protection

  • Never expose sensitive fields in API responses
  • Always validate and sanitize user input
  • Use parameterized queries to prevent SQL injection
  • Implement rate limiting for public endpoints

Multi-tenancy

  • Always include tenant isolation in database queries
  • Validate merchant/shop ID ownership before operations
  • Never allow cross-tenant data access
  • Test multi-tenancy isolation thoroughly

Error Handling

Consistent Error Responses

Use CustomError for all business logic errors:
// Good: Structured error with context
if (!product) {
  throw new CustomError(
    "PRODUCT_NOT_FOUND",
    "Product not found with given ID",
    { productId: id, merchantId: req.merchant_id }
  );
}

// Bad: Generic error without context
throw new Error("Product not found");

Error Response Format

Maintain consistent error response structure:
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Required fields are missing",
    "metadata": {
      "fields": ["name", "price"]
    }
  }
}

Logging and Monitoring

  • Log errors with sufficient context for debugging
  • Include request ID and user context in error logs
  • Monitor error rates and patterns
  • Set up alerts for critical errors

Performance Considerations

Database Optimization

  • Use appropriate database indexes for frequent queries
  • Implement pagination for list endpoints
  • Use connection pooling for database connections
  • Monitor slow queries and optimize as needed

Caching Strategy

  • Use Redis for frequently accessed data
  • Implement cache invalidation strategies
  • Cache authentication tokens and user sessions
  • Monitor cache hit rates and effectiveness

API Design

  • Implement proper pagination for large datasets
  • Use filtering and sorting for list endpoints
  • Avoid N+1 query problems in related data
  • Consider response payload size for mobile clients

Code Quality

TypeScript Usage

  • Use strict TypeScript configuration
  • Define proper interfaces for request/response data
  • Avoid any types in production code
  • Use path aliases for clean imports

Testing

  • Test all new endpoints with Bruno collections
  • Include both success and error scenarios in tests
  • Test authentication and authorization flows
  • Maintain test data isolation between tests

Code Review

  • Review code for security vulnerabilities
  • Check multi-tenancy implementation
  • Verify error handling and logging
  • Ensure consistent code style and patterns

API Design Principles

RESTful Design

  • Use appropriate HTTP methods (GET, POST, PUT, DELETE)
  • Follow consistent URL naming conventions
  • Return appropriate HTTP status codes
  • Use standard response formats across all endpoints

Request/Response Format

// Standard success response
{
  "success": true,
  "data": { /* response data */ },
  "message": "Operation completed successfully",
  "pagination": { /* if applicable */ }
}

// Standard error response
{
  "success": false,
  "error": {
    "code": "ERROR_CODE",
    "message": "Human readable message"
  }
}

Versioning

  • Consider API versioning for breaking changes
  • Maintain backward compatibility when possible
  • Document API changes and deprecation notices
  • Plan migration paths for API consumers

Deployment Best Practices

Environment Configuration

  • Use environment variables for all configuration
  • Never commit secrets or credentials to version control
  • Maintain separate configurations for dev/staging/prod
  • Validate required environment variables on startup

Service Deployment

  • Test individual services in single-service mode
  • Use health check endpoints for monitoring
  • Implement graceful shutdown handling
  • Monitor service dependencies and external APIs

Database Management

  • Run database migrations in deployment pipeline
  • Back up database before major changes
  • Test migrations on staging environment first
  • Have rollback procedures for failed deployments

Monitoring and Observability

Application Metrics

  • Monitor API response times and error rates
  • Track database query performance
  • Monitor memory and CPU usage
  • Set up alerts for service health

Business Metrics

  • Track key business metrics (orders, users, revenue)
  • Monitor API usage patterns and trends
  • Analyze error patterns and user behavior
  • Generate reports for stakeholders

Logging Strategy

  • Use structured logging with consistent formats
  • Include request correlation IDs
  • Log important business events
  • Implement log rotation and retention policies

Documentation

API Documentation

  • Keep OpenAPI specifications up to date
  • Document all request/response formats
  • Include example requests and responses
  • Document authentication and authorization requirements

Code Documentation

  • Write clear comments for complex business logic
  • Document API endpoints and their purposes
  • Maintain README files for setup instructions
  • Document deployment and configuration procedures

Team Collaboration

Git Workflow

  • Use descriptive commit messages
  • Create pull requests for code reviews
  • Keep commits focused and atomic
  • Use conventional commit messages

Communication

  • Document architectural decisions
  • Share knowledge about complex features
  • Communicate breaking changes early
  • Maintain team coding standards