---
name: monstermq-device-integrator
description: >
  Guide for integrating new device types into the MonsterMQ broker. Use this skill whenever
  the user wants to add a new device connector, bridge, or protocol integration to MonsterMQ.
  This includes creating backend Kotlin verticles (Connector + Extension), GraphQL schema/resolvers,
  and dashboard UI pages. Trigger on requests like "add a new device type", "integrate Modbus",
  "create an OPC UA connector", "bridge protocol X to MQTT", "add a new client type",
  or any mention of connecting external systems/devices to MonsterMQ.
---

# Device Integration Skill for MonsterMQ

This skill provides step-by-step instructions for adding a new device connector, industrial protocol bridge, or database logger into MonsterMQ across the Kotlin backend, GraphQL API, and Vite dashboard.

---

## Architecture Blueprint & Core Reference

Read the primary specification guide at [`dev/plans/plan-device-integration.md`](file:///home/vogler/Workspace/monster-mq/dev/plans/plan-device-integration.md) — it contains the complete Extension + Connector architecture overview, code templates, and verification checklist.

### Reference Implementations by Complexity
- **Simple Bridge**: MQTT Client (`devices/mqttclient/`, `graphql/MqttClient*`, dashboard `mqtt-client*`)
- **Medium Protocol**: PLC4X (`devices/plc4x/`, `graphql/Plc4x*`, dashboard `plc4x-*`)
- **Complex Industrial**: WinCC Unified (`devices/winccua/`, `graphql/WinCCUa*`, dashboard `winccua-*`)

---

## End-to-End Implementation Order

Follow this 9-step sequence:

### 1. Configuration Data Class
**Location**: `broker/src/main/kotlin/stores/devices/YourDeviceConfig.kt`
- Define data class with `fromJsonObject()` companion and `toJsonObject()` method.
- Support address/tag mappings if the device bridges external points to MQTT topics.
- Include sensible defaults for timeouts, reconnect delays, and retry counts.

### 2. Connector Verticle (Per-Device Instance)
**Location**: `broker/src/main/kotlin/devices/yourdevice/YourDeviceConnector.kt`
- Extends Vert.x `AbstractVerticle`.
- Loads configuration from `config().getJsonObject("device")`.
- Implements connection lifecycle: connect, disconnect, exponential backoff reconnect.
- Publishes incoming messages to the message bus or Vert.x eventbus.
- Tracks metrics (`messagesInCounter`, `messagesOutCounter`, `isConnected`) and responds to eventbus queries.

### 3. Extension Verticle (Coordinator & Cluster Manager)
**Location**: `broker/src/main/kotlin/devices/yourdevice/YourDeviceExtension.kt`
- Manages connector verticles for this device type across the node.
- Cluster-aware: checks `clusterManager.isLocalNodeResponsible(device.id)`.
- Listens for configuration changes on `EventBusAddresses.Device.configChanged(TYPE)`.
- Deploys/undeploys connector verticles via `vertx.deployVerticle()`.

### 4. Register Verticle in Main (`Monster.kt`) & Feature Flag
**Location**: `broker/src/main/kotlin/Monster.kt` and `Features.kt`
- Declare top-level feature flag constant in `broker/src/main/kotlin/Features.kt` (`const val YourDevice = "YourDevice"`) and append to `Features.all`.
- Declare feature property under `properties.Features.properties` in `broker/yaml-json-schema.json`.
- Gate verticle deployment in `Monster.kt` (`if (Monster.isFeatureEnabled(Features.YourDevice)) { ... }`).
- Gate all GraphQL query and mutation resolver methods with `if (!Monster.isFeatureEnabled(Features.YourDevice))`.

### 5. GraphQL Schema Definition
**Location**: `broker/src/main/resources/` (`schema-types.graphqls`, `schema-queries.graphqls`, `schema-mutations.graphqls`)
- Add data types and status types in `schema-types.graphqls`.
- Add query endpoints in `schema-queries.graphqls` and mutation endpoints in `schema-mutations.graphqls`.
- Always keep query output `Type` models separate from mutation input `InputType` models.

### 6. GraphQL Resolvers
**Location**: `broker/src/main/kotlin/graphql/YourDeviceConfigQueries.kt` and `YourDeviceConfigMutations.kt`
- Gate resolver methods with `if (!Monster.isFeatureEnabled(Features.YourDevice))`.
- Query resolver fetches live metrics via EventBus.
- Mutation resolver creates/updates/deletes device configuration via `IDeviceConfigStore`.
- Preserve existing passwords on update if not provided in input.

### 7. Dashboard List Page
**Location**: `dashboard/src/pages/yourdevice-clients.html` + `src/js/yourdevice-clients.js`
- Build using **List Page Shape** (header, metric-cards, table with status indicators and action buttons).
- Use `window.graphqlClient` for queries and `window.ui` for notifications.

### 8. Dashboard Detail Page
**Location**: `dashboard/src/pages/yourdevice-client-detail.html` + `src/js/yourdevice-client-detail.js`
- Build using **Detail Page Shape** (breadcrumb header, section-cards, form controls).
- Read ID from URL params (`new URLSearchParams(window.location.search).get('id')`).
- Handle both Create mode and Edit mode without clearing existing passwords.

### 9. Dashboard Sidebar Navigation
**Location**: `dashboard/src/js/sidebar.js`
- Add menu item to `getMenuConfig()` under the `Bridging` section with `feature: 'YourDevice'`.

---

## Verification Checklist

After implementation, verify:
- [ ] Backend verticle starts cleanly when enabled via feature flag.
- [ ] GraphQL query returns active device configuration and live metrics.
- [ ] GraphQL mutation correctly creates, updates, and deletes devices.
- [ ] Dashboard list and detail views function properly without CSS component overrides.
- [ ] Reconnection logic handles external device disconnects smoothly.
