Skip to content

Commit 47a7a27

Browse files
tottoclaude
andcommitted
Add Claude Code skills: cantara-visuale
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 0a1efa0 commit 47a7a27

File tree

1 file changed

+226
-0
lines changed

1 file changed

+226
-0
lines changed
Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
name: cantara-visuale
2+
version: 1.0.0
3+
description: >
4+
Visuale real-time microservice health dashboard. Covers the backend (Helidon,
5+
StatusService event-driven architecture, health check probing, Slack notifications),
6+
the frontend (Nuxt 2 + Vue SPA), the REST API, and integration patterns for
7+
registering services. Useful operational context for monitoring Cantara fleets.
8+
9+
Trigger phrases: "visuale, visuale dashboard, service monitoring, health dashboard,
10+
microservice health, visuale status, health check probing, service grid,
11+
visuale api, visuale slack, fleet monitoring"
12+
13+
context:
14+
org: cantara
15+
repos:
16+
- visuale
17+
18+
instructions: |
19+
## Overview
20+
21+
Visuale is Cantara's near-real-time dashboard for monitoring microservice health in
22+
production. It displays a grid of services with health status, version info, and
23+
health trends. Designed as a lightweight complement to Grafana/Prometheus.
24+
25+
**Version:** 12.24.2-SNAPSHOT
26+
**Port:** 8080 (default, overridable via `local_override.properties`)
27+
**Backend:** Java 11+, Helidon SE (not Jetty/Jersey)
28+
**Frontend:** Nuxt 2 + Vue (SPA, built during Maven package)
29+
30+
## Architecture
31+
32+
```
33+
Services (push health via PUT) Health Check Probing
34+
| |
35+
v v
36+
StatusResource (REST API) HealthCheckProber (scheduled, 10s)
37+
| |
38+
v v
39+
StatusService (event-driven, blocking queue)
40+
|
41+
v
42+
Cached JSON (environment state) --> Nuxt SPA (polls GET /status)
43+
|
44+
v
45+
NotificationService (Slack alerts)
46+
```
47+
48+
## Backend Components
49+
50+
### Entry Point
51+
- `no.cantara.tools.visuale.Main` -- application startup (Helidon SE)
52+
53+
### StatusService (Core Engine)
54+
- Event-driven architecture using a blocking queue
55+
- Processes health updates asynchronously
56+
- Throttled: minimum 1 second between updates
57+
- Batch processing: every 25 events when backlogged
58+
- Publishes changes to a cached JSON string for the frontend
59+
60+
### StatusResource (REST API)
61+
| Endpoint | Method | Purpose |
62+
|----------|--------|---------|
63+
| `/status` or `/api/status` | GET | Returns full environment JSON |
64+
| `/status` or `/api/status` | PUT | Update health (body: service_name, service_tag, service_type, name) |
65+
| `/status/{env}/{service}/{node}` | PUT | Update specific node health |
66+
67+
### HealthCheckProber
68+
- Scheduled polling service: probes configured health endpoints every 10 seconds
69+
- Configuration: `environment_config.json` (list of services and health URLs)
70+
- Normalizes diverse health JSON formats via `HealthMapper`
71+
72+
### NotificationService
73+
- Slack alerting when services go down or come back up
74+
- Configured via `local_override.properties`
75+
76+
### Domain Model
77+
- `Environment` -- top-level: contains services
78+
- `Service` -- a logical service: contains nodes
79+
- `Node` -- a single instance/replica of a service
80+
- `Health` -- a health check response (status, version, IP, running_since)
81+
- `HealthMapper` -- normalizes various health JSON formats to standard `Health` model
82+
83+
**Identification:** Services and nodes are matched by name + tag combination.
84+
Tags are case-insensitive. Nodes are matched by name first, then IP address.
85+
86+
## Frontend (Nuxt 2 + Vue SPA)
87+
88+
Located in `src/main/resources/nuxt-spa/`.
89+
90+
**Key components:**
91+
- `PollingService.vue` -- periodically fetches status JSON from backend
92+
- `Service.vue` -- renders a service card with its nodes
93+
- `ServiceBattery.vue` -- visual health indicator (traffic light)
94+
- `Node.vue` -- individual node status display
95+
- `groupedServicesOverTag.vue` -- group by tag view
96+
- `groupTagOverService.vue` -- group by service view
97+
98+
**UI Extensions (query params):**
99+
- `?ui_extension=groupByTag` -- group services by tag
100+
- `?ui_extension=groupByService` -- group by service
101+
- `&servicetype=true` -- show service type icons
102+
103+
**Development:**
104+
```bash
105+
cd src/main/resources/nuxt-spa
106+
npm run dev # Dev server on localhost:3000
107+
npm run lint # ESLint
108+
npm run test # Jest tests
109+
npm run generate # Build static site
110+
```
111+
112+
## Configuration
113+
114+
### environment_config.json
115+
Defines services and their health endpoint URLs for probing:
116+
```json
117+
{
118+
"environment_name": "production",
119+
"services": [
120+
{
121+
"service_name": "my-service",
122+
"service_tag": "prod",
123+
"service_type": "java",
124+
"health_url": "http://my-service:8080/health"
125+
}
126+
]
127+
}
128+
```
129+
130+
### local_override.properties
131+
```properties
132+
server.port=8080
133+
access_token=my-secret-token
134+
slack_webhook_url=https://hooks.slack.com/...
135+
slack_alerting_enabled=true
136+
```
137+
138+
## How To: Common Tasks
139+
140+
### Register a service with Visuale (push model)
141+
Services push their health status via PUT:
142+
```bash
143+
curl -X PUT http://visuale:8080/api/status \
144+
-H "Content-Type: application/json" \
145+
-d '{
146+
"service_name": "my-service",
147+
"service_tag": "prod",
148+
"service_type": "java",
149+
"name": "node-1",
150+
"status": "OK",
151+
"version": "1.2.3",
152+
"ip": "10.0.1.5",
153+
"running_since": "2026-01-15T10:00:00Z"
154+
}'
155+
```
156+
157+
### Register a service with Visuale (pull model)
158+
Add the service to `environment_config.json` and HealthCheckProber will poll it
159+
every 10 seconds.
160+
161+
### Build and run
162+
```bash
163+
cd /src/cantara/visuale
164+
165+
# Full build (Java + Nuxt)
166+
mvn clean package
167+
168+
# Run
169+
java -jar target/visuale.jar
170+
171+
# Test
172+
mvn test
173+
mvn test -Dtest=StatusServiceTest
174+
```
175+
176+
### Develop frontend only
177+
```bash
178+
cd /src/cantara/visuale/src/main/resources/nuxt-spa
179+
npm install
180+
npm run dev # Hot-reload dev server on :3000
181+
```
182+
183+
## Integration with Cantara Ecosystem
184+
185+
Visuale integrates with other Cantara components:
186+
187+
- **Stingray-based services:** Stingray health endpoints (`StingrayHealthResource`) follow
188+
Cantara health conventions that `HealthMapper` understands automatically.
189+
- **Whydah services:** STS, UAS, OAuth2Service all expose `/health` endpoints compatible
190+
with Visuale probing.
191+
- **Valuereporter:** Complementary monitoring. Visuale = service-level health status.
192+
Valuereporter = method-level performance metrics.
193+
- **ConfigService:** Can be monitored by Visuale like any other service.
194+
195+
## Gotchas & Pitfalls
196+
197+
1. **Helidon, not Jetty:** Visuale uses Helidon SE, NOT embedded Jetty. This is different
198+
from most Cantara services (which use Stingray/Jetty). The REST patterns are slightly
199+
different (Helidon routing, not JAX-RS annotations).
200+
201+
2. **Frontend built during Maven package:** The Nuxt SPA is compiled during `mvn package`
202+
and served as static content from the JAR. Changes to the frontend require a full
203+
Maven build unless using `npm run dev` for local development.
204+
205+
3. **Health format normalization:** `HealthMapper` handles diverse health JSON formats from
206+
different services. If a new service has an unusual health format, `HealthMapper` may
207+
need to be extended.
208+
209+
4. **Tag case-insensitivity:** Service tags are case-insensitive for matching. "PROD" and
210+
"prod" are the same tag. Names are case-sensitive.
211+
212+
5. **Throttling:** StatusService throttles updates to minimum 1 second apart. Rapid health
213+
changes may be batched and the dashboard may lag slightly behind real-time.
214+
215+
6. **Access token:** If `access_token` is set in properties, all PUT requests must include
216+
it in the request. GET requests are always open.
217+
218+
## Related Skills
219+
220+
- `cantara-stingray.yaml` -- Stingray framework (Visuale monitors Stingray-based services)
221+
- `cantara-valuereporter.yaml` -- Valuereporter (complementary monitoring)
222+
- `cantara-whydah.yaml` -- Whydah (Visuale can monitor Whydah services)
223+
224+
## Repository Path
225+
226+
- Visuale: `/src/cantara/visuale/`

0 commit comments

Comments
 (0)