docs: refactor documentation and upgrade to Node.js 24

This commit upgrades the project to Node.js 24 (LTS) and performs a major refactoring of the documentation to support both advanced users and AI-based automation (MCP).

Changes:
- Environment & CI/CD:
  - Set Node.js version to >=24 in package.json and .nvmrc.
  - Updated Dockerfile to use Node 24 base image.
  - Updated @types/node to ^24.10.9.
- Documentation:
  - Refactored README.md with comprehensive technical reference, configuration details, and Zabbix-to-GraphQL mapping.
  - Created docs/howtos/cookbook.md with practical recipes for common tasks and AI test generation.
  - Updated docs/howtos/mcp.md to emphasize GraphQL's advantages for AI agents and Model Context Protocol.
  - Added readme.improvement.plan.md to track documentation evolution.
  - Enhanced all how-to guides with improved cross-references and up-to-date information.
- Guidelines:
  - Updated .junie/guidelines.md with Node 24 requirements and enhanced commit message standards (Conventional Commits 1.0.0).
- Infrastructure & Code:
  - Updated docker-compose.yml with Apollo MCP server integration.
  - Refined configuration and schema handling in src/api/ and src/datasources/.
  - Synchronized generated TypeScript types with schema updates.
This commit is contained in:
Andreas Hilbig 2026-01-30 14:34:09 +01:00
parent 4ec61ffba1
commit a01bfabfba
28 changed files with 395 additions and 170 deletions

View file

@ -4,7 +4,7 @@
<env name="ADDITIONAL_RESOLVERS" value="SinglePanelDevice,FourPanelDevice,DistanceTrackerDevice" />
<env name="ADDITIONAL_SCHEMAS" value="./schema/extensions/display_devices.graphql,./schema/extensions/location_tracker_devices.graphql,./schema/extensions/location_tracker_commons.graphql" />
<env name="DEBUG" value="device-control-center-api:*" />
<env name="ZABBIX_AUTH_TOKEN" value="$ZABBIX_AUTH_TOKEN_VCR_DEV$" />
<env name="ZABBIX_PRIVILEGE_ESCALATION_TOKEN" value="$ZABBIX_AUTH_TOKEN_VCR_DEV$" />
<env name="ZABBIX_BASE_URL" value="http://cockpit.vcr.develop.hilbigit.com/" />
<env name="ZABBIX_PERMISSION_TEMPLATE_GROUP_NAME_PREFIX" value="Permissions" />
<env name="ZABBIX_ROADWORK_BASE_GROUP" value="Roadwork/Devices" />

125
.idea/workspace.xml generated
View file

