Behind a reverse proxy the browser sends Origin matching the proxy's public URL, which the single-origin CAMELEER_UI_ORIGIN rejects. New env var accepts comma-separated origins and takes priority over UI_ORIGIN, which remains as a backwards-compatible fallback. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
71 lines
5.5 KiB
Markdown
71 lines
5.5 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Project
|
|
|
|
Cameleer3 Server — observability server that receives, stores, and serves Camel route execution data and route diagrams from Cameleer3 agents. Pushes config and commands to agents via SSE.
|
|
|
|
## Related Project
|
|
|
|
- **cameleer3** (`https://gitea.siegeln.net/cameleer/cameleer3`) — the Java agent that instruments Camel applications
|
|
- Protocol defined in `cameleer3-common/PROTOCOL.md` in the agent repo
|
|
- This server depends on `com.cameleer3:cameleer3-common` (shared models and graph API)
|
|
|
|
## Modules
|
|
|
|
- `cameleer3-server-core` — domain logic, storage, agent registry
|
|
- `cameleer3-server-app` — Spring Boot web app, REST controllers, SSE, static resources
|
|
|
|
## Build Commands
|
|
|
|
```bash
|
|
mvn clean compile # Compile all modules
|
|
mvn clean verify # Full build with tests
|
|
```
|
|
|
|
## Run
|
|
|
|
```bash
|
|
java -jar cameleer3-server-app/target/cameleer3-server-app-1.0-SNAPSHOT.jar
|
|
```
|
|
|
|
## Key Conventions
|
|
|
|
- Java 17+ required
|
|
- Spring Boot 3.4.3 parent POM
|
|
- Depends on `com.cameleer3:cameleer3-common` from Gitea Maven registry
|
|
- Jackson `JavaTimeModule` for `Instant` deserialization
|
|
- Communication: receives HTTP POST data from agents (executions, diagrams, metrics, logs), serves SSE event streams for config push/commands (config-update, deep-trace, replay, route-control)
|
|
- Maintains agent instance registry (in-memory) with states: LIVE → STALE → DEAD. Auto-heals from JWT `env` claim + heartbeat body on heartbeat/SSE after server restart (priority: heartbeat `environmentId` > JWT `env` claim > `"default"`). Capabilities and route states updated on every heartbeat (protocol v2). Route catalog falls back to ClickHouse stats for route discovery when registry has incomplete data.
|
|
- Multi-tenancy: each server instance serves one tenant (configured via `CAMELEER_TENANT_ID`, default: `"default"`). Environments (dev/staging/prod) are first-class — agents send `environmentId` at registration and in heartbeats. JWT carries `env` claim for environment persistence across token refresh. PostgreSQL isolated via schema-per-tenant (`?currentSchema=tenant_{id}`). ClickHouse shared DB with `tenant_id` + `environment` columns, partitioned by `(tenant_id, toYYYYMM(timestamp))`.
|
|
- Storage: PostgreSQL for RBAC, config, and audit; ClickHouse for all observability data (executions, search, logs, metrics, stats, diagrams). ClickHouse schema migrations in `clickhouse/*.sql`, run idempotently on startup by `ClickHouseSchemaInitializer`. Use `IF NOT EXISTS` for CREATE and ADD PROJECTION.
|
|
- Logging: ClickHouse JDBC set to INFO (`com.clickhouse`), HTTP client to WARN (`org.apache.hc.client5`) in application.yml
|
|
- Security: JWT auth with RBAC (AGENT/VIEWER/OPERATOR/ADMIN roles), Ed25519 config signing (key derived deterministically from JWT secret via HMAC-SHA256), bootstrap token for registration. CORS: `CAMELEER_CORS_ALLOWED_ORIGINS` (comma-separated) overrides `CAMELEER_UI_ORIGIN` for multi-origin setups (e.g., reverse proxy).
|
|
- OIDC: Optional external identity provider support (token exchange pattern). Configured via admin API, stored in database (`server_config` table). Resource server mode: accepts external access tokens (Logto M2M) via JWKS validation when `CAMELEER_OIDC_ISSUER_URI` is set. `CAMELEER_OIDC_JWK_SET_URI` overrides JWKS discovery for container networking. `CAMELEER_OIDC_TLS_SKIP_VERIFY=true` disables TLS cert verification for OIDC calls (self-signed CAs). Scope-based role mapping: `admin`/`operator`/`viewer` scopes map to RBAC roles.
|
|
- User persistence: PostgreSQL `users` table, admin CRUD at `/api/v1/admin/users`
|
|
- Usage analytics: ClickHouse `usage_events` table tracks authenticated UI requests, flushed every 5s
|
|
|
|
## CI/CD & Deployment
|
|
|
|
- CI workflow: `.gitea/workflows/ci.yml` — build → docker → deploy on push to main or feature branches
|
|
- Build step skips integration tests (`-DskipITs`) — Testcontainers needs Docker daemon
|
|
- Docker: multi-stage build (`Dockerfile`), `$BUILDPLATFORM` for native Maven on ARM64 runner, amd64 runtime
|
|
- `REGISTRY_TOKEN` build arg required for `cameleer3-common` dependency resolution
|
|
- Registry: `gitea.siegeln.net/cameleer/cameleer3-server` (container images)
|
|
- K8s manifests in `deploy/` — Kustomize base + overlays (main/feature), shared infra (PostgreSQL, ClickHouse, Logto) as top-level manifests
|
|
- Deployment target: k3s at 192.168.50.86, namespace `cameleer` (main), `cam-<slug>` (feature branches)
|
|
- Feature branches: isolated namespace, PG schema; Traefik Ingress at `<slug>-api.cameleer.siegeln.net`
|
|
- Secrets managed in CI deploy step (idempotent `--dry-run=client | kubectl apply`): `cameleer-auth`, `postgres-credentials`, `clickhouse-credentials`
|
|
- K8s probes: server uses `/api/v1/health`, PostgreSQL uses `pg_isready`
|
|
- Docker build uses buildx registry cache + `--provenance=false` for Gitea compatibility
|
|
|
|
## UI Styling
|
|
|
|
- Always use `@cameleer/design-system` CSS variables for colors (`var(--amber)`, `var(--error)`, `var(--success)`, etc.) — never hardcode hex values. This applies to CSS modules, inline styles, and SVG `fill`/`stroke` attributes. SVG presentation attributes resolve `var()` correctly.
|
|
- Global user preferences (environment selection) use Zustand stores with localStorage persistence — never URL search params. URL params are for page-specific state only (e.g. `?text=` search query). Switching environment resets all filters and remounts pages.
|
|
|
|
## Disabled Skills
|
|
|
|
- Do NOT use any `gsd:*` skills in this project. This includes all `/gsd:` prefixed commands.
|