# Zabbix GraphQL API - AI Coding Instructions ## Project Overview This is a **GraphQL wrapper for Zabbix API** that provides enhanced mass import/export operations, hierarchical host group management, and dynamic schema extensibility. It's built with **Apollo Server**, TypeScript, and uses ES modules throughout. ## Architecture & Key Patterns ### Core Components - **Entry Point**: `src/index.ts` → `src/api/start.ts` (Apollo Server setup) - **Schema Loading**: `src/api/schema.ts` - Dynamic schema merging with extensibility via env vars - **Resolvers**: `src/api/resolvers.ts` + dynamic hierarchical resolvers via `resolver_helpers.ts` - **DataSources**: `src/datasources/` - Zabbix API wrappers extending `RESTDataSource` - **Execution**: `src/execution/` - Complex business logic (importers, deleters) ### Critical Patterns #### 1. Hierarchical Data Mapping The core innovation is **automatic mapping** of Zabbix items/tags to GraphQL nested objects: - Zabbix item key `state.current.values.temperature` → GraphQL `{ state: { current: { values: { temperature } } } }` - Use `createHierarchicalValueFieldResolver()` in `resolver_helpers.ts` - Type hints: `json_`, `str_`, `bool_`, `float_` prefixes for value conversion #### 2. Dynamic Schema Extension (No-Code) Configure via environment variables: ```bash ADDITIONAL_SCHEMAS=./schema/extensions/display_devices.graphql,./schema/extensions/location_tracker_devices.graphql ADDITIONAL_RESOLVERS=SinglePanelDevice,FourPanelDevice,DistanceTrackerDevice ``` Schema loads dynamically in `schema.ts`, resolvers auto-generated for listed types. #### 3. Mass Import/Export Pattern All importers follow hierarchy-first approach: - **Host Groups**: Process parent groups before children (`getHostGroupHierarchyNames()`) - **Template Dependencies**: Handle dependent items via deferred creation logic - **Batch Processing**: Each importer returns array of `Response` objects with success/error details #### 4. Permission System Uses Zabbix template groups as permission containers: - Template groups with prefix `Permissions/` (configurable via `ZABBIX_PERMISSION_TEMPLATE_GROUP_NAME_PREFIX`) - Queries: `hasPermissions()`, `userPermissions()` in resolvers - Integration: `ZabbixRequestWithPermissions` wrapper class ## Development Workflow ### Essential Commands ```bash # Development with hot reload npm run start # Production build & run npm run compile && npm run prod # GraphQL code generation (watch mode) npm run codegen # Testing (with ES modules + mocking setup) npm test ``` ### Environment Setup Key variables (see README for complete list): ```bash ZABBIX_BASE_URL=http://zabbix.example.com/zabbix ZABBIX_AUTH_TOKEN=your-super-admin-token ZABBIX_EDGE_DEVICE_BASE_GROUP=Roadwork SCHEMA_PATH=./schema/ ``` ### Testing Patterns - **ES Module Mocking**: Uses `jest.mock()` with proper module resolution - **API Mocking**: Mock `zabbixAPI.executeRequest()` and `zabbixAPI.post()` - **Permission Bypass**: Mock `ZabbixRequestWithPermissions` for unit tests - **Integration Tests**: Use real GraphQL queries against mocked Zabbix responses ## File Organization & Conventions ### Schema Files (`schema/`) - `queries.graphql`, `mutations.graphql` - Main API surface - `devices.graphql`, `zabbix.graphql` - Core types - `extensions/` - Custom device types for schema extension ### DataSource Naming - Pattern: `zabbix-{entity}.ts` (e.g., `zabbix-hosts.ts`, `zabbix-templates.ts`) - Each exports specialized request classes extending `ZabbixRequest` - Helper classes: `{Entity}Helper` for common operations ### Generated Code - `src/schema/generated/graphql.ts` - Auto-generated from schema via GraphQL Code Generator - Enum values imported from `src/model/model_enum_values.ts` - **Never edit generated files directly** ### Import Statements **Always use `.js` extensions** in imports due to ES modules: ```typescript import {logger} from "../logging/logger.js"; // ✅ Correct import {logger} from "../logging/logger"; // ❌ Will fail ``` ## Debugging & Extensions ### Adding New Device Types 1. Create schema in `schema/extensions/{name}.graphql` 2. Add to `ADDITIONAL_SCHEMAS` env var 3. Add type name to `ADDITIONAL_RESOLVERS` env var 4. Ensure Zabbix items use dot-separated keys matching GraphQL field names ### Common Issues - **Module Resolution**: Check `.js` extensions in imports - **Permission Errors**: Verify `ZABBIX_AUTH_TOKEN` has Super Admin rights - **Schema Changes**: Run `npm run codegen` after modifying `.graphql` files - **Hierarchical Mapping**: Debug via `createHierarchicalValueFieldResolver()` logs ### Integration Points - **Zabbix API**: All requests go through `ZabbixAPI` class (extends `RESTDataSource`) - **Authentication**: Supports both API tokens and session cookies - **WebSocket**: GraphQL subscriptions enabled via `graphql-ws` - **Docker**: Multi-stage build with `API_VERSION` build arg ## Testing Strategy Focus on: 1. **Unit Tests**: Mock Zabbix API responses, test business logic 2. **Integration Tests**: Real GraphQL operations with mocked datasources 3. **Permission Tests**: Verify access control logic 4. **Import/Export Tests**: Test hierarchical processing and error handling