UNPKG

espocrm-graphql-server

Version:

A modern GraphQL server for EspoCRM with TypeScript, MCP integration, and AI-optimized dynamic schema generation

1,226 lines (978 loc) โ€ข 29.8 kB
# EspoCRM GraphQL Server ๐Ÿš€ A high-performance, AI-optimized GraphQL server that dynamically generates schemas from EspoCRM metadata. Built specifically for modern AI agents and property management workflows. ![GraphQL](https://img.shields.io/badge/GraphQL-E10098?style=for-the-badge&logo=graphql&logoColor=white) ![Node.js](https://img.shields.io/badge/Node.js-339933?style=for-the-badge&logo=node.js&logoColor=white) ![TypeScript](https://img.shields.io/badge/TypeScript-007ACC?style=for-the-badge&logo=typescript&logoColor=white) ![Docker](https://img.shields.io/badge/Docker-2496ED?style=for-the-badge&logo=docker&logoColor=white) ![Apollo GraphQL](https://img.shields.io/badge/Apollo-311C87?style=for-the-badge&logo=apollo-graphql&logoColor=white) ## ๐ŸŒŸ Features ### ๐Ÿค– AI Agent Optimized - **Dynamic Schema Generation** - Automatically creates GraphQL schemas from EspoCRM metadata - **Intelligent Field Validation** - Smart required field detection with error prediction - **Advanced Type Handling** - Optimized array, enum, and multi-enum field processing - **Neural Query Optimization** - AI-powered performance optimization and caching - **Predictive Error Recovery** - Context-aware error handling with suggestions - **Optional EspoCRM** - Server can start without EspoCRM configured for easier deployment ### โšก High Performance - **Multi-layer Caching** - Redis + in-memory caching with intelligent invalidation - **Query Optimization** - DataLoader integration preventing N+1 queries - **Real-time Sync** - Auto-refreshing schema stays synchronized with EspoCRM - **Connection Pooling** - Optimized database connections and API calls - **Performance Monitoring** - Built-in metrics and bottleneck analysis ### ๐Ÿข Real Estate & CRM Ready - **Property Management** - Optimized for real estate workflows and data structures - **Multi-currency Support** - International business operations with currency handling - **Compliance Features** - GDPR and data protection compliance built-in - **Mobile-Optimized** - Responsive queries for mobile applications - **Business Rule Engine** - Automated validation for complex business workflows ### ๐Ÿ” Enterprise Security - **Multi-auth Support** - JWT, API keys, role-based access control - **Rate Limiting** - Configurable rate limiting with IP whitelisting - **Data Protection** - GDPR compliance with audit trails - **Security Headers** - Comprehensive security middleware - **Vulnerability Scanning** - Automated security scanning in CI/CD ## ๐Ÿ“‹ Table of Contents - [Quick Start](#-quick-start) - [Installation](#-installation) - [Configuration](#-configuration) - [Coolify Deployment](#-coolify-deployment) - [Development](#-development) - [API Documentation](#-api-documentation) - [Performance Optimization](#-performance-optimization) - [MCP Integration](#-mcp-integration) - [Testing](#-testing) - [Monitoring](#-monitoring) - [Contributing](#-contributing) - [Support](#-support) ## ๐Ÿš€ Quick Start ### ๐Ÿ“ฆ NPX Usage (Recommended) The fastest way to get started: ```bash # Start GraphQL server npx espocrm-graphql-server # Start MCP server for AI assistants npx espocrm-mcp # Initialize configuration files npx espocrm-graphql-server init # View help npx espocrm-graphql-server --help ``` ### ๐Ÿ“ฅ Installation ```bash # Global installation npm install -g espocrm-graphql-server # Or use directly with npx (no installation required) npx espocrm-graphql-server --version ``` ## ๐Ÿ› ๏ธ Development Setup ### Prerequisites - Node.js 20+ and npm/yarn - EspoCRM instance with API access (optional - server can run without it) - Redis (optional, for caching) - Docker (for containerized deployment) ### 1. Clone and Install ```bash git clone https://github.com/CG-Labs/EspoCRM-GraphQL-Server.git cd EspoCRM-GraphQL-Server npm install ``` ### 2. Configure Environment ```bash cp .env.example .env # Edit .env with your EspoCRM credentials ``` ### 3. Start Development Server ```bash npm run dev ``` GraphQL Playground will be available at `http://localhost:4000/graphql` ## ๐Ÿ“ฆ Installation ### Local Development ```bash # Install dependencies npm install # Setup database (if using direct MySQL) npm run setup:db # Generate initial schema npm run schema:generate # Start development server with hot reload npm run dev ``` ### Docker Development ```bash # Start with Docker Compose docker-compose up -d # View logs docker-compose logs -f graphql # Stop services docker-compose down ``` ### Production Docker ```bash # Build production image docker build -f Dockerfile.prod -t espocrm-graphql:latest . # Run with production compose docker-compose -f docker-compose.prod.yml up -d ``` ## โš™๏ธ Configuration ### Environment Variables Create a `.env` file based on `.env.example`: ```bash # EspoCRM Connection ESPOCRM_API_URL=https://your-espocrm.com/api/v1 ESPOCRM_API_KEY=your_api_key_here ESPOCRM_USERNAME=admin ESPOCRM_PASSWORD=your_password # Optional: Direct MySQL Connection (for performance) MYSQL_HOST=your-mysql-host MYSQL_PORT=3306 MYSQL_USER=espocrm_user MYSQL_PASSWORD=your_mysql_password MYSQL_DATABASE=espocrm_db # Server Configuration PORT=4000 NODE_ENV=production LOG_LEVEL=info # Security JWT_SECRET=your-super-secret-jwt-key-here API_RATE_LIMIT=100 API_RATE_WINDOW=15 # Redis Cache (Optional) REDIS_URL=redis://localhost:6379 CACHE_TTL=300 # AI Optimization Features AI_OPTIMIZATION_ENABLED=true PERFORMANCE_MONITORING=true AUTO_SCHEMA_REFRESH=true SCHEMA_REFRESH_INTERVAL=3600 # Organization Specific ORGANIZATION_NAME=Your Organization DEFAULT_CURRENCY=GBP PROPERTY_MANAGEMENT_MODE=true COMPLIANCE_MODE=GDPR_UK # Monitoring & Observability ENABLE_METRICS=true METRICS_PORT=9090 ENABLE_TRACING=false JAEGER_ENDPOINT=http://localhost:14268/api/traces # Development GRAPHQL_PLAYGROUND=true GRAPHQL_INTROSPECTION=true DEBUG_MODE=false ``` ### Advanced Configuration For advanced configuration, edit `config/default.json`: ```json { "server": { "port": 4000, "cors": { "origin": ["http://localhost:3000", "https://yourdomain.com"], "credentials": true } }, "espocrm": { "apiUrl": "https://your-espocrm.com/api/v1", "timeout": 30000, "retries": 3, "rateLimit": { "requests": 100, "window": 60000 } }, "cache": { "type": "redis", "ttl": 300, "prefix": "espocrm:graphql:" }, "ai": { "optimizationEnabled": true, "learningEnabled": true, "performancePrediction": true } } ``` ## ๐Ÿ”’ Security ### Authentication The GraphQL server supports multiple authentication methods to protect your data: #### API Key Authentication Configure API key authentication by setting the following environment variables: ```env GRAPHQL_REQUIRE_AUTH=true GRAPHQL_API_KEYS=key1,key2,key3 # Comma-separated list GRAPHQL_MASTER_KEY=master-key-for-admin ``` Include the API key in your requests: ```bash # Using X-API-Key header curl -X POST https://your-server/graphql \ -H "Content-Type: application/json" \ -H "X-API-Key: your-api-key" \ -d '{"query": "{ contacts { edges { node { id } } } }"}' # Using Authorization Bearer curl -X POST https://your-server/graphql \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your-api-key" \ -d '{"query": "{ contacts { edges { node { id } } } }"}' ``` ### Security Features #### Rate Limiting Prevents abuse by limiting the number of requests: ```env RATE_LIMIT_MAX_REQUESTS=30 # Max requests per window RATE_LIMIT_WINDOW_MS=60000 # Time window (1 minute) ``` #### Query Depth Limiting Prevents malicious deeply nested queries: ```env GRAPHQL_DEPTH_LIMIT=10 # Maximum query depth GRAPHQL_COMPLEXITY_LIMIT=1000 # Maximum complexity score ``` #### CORS Configuration Control which origins can access your API: ```env CORS_ORIGIN=https://your-frontend.com # Specific origin # or CORS_ORIGIN=* # Allow all (not recommended for production) ``` ### Production Security Checklist - โœ… **Enable HTTPS** - Always use SSL/TLS in production - โœ… **Set NODE_ENV=production** - Enables production optimizations - โœ… **Enable Authentication** - Set `GRAPHQL_REQUIRE_AUTH=true` - โœ… **Use Strong API Keys** - Minimum 32 characters, randomly generated - โœ… **Configure CORS** - Restrict to your specific frontend domain - โœ… **Set Rate Limits** - Adjust based on your usage patterns - โœ… **Disable Introspection** - Set `ENABLE_INTROSPECTION=false` - โœ… **Hide Error Details** - Production mode sanitizes error messages - โœ… **Regular Updates** - Keep dependencies and Node.js updated - โœ… **Monitor Access Logs** - Track and audit API usage ### Security Headers The server includes Helmet.js for security headers: - X-Content-Type-Options: nosniff - X-Frame-Options: DENY - X-XSS-Protection: 1; mode=block - Strict-Transport-Security (when using HTTPS) - Content-Security-Policy (configurable) ### Endpoint Security | Endpoint | Authentication | Rate Limit | Description | |----------|---------------|------------|-------------| | `/graphql` | Optional/Required | Yes | Main GraphQL API | | `/health` | None | No | Health check | | `/schema-info` | Optional | Yes | Schema information | | `/refresh-schema` | Required | Strict | Manual schema refresh | ## ๐Ÿณ Coolify Deployment ### Step 1: Prepare Your Coolify Server 1. **Install Coolify** on your server following the [official documentation](https://coolify.io/docs/installation) 2. **Access Coolify** dashboard at `https://your-server.com:8000` ### Step 2: Create New Application 1. **Create Project**: - Go to "Projects" โ†’ "Create New Project" - Name: `EspoCRM GraphQL Server` - Description: `AI-optimized GraphQL server for EspoCRM` 2. **Add Application**: - Click "Create Application" - Choose "Dockerfile" deployment (NOT Docker Compose) - Repository: `https://github.com/CG-Labs/EspoCRM-GraphQL-Server.git` - Branch: `main` - Dockerfile Location: `./Dockerfile.coolify` ### Step 3: Configure Environment Variables In Coolify dashboard, add these **minimum required** environment variables: ```bash # Required Server Configuration NODE_ENV=production PORT=4000 LOG_LEVEL=info # Optional: EspoCRM Configuration (server will run without these) ESPOCRM_URL=https://your-espocrm.example.com # Note: Use ESPOCRM_URL not ESPOCRM_API_URL ESPOCRM_API_KEY=your_api_key_here # Optional: Database (for better performance) MYSQL_HOST=your_mysql_host MYSQL_USER=espocrm_user MYSQL_PASSWORD=your_secure_password MYSQL_DATABASE=espocrm_db # Optional: Security JWT_SECRET=generate_a_secure_random_string_here API_RATE_LIMIT=100 # Optional: Redis (Coolify can provision this) REDIS_URL=redis://redis:6379 # Optional: AI & Performance AI_OPTIMIZATION_ENABLED=true PERFORMANCE_MONITORING=true AUTO_SCHEMA_REFRESH=true # Optional: Organization Settings ORGANIZATION_NAME=Your Organization DEFAULT_CURRENCY=GBP PROPERTY_MANAGEMENT_MODE=true COMPLIANCE_MODE=GDPR_UK ``` **Important Notes:** - The server can start without EspoCRM configured - Use `ESPOCRM_URL` (not `ESPOCRM_API_URL`) for the base URL - The API path `/api/v1` is added automatically - Health checks will pass even without EspoCRM ### Step 4: Configure Docker Compose Coolify will use the `docker-compose.prod.yml` file: ```yaml version: '3.8' services: graphql: image: node:18-alpine working_dir: /app command: sh -c "npm ci --only=production && npm start" ports: - "4000:4000" environment: - NODE_ENV=production volumes: - .:/app depends_on: - redis healthcheck: test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:4000/health"] interval: 30s timeout: 10s retries: 3 start_period: 40s restart: unless-stopped redis: image: redis:7-alpine restart: unless-stopped volumes: - redis_data:/data healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 30s timeout: 10s retries: 3 volumes: redis_data: ``` ### Step 5: Deploy 1. **Deploy Application**: - Click "Deploy" in Coolify dashboard - Monitor deployment logs - Wait for health checks to pass 2. **Configure Domain** (Optional): - Go to "Domains" tab - Add your domain: `graphql.yourdomain.com` - Enable SSL/TLS (automatic with Let's Encrypt) 3. **Verify Deployment**: - Access GraphQL Playground: `https://graphql.yourdomain.com/graphql` - Check health endpoint: `https://graphql.yourdomain.com/health` ### Step 6: Production Optimizations #### Configure Monitoring ```bash # Add monitoring environment variables ENABLE_METRICS=true METRICS_PORT=9090 PROMETHEUS_ENDPOINT=/metrics ``` #### Setup Backups ```bash # In Coolify, configure automatic backups BACKUP_ENABLED=true BACKUP_SCHEDULE=0 2 * * * # Daily at 2 AM BACKUP_RETENTION=7 # Keep 7 days ``` #### Configure Scaling ```bash # Enable auto-scaling based on load COOLIFY_SCALE_MIN=1 COOLIFY_SCALE_MAX=5 COOLIFY_CPU_LIMIT=1000m COOLIFY_MEMORY_LIMIT=2Gi ``` ### Coolify Health Checks The application includes comprehensive health checks: ```bash # Health check endpoint GET /health # Response: { "status": "healthy", "timestamp": "2024-01-01T00:00:00.000Z", "uptime": 3600, "version": "1.0.0", "services": { "espocrm": "connected", "redis": "connected", "database": "connected" }, "performance": { "memoryUsage": "125MB", "cpuUsage": "15%", "responseTime": "45ms" } } ``` ### Troubleshooting Coolify Deployment **Common Issues:** 1. **Environment Variables Not Loading**: ```bash # Check environment in Coolify logs docker-compose logs graphql | grep ENV ``` 2. **Redis Connection Issues**: ```bash # Verify Redis service docker-compose ps redis docker-compose exec redis redis-cli ping ``` 3. **EspoCRM API Connection**: ```bash # Test API connectivity curl -H "X-Api-Key: $ESPOCRM_API_KEY" $ESPOCRM_API_URL/App/user ``` 4. **Memory Issues**: ```bash # Increase memory limit in Coolify COOLIFY_MEMORY_LIMIT=4Gi ``` ## ๐Ÿ—๏ธ Development ### Project Structure ``` espocrm-graphql/ โ”œโ”€โ”€ src/ โ”‚ โ”œโ”€โ”€ core/ # Core GraphQL logic โ”‚ โ”‚ โ”œโ”€โ”€ SchemaManager.js # Dynamic schema generation โ”‚ โ”‚ โ”œโ”€โ”€ TypeGenerator.js # GraphQL type creation โ”‚ โ”‚ โ”œโ”€โ”€ ResolverGenerator.js # Resolver generation โ”‚ โ”‚ โ””โ”€โ”€ AIOptimizer.js # AI-powered optimizations โ”‚ โ”œโ”€โ”€ clients/ # External service clients โ”‚ โ”‚ โ””โ”€โ”€ EspoCRMClient.js # EspoCRM API client โ”‚ โ”œโ”€โ”€ services/ # Business logic services โ”‚ โ”œโ”€โ”€ middleware/ # Express middleware โ”‚ โ”œโ”€โ”€ cache/ # Caching layer โ”‚ โ””โ”€โ”€ utils/ # Utility functions โ”œโ”€โ”€ tests/ # Test suites โ”œโ”€โ”€ config/ # Configuration files โ”œโ”€โ”€ docs/ # Documentation โ””โ”€โ”€ scripts/ # Deployment scripts ``` ### Development Commands ```bash # Development with hot reload npm run dev # Type checking npm run type-check # Linting npm run lint npm run lint:fix # Testing npm run test # Run all tests npm run test:unit # Unit tests only npm run test:integration # Integration tests npm run test:e2e # End-to-end tests npm run test:coverage # Test coverage report # Schema operations npm run schema:generate # Generate fresh schema npm run schema:validate # Validate current schema npm run schema:introspect # Introspect EspoCRM metadata # Performance testing npm run test:performance # Performance benchmarks npm run test:load # Load testing with Artillery # Build and deployment npm run build # Production build npm run start # Start production server npm run docker:build # Build Docker image npm run docker:run # Run Docker container ``` ### Adding New Features 1. **Create Feature Branch**: ```bash git checkout -b feature/new-feature ``` 2. **Implement Feature**: - Add code in appropriate `src/` directory - Follow TypeScript best practices - Add comprehensive tests 3. **Test Feature**: ```bash npm run test npm run test:integration npm run lint ``` 4. **Submit Pull Request**: - Ensure all tests pass - Include documentation updates - Add performance benchmarks if applicable ## ๐Ÿ“š API Documentation ### GraphQL Schema The server dynamically generates GraphQL schemas based on your EspoCRM metadata. Here are some example queries: #### Query Examples ```graphql # Get all contacts with pagination query GetContacts($first: Int, $after: String) { contacts(first: $first, after: $after) { edges { node { id name emailAddress phoneNumber account { name website } } } pageInfo { hasNextPage hasPreviousPage startCursor endCursor } } } # Property management specific query query GetProperties($filter: PropertyFilter) { properties(filter: $filter) { edges { node { id address propertyType rentAmount currency tenancies { edges { node { id status startDate endDate tenant { name emailAddress } } } } } } } } # AI-optimized bulk query query GetDashboardData { properties(first: 10) { totalCount edges { node { id address status } } } activeTenancies: tenancies(filter: { status: ACTIVE }) { totalCount } maintenanceRequests(filter: { status: OPEN }) { totalCount edges { node { id priority description property { address } } } } } ``` #### Mutation Examples ```graphql # Create a new property mutation CreateProperty($input: PropertyInput!) { createProperty(input: $input) { id address propertyType rentAmount currency status } } # Update tenancy status mutation UpdateTenancy($id: ID!, $input: TenancyUpdateInput!) { updateTenancy(id: $id, input: $input) { id status startDate endDate rentAmount } } # Bulk create maintenance requests mutation CreateMaintenanceRequests($inputs: [MaintenanceRequestInput!]!) { createMaintenanceRequests(inputs: $inputs) { id priority description status property { address } } } ``` #### Subscription Examples ```graphql # Real-time property updates subscription PropertyUpdates($propertyId: ID!) { propertyUpdated(id: $propertyId) { id status lastUpdated tenancy { status tenant { name } } } } # Maintenance request notifications subscription MaintenanceAlerts { maintenanceRequestCreated { id priority description property { address } } } ``` ### Authentication #### JWT Authentication ```javascript // Login to get JWT token const response = await fetch('/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username: 'user@example.com', password: 'password' }) }); const { token } = await response.json(); // Use token in GraphQL requests const graphqlResponse = await fetch('/graphql', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, body: JSON.stringify({ query: `query { contacts { edges { node { name } } } }` }) }); ``` #### API Key Authentication ```javascript // Use API key directly const response = await fetch('/graphql', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-API-Key': 'your-api-key-here' }, body: JSON.stringify({ query: `query { properties { totalCount } }` }) }); ``` ## โšก Performance Optimization ### Caching Strategy The server implements multi-layer caching: 1. **Schema Cache** (30 minutes TTL) 2. **Query Result Cache** (5 minutes TTL) 3. **Metadata Cache** (1 hour TTL) 4. **DataLoader Cache** (per-request) ### Query Optimization #### Use DataLoader for Related Data ```javascript // Instead of N+1 queries const contacts = await getContacts(); for (const contact of contacts) { const account = await getAccount(contact.accountId); // N+1 problem } // Use DataLoader (automatic) const contacts = await getContactsWithAccounts(); // Single optimized query ``` #### Pagination Best Practices ```graphql # Use cursor-based pagination for large datasets query GetLargeDataset($first: Int = 50, $after: String) { properties(first: $first, after: $after) { edges { cursor node { id address } } pageInfo { hasNextPage endCursor } } } ``` ### Performance Monitoring Access performance metrics at `/metrics`: ``` # GraphQL query performance graphql_query_duration_seconds{operation="GetContacts"} 0.045 graphql_query_count{operation="GetContacts",status="success"} 1523 # Cache performance cache_hit_rate{cache="schema"} 0.95 cache_miss_count{cache="query"} 145 # EspoCRM API performance espocrm_api_duration_seconds{endpoint="/Contact"} 0.120 espocrm_api_error_count{endpoint="/Contact"} 3 ``` ## ๐Ÿค– MCP Integration The server includes built-in support for the Model Context Protocol (MCP), allowing AI assistants like Claude to directly interact with your CRM data. ### What is MCP? MCP (Model Context Protocol) is an open protocol that enables AI assistants to connect with external data sources and tools in a secure, standardized way. ### Quick Setup #### Local MCP Server (Claude Desktop) 1. **Configure Claude Desktop:** Edit your Claude Desktop config: - macOS: `~/Library/Application Support/Claude/claude_desktop_config.json` ```json { "mcpServers": { "espocrm": { "command": "node", "args": ["/path/to/espocrm-graphql-server/dist/mcp/index.js"], "env": { "MCP_GRAPHQL_ENDPOINT": "http://localhost:4000/graphql", "MCP_API_KEY": "your-api-key" } } } } ``` 2. **Restart Claude Desktop** to load the MCP server. #### Remote MCP Server (Cloudflare Workers) Deploy as an internet-accessible MCP server: ```bash # Create Cloudflare Worker npm create cloudflare@latest espocrm-mcp --template=cloudflare/ai/demos/remote-mcp-authless # Deploy wrangler deploy ``` ### Available MCP Tools - **query_contacts** - Search and retrieve contacts - **query_accounts** - Search company information - **query_leads** - Retrieve sales leads - **create_contact** - Create new contacts - **execute_graphql** - Run custom GraphQL queries ### Use Cases - **Customer Support** - Quick customer lookups during support - **Sales Intelligence** - Query leads and opportunities - **Data Analysis** - Complex queries through natural language - **Automation** - Bulk operations via AI commands For complete MCP documentation, see [docs/MCP_INTEGRATION.md](docs/MCP_INTEGRATION.md). ## ๐Ÿงช Testing ### Running Tests ```bash # Run all tests npm test # Run specific test suites npm run test:unit # Unit tests npm run test:integration # Integration tests npm run test:e2e # End-to-end tests npm run test:performance # Performance tests # Run tests with coverage npm run test:coverage # Run tests in watch mode npm run test:watch ``` ### Test Structure ``` tests/ โ”œโ”€โ”€ unit/ # Unit tests โ”‚ โ”œโ”€โ”€ core/ # Core component tests โ”‚ โ”œโ”€โ”€ services/ # Service tests โ”‚ โ””โ”€โ”€ utils/ # Utility tests โ”œโ”€โ”€ integration/ # Integration tests โ”‚ โ”œโ”€โ”€ espocrm/ # EspoCRM API tests โ”‚ โ””โ”€โ”€ graphql/ # GraphQL API tests โ”œโ”€โ”€ e2e/ # End-to-end tests โ”œโ”€โ”€ performance/ # Performance benchmarks โ”œโ”€โ”€ load/ # Load testing โ””โ”€โ”€ fixtures/ # Test data ``` ### Writing Tests #### Unit Test Example ```javascript // tests/unit/core/SchemaManager.test.js import { SchemaManager } from '../../../src/core/SchemaManager.js'; describe('SchemaManager', () => { let schemaManager; beforeEach(() => { schemaManager = new SchemaManager({ espocrm: { apiUrl: 'http://test.com' } }); }); test('should generate schema from metadata', async () => { const metadata = { entities: ['Contact', 'Account'] }; const schema = await schemaManager.generateSchema(metadata); expect(schema).toBeDefined(); expect(schema.getType('Contact')).toBeDefined(); expect(schema.getType('Account')).toBeDefined(); }); }); ``` #### Integration Test Example ```javascript // tests/integration/graphql/queries.test.js import { createTestServer } from '../../utils/testServer.js'; describe('GraphQL Queries', () => { let server; beforeAll(async () => { server = await createTestServer(); }); test('should fetch contacts with pagination', async () => { const query = ` query { contacts(first: 10) { edges { node { id name } } pageInfo { hasNextPage } } } `; const response = await server.executeOperation({ query }); expect(response.errors).toBeUndefined(); expect(response.data.contacts.edges).toHaveLength(10); }); }); ``` ### Performance Testing ```bash # Run performance benchmarks npm run test:performance # Run load tests npm run test:load # Custom load test artillery run tests/load/artillery.config.yml ``` ## ๐Ÿ“Š Monitoring ### Health Checks The server provides comprehensive health checks: ```bash # Basic health check curl http://localhost:4000/health # Detailed health check curl http://localhost:4000/health/detailed # Readiness check (for Kubernetes) curl http://localhost:4000/ready # Liveness check (for Kubernetes) curl http://localhost:4000/live ``` ### Metrics and Observability #### Prometheus Metrics Access metrics at `http://localhost:4000/metrics`: - **HTTP Request Metrics**: Duration, status codes, request counts - **GraphQL Metrics**: Query performance, error rates, complexity scores - **EspoCRM API Metrics**: Response times, error rates, rate limiting - **Cache Metrics**: Hit rates, miss counts, evictions - **System Metrics**: Memory usage, CPU utilization, uptime #### Grafana Dashboard A pre-configured Grafana dashboard is available in `monitoring/grafana/`: 1. **GraphQL Performance**: Query response times, throughput, error rates 2. **EspoCRM Integration**: API response times, success rates, quota usage 3. **System Health**: Memory, CPU, disk usage, network I/O 4. **Business Metrics**: Property queries, tenant searches, maintenance requests #### Logging Structured logging with Winston: ```javascript // Log levels: error, warn, info, debug, trace logger.info('Schema generated successfully', { entities: metadata.entities.length, duration: Date.now() - startTime, version: schemaVersion }); logger.error('EspoCRM API error', { endpoint: '/Contact', statusCode: 500, error: error.message, requestId: req.id }); ``` ## ๐Ÿค Contributing We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details. ### Development Workflow 1. **Fork the repository** 2. **Create a feature branch**: `git checkout -b feature/amazing-feature` 3. **Make your changes** with proper tests 4. **Run the test suite**: `npm test` 5. **Commit your changes**: `git commit -m 'Add amazing feature'` 6. **Push to the branch**: `git push origin feature/amazing-feature` 7. **Open a Pull Request** ### Code Style - Use TypeScript for new code - Follow ESLint configuration - Write comprehensive tests - Document public APIs - Follow conventional commits ### Pull Request Process 1. Ensure all tests pass 2. Update documentation if needed 3. Add entry to CHANGELOG.md 4. Request review from maintainers 5. Address review feedback 6. Squash commits before merge ## ๐Ÿ“ž Support ### Getting Help - **Documentation**: Check this README and `/docs` folder - **GitHub Issues**: Report bugs and request features - **Discussions**: Community support and questions - **Email**: support@example.com ### Common Issues #### Schema Not Updating ```bash # Force schema refresh curl -X POST http://localhost:4000/admin/refresh-schema # Check schema cache curl http://localhost:4000/admin/cache-stats ``` #### Performance Issues ```bash # Check metrics curl http://localhost:4000/metrics # Enable debug logging export LOG_LEVEL=debug npm restart ``` #### EspoCRM Connection Problems ```bash # Test API connectivity curl -H "X-Api-Key: $ESPOCRM_API_KEY" $ESPOCRM_API_URL/App/user # Check API quota curl -H "X-Api-Key: $ESPOCRM_API_KEY" $ESPOCRM_API_URL/App/user/acl ``` ### Troubleshooting Guide See our detailed [Troubleshooting Guide](docs/TROUBLESHOOTING.md) for common issues and solutions. ## ๐Ÿ“„ License This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. ## ๐Ÿ™ Acknowledgments - [Apollo GraphQL](https://www.apollographql.com/) for the excellent GraphQL server - [EspoCRM](https://www.espocrm.com/) for the flexible CRM platform - Our amazing community of contributors --- **Built with โค๏ธ for the open source community** For more information, visit the [GitHub repository](https://github.com/davidkennedy/espocrm-graphql-server).