2026-04-16 09:26:53 +02:00
---
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
- `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, jarRetentionCount
- `Deployment` — record: id, appId, appVersionId, environmentId, status, targetState, deploymentStrategy, replicaStates (JSONB), deployStage, containerId, containerName
- `DeploymentStatus` — enum: STOPPED, STARTING, RUNNING, DEGRADED, STOPPING, FAILED
- `DeployStage` — enum: PRE_FLIGHT, PULL_IMAGE, CREATE_NETWORK, START_REPLICAS, HEALTH_CHECK, SWAP_TRAFFIC, COMPLETE
- `DeploymentService` — createDeployment (deletes terminal deployments first), 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
- `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
2026-04-16 19:49:55 +02:00
- `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` .
2026-04-16 09:26:53 +02:00
- `SearchRequest` / `SearchResult` — search DTOs
- `ExecutionStats` , `ExecutionSummary` — stats aggregation records
- `StatsTimeseries` , `TopError` — timeseries and error DTOs
- `LogSearchRequest` / `LogSearchResponse` — log search DTOs
## storage/ — Storage abstractions
2026-04-16 18:50:39 +02:00
- `ExecutionStore` , `MetricsStore` , `MetricsQueryStore` , `StatsStore` , `DiagramStore` , `RouteCatalogStore` , `SearchIndex` , `LogIndex` — interfaces
- `RouteCatalogEntry` — record: applicationId, routeId, environment, firstSeen, lastSeen
2026-04-16 09:26:53 +02:00
- `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<String>, 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.
feat!: scope per-app config and settings by environment
BREAKING: wipe dev PostgreSQL before deploying — V1 checksum changes.
Agents must now send environmentId on registration (400 if missing).
Two tables previously keyed on app name alone caused cross-environment
data bleed: writing config for (app=X, env=dev) would overwrite the row
used by (app=X, env=prod) agents, and agent startup fetches ignored env
entirely.
- V1 schema: application_config and app_settings are now PK (app, env).
- Repositories: env-keyed finders/saves; env is the authoritative column,
stamped on the stored JSON so the row agrees with itself.
- ApplicationConfigController.getConfig is dual-mode — AGENT role uses
JWT env claim (agents cannot spoof env); non-agent callers provide env
via ?environment= query param.
- AppSettingsController endpoints now require ?environment=.
- SensitiveKeysAdminController fan-out iterates (app, env) slices so each
env gets its own merged keys.
- DiagramController ingestion stamps env on TaggedDiagram; ClickHouse
route_diagrams INSERT + findProcessorRouteMapping are env-scoped.
- AgentRegistrationController: environmentId is required on register;
removed all "default" fallbacks from register/refresh/heartbeat auto-heal.
- UI hooks (useApplicationConfig, useProcessorRouteMapping, useAppSettings,
useAllAppSettings, useUpdateAppSettings) take env, wired to
useEnvironmentStore at all call sites.
- New ConfigEnvIsolationIT covers env-isolation for both repositories.
Plan in docs/superpowers/plans/2026-04-16-environment-scoping.md.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-16 22:25:21 +02:00
- `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.
2026-04-16 09:26:53 +02:00
- `ThresholdConfig` , `ThresholdRepository` — alerting threshold config and persistence
- `AuditService` — audit logging facade
- `AuditRecord` , `AuditResult` , `AuditCategory` , `AuditRepository` — audit trail records and persistence
## 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` — ingestExecution, ingestMetric, ingestLog, ingestDiagram
- `ChunkAccumulator` — batches data for efficient flush
- `WriteBuffer` — bounded ring buffer for async flush
- `BufferedLogEntry` — log entry wrapper with metadata
feat!: scope per-app config and settings by environment
BREAKING: wipe dev PostgreSQL before deploying — V1 checksum changes.
Agents must now send environmentId on registration (400 if missing).
Two tables previously keyed on app name alone caused cross-environment
data bleed: writing config for (app=X, env=dev) would overwrite the row
used by (app=X, env=prod) agents, and agent startup fetches ignored env
entirely.
- V1 schema: application_config and app_settings are now PK (app, env).
- Repositories: env-keyed finders/saves; env is the authoritative column,
stamped on the stored JSON so the row agrees with itself.
- ApplicationConfigController.getConfig is dual-mode — AGENT role uses
JWT env claim (agents cannot spoof env); non-agent callers provide env
via ?environment= query param.
- AppSettingsController endpoints now require ?environment=.
- SensitiveKeysAdminController fan-out iterates (app, env) slices so each
env gets its own merged keys.
- DiagramController ingestion stamps env on TaggedDiagram; ClickHouse
route_diagrams INSERT + findProcessorRouteMapping are env-scoped.
- AgentRegistrationController: environmentId is required on register;
removed all "default" fallbacks from register/refresh/heartbeat auto-heal.
- UI hooks (useApplicationConfig, useProcessorRouteMapping, useAppSettings,
useAllAppSettings, useUpdateAppSettings) take env, wired to
useEnvironmentStore at all call sites.
- New ConfigEnvIsolationIT covers env-isolation for both repositories.
Plan in docs/superpowers/plans/2026-04-16-environment-scoping.md.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-16 22:25:21 +02:00
- `MergedExecution` , `TaggedExecution` , `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.