@ -4,30 +4,9 @@
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="d7a71994-2699-4ae4-9fd2-ee13b7f33d35" name="Changes" comment="chore: update `.idea/workspace.xml` and project guidelines &#10;&#10;- Refined IntelliJ IDEA settings in `.idea/workspace.xml`, including updates to `ProblemsViewState` and `PropertiesComponent` for project consistency. &#10;- Renamed and expanded `.junie/guidelines.md` to reflect updated best practices, project structure, and development workflows.">
<list default="true" id="d7a71994-2699-4ae4-9fd2-ee13b7f33d35" name="Changes" comment="chore: add MCP integration and refactor documentation into modular how-to guides &#10;&#10;- Moved GraphQL query samples into a new `docs/queries` directory for better organization. &#10;- Added new queries and mutations, including `createHost.graphql` and `GetApiVersion.graphql`. &#10;- Introduced `mcp-config.yaml` and updated `docker-compose.yml` for MCP integration. &#10;- Updated IntelliJ `.idea/workspace.xml` settings to reflect project changes. &#10;- Added new how-to guides (`docs/howtos`) for permissions, tags, MCP integration, and schema usage. &#10;- Enhanced tests by updating file paths and improving sample data locations. &#10;- Refined permissions and host group structures in `zabbix-hostgroups.ts` and `resolvers.ts`.">
<change beforePath="$PROJECT_DIR$/.idea/runConfigurations/index_ts.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/runConfigurations/index_ts.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.junie/guidelines.md" beforeDir="false" afterPath="$PROJECT_DIR$/.junie/guidelines.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/README.md" beforeDir="false" afterPath="$PROJECT_DIR$/README.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/docs/sample_all_devices_query.graphql" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/docs/sample_all_host_groups_query.graphql" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/docs/sample_all_hosts_query.graphql" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/docs/sample_all_template_groups_query.graphql" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/docs/sample_delete_template_groups_mutation.graphql" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/docs/sample_delete_templates_mutation.graphql" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/docs/sample_export_user_rights_query.graphql" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/docs/sample_import_distance_tracker_template.graphql" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/docs/sample_import_host_groups_mutation.graphql" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/docs/sample_import_host_template_groups_mutation.graphql" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/docs/sample_import_hosts_mutation.graphql" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/docs/sample_import_permissions_template_groups_mutation.graphql" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/docs/sample_import_templates_mutation.graphql" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/docs/sample_import_user_rights_mutation.graphql" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/docs/sample_templates_query.graphql" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/api/resolvers.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/api/resolvers.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/datasources/zabbix-hostgroups.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/datasources/zabbix-hostgroups.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/test/host_integration.test.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/test/host_integration.test.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/test/template_integration.test.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/test/template_integration.test.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/test/user_rights_integration.test.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/test/user_rights_integration.test.ts" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@ -38,7 +17,7 @@
<execution />
</component>
<component name="EmbeddingIndexingInfo">
<option name="cachedIndexableFilesCount" value="106" />
<option name="cachedIndexableFilesCount" value="109" />
<option name="fileBasedEmbeddingIndicesEnabled" value="true" />
</component>
<component name="Git.Settings">
@ -80,45 +59,45 @@
<option name="openDirectoriesWithSingleClick" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"NIXITCH_NIXPKGS_CONFIG": "",
"NIXITCH_NIX_CONF_DIR": "",
"NIXITCH_NIX_OTHER_STORES": "",
"NIXITCH_NIX_PATH": "",
"NIXITCH_NIX_PROFILES": "",
"NIXITCH_NIX_REMOTE": "",
"NIXITCH_NIX_USER_PROFILE_DIR": "",
"Node.js.index.ts.executor": "Run",
"RunOnceActivity.MCP Project settings loaded": "true",
"RunOnceActivity.ShowReadmeOnStart": "true",
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
"RunOnceActivity.git.unshallow": "true",
"RunOnceActivity.typescript.service.memoryLimit.init": "true",
"com.intellij.ml.llm.matterhorn.ej.ui.settings.DefaultModelSelectionForGA.v1": "true",
"git-widget-placeholder": "main",
"go.import.settings.migrated": "true",
"javascript.preferred.runtime.type.id": "node",
"junie.onboarding.icon.badge.shown": "true",
"last_opened_file_path": "//wsl.localhost/Ubuntu/home/ahilbig/git/vcr/zabbix-graphql-api/src",
"node.js.detected.package.eslint": "true",
"node.js.detected.package.tslint": "true",
"node.js.selected.package.eslint": "(autodetect)",
"node.js.selected.package.tslint": "(autodetect)",
"nodejs_interpreter_path": "wsl://Ubuntu@/home/ahilbig/.nvm/versions/node/v24.12.0/bin/node",
"nodejs_package_manager_path": "npm",
"npm.codegen.executor": "Run",
"npm.compile.executor": "Run",
"npm.copy-schema.executor": "Run",
"npm.prod.executor": "Run",
"npm.test.executor": "Run",
"settings.editor.selected.configurable": "junie.mcp",
"settings.editor.splitter.proportion": "0.28812414",
"to.speed.mode.migration.done": "true",
"ts.external.directory.path": "\\\\wsl.localhost\\Ubuntu\\home\\ahilbig\\git\\vcr\\zabbix-graphql-api\\node_modules\\typescript\\lib",
"vue.rearranger.settings.migration": "true"
<component name="PropertiesComponent">{
&quot;keyToString&quot;: {
&quot;NIXITCH_NIXPKGS_CONFIG&quot;: &quot;&quot;,
&quot;NIXITCH_NIX_CONF_DIR&quot;: &quot;&quot;,
&quot;NIXITCH_NIX_OTHER_STORES&quot;: &quot;&quot;,
&quot;NIXITCH_NIX_PATH&quot;: &quot;&quot;,
&quot;NIXITCH_NIX_PROFILES&quot;: &quot;&quot;,
&quot;NIXITCH_NIX_REMOTE&quot;: &quot;&quot;,
&quot;NIXITCH_NIX_USER_PROFILE_DIR&quot;: &quot;&quot;,
&quot;Node.js.index.ts.executor&quot;: &quot;Run&quot;,
&quot;RunOnceActivity.MCP Project settings loaded&quot;: &quot;true&quot;,
&quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
&quot;RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252&quot;: &quot;true&quot;,
&quot;RunOnceActivity.git.unshallow&quot;: &quot;true&quot;,
&quot;RunOnceActivity.typescript.service.memoryLimit.init&quot;: &quot;true&quot;,
&quot;com.intellij.ml.llm.matterhorn.ej.ui.settings.DefaultModelSelectionForGA.v1&quot;: &quot;true&quot;,
&quot;git-widget-placeholder&quot;: &quot;main&quot;,
&quot;go.import.settings.migrated&quot;: &quot;true&quot;,
&quot;javascript.preferred.runtime.type.id&quot;: &quot;node&quot;,
&quot;junie.onboarding.icon.badge.shown&quot;: &quot;true&quot;,
&quot;last_opened_file_path&quot;: &quot;//wsl.localhost/Ubuntu/home/ahilbig/git/vcr/zabbix-graphql-api/src&quot;,
&quot;node.js.detected.package.eslint&quot;: &quot;true&quot;,
&quot;node.js.detected.package.tslint&quot;: &quot;true&quot;,
&quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;,
&quot;node.js.selected.package.tslint&quot;: &quot;(autodetect)&quot;,
&quot;nodejs_interpreter_path&quot;: &quot;wsl://Ubuntu@/home/ahilbig/.nvm/versions/node/v24.12.0/bin/node&quot;,
&quot;nodejs_package_manager_path&quot;: &quot;npm&quot;,
&quot;npm.codegen.executor&quot;: &quot;Run&quot;,
&quot;npm.compile.executor&quot;: &quot;Run&quot;,
&quot;npm.copy-schema.executor&quot;: &quot;Run&quot;,
&quot;npm.prod.executor&quot;: &quot;Run&quot;,
&quot;npm.test.executor&quot;: &quot;Run&quot;,
&quot;settings.editor.selected.configurable&quot;: &quot;ml.llm.mcp&quot;,
&quot;settings.editor.splitter.proportion&quot;: &quot;0.28812414&quot;,
&quot;to.speed.mode.migration.done&quot;: &quot;true&quot;,
&quot;ts.external.directory.path&quot;: &quot;\\\\wsl.localhost\\Ubuntu\\home\\ahilbig\\git\\vcr\\zabbix-graphql-api\\node_modules\\typescript\\lib&quot;,
&quot;vue.rearranger.settings.migration&quot;: &quot;true&quot;
}
}]]></component>
}</component>
<component name="RecapSpentCounter">
<option name="endsOfQuotaMs" value="1768327208764" />
<option name="spentUsd" value="0.04010335" />
@ -160,7 +139,7 @@
<env name="ADDITIONAL_RESOLVERS" value="SinglePanelDevice,FourPanelDevice,DistanceTrackerDevice" />
<env name="ADDITIONAL_SCHEMAS" value="./schema/extensions/display_devices.graphql,./schema/extensions/location_tracker_devices.graphql,./schema/extensions/location_tracker_commons.graphql" />
<env name="DEBUG" value="device-control-center-api:*" />
<env name="ZABBIX_AUTH_TOKEN" value="$ZABBIX_AUTH_TOKEN_VCR_DEV$" />
<env name="ZABBIX_PRIVILEGE_ESCALATION_TOKEN" value="$ZABBIX_AUTH_TOKEN_VCR_DEV$" />
<env name="ZABBIX_BASE_URL" value="http://cockpit.vcr.develop.hilbigit.com/" />
<env name="ZABBIX_PERMISSION_TEMPLATE_GROUP_NAME_PREFIX" value="Permissions" />
<env name="ZABBIX_ROADWORK_BASE_GROUP" value="Roadwork/Devices" />
@ -220,7 +199,7 @@
<workItem from="1769256682556" duration="8928000" />
<workItem from="1769699975260" duration="75000" />
<workItem from="1769700092648" duration="5212000" />
<workItem from="1769724930397" duration="3476000" />
<workItem from="1769724930397" duration="14118000" />
</task>
<task id="LOCAL-00001" summary="chore: Update IntelliJ workspace settings and add GitHub Actions workflow for Docker deployment">
<option name="closed" value="true" />
@ -406,7 +385,15 @@
<option name="project" value="LOCAL" />
<updated>1769597550348</updated>
</task>
<option name="localTasksCounter" value="24" />
<task id="LOCAL-00024" summary="chore: add MCP integration and refactor documentation into modular how-to guides &#10;&#10;- Moved GraphQL query samples into a new `docs/queries` directory for better organization. &#10;- Added new queries and mutations, including `createHost.graphql` and `GetApiVersion.graphql`. &#10;- Introduced `mcp-config.yaml` and updated `docker-compose.yml` for MCP integration. &#10;- Updated IntelliJ `.idea/workspace.xml` settings to reflect project changes. &#10;- Added new how-to guides (`docs/howtos`) for permissions, tags, MCP integration, and schema usage. &#10;- Enhanced tests by updating file paths and improving sample data locations. &#10;- Refined permissions and host group structures in `zabbix-hostgroups.ts` and `resolvers.ts`.">
<option name="closed" value="true" />
<created>1769730441542</created>
<option name="number" value="00024" />
<option name="presentableId" value="LOCAL-00024" />
<option name="project" value="LOCAL" />
<updated>1769730441542</updated>
</task>
<option name="localTasksCounter" value="25" />
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
@ -436,9 +423,6 @@
</option>
</component>
<component name="VcsManagerConfiguration">
<MESSAGE value="chore: Update IntelliJ workspace settings and add GitHub Actions workflow for Docker deployment" />
<MESSAGE value="chore: Add missing &quot;.js&quot; extensions to imports and improve Node.js compatibility for dynamic schema loading" />
<MESSAGE value="chore: Update IntelliJ workspace and fix Docker image tag in workflow" />
<MESSAGE value="chore: Add dry-run mode and configure logger for operation mode logging" />
<MESSAGE value="chore: Add test for Zabbix API arguments parsing" />
<MESSAGE value="chore: Replace copying of `schema.graphql` with `extensions` in Dockerfile" />
@ -461,7 +445,10 @@
<MESSAGE value="chore: add tests for schema and API config mocking&#10;&#10;- Added unit tests for schema loader, mocking Config variables and resolvers.&#10;- Added unit tests for Zabbix API configuration, verifying constants derived from Config.&#10;- Mocked relevant modules and filesystem behaviors to enable isolated testing.&#10;- Optimized imports on all files" />
<MESSAGE value="chore: add tests for schema and API config mocking&#10;&#10;- Added unit tests for schema loader, mocking Config variables and resolvers.&#10;- Added unit tests for Zabbix API configuration, verifying constants derived from Config.&#10;- Mocked relevant modules and filesystem behaviors to enable isolated testing.&#10;- Optimized imports on all files and include this within a new .junie/guidelines.md file" />
<MESSAGE value="chore: update `.idea/workspace.xml` and project guidelines &#10;&#10;- Refined IntelliJ IDEA settings in `.idea/workspace.xml`, including updates to `ProblemsViewState` and `PropertiesComponent` for project consistency. &#10;- Renamed and expanded `.junie/guidelines.md` to reflect updated best practices, project structure, and development workflows." />
<option name="LAST_COMMIT_MESSAGE" value="chore: update `.idea/workspace.xml` and project guidelines &#10;&#10;- Refined IntelliJ IDEA settings in `.idea/workspace.xml`, including updates to `ProblemsViewState` and `PropertiesComponent` for project consistency. &#10;- Renamed and expanded `.junie/guidelines.md` to reflect updated best practices, project structure, and development workflows." />
<MESSAGE value="feat: add MCP integration and refactor documentation into modular how-to guides&quot; &#10;&#10;- Moved query files to a centralized `docs/queries/` directory for better organization. &#10;- Added example files under `mcp/operations` to support MCP integration. &#10;- Introduced a `docker-compose.yml` file for easier local development and deployment of services. &#10;- Updated tests to reflect the relocation of query files. &#10;- Enhanced IntelliJ `.idea/workspace.xml` settings for project consistency. " />
<MESSAGE value="chore: add MCP integration and refactor documentation into modular how-to guides &#10;&#10;- Moved GraphQL query samples into a new `docs/queries` directory for better organization. &#10;- Added new queries and mutations, including `createHost.graphql` and `GetApiVersion.graphql`. &#10;- Introduced `mcp-config.yaml` and updated `docker-compose.yml` for MCP integration. &#10;- Updated IntelliJ `.idea/workspace.xml` settings to reflect project changes. &#10;- Added new how-to guides (`docs/howtos`) for permissions, tags, MCP integration, and schema usage. &#10;- Enhanced tests by updating file paths and improving sample data locations. &#10;- Refined permissions and host group structures in `zabbix-hostgroups.ts` and `resolvers.ts`." />
<MESSAGE value="docs: refactor documentation and upgrade to Node.js 24&#10;&#10;This commit upgrades the project to Node.js 24 (LTS) and performs a major refactoring of the documentation to support both advanced users and AI-based automation (MCP).&#10;&#10;Changes:&#10;- Environment &amp; CI/CD:&#10; - Set Node.js version to &gt;=24 in package.json and .nvmrc.&#10; - Updated Dockerfile to use Node 24 base image.&#10; - Updated @types/node to ^24.10.9.&#10;- Documentation:&#10; - Refactored README.md with comprehensive technical reference, configuration details, and Zabbix-to-GraphQL mapping.&#10; - Created docs/howtos/cookbook.md with practical recipes for common tasks and AI test generation.&#10; - Updated docs/howtos/mcp.md to emphasize GraphQL's advantages for AI agents and Model Context Protocol.&#10; - Added readme.improvement.plan.md to track documentation evolution.&#10; - Enhanced all how-to guides with improved cross-references and up-to-date information.&#10;- Guidelines:&#10; - Updated .junie/guidelines.md with Node 24 requirements and enhanced commit message standards (Conventional Commits 1.0.0).&#10;- Infrastructure &amp; Code:&#10; - Updated docker-compose.yml with Apollo MCP server integration.&#10; - Refined configuration and schema handling in src/api/ and src/datasources/.&#10; - Synchronized generated TypeScript types with schema updates." />
<option name="LAST_COMMIT_MESSAGE" value="docs: refactor documentation and upgrade to Node.js 24&#10;&#10;This commit upgrades the project to Node.js 24 (LTS) and performs a major refactoring of the documentation to support both advanced users and AI-based automation (MCP).&#10;&#10;Changes:&#10;- Environment &amp; CI/CD:&#10; - Set Node.js version to &gt;=24 in package.json and .nvmrc.&#10; - Updated Dockerfile to use Node 24 base image.&#10; - Updated @types/node to ^24.10.9.&#10;- Documentation:&#10; - Refactored README.md with comprehensive technical reference, configuration details, and Zabbix-to-GraphQL mapping.&#10; - Created docs/howtos/cookbook.md with practical recipes for common tasks and AI test generation.&#10; - Updated docs/howtos/mcp.md to emphasize GraphQL's advantages for AI agents and Model Context Protocol.&#10; - Added readme.improvement.plan.md to track documentation evolution.&#10; - Enhanced all how-to guides with improved cross-references and up-to-date information.&#10;- Guidelines:&#10; - Updated .junie/guidelines.md with Node 24 requirements and enhanced commit message standards (Conventional Commits 1.0.0).&#10;- Infrastructure &amp; Code:&#10; - Updated docker-compose.yml with Apollo MCP server integration.&#10; - Refined configuration and schema handling in src/api/ and src/datasources/.&#10; - Synchronized generated TypeScript types with schema updates." />
<option name="OPTIMIZE_IMPORTS_BEFORE_PROJECT_COMMIT" value="true" />
</component>
<component name="XDebuggerManager">

