Files
cameleer-server/.claude/rules/core-classes.md
hsiegeln 9aad2f3871
All checks were successful
CI / cleanup-branch (pull_request) Has been skipped
CI / build (pull_request) Successful in 1m50s
CI / docker (pull_request) Has been skipped
CI / deploy (pull_request) Has been skipped
CI / deploy-feature (pull_request) Has been skipped
docs(rules): document AttributeFilter + SearchController attr param
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 11:22:27 +02:00

12 KiB

paths
paths
cameleer-server-core/**

Core Module Key Classes

cameleer-server-core/src/main/java/com/cameleer/server/core/

agent/ — Agent lifecycle and commands

  • AgentRegistryService — in-memory registry (ConcurrentHashMap), register/heartbeat/lifecycle
  • AgentInfo — record: id, name, application, environmentId, version, routeIds, capabilities, state
  • AgentCommand — record: id, type, targetAgent, payload, createdAt, expiresAt
  • AgentEventService — records agent state changes, heartbeats
  • AgentState — enum: LIVE, STALE, DEAD, SHUTDOWN
  • CommandType — enum for command types (config-update, deep-trace, replay, route-control, etc.)
  • CommandStatus — enum for command acknowledgement states
  • CommandReply — record: command execution result from agent
  • AgentEventRecord, AgentEventRepository — event persistence. AgentEventRepository.queryPage(...) is cursor-paginated (AgentEventPage{data, nextCursor, hasMore}); the legacy non-paginated query(...) path is gone. AgentEventRepository.findInWindow(env, appSlug, agentId, eventTypes, from, to, limit) returns matching events ordered by (timestamp ASC, insert_id ASC) — consumed by AgentLifecycleEvaluator.
  • AgentEventPage — record: (List<AgentEventRecord> data, String nextCursor, boolean hasMore) returned by AgentEventRepository.queryPage
  • AgentEventListener — callback interface for agent events
  • RouteStateRegistry — tracks per-agent route states

runtime/ — App/Environment/Deployment domain

  • App — record: id, environmentId, slug, displayName, containerConfig (JSONB)
  • AppVersion — record: id, appId, version, jarPath, detectedRuntimeType, detectedMainClass
  • Environment — record: id, slug, displayName, production, enabled, defaultContainerConfig, jarRetentionCount, color, createdAt. color is one of the 8 preset palette values validated by EnvironmentColor.VALUES and CHECK-constrained in PostgreSQL (V2 migration).
  • EnvironmentColor — constants: DEFAULT = "slate", VALUES = {slate,red,amber,green,teal,blue,purple,pink}, isValid(String).
  • Deployment — record: id, appId, appVersionId, environmentId, status, targetState, deploymentStrategy, replicaStates (JSONB), deployStage, containerId, containerName, createdBy (String, user_id reference; nullable for pre-V4 historical rows)
  • DeploymentStatus — enum: STOPPED, STARTING, RUNNING, DEGRADED, STOPPING, FAILED. DEGRADED is reserved for post-deploy drift (a replica died after RUNNING); DeploymentExecutor now marks partial-healthy deploys FAILED, not DEGRADED.
  • DeployStage — enum: PRE_FLIGHT, PULL_IMAGE, CREATE_NETWORK, START_REPLICAS, HEALTH_CHECK, SWAP_TRAFFIC, COMPLETE
  • DeploymentStrategy — enum: BLUE_GREEN, ROLLING. Stored on ResolvedContainerConfig.deploymentStrategy as kebab-case string ("blue-green" / "rolling"). fromWire(String) is the only conversion entry point; unknown/null inputs fall back to BLUE_GREEN so the executor dispatch site never null-checks or throws.
  • DeploymentService — createDeployment (calls deleteFailedByAppAndEnvironment first so FAILED rows don't pile up; STOPPED rows are preserved as restorable checkpoints), markRunning, markFailed, markStopped
  • RuntimeType — enum: AUTO, SPRING_BOOT, QUARKUS, PLAIN_JAVA, NATIVE
  • RuntimeDetector — probes JAR files at upload time: detects runtime from manifest Main-Class (Spring Boot loader, Quarkus entry point, plain Java) or native binary (non-ZIP magic bytes)
  • ContainerRequest — record: 20 fields for Docker container creation (includes runtimeType, customArgs, mainClass)
  • ContainerStatus — record: state, running, exitCode, error
  • ResolvedContainerConfig — record: typed config with memoryLimitMb, memoryReserveMb, cpuRequest, cpuLimit, appPort, exposedPorts, customEnvVars, stripPathPrefix, sslOffloading, routingMode, routingDomain, serverUrl, replicas, deploymentStrategy, routeControlEnabled, replayEnabled, runtimeType, customArgs, extraNetworks, externalRouting (default true; when false, TraefikLabelBuilder strips all traefik.* labels so the container is not publicly routed), certResolver (server-wide, sourced from CAMELEER_SERVER_RUNTIME_CERTRESOLVER; when blank the tls.certresolver label is omitted — use for dev installs with a static TLS store)
  • RoutingMode — enum for routing strategies
  • ConfigMerger — pure function: resolve(globalDefaults, envConfig, appConfig) -> ResolvedContainerConfig
  • RuntimeOrchestrator — interface: startContainer, stopContainer, getContainerStatus, getLogs, startLogCapture, stopLogCapture
  • AppRepository, AppVersionRepository, EnvironmentRepository, DeploymentRepository — repository interfaces
  • AppService, EnvironmentService — domain services

search/ — Execution search and stats

  • SearchService — search, count, stats, statsForApp, statsForRoute, timeseries, timeseriesForApp, timeseriesForRoute, timeseriesGroupedByApp, timeseriesGroupedByRoute, slaCompliance, slaCountsByApp, slaCountsByRoute, topErrors, activeErrorTypes, punchcard, distinctAttributeKeys. statsForRoute/timeseriesForRoute take (routeId, applicationId) — app filter is applied to stats_1m_route.
  • SearchRequest / SearchResult — search DTOs. SearchRequest.attributeFilters: List<AttributeFilter> carries structured facet filters for execution attributes — key-only (exists), exact (key=value), or wildcard (* in value). The 21-arg legacy ctor is preserved for call-site churn; the compact ctor normalises null → List.of().
  • AttributeFilter(key, value) — record with key regex ^[a-zA-Z0-9._-]+$ (inlined into SQL, same constraint as alerting), value == null means key-exists, value containing * becomes a SQL LIKE pattern via toLikePattern().
  • ExecutionStats, ExecutionSummary — stats aggregation records
  • StatsTimeseries, TopError — timeseries and error DTOs
  • LogSearchRequest / LogSearchResponse — log search DTOs. LogSearchRequest.sources / levels are List<String> (null-normalized, multi-value OR); cursor + limit + sort drive keyset pagination. Response carries nextCursor + hasMore + per-level levelCounts.

storage/ — Storage abstractions

  • ExecutionStore, MetricsStore, MetricsQueryStore, StatsStore, DiagramStore, RouteCatalogStore, SearchIndex, LogIndex — interfaces. DiagramStore.findLatestContentHashForAppRoute(appId, routeId, env) resolves the latest diagram by (app, env, route) without consulting the agent registry, so routes whose publishing agents were removed between app versions still resolve. findContentHashForRoute(route, instance) is retained for the ingestion path that stamps a per-execution diagramContentHash at ingest time (point-in-time link from ExecutionDetail/ExecutionSummary).
  • RouteCatalogEntry — record: applicationId, routeId, environment, firstSeen, lastSeen
  • LogEntryResult — log query result record
  • model/ExecutionDocument, MetricTimeSeries, MetricsSnapshot

rbac/ — Role-based access control

  • RbacService — interface: role/group CRUD, assignRoleToUser, removeRoleFromUser, addUserToGroup, removeUserFromGroup, getDirectRolesForUser, getEffectiveRolesForUser, clearManagedAssignments, assignManagedRole, addUserToManagedGroup, getStats, listUsers
  • SystemRole — enum: AGENT, VIEWER, OPERATOR, ADMIN; normalizeScope() maps scopes
  • UserDetail, RoleDetail, GroupDetail — records
  • UserSummary, RoleSummary, GroupSummary — lightweight list records
  • RbacStats — aggregate stats record
  • AssignmentOrigin — enum: DIRECT, CLAIM_MAPPING (tracks how roles were assigned)
  • ClaimMappingRule — record: OIDC claim-to-role mapping rule
  • ClaimMappingService — interface: CRUD for claim mapping rules
  • ClaimMappingRepository — persistence interface
  • RoleRepository, GroupRepository — persistence interfaces

admin/ — Server-wide admin config

  • SensitiveKeysConfig — record: keys (List, immutable)
  • SensitiveKeysRepository — interface: find(), save()
  • SensitiveKeysMerger — pure function: merge(global, perApp) -> union with case-insensitive dedup, preserves first-seen casing. Returns null when both inputs null.
  • AppSettings, AppSettingsRepository — per-app-per-env settings config and persistence. Record carries (applicationId, environment, …); repository methods are findByApplicationAndEnvironment, findByEnvironment, save, delete(appId, env). AppSettings.defaults(appId, env) produces a default instance scoped to an environment.
  • ThresholdConfig, ThresholdRepository — alerting threshold config and persistence
  • AuditService — audit logging facade
  • AuditRecord, AuditResult, AuditCategory (enum: INFRA, AUTH, USER_MGMT, CONFIG, RBAC, AGENT, OUTBOUND_CONNECTION_CHANGE, OUTBOUND_HTTP_TRUST_CHANGE, ALERT_RULE_CHANGE, ALERT_SILENCE_CHANGE, DEPLOYMENT), AuditRepository — audit trail records and persistence

http/ — Outbound HTTP primitives (cross-cutting)

  • OutboundHttpClientFactory — interface: clientFor(context) returns memoized CloseableHttpClient
  • OutboundHttpProperties — record: trustAll, trustedCaPemPaths, defaultConnectTimeout, defaultReadTimeout, proxyUrl, proxyUsername, proxyPassword
  • OutboundHttpRequestContext — record of per-call TLS/timeout overrides; systemDefault() static factory
  • TrustMode — enum: SYSTEM_DEFAULT | TRUST_ALL | TRUST_PATHS

outbound/ — Admin-managed outbound connections

  • OutboundConnection — record: id, tenantId, name, description, url, method, defaultHeaders, defaultBodyTmpl, tlsTrustMode, tlsCaPemPaths, hmacSecretCiphertext, auth, allowedEnvironmentIds, createdAt, createdBy (String user_id), updatedAt, updatedBy (String user_id). isAllowedInEnvironment(envId) returns true when allowed-envs list is empty OR contains the env.
  • OutboundAuth — sealed interface + records: None | Bearer(tokenCiphertext) | Basic(username, passwordCiphertext). Jackson @JsonTypeInfo(use = DEDUCTION) — wire shape has no discriminator, subtype inferred from fields.
  • OutboundAuthKind, OutboundMethod — enums
  • OutboundConnectionRepository — CRUD by (tenantId, id): save/findById/findByName/listByTenant/delete
  • OutboundConnectionService — create/update/delete/get/list with uniqueness + narrow-envs + delete-if-referenced guards. rulesReferencing(id) stubbed in Plan 01 (returns []); populated in Plan 02 against AlertRuleRepository.

security/ — Auth

  • JwtService — interface: createAccessToken, createRefreshToken, validateAccessToken, validateRefreshToken
  • Ed25519SigningService — interface: sign, getPublicKeyBase64 (config signing)
  • OidcConfig — record: enabled, issuerUri, clientId, clientSecret, rolesClaim, defaultRoles, autoSignup, displayNameClaim, userIdClaim, audience, additionalScopes
  • OidcConfigRepository — persistence interface
  • PasswordPolicyValidator — min 12 chars, 3-of-4 character classes, no username match
  • UserInfo, UserRepository — user identity records and persistence
  • InvalidTokenException — thrown on revoked/expired tokens

ingestion/ — Buffered data pipeline

  • IngestionService — diagram + metrics facade (ingestDiagram, acceptMetrics, getMetricsBuffer). Execution ingestion went through here via the legacy RouteExecution shape until ChunkAccumulator took over writes from the chunked pipeline — the ingestExecution path plus its ExecutionStore.upsert / upsertProcessors dependencies were removed.
  • ChunkAccumulator — batches data for efficient flush; owns the execution write path (chunks → buffers → flush scheduler → ClickHouseExecutionStore.insertExecutionBatch).
  • WriteBuffer — bounded ring buffer for async flush
  • BufferedLogEntry — log entry wrapper with metadata
  • MergedExecution, TaggedDiagram — tagged ingestion records. TaggedDiagram carries (instanceId, applicationId, environment, graph) — env is resolved from the agent registry in the controller and stamped on the ClickHouse route_diagrams row.