zabbix-graphql-api/AGENTS.md

124 lines
No EOL
5.1 KiB
Markdown

# 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<T>`
- 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