View file

@ -4,11 +4,11 @@ This document provides concise information and best practices for developers wor
### Environment
- **Operating System:** Windows with WSL + Ubuntu installed.
- **Commands:** Always execute Linux commands (e.g., use `ls` instead of `dir`).
- **Commands:** Always execute Linux commands (e.g. use `ls` instead of `dir`).
## Tech Stack
- **Runtime**: Node.js (v18+)
- **Runtime**: Node.js (v24+)
- **Language**: TypeScript (ESM)
- **API**: GraphQL (Apollo Server 4)
- **Testing**: Jest
@ -30,16 +30,17 @@ This document provides concise information and best practices for developers wor
- `npm run prod`: Prepares the schema and runs the compiled production build.
## Best Practices & Standards
- **ESM & Imports**: The project uses ECMAScript Modules (ESM). Always use the `.js` extension when importing local files (e.g., `import { Config } from "../common_utils.js";`), even though the source files are `.ts`.
- **ESM & Imports**: The project uses ECMAScript Modules (ESM). Always use the `.js` extension when importing local files (e.g. `import { Config } from "../common_utils.js";`), even though the source files are `.ts`.
- **Configuration**: Always use the `Config` class to access environment variables. Avoid direct `process.env` calls.
- **Type Safety**: Leverage types generated via `npm run codegen` for resolvers and data handling to ensure consistency with the schema.
- **Import Optimization**:
- Always optimize imports before committing.
- Project setting `OPTIMIZE_IMPORTS_BEFORE_PROJECT_COMMIT` is enabled.
- Junie should include "Optimize imports" as a step in every plan.
- **Modular Datasources**: When adding support for new Zabbix features, create a new datasource class in `src/datasources/` extending `ZabbixRESTDataSource`.
- **Schema Organization**: Place GraphQL SDL files in the `schema/` directory. Use descriptive comments in SDL as they are used for API documentation.
- **Testing**: Write reproduction tests for bugs and cover new features with both unit and integration tests in `src/test/`.
- **Grammar & Style**: Avoid using a comma after "e.g." or "i.e." (e.g. use "e.g. example" instead of "e.g., example").
### Git Standards
- **Commit Messages:** Use [Conventional Commits](https://www.conventionalcommits.org/) (e.g., `feat:`, `fix:`, `chore:`, `docs:`, `test:`, `refactor:`, `style:`).
- **Commit Messages:** Use [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) (e.g. `feat:`, `fix:`, `chore:`, `docs:`, `test:`, `refactor:`, `style:`).
- If a commit is complex and covers different aspects, the message **must** always contain a detailed list of what was changed within the optional "body" section, in addition to the short "description" in the header.

1
.nvmrc Normal file
View file

@ -0,0 +1 @@
24

View file

@ -1,7 +1,7 @@
# Hint: With node_version>=21.6.0 there are problems with debugging,
# therefore the development node version is set to 21.5.0 + in order to keep dev + prod versions aligned
# therefore the development node version is set to 24 + in order to keep dev + prod versions aligned
# this was also reflected in the Dockerfile
ARG node_version=21.5.0
ARG node_version=24
#stage1
FROM node:${node_version} as builder

120
README.md
View file

@ -6,37 +6,39 @@ A modern GraphQL interface for Zabbix, providing enhanced features and easier in
The Zabbix GraphQL API acts as a wrapper and enhancer for the native Zabbix JSON-RPC API. It simplifies complex operations, provides a strongly-typed schema, and adds advanced logic for importing, querying, and managing Zabbix entities like hosts, templates, and user rights.
## Key Features & Enhancements
## 🚀 Features
Compared to the original Zabbix API, this GraphQL API provides several key enhancements:
- **GraphQL Interface**: Modern GraphQL API wrapping Zabbix functionality
- *Reference*: `schema/queries.graphql`, `schema/mutations.graphql`, `src/api/start.ts`
* **Mass Import/Export**: Robust support for importing and exporting templates, template groups, hosts, and host groups in bulk.
* **Hierarchical Host Groups**: Automatically handles the creation and resolution of nested host group hierarchies (e.g., `Parent/Child/Leaf`).
* **Template Management**:
* Full support for template items, including complex preprocessing steps and tags.
* **Dependent Item Support**: Intelligent deferred creation logic to handle item dependencies within a template.
* Linked template resolution by name.
* **Advanced Deletion**: Ability to delete templates and template groups not only by ID but also by **name patterns** (supporting Zabbix wildcards like `%`).
* **User Rights & Permissions**:
* Integrated management of user roles and user groups.
* Support for importing/exporting user rights with UUID-based matching for cross-instance consistency.
* On-the-fly permission checks (`hasPermissions`, `userPermissions`).
* **Improved Error Reporting**: Detailed error data from Zabbix is appended to GraphQL error messages, making debugging significantly easier.
* **Strongly Typed Schema**: Leverages GraphQL's type system for clear API documentation and client-side code generation.
* **Dynamic Schema Extensibility**: Easily extend the API with custom schema snippets and dynamic resolvers for specialized device types without modifying the core code.
* **CI/CD Integration**: Includes a ready-to-use Forgejo/Gitea/GitHub Actions workflow for automated building, testing, and deployment.
* **MCP Integration**: Native support for the **Model Context Protocol (MCP)**, enabled by GraphQL's introspectable schema, allowing LLMs to seamlessly interact with Zabbix data.
* **Sample Application (VCR)**: Designed to power the **Virtual Control Room**, a professional cockpit for managing thousands of IoT/Edge devices.
- **Hierarchical Data Mapping**: Automatic mapping of Zabbix items/tags to nested GraphQL objects
- *Reference*: `src/api/resolver_helpers.ts`, `schema/device_value_commons.graphql`, `docs/sample_all_devices_query.graphql`
- **Mass Operations**: Import/export capabilities for hosts, templates, and user rights
- *Reference*: `schema/mutations.graphql` (importHosts, importTemplates, importUserRights, etc.), `docs/sample_import_*.graphql`
- **Dynamic Schema Extension**: Extend the schema without code changes using environment variables
- *Reference*: `src/api/schema.ts`, `schema/extensions/`, `src/common_utils.ts` (ADDITIONAL_SCHEMAS, ADDITIONAL_RESOLVERS)
- **Permission System**: Role-based access control using Zabbix template groups
- *Reference*: `schema/api_commons.graphql` (Permission enum, PermissionRequest), `src/api/resolvers.ts` (hasPermissions, userPermissions), `docs/sample_import_permissions_template_groups_mutation.graphql`
- **Type Safety**: Full TypeScript support with generated types
- *Reference*: `codegen.ts`, `src/schema/generated/graphql.ts`, `tsconfig.json`, `package.json` (devDependencies for GraphQL Codegen)
- **AI Agent & MCP Enablement**: Native support for Model Context Protocol (MCP) and AI-driven automation. GraphQL's strongly-typed, introspectable nature provides a superior interface for AI agents compared to traditional REST APIs.
- *Reference*: `docs/howtos/mcp.md`, `mcp-config.yaml`, `docker-compose.yml` (MCP service)
## How-To Guides
For detailed information on specific topics, please refer to our how-to guides:
* [**Cookbook**](./docs/howtos/cookbook.md): Practical, step-by-step recipes for quick start and AI test generation.
* [**Schema & Extension Overview**](./docs/howtos/schema.md): Detailed explanation of the schema structure and extension mechanism.
* [**Hierarchical Data Mapping**](./docs/howtos/hierarchical_data_mapping.md): How Zabbix items are mapped to nested GraphQL fields.
* [**Roles & Permissions**](./docs/howtos/permissions.md): Managing user rights through Zabbix template groups.
* [**Zabbix Tags Usage**](./docs/howtos/tags.md): Using tags for classification and metadata.
* [**MCP Integration**](./docs/howtos/mcp.md): Connecting LLMs to Zabbix via Model Context Protocol.
* [**MCP & Agent Integration**](./docs/howtos/mcp.md): Connecting LLMs and autonomous agents to Zabbix via Model Context Protocol.
See the [How-To Overview](./docs/howtos/README.md) for a complete list of documentation.
@ -44,7 +46,7 @@ See the [How-To Overview](./docs/howtos/README.md) for a complete list of docume
### Prerequisites
* **Node.js**: Version 18 or higher recommended.
* **Node.js**: Version 24 (LTS) or higher recommended.
* **Zabbix**: A running Zabbix instance (compatible with Zabbix 6.0+).
### Installation
@ -60,19 +62,59 @@ See the [How-To Overview](./docs/howtos/README.md) for a complete list of docume
npm install
```
### Configuration
## ⚙️ Configuration
### Environment Variables
The API is configured via environment variables. Create a `.env` file or set them in your environment:
| Variable | Description | Default |
| :--- | :--- | :--- |
| `ZABBIX_BASE_URL` | URL to your Zabbix API (e.g., `http://zabbix.example.com/zabbix`) | |
| `ZABBIX_AUTH_TOKEN` | Zabbix Super Admin API token for administrative tasks | |
| `ZABBIX_EDGE_DEVICE_BASE_GROUP` | Base host group for devices | `Roadwork` |
| `ZABBIX_PERMISSION_TEMPLATE_GROUP_NAME_PREFIX` | Prefix for template groups used as permissions | `Permissions` |
| `SCHEMA_PATH` | Path to the directory containing `.graphql` schema files | `./schema/` |
| `HOST_GROUP_FILTER_DEFAULT` | Default search pattern for `allHostGroups` query | |
| `HOST_TYPE_FILTER_DEFAULT` | Default value for `tag_hostType` filter in `allHosts` and `allDevices` queries | |
| Variable | Description | Default | Required |
|----------|-------------|---------|----------|
| `ZABBIX_BASE_URL` | URL to your Zabbix server (include `/zabbix` path) | - | Yes |
| `ZABBIX_PRIVILEGE_ESCALATION_TOKEN` | Zabbix Super Admin API token used for privilege escalation (e.g. during import operations) | - | Yes |
| `ZABBIX_DEVELOPMENT_TOKEN` | Token used ONLY for local development and isolated testing to simulate a "real end user" | - | No |
| `ZABBIX_EDGE_DEVICE_BASE_GROUP` | Base group for edge devices | `Roadwork` | No |
| `ZABBIX_PERMISSION_TEMPLATE_GROUP_NAME_PREFIX` | Prefix for permission template groups (used to identify permission-related template groups in Zabbix) | `Permissions` | No |
| `SCHEMA_PATH` | Path to schema files | `./schema/` | No |
| `ADDITIONAL_SCHEMAS` | Comma-separated list of additional schema files | - | No |
| `ADDITIONAL_RESOLVERS` | Comma-separated list of resolver types to generate | - | No |
| `LOG_LEVEL` | Log level configuration (e.g. `debug`, `info`, `warn`, `error`) | `info` | No |
| `HOST_TYPE_FILTER_DEFAULT` | Default filter for host types | - | No |
| `HOST_GROUP_FILTER_DEFAULT` | Default filter for host groups | - | No |
## 🔐 Authorization
The application operates with different authentication and authorization mechanisms depending on the scenario:
### 1. Production Use
In production environments, the `ZABBIX_DEVELOPMENT_TOKEN` should **always be unset** to ensure proper security.
* **Zabbix Frontend Widgets**: When accessing the API from widgets embedded in the Zabbix frontend, no static token is needed. Authentication is automatically derived from the `zbx_session` cookie provided by the Zabbix web login, which is forwarded to the Zabbix API.
* **Other Production Tools**: For other purposes (e.g. accessing the API from external tools or scripts), a Zabbix session or auth token must be passed via the `zabbix-auth-token` HTTP header.
### 2. Privilege Escalation
* **`ZABBIX_PRIVILEGE_ESCALATION_TOKEN`**: Certain operations, such as importing hosts, templates, or user rights, require Super Admin access to Zabbix for specific parts of the process. This token allows the API to perform these administrative tasks even when the initiating user does not have Super Admin rights themselves.
### 3. Local Development and Testing
* **`ZABBIX_DEVELOPMENT_TOKEN`**: This environment variable is intended **only** for local development and isolated testing. It allows developers to "simulate" a Zabbix access token representing a "real end user" without needing to provide the HTTP header in every request.
* **Warning**: This should be avoided in production as it undermines security by bypassing per-request authentication.
### Zabbix to GraphQL Mapping
The API maps Zabbix entities to GraphQL types as follows:
| Zabbix Entity | GraphQL Type | Description |
|---------------|--------------|-------------|
| Host | `Host` / `Device` | Represents a Zabbix host; `Device` is a specialized `Host` with a `deviceType` tag |
| Host Group | `HostGroup` | Represents a Zabbix host group |
| Template | `Template` | Represents a Zabbix template |
| Template Group | `HostGroup` | Represents a Zabbix template group |
| Item | Nested fields | Zabbix items become nested fields based on their key names (hierarchical mapping) |
| Tag | `Tag` | Represents a Zabbix tag associated with a host or template |
| Inventory | `Location` | Host inventory information maps to location data |
### Starting the API
@ -107,7 +149,7 @@ docker run -d \
--name zabbix-graphql-api \
-p 4000:4000 \
-e ZABBIX_BASE_URL=http://your-zabbix-instance/zabbix \
-e ZABBIX_AUTH_TOKEN=your-super-admin-token \
-e ZABBIX_PRIVILEGE_ESCALATION_TOKEN=your-super-admin-token \
forgejo.tooling.hilbigit.com/zabbix/zabbix-graphql-api:latest
```
@ -126,7 +168,7 @@ If you prefer to build the image yourself using the provided `Dockerfile`:
--name zabbix-graphql-api \
-p 4000:4000 \
-e ZABBIX_BASE_URL=http://your-zabbix-instance/zabbix \
-e ZABBIX_AUTH_TOKEN=your-super-admin-token \
-e ZABBIX_PRIVILEGE_ESCALATION_TOKEN=your-super-admin-token \
zabbix-graphql-api
```
@ -136,7 +178,7 @@ The **Virtual Control Room (VCR)** is a professional cockpit and control center
### How VCR uses the GraphQL API:
* **Unified Cockpit**: VCR utilizes the API's **hierarchical mapping** to provide a unified view of diverse device types. It maps Zabbix items and tags directly to structured GraphQL objects (e.g., `operational` telemetry and `current` business state).
* **Unified Cockpit**: VCR utilizes the API's **hierarchical mapping** to provide a unified view of diverse device types. It maps Zabbix items and tags directly to structured GraphQL objects (e.g. `operational` telemetry and `current` business state).
* **Dynamic Authorization**: The `hasPermissions` query is used to implement a **Dynamic UI**. Buttons, controls, and status indicators are shown or enabled only if the user has the required `READ` or `READ_WRITE` permissions for that specific object.
* **Mass Provisioning**: VCR leverages the **mass import** capabilities to provision thousands of devices and templates in a single operation, significantly reducing manual configuration effort in Zabbix.
* **Data Visualization**: It uses the `exportHostValueHistory` endpoint to power dashboards showing historical trends, such as traffic density, battery levels, or sensor readings over time.
@ -151,7 +193,7 @@ Below is a complete example of a `.env` file showing all available configuration
```env
# Zabbix Connection
ZABBIX_BASE_URL=http://your-zabbix-instance/zabbix
ZABBIX_AUTH_TOKEN=your-super-admin-token-here
ZABBIX_PRIVILEGE_ESCALATION_TOKEN=your-super-admin-token-here
# General Configuration
ZABBIX_EDGE_DEVICE_BASE_GROUP=Roadwork
@ -188,6 +230,14 @@ The `docs/queries` directory contains several sample GraphQL queries and mutatio
* [Export User Rights](docs/queries/sample_export_user_rights_query.graphql)
* [Import User Rights](docs/queries/sample_import_user_rights_mutation.graphql)
## 🔄 API Version
The API version is automatically set during the Docker build process based on the Git tag or commit hash. This version information is embedded into the Docker image and becomes accessible through the `API_VERSION` environment variable at runtime.
### Zabbix Version Compatibility
This API is designed to work with Zabbix 7.4, which is the version it runs productively with. While it may work with earlier versions (like 6.0+), 7.4 is the officially supported and tested version.
## License
This project is licensed under the **GNU Affero General Public License v3.0**. See the [LICENSE](LICENSE) file for details.

View file

@ -16,8 +16,7 @@ const config: CodegenConfig = {
declarationKind: 'interface'
}
}
},
watch: true
}
};
export default config;

View file

@ -10,7 +10,7 @@ services:
- .env
environment:
- SCHEMA_PATH=/usr/app/dist/schema/
- ZABBIX_AUTH_TOKEN_FOR_REQUESTS=${ZABBIX_AUTH_TOKEN_FOR_REQUESTS}
- ZABBIX_DEVELOPMENT_TOKEN=${ZABBIX_DEVELOPMENT_TOKEN}
apollo-mcp-server:
image: ghcr.io/apollographql/apollo-mcp-server:latest

View file

@ -4,6 +4,9 @@ This directory contains detailed guides on how to use and extend the Zabbix Grap
## Available Guides
### 🍳 [Cookbook](./cookbook.md)
Practical, step-by-step recipes for common tasks, designed for both humans and AI-based test generation.
### 📊 [Schema and Schema Extension](./schema.md)
Learn about the GraphQL schema structure, how Zabbix entities map to GraphQL types, and how to use the dynamic schema extension system.
@ -16,8 +19,8 @@ Discover how the permission system works, how to define permission levels using
### 🏷️ [Zabbix Tags Usage](./tags.md)
Learn how Zabbix tags are used for device classification, host categorization, and as metadata within the GraphQL API.
### 🤖 [MCP Integration](./mcp.md)
Discover how to integrate the Zabbix GraphQL API with the Model Context Protocol (MCP) to enable LLMs to interact with your Zabbix data.
### 🤖 [MCP & Agent Integration](./mcp.md)
Discover how to integrate the Zabbix GraphQL API with the Model Context Protocol (MCP) to enable LLMs and autonomous agents to interact with your Zabbix data efficiently.
---

87
docs/howtos/cookbook.md Normal file
View file

@ -0,0 +1,87 @@
# Zabbix GraphQL API Cookbook
This cookbook provides step-by-step "recipes" for common tasks. These instructions are designed to be easy for humans to follow and structured enough for AI agents (using the MCP server) to generate test cases.
## 🤖 AI-Based Test Generation
To generate a test case from a recipe:
1. Start the `zabbix-graphql` MCP server.
2. Provide the recipe to your AI agent.
3. Ask the agent to "Implement a test case for this recipe using the Zabbix GraphQL API".
4. The agent will use the MCP server to explore the schema and generate appropriate GraphQL operations.
---
## 🍳 Recipe: Extending Schema with a New Device Type
This recipe shows how to add support for a new specialized device type without modifying the core API code.
### Prerequisites
- Zabbix Template Group `Templates/Roadwork/Devices` exists.
- Zabbix GraphQL API is running.
### Step 1: Define the Schema Extension
Create a new `.graphql` file in `schema/extensions/` (e.g. `distance_tracker.graphql`):
```graphql
type DistanceTrackerDevice {
id: String
name: String
location: Location
distance: Float
batteryLevel: Float
lastSeen: DateTime
}
```
### Step 2: Configure Environment Variables
Add the new schema and resolver to your `.env` file:
```env
ADDITIONAL_SCHEMAS=./schema/extensions/distance_tracker.graphql
ADDITIONAL_RESOLVERS=DistanceTrackerDevice
```
Restart the API server.
### Step 3: Import the Template
Execute the `importTemplates` mutation to create the template in Zabbix. Use Zabbix item keys that match your GraphQL fields (e.g. `distance.current` for `distance`).
---
## 🍳 Recipe: Provisioning a New Host
### Prerequisites
- A target Host Group exists in Zabbix.
- At least one Template exists in Zabbix.
### Step 1: Prepare the Host Object
Define the host name, groups, and templates to link.
### Step 2: Execute `createHost` Mutation
```graphql
mutation CreateNewHost($host: String!, $groups: [Int!]!, $templates: [Int!]!) {
createHost(host: $host, hostgroupids: $groups, templateids: $templates) {
hostids
error {
message
}
}
}
```
---
## 🍳 Recipe: Managing User Permissions
### Step 1: Create Permission Template Group
Create a template group with the prefix `Permissions/` in Zabbix (e.g. `Permissions/Read-Only-Access`).
### Step 2: Assign to User Group
In Zabbix, give a User Group `Read` access to this template group.
### Step 3: Verify via API
```graphql
query CheckMyPermissions {
hasPermissions(permissions: [
{ objectName: "Read-Only-Access", permission: READ }
])
}
```

View file

@ -58,8 +58,25 @@ To use this integration with Claude Desktop, add the following configuration to
**Note**: Ensure the `zabbix-graphql-api` is running and accessible. If running locally, you might need to use `host.docker.internal:4001/graphql` in your `mcp-config.yaml` to allow the containerized MCP server to reach your host.
### Benefits of GraphQL-enabled MCP
### Benefits of GraphQL-enabled MCP over REST
- **Self-Documenting**: The GraphQL schema provides all necessary metadata for the LLM to understand how to use the tools.
- **Efficient**: LLMs can request exactly the data they need, reducing token usage and improving response speed.
- **Secure**: Uses the same authentication and permission model as the rest of the API.
Integrating via GraphQL offers significant advantages for AI agents and MCP compared to the traditional Zabbix JSON-RPC (REST-like) API:
- **Introspection & Discovery**: Unlike REST, GraphQL is natively introspectable. An AI agent can query the schema itself to discover all available types, fields, and operations. This allows agents to "learn" the API capabilities without manual documentation parsing.
- **Strong Typing**: The schema provides explicit types for every field. AI agents can use this to validate their own generated queries and understand the exact data format expected or returned, reducing errors in agent-driven actions.
- **Precision (Over-fetching/Under-fetching)**: In REST, endpoints often return fixed data structures, leading to token waste (over-fetching) or requiring multiple round-trips (under-fetching). With GraphQL, the agent requests exactly the fields it needs, which is crucial for staying within LLM context window limits and reducing latency.
- **Single Endpoint**: AI agents only need to know one endpoint. They don't have to manage a complex tree of URL paths and HTTP methods; they simply send their intent as a GraphQL operation.
- **Complex Relationships**: Agents can navigate complex Zabbix relationships (e.g. Host -> Items -> History) in a single request, which is much more intuitive for LLMs than orchestrating multiple REST calls.
- **Self-Documenting**: Descriptive comments in the SDL are automatically exposed to the agent, providing immediate context for what each field represents.
### AI-Based Test Generation via Cookbook
The MCP server can be used in conjunction with the [**Cookbook**](./cookbook.md) to automate the generation of test cases. By providing a cookbook "recipe" to an LLM with access to the `zabbix-graphql` MCP server, the LLM can:
1. Analyze the step-by-step instructions in the recipe.
2. Use the MCP server's tools to inspect the current Zabbix state and schema.
3. Generate and execute the necessary GraphQL operations to fulfill the recipe's task.
4. Verify the outcome and suggest assertions for a formal test script.
Example prompt for an LLM:
> "Using the `zabbix-graphql` MCP server, follow the 'Provisioning a New Host' recipe from the cookbook. Create a host named 'Test-Host-01' in the 'Linux servers' group and link the 'ICMP Ping' template."

View file

@ -38,7 +38,7 @@ query GetUserPermissions {
### Setting Up Permissions
1. Create template groups with the prefix `Permissions/` (e.g., `Permissions/hosts`, `Permissions/templates`)
1. Create template groups with the prefix `Permissions/` (e.g. `Permissions/hosts`, `Permissions/templates`)
2. Assign these template groups to user groups in Zabbix with appropriate permission levels
3. Users in those user groups will inherit the permissions

View file

@ -13,7 +13,7 @@ The `hostType` tag is used to categorize hosts and templates. This allows the AP
To classify a host or a template, add a tag in Zabbix:
* **Tag Name**: `hostType`
* **Tag Value**: A string representing the category (e.g., `Roadwork/Devices`, `SmartCity/Sensors`).
* **Tag Value**: A string representing the category (e.g. `Roadwork/Devices`, `SmartCity/Sensors`).
This tag can be defined directly on the host or on a template (where linked hosts will inherit it).

View file

@ -21,7 +21,7 @@ mutation ImportDistanceTrackerTemplate($templates: [CreateTemplate!]!) {
### Variables
The following sample defines the `DISTANCE_TRACKER` template. Note the `deviceType` tag set to `DistanceTrackerDevice`, which instructs the GraphQL API to resolve this host using the specialized `DistanceTrackerDevice` type.
The item keys use the `json_` prefix where appropriate (e.g., `state.current.json_distances`) to ensure that the JSON strings received from Zabbix are automatically parsed into objects/arrays by the GraphQL resolver.
The item keys use the `json_` prefix where appropriate (e.g. `state.current.json_distances`) to ensure that the JSON strings received from Zabbix are automatically parsed into objects/arrays by the GraphQL resolver.
```json
{

19
package-lock.json generated
View file

@ -32,7 +32,7 @@
"@types/cors": "^2.8.17",
"@types/express": "^5.0.6",
"@types/jest": "^29.5.13",
"@types/node": "^22.6.1",
"@types/node": "^24.10.9",
"@types/simple-mock": "^0.8.6",
"@types/ws": "^8.5.12",
"jest": "^29.7.0",
@ -43,6 +43,9 @@
"ts-node": "^10.9.2",
"tsx": "^4.19.1",
"typescript": "^5.6.2"
},
"engines": {
"node": ">=24"
}
},
"node_modules/@apollo/cache-control-types": {
@ -3764,14 +3767,14 @@
"license": "MIT"
},
"node_modules/@types/node": {
"version": "22.19.3",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.3.tgz",
"integrity": "sha512-1N9SBnWYOJTrNZCdh/yJE+t910Y128BoyY+zBLWhL3r0TYzlTmFdXrPwHL9DyFZmlEXNQQolTZh3KHV31QDhyA==",
"version": "24.10.9",
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.9.tgz",
"integrity": "sha512-ne4A0IpG3+2ETuREInjPNhUGis1SFjv1d5asp8MzEAGtOZeTeHVDOYqOgqfhvseqg/iXty2hjBf1zAOb7RNiNw==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"undici-types": "~6.21.0"
"undici-types": "~7.16.0"
}
},
"node_modules/@types/qs": {
@ -10091,9 +10094,9 @@
"license": "MIT"
},
"node_modules/undici-types": {
"version": "6.21.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
"version": "7.16.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
"integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
"dev": true,
"license": "MIT"
},

View file

@ -9,7 +9,7 @@
"start": "nodemon --watch \"src/**\" --watch \"schema.graphql\" --ext \"ts,json\" --exec \"node --import tsx ./src/index.ts\"",
"prod": "npm run copy-schema && node ./dist/index.js",
"test": "jest --detectOpenHandles --forceExit --bail",
"codegen": "graphql-codegen --config codegen.ts --watch \"schema.graphql\"",
"codegen": "graphql-codegen --config codegen.ts --watch",
"nodemon": "nodemon --watch \"src/**\" --watch \"schema.graphql\" --ext \"ts,json\" --exec \"tsc",
"copy-schema": "cp -R schema ./dist/"
},
@ -17,6 +17,9 @@
"license": "AGPL-3.0-only",
"author": "Andreas Hilbig",
"copyright": "All rights reserved by Hilbig IT GmbH",
"engines": {
"node": ">=24"
},
"dependencies": {
"@apollo/datasource-rest": "^6.3.0",
"@apollo/server": "^5.2.0",
@ -41,7 +44,7 @@
"@types/cors": "^2.8.17",
"@types/express": "^5.0.6",
"@types/jest": "^29.5.13",
"@types/node": "^22.6.1",
"@types/node": "^24.10.9",
"@types/simple-mock": "^0.8.6",
"@types/ws": "^8.5.12",
"jest": "^29.7.0",

View file

@ -0,0 +1,72 @@
# Documentation Improvement Plan
This plan outlines the steps to refactor and improve the Zabbix GraphQL API documentation, combining a technical reference with a practical "Cookbook" for quick start and AI-based test generation.
## Priority 1: Reference Documentation (Advanced Users)
### 1.1 Enhance README.md
- **Feature-to-Code Mapping**: Add "Reference" links to each feature in the features list (from public origin).
- **Comprehensive Config Reference**: Update environment variables table with detailed descriptions, defaults, and requirements.
- **Auth Separation**: Explain `ZABBIX_PRIVILEGE_ESCALATION_TOKEN` vs `ZABBIX_DEVELOPMENT_TOKEN`.
- **Entity Mapping Table**: Include the Zabbix-to-GraphQL entity mapping table.
- **API Versioning**: Document how the version is determined and Zabbix version compatibility (7.4 focus).
### 1.2 Update Detailed Guides
- Ensure `docs/howtos/schema.md`, `permissions.md`, etc., are up-to-date with the latest implementation details.
## Priority 2: Cookbook & AI-Ready Instructions
### 2.1 Create the Cookbook (`docs/howtos/cookbook.md`)
- **Step-by-Step Recipes**: Create practical, task-oriented guides.
- **Recipe: Schema Extension**: Move the "Distance Tracker" example into the cookbook.
- **Recipe: Basic Monitoring**: Step-by-step to monitor a new host.
- **Recipe: Bulk Import**: Guide for mass importing templates and hosts.
### 2.2 AI/MCP Integration for Test Generation
- **MCP Server Documentation**: Explicitly document how to start and use the `zabbix-graphql` MCP server.
- **Test Generation Instructions**: Provide specific instructions on how an AI can use the Cookbook recipes to generate test cases.
- **Metadata for AI**: Use structured headers and clear prerequisites in recipes to make them "AI-parsable".
## Priority 3: Technical Maintenance (from Public Origin)
### 3.1 Code Generation Section
- Explain the GraphQL Codegen setup and how to regenerate types.
- Document the `codegen.ts` configuration.
- Add instructions for updating generated types after schema changes.
## Priority 4: Improve Examples
### 4.1 Complete Examples
- Add more complete examples for each major operation.
- Include error handling examples.
- Add examples for common use cases beyond the distance tracker.
### 4.2 Testing Examples
- Add information about how to run tests.
- Include examples of unit and integration tests.
- Explain the test structure and how to add new tests.
## Priority 5: Documentation Links
### 5.1 Cross-Reference Improvements
- Add links to relevant sections in schema files.
- Include references to specific resolver implementations.
- Link to related documentation files in the docs directory.
### 5.2 External Resources
- Link to official Zabbix API documentation.
- Include references to Apollo Server documentation.
## Implementation Order
1. **Foundation**: Update `README.md` with missing reference information from public origin.
2. **Cookbook Alpha**: Create `docs/howtos/cookbook.md` with the first set of recipes.
3. **AI Bridge**: Document MCP server usage and test generation workflow.
4. **Maintenance**: Add Codegen and Testing sections.
5. **Cross-Linking**: Optimize all links and cross-references.
6. **Optimize**: Run import optimization across the project.
## Success Metrics
- All environment variables documented.
- Clear distinction between Reference and Cookbook.
- Functional MCP-based test generation using cookbook instructions.
- Accurate representation of features and compatibility.

View file

@ -13,7 +13,7 @@ interface DeviceValueMessage {
"""
Represents the timestamp at which a specific event, message, or data point was created or recorded.
The format should align with standard expectations (e.g., ISO 8601).
The format should align with standard expectations (e.g. ISO 8601).
"""
timestamp: String

View file

@ -74,7 +74,7 @@ type OperationalDeviceData {
temperature: Float
"""Device voltage."""
voltage: Float
"""Signal strength (e.g., WiFi or GSM)."""
"""Signal strength (e.g. WiFi or GSM)."""
signalstrength: Float
"""Current location of the device."""
location: Location

View file

@ -12,7 +12,7 @@ type SensorDistanceValue implements DeviceValue {
"""
Represents the MAC address of the device. Typically formatted as a 12-character
hexadecimal string (e.g., "00:1A:2B:3C:4D:5E").
hexadecimal string (e.g. "00:1A:2B:3C:4D:5E").
"""
mac: String

View file

@ -85,7 +85,7 @@ type Mutation {
deleteTemplates(
"""List of template IDs to delete."""
templateids: [Int!],
"""Wildcard name pattern for templates to delete (e.g., 'Template%')."""
"""Wildcard name pattern for templates to delete (e.g. 'Template%')."""
name_pattern: String
): [DeleteResponse!]
@ -189,7 +189,7 @@ input CreateTemplateItem {
"""
name: String!
"""
Zabbix item type (e.g., 0 for Zabbix Agent, 18 for Dependent).
Zabbix item type (e.g. 0 for Zabbix Agent, 18 for Dependent).
"""
type: Int
"""
@ -197,11 +197,11 @@ input CreateTemplateItem {
"""
key: String!
"""
Type of information (e.g., 0 for Float, 3 for Int, 4 for Text).
Type of information (e.g. 0 for Float, 3 for Int, 4 for Text).
"""
value_type: Int
"""
History storage period (e.g., '2d', '90d').
History storage period (e.g. '2d', '90d').
"""
history: String
"""
@ -245,7 +245,7 @@ Input for an item preprocessing step.
"""
input CreateItemPreprocessing {
"""
Type of preprocessing step (e.g., 12 for JSONPath, 21 for JavaScript).
Type of preprocessing step (e.g. 12 for JSONPath, 21 for JavaScript).
"""
type: Int!
"""
@ -477,7 +477,7 @@ input UserRoleInput {
"""
name: String
"""
Type of role (e.g., 1 for User, 2 for Admin, 3 for Super Admin).
Type of role (e.g. 1 for User, 2 for Admin, 3 for Super Admin).
"""
type: Int
"""
@ -515,7 +515,7 @@ input UserRoleRulesInput {
"""
api_access: Int
"""
API mode (e.g., 0 for white-list, 1 for black-list).
API mode (e.g. 0 for white-list, 1 for black-list).
"""
api_mode: Int
"""
@ -541,7 +541,7 @@ input UserRoleRuleInput {
"""
name: String
"""
Status (e.g., 1 for enabled, 0 for disabled).
Status (e.g. 1 for enabled, 0 for disabled).
"""
status: Int
}

View file

@ -72,7 +72,7 @@ type ZabbixItem {
"""
lastvalue: String
"""
Type of information (e.g., 0 for Float, 3 for Int, 4 for Text).
Type of information (e.g. 0 for Float, 3 for Int, 4 for Text).
"""
value_type: Int!
"""

View file

@ -8,7 +8,7 @@ import express from 'express';
import cors from "cors";
import {ApolloServerPluginDrainHttpServer} from '@apollo/server/plugin/drainHttpServer';
import {logger} from "../logging/logger.js";
import {zabbixAPI, zabbixRequestAuthToken} from "../datasources/zabbix-api.js";
import {zabbixAPI, zabbixDevelopmentToken} from "../datasources/zabbix-api.js";
import {WebSocketServer} from "ws";
import {useServer} from "graphql-ws/lib/use/ws";
@ -82,7 +82,7 @@ async function startApolloServer() {
dataSources: {
zabbixAPI: zabbixAPI,
},
zabbixAuthToken: req.headers["zabbix-auth-token"] ?? zabbixRequestAuthToken,
zabbixAuthToken: req.headers["zabbix-auth-token"] ?? zabbixDevelopmentToken,
cookie: req.headers.cookie,
token: req.headers.token
};

View file

@ -9,8 +9,8 @@ static readonly DRY_RUN = process.env.DRY_RUN
static readonly SCHEMA_PATH = process.env.SCHEMA_PATH || './schema/'
static readonly ADDITIONAL_SCHEMAS = process.env.ADDITIONAL_SCHEMAS
static readonly ADDITIONAL_RESOLVERS = process.env.ADDITIONAL_RESOLVERS
static readonly ZABBIX_AUTH_TOKEN_FOR_REQUESTS = process.env.ZABBIX_AUTH_TOKEN_FOR_REQUESTS
static readonly ZABBIX_AUTH_TOKEN = process.env.ZABBIX_AUTH_TOKEN
static readonly ZABBIX_DEVELOPMENT_TOKEN = process.env.ZABBIX_DEVELOPMENT_TOKEN
static readonly ZABBIX_PRIVILEGE_ESCALATION_TOKEN = process.env.ZABBIX_PRIVILEGE_ESCALATION_TOKEN
static readonly ZABBIX_EDGE_DEVICE_BASE_GROUP = process.env.ZABBIX_EDGE_DEVICE_BASE_GROUP
static readonly ZABBIX_ROADWORK_BASE_GROUP = process.env.ZABBIX_ROADWORK_BASE_GROUP
static readonly ZABBIX_PERMISSION_TEMPLATE_GROUP_NAME_PREFIX = process.env.ZABBIX_PERMISSION_TEMPLATE_GROUP_NAME_PREFIX || "Permissions"

View file

@ -9,8 +9,8 @@ import {logger} from "../logging/logger.js";
import {ParsedArgs, ZabbixErrorResult, ZabbixRequest, ZabbixResult} from "./zabbix-request.js";
import {Config} from "../common_utils.js";
export const zabbixRequestAuthToken = Config.ZABBIX_AUTH_TOKEN_FOR_REQUESTS
export const zabbixSuperAuthToken = Config.ZABBIX_AUTH_TOKEN
export const zabbixDevelopmentToken = Config.ZABBIX_DEVELOPMENT_TOKEN
export const zabbixPrivilegeEscalationToken = Config.ZABBIX_PRIVILEGE_ESCALATION_TOKEN
export const ZABBIX_EDGE_DEVICE_BASE_GROUP = Config.ZABBIX_EDGE_DEVICE_BASE_GROUP || Config.ZABBIX_ROADWORK_BASE_GROUP || "Roadwork"
export const FIND_ZABBIX_EDGE_DEVICE_BASE_GROUP_PREFIX = new RegExp(`^(${ZABBIX_EDGE_DEVICE_BASE_GROUP})\/`)

View file

@ -4,7 +4,7 @@ import {
FIND_ZABBIX_EDGE_DEVICE_BASE_GROUP_PREFIX,
ZABBIX_EDGE_DEVICE_BASE_GROUP,
ZabbixAPI,
zabbixSuperAuthToken
zabbixPrivilegeEscalationToken
} from "./zabbix-api.js";
import {logger} from "../logging/logger.js";
import {ZabbixRequestWithPermissions} from "./zabbix-permissions.js";
@ -23,7 +23,7 @@ const hostGroupReadWritePermissions = {
export class ZabbixCreateHostGroupRequest extends ZabbixRequestWithPermissions<CreateHostGroupResult> {
constructor(_authToken?: string | null, cookie?: string) {
super("hostgroup.create", zabbixSuperAuthToken, cookie, hostGroupReadWritePermissions);
super("hostgroup.create", zabbixPrivilegeEscalationToken, cookie, hostGroupReadWritePermissions);
}
}

View file

@ -1,6 +1,8 @@
import {DeviceCommunicationType, DeviceStatus, Permission, StorageItemType} from '../../model/model_enum_values.js';
import { DeviceCommunicationType } from '../../model/model_enum_values.js';
import { StorageItemType } from '../../model/model_enum_values.js';
import { DeviceStatus } from '../../model/model_enum_values.js';
import { Permission } from '../../model/model_enum_values.js';
import { GraphQLResolveInfo, GraphQLScalarType, GraphQLScalarTypeConfig } from 'graphql';
export type Maybe<T> = T | null;
export type InputMaybe<T> = Maybe<T>;
export type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };
@ -94,7 +96,7 @@ export interface CreateItemPreprocessing {
error_handler_params?: InputMaybe<Scalars['String']['input']>;
/** Parameters for the preprocessing step. */
params: Array<Scalars['String']['input']>;
/** Type of preprocessing step (e.g., 12 for JSONPath, 21 for JavaScript). */
/** Type of preprocessing step (e.g. 12 for JSONPath, 21 for JavaScript). */
type: Scalars['Int']['input'];
}
@ -165,7 +167,7 @@ export interface CreateTemplateItem {
delay?: InputMaybe<Scalars['String']['input']>;
/** Description of the item. */
description?: InputMaybe<Scalars['String']['input']>;
/** History storage period (e.g., '2d', '90d'). */
/** History storage period (e.g. '2d', '90d'). */
history?: InputMaybe<Scalars['String']['input']>;
/** Technical key of the item. */
key: Scalars['String']['input'];
@ -177,13 +179,13 @@ export interface CreateTemplateItem {
preprocessing?: InputMaybe<Array<CreateItemPreprocessing>>;
/** Tags to assign to the item. */
tags?: InputMaybe<Array<CreateTag>>;
/** Zabbix item type (e.g., 0 for Zabbix Agent, 18 for Dependent). */
/** Zabbix item type (e.g. 0 for Zabbix Agent, 18 for Dependent). */
type?: InputMaybe<Scalars['Int']['input']>;
/** Units of the value. */
units?: InputMaybe<Scalars['String']['input']>;
/** Internally used unique id. */
uuid?: InputMaybe<Scalars['String']['input']>;
/** Type of information (e.g., 0 for Float, 3 for Int, 4 for Text). */
/** Type of information (e.g. 0 for Float, 3 for Int, 4 for Text). */
value_type?: InputMaybe<Scalars['Int']['input']>;
}
@ -266,7 +268,7 @@ export interface DeviceValueMessage {
deviceType?: Maybe<Scalars['String']['output']>;
/**
* Represents the timestamp at which a specific event, message, or data point was created or recorded.
* The format should align with standard expectations (e.g., ISO 8601).
* The format should align with standard expectations (e.g. ISO 8601).
*/
timestamp?: Maybe<Scalars['String']['output']>;
/**
@ -581,7 +583,7 @@ export interface OperationalDeviceData {
error?: Maybe<Array<ErrorPayload>>;
/** Current location of the device. */
location?: Maybe<Location>;
/** Signal strength (e.g., WiFi or GSM). */
/** Signal strength (e.g. WiFi or GSM). */
signalstrength?: Maybe<Scalars['Float']['output']>;
/** Device temperature. */
temperature?: Maybe<Scalars['Float']['output']>;
@ -843,7 +845,7 @@ export interface UserRoleInput {
readonly?: InputMaybe<Scalars['Int']['input']>;
/** Specific rules for the role. */
rules?: InputMaybe<UserRoleRulesInput>;
/** Type of role (e.g., 1 for User, 2 for Admin, 3 for Super Admin). */
/** Type of role (e.g. 1 for User, 2 for Admin, 3 for Super Admin). */
type?: InputMaybe<Scalars['Int']['input']>;
}
@ -883,7 +885,7 @@ export interface UserRoleRule {
export interface UserRoleRuleInput {
/** Name of the rule/element. */
name?: InputMaybe<Scalars['String']['input']>;
/** Status (e.g., 1 for enabled, 0 for disabled). */
/** Status (e.g. 1 for enabled, 0 for disabled). */
status?: InputMaybe<Scalars['Int']['input']>;
}
@ -920,7 +922,7 @@ export interface UserRoleRulesInput {
api?: InputMaybe<Array<Scalars['String']['input']>>;
/** Whether API access is enabled (1) or not (0). */
api_access?: InputMaybe<Scalars['Int']['input']>;
/** API mode (e.g., 0 for white-list, 1 for black-list). */
/** API mode (e.g. 0 for white-list, 1 for black-list). */
api_mode?: InputMaybe<Scalars['Int']['input']>;
/** Module access rules. */
modules?: InputMaybe<Array<UserRoleModuleInput>>;
@ -1020,7 +1022,7 @@ export interface ZabbixItem {
status?: Maybe<DeviceStatus>;
/** Communication type used by the item. */
type?: Maybe<DeviceCommunicationType>;
/** Type of information (e.g., 0 for Float, 3 for Int, 4 for Text). */
/** Type of information (e.g. 0 for Float, 3 for Int, 4 for Text). */
value_type: Scalars['Int']['output'];
}

View file

@ -1,11 +1,11 @@
// Import after mocking Config
import {ZABBIX_EDGE_DEVICE_BASE_GROUP, zabbixAPI, zabbixSuperAuthToken} from "../datasources/zabbix-api.js";
import {ZABBIX_EDGE_DEVICE_BASE_GROUP, zabbixAPI, zabbixPrivilegeEscalationToken} from "../datasources/zabbix-api.js";
// Mocking Config
jest.mock("../common_utils.js", () => ({
Config: {
ZABBIX_EDGE_DEVICE_BASE_GROUP: "CustomEdgeGroup",
ZABBIX_AUTH_TOKEN: "super-secret-token",
ZABBIX_PRIVILEGE_ESCALATION_TOKEN: "super-secret-token",
ZABBIX_BASE_URL: "http://custom-zabbix"
}
}));
@ -13,7 +13,7 @@ jest.mock("../common_utils.js", () => ({
describe("Zabbix API Config Mocking", () => {
test("constants are derived from Config", () => {
expect(ZABBIX_EDGE_DEVICE_BASE_GROUP).toBe("CustomEdgeGroup");
expect(zabbixSuperAuthToken).toBe("super-secret-token");
expect(zabbixPrivilegeEscalationToken).toBe("super-secret-token");
expect(zabbixAPI.baseURL).toBe("http://custom-zabbix");
});
});