chore: rename cameleer3 to cameleer
Rename Java packages from com.cameleer3 to com.cameleer, module directories from cameleer3-* to cameleer-*, and all references throughout workflows, Dockerfiles, docs, migrations, and pom.xml. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -16,7 +16,7 @@
|
||||
|
||||
### New files
|
||||
|
||||
**Core module** (`cameleer3-server-core/src/main/java/com/cameleer3/server/core/`):
|
||||
**Core module** (`cameleer-server-core/src/main/java/com/cameleer/server/core/`):
|
||||
- `storage/ExecutionStore.java` — new interface replacing ExecutionRepository
|
||||
- `storage/StatsStore.java` — new interface for stats from continuous aggregates
|
||||
- `storage/SearchIndex.java` — new interface for OpenSearch operations
|
||||
@@ -28,7 +28,7 @@
|
||||
- `indexing/SearchIndexer.java` — debounced event listener for OpenSearch indexing
|
||||
- `indexing/ExecutionUpdatedEvent.java` — event published after execution write
|
||||
|
||||
**App module** (`cameleer3-server-app/src/main/java/com/cameleer3/server/app/`):
|
||||
**App module** (`cameleer-server-app/src/main/java/com/cameleer/server/app/`):
|
||||
- `storage/PostgresExecutionStore.java` — ExecutionStore impl with upsert
|
||||
- `storage/PostgresStatsStore.java` — StatsStore impl querying continuous aggregates
|
||||
- `storage/PostgresDiagramStore.java` — DiagramStore impl
|
||||
@@ -41,7 +41,7 @@
|
||||
- `ingestion/MetricsFlushScheduler.java` — scheduled metrics buffer flush (replaces ClickHouseFlushScheduler, metrics only)
|
||||
- `retention/RetentionScheduler.java` — scheduled job for drop_chunks and OpenSearch index deletion
|
||||
|
||||
**Flyway migrations** (`cameleer3-server-app/src/main/resources/db/migration/`):
|
||||
**Flyway migrations** (`cameleer-server-app/src/main/resources/db/migration/`):
|
||||
- `V1__extensions.sql` — CREATE EXTENSION timescaledb, timescaledb_toolkit
|
||||
- `V2__executions.sql` — executions hypertable
|
||||
- `V3__processor_executions.sql` — processor_executions hypertable
|
||||
@@ -53,7 +53,7 @@
|
||||
|
||||
Note: Retention is NOT in a Flyway migration (Flyway migrations are immutable once applied). No V9 file. Retention is handled by `RetentionScheduler` at runtime with configurable intervals.
|
||||
|
||||
**Test files** (`cameleer3-server-app/src/test/java/com/cameleer3/server/app/`):
|
||||
**Test files** (`cameleer-server-app/src/test/java/com/cameleer/server/app/`):
|
||||
- `AbstractPostgresIT.java` — replaces AbstractClickHouseIT (TimescaleDB Testcontainer)
|
||||
- `storage/PostgresExecutionStoreIT.java` — upsert, dedup, chunked arrival tests
|
||||
- `storage/PostgresStatsStoreIT.java` — continuous aggregate query tests
|
||||
@@ -64,35 +64,35 @@ Note: Retention is NOT in a Flyway migration (Flyway migrations are immutable on
|
||||
### Files to modify
|
||||
|
||||
- `pom.xml` (root) — no changes needed
|
||||
- `cameleer3-server-app/pom.xml` — swap clickhouse-jdbc for postgresql + opensearch-java + flyway
|
||||
- `cameleer3-server-core/.../core/search/SearchService.java` — split: search delegates to SearchIndex, stats/timeseries to StatsStore
|
||||
- `cameleer3-server-core/.../core/detail/DetailService.java` — use ExecutionStore instead of ExecutionRepository
|
||||
- `cameleer3-server-core/.../core/detail/RawExecutionRow.java` — remove (replaced by normalized model)
|
||||
- `cameleer3-server-core/.../core/ingestion/IngestionService.java` — synchronous execution/diagram writes, keep buffer for metrics
|
||||
- `cameleer3-server-app/.../app/config/SearchBeanConfig.java` — wire StatsStore into SearchService
|
||||
- `cameleer3-server-app/.../app/config/IngestionBeanConfig.java` — update bean wiring
|
||||
- `cameleer3-server-app/src/main/resources/application.yml` — PostgreSQL + OpenSearch config
|
||||
- `cameleer3-server-app/src/test/resources/application-test.yml` — test config
|
||||
- `cameleer-server-app/pom.xml` — swap clickhouse-jdbc for postgresql + opensearch-java + flyway
|
||||
- `cameleer-server-core/.../core/search/SearchService.java` — split: search delegates to SearchIndex, stats/timeseries to StatsStore
|
||||
- `cameleer-server-core/.../core/detail/DetailService.java` — use ExecutionStore instead of ExecutionRepository
|
||||
- `cameleer-server-core/.../core/detail/RawExecutionRow.java` — remove (replaced by normalized model)
|
||||
- `cameleer-server-core/.../core/ingestion/IngestionService.java` — synchronous execution/diagram writes, keep buffer for metrics
|
||||
- `cameleer-server-app/.../app/config/SearchBeanConfig.java` — wire StatsStore into SearchService
|
||||
- `cameleer-server-app/.../app/config/IngestionBeanConfig.java` — update bean wiring
|
||||
- `cameleer-server-app/src/main/resources/application.yml` — PostgreSQL + OpenSearch config
|
||||
- `cameleer-server-app/src/test/resources/application-test.yml` — test config
|
||||
|
||||
### Files to delete
|
||||
|
||||
- `cameleer3-server-app/.../app/storage/ClickHouseExecutionRepository.java`
|
||||
- `cameleer3-server-app/.../app/storage/ClickHouseDiagramRepository.java`
|
||||
- `cameleer3-server-app/.../app/storage/ClickHouseMetricsRepository.java`
|
||||
- `cameleer3-server-app/.../app/storage/ClickHouseUserRepository.java`
|
||||
- `cameleer3-server-app/.../app/storage/ClickHouseOidcConfigRepository.java`
|
||||
- `cameleer3-server-app/.../app/search/ClickHouseSearchEngine.java`
|
||||
- `cameleer3-server-app/.../app/ingestion/ClickHouseFlushScheduler.java`
|
||||
- `cameleer3-server-app/.../app/config/ClickHouseConfig.java`
|
||||
- `cameleer3-server-core/.../core/storage/ExecutionRepository.java`
|
||||
- `cameleer3-server-core/.../core/storage/DiagramRepository.java`
|
||||
- `cameleer3-server-core/.../core/storage/MetricsRepository.java`
|
||||
- `cameleer3-server-core/.../core/search/SearchEngine.java`
|
||||
- `cameleer3-server-core/.../core/detail/RawExecutionRow.java`
|
||||
- `cameleer-server-app/.../app/storage/ClickHouseExecutionRepository.java`
|
||||
- `cameleer-server-app/.../app/storage/ClickHouseDiagramRepository.java`
|
||||
- `cameleer-server-app/.../app/storage/ClickHouseMetricsRepository.java`
|
||||
- `cameleer-server-app/.../app/storage/ClickHouseUserRepository.java`
|
||||
- `cameleer-server-app/.../app/storage/ClickHouseOidcConfigRepository.java`
|
||||
- `cameleer-server-app/.../app/search/ClickHouseSearchEngine.java`
|
||||
- `cameleer-server-app/.../app/ingestion/ClickHouseFlushScheduler.java`
|
||||
- `cameleer-server-app/.../app/config/ClickHouseConfig.java`
|
||||
- `cameleer-server-core/.../core/storage/ExecutionRepository.java`
|
||||
- `cameleer-server-core/.../core/storage/DiagramRepository.java`
|
||||
- `cameleer-server-core/.../core/storage/MetricsRepository.java`
|
||||
- `cameleer-server-core/.../core/search/SearchEngine.java`
|
||||
- `cameleer-server-core/.../core/detail/RawExecutionRow.java`
|
||||
|
||||
Note: `UserRepository` and `OidcConfigRepository` interfaces in `core.security` are **kept** — the new Postgres implementations implement these existing interfaces. No rename needed since their contracts are unchanged.
|
||||
- `cameleer3-server-app/src/main/resources/clickhouse/*.sql` (all 8 files)
|
||||
- `cameleer3-server-app/src/test/.../app/AbstractClickHouseIT.java`
|
||||
- `cameleer-server-app/src/main/resources/clickhouse/*.sql` (all 8 files)
|
||||
- `cameleer-server-app/src/test/.../app/AbstractClickHouseIT.java`
|
||||
|
||||
---
|
||||
|
||||
@@ -101,11 +101,11 @@ Note: `UserRepository` and `OidcConfigRepository` interfaces in `core.security`
|
||||
### Task 1: Update Maven dependencies
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-app/pom.xml`
|
||||
- Modify: `cameleer-server-app/pom.xml`
|
||||
|
||||
- [ ] **Step 1: Replace ClickHouse JDBC with PostgreSQL driver + Flyway + OpenSearch client**
|
||||
|
||||
In `cameleer3-server-app/pom.xml`, replace the ClickHouse dependency and add new ones:
|
||||
In `cameleer-server-app/pom.xml`, replace the ClickHouse dependency and add new ones:
|
||||
|
||||
Remove:
|
||||
```xml
|
||||
@@ -165,22 +165,22 @@ Note: `postgresql` driver and `flyway-core` versions are managed by Spring Boot
|
||||
- [ ] **Step 2: Commit** (compilation will fail until ClickHouse code is deleted in Task 16 — this is expected)
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/pom.xml
|
||||
git add cameleer-server-app/pom.xml
|
||||
git commit -m "chore: swap ClickHouse deps for PostgreSQL, Flyway, OpenSearch"
|
||||
```
|
||||
|
||||
### Task 2: Write Flyway migrations
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/main/resources/db/migration/V1__extensions.sql`
|
||||
- Create: `cameleer3-server-app/src/main/resources/db/migration/V2__executions.sql`
|
||||
- Create: `cameleer3-server-app/src/main/resources/db/migration/V3__processor_executions.sql`
|
||||
- Create: `cameleer3-server-app/src/main/resources/db/migration/V4__agent_metrics.sql`
|
||||
- Create: `cameleer3-server-app/src/main/resources/db/migration/V5__route_diagrams.sql`
|
||||
- Create: `cameleer3-server-app/src/main/resources/db/migration/V6__users.sql`
|
||||
- Create: `cameleer3-server-app/src/main/resources/db/migration/V7__oidc_config.sql`
|
||||
- Create: `cameleer3-server-app/src/main/resources/db/migration/V8__continuous_aggregates.sql`
|
||||
- Create: `cameleer3-server-app/src/main/resources/db/migration/V9__retention_policies.sql`
|
||||
- Create: `cameleer-server-app/src/main/resources/db/migration/V1__extensions.sql`
|
||||
- Create: `cameleer-server-app/src/main/resources/db/migration/V2__executions.sql`
|
||||
- Create: `cameleer-server-app/src/main/resources/db/migration/V3__processor_executions.sql`
|
||||
- Create: `cameleer-server-app/src/main/resources/db/migration/V4__agent_metrics.sql`
|
||||
- Create: `cameleer-server-app/src/main/resources/db/migration/V5__route_diagrams.sql`
|
||||
- Create: `cameleer-server-app/src/main/resources/db/migration/V6__users.sql`
|
||||
- Create: `cameleer-server-app/src/main/resources/db/migration/V7__oidc_config.sql`
|
||||
- Create: `cameleer-server-app/src/main/resources/db/migration/V8__continuous_aggregates.sql`
|
||||
- Create: `cameleer-server-app/src/main/resources/db/migration/V9__retention_policies.sql`
|
||||
|
||||
- [ ] **Step 1: Create V1__extensions.sql**
|
||||
|
||||
@@ -405,19 +405,19 @@ SELECT add_continuous_aggregate_policy('stats_1m_processor',
|
||||
- [ ] **Step 9: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/resources/db/migration/
|
||||
git add cameleer-server-app/src/main/resources/db/migration/
|
||||
git commit -m "feat: add Flyway migrations for PostgreSQL/TimescaleDB schema"
|
||||
```
|
||||
|
||||
### Task 3: Create test base class with TimescaleDB Testcontainer
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/test/java/com/cameleer3/server/app/AbstractPostgresIT.java`
|
||||
- Create: `cameleer-server-app/src/test/java/com/cameleer/server/app/AbstractPostgresIT.java`
|
||||
|
||||
- [ ] **Step 1: Write AbstractPostgresIT**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app;
|
||||
package com.cameleer.server.app;
|
||||
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.DynamicPropertyRegistry;
|
||||
@@ -433,7 +433,7 @@ public abstract class AbstractPostgresIT {
|
||||
@Container
|
||||
static final PostgreSQLContainer<?> postgres =
|
||||
new PostgreSQLContainer<>("timescale/timescaledb:latest-pg16")
|
||||
.withDatabaseName("cameleer3")
|
||||
.withDatabaseName("cameleer")
|
||||
.withUsername("cameleer")
|
||||
.withPassword("test");
|
||||
|
||||
@@ -450,12 +450,12 @@ public abstract class AbstractPostgresIT {
|
||||
|
||||
- [ ] **Step 2: Write a smoke test to verify migrations run**
|
||||
|
||||
Create `cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/FlywayMigrationIT.java`:
|
||||
Create `cameleer-server-app/src/test/java/com/cameleer/server/app/storage/FlywayMigrationIT.java`:
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.storage;
|
||||
package com.cameleer.server.app.storage;
|
||||
|
||||
import com.cameleer3.server.app.AbstractPostgresIT;
|
||||
import com.cameleer.server.app.AbstractPostgresIT;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
@@ -493,22 +493,22 @@ class FlywayMigrationIT extends AbstractPostgresIT {
|
||||
|
||||
- [ ] **Step 3: Verify test passes** (this test will not compile until Task 16 deletes ClickHouse code. Run it after Task 16 is complete. Listed here for logical grouping.)
|
||||
|
||||
Run: `mvn test -pl cameleer3-server-app -Dtest=FlywayMigrationIT -q`
|
||||
Run: `mvn test -pl cameleer-server-app -Dtest=FlywayMigrationIT -q`
|
||||
Expected: PASS — all migrations apply, tables and continuous aggregates exist
|
||||
|
||||
- [ ] **Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/test/java/com/cameleer3/server/app/AbstractPostgresIT.java
|
||||
git add cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/FlywayMigrationIT.java
|
||||
git add cameleer-server-app/src/test/java/com/cameleer/server/app/AbstractPostgresIT.java
|
||||
git add cameleer-server-app/src/test/java/com/cameleer/server/app/storage/FlywayMigrationIT.java
|
||||
git commit -m "test: add TimescaleDB test base class and Flyway migration smoke test"
|
||||
```
|
||||
|
||||
### Task 4: Update application.yml for PostgreSQL + OpenSearch
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-app/src/main/resources/application.yml`
|
||||
- Modify: `cameleer3-server-app/src/test/resources/application-test.yml`
|
||||
- Modify: `cameleer-server-app/src/main/resources/application.yml`
|
||||
- Modify: `cameleer-server-app/src/test/resources/application-test.yml`
|
||||
|
||||
- [ ] **Step 1: Update application.yml datasource section**
|
||||
|
||||
@@ -516,7 +516,7 @@ Replace:
|
||||
```yaml
|
||||
spring:
|
||||
datasource:
|
||||
url: jdbc:ch://localhost:8123/cameleer3
|
||||
url: jdbc:ch://localhost:8123/cameleer
|
||||
username: cameleer
|
||||
password: cameleer_dev
|
||||
driver-class-name: com.clickhouse.jdbc.ClickHouseDriver
|
||||
@@ -526,7 +526,7 @@ With:
|
||||
```yaml
|
||||
spring:
|
||||
datasource:
|
||||
url: jdbc:postgresql://localhost:5432/cameleer3
|
||||
url: jdbc:postgresql://localhost:5432/cameleer
|
||||
username: cameleer
|
||||
password: ${CAMELEER_DB_PASSWORD:cameleer_dev}
|
||||
driver-class-name: org.postgresql.Driver
|
||||
@@ -565,8 +565,8 @@ opensearch:
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/resources/application.yml
|
||||
git add cameleer3-server-app/src/test/resources/application-test.yml
|
||||
git add cameleer-server-app/src/main/resources/application.yml
|
||||
git add cameleer-server-app/src/test/resources/application-test.yml
|
||||
git commit -m "config: switch datasource to PostgreSQL, add OpenSearch and Flyway config"
|
||||
```
|
||||
|
||||
@@ -577,18 +577,18 @@ git commit -m "config: switch datasource to PostgreSQL, add OpenSearch and Flywa
|
||||
### Task 5: Create new storage interfaces in core module
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/storage/ExecutionStore.java`
|
||||
- Create: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/storage/StatsStore.java`
|
||||
- Create: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/storage/SearchIndex.java`
|
||||
- Create: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/storage/DiagramStore.java`
|
||||
- Create: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/storage/MetricsStore.java`
|
||||
- Create: `cameleer-server-core/src/main/java/com/cameleer/server/core/storage/ExecutionStore.java`
|
||||
- Create: `cameleer-server-core/src/main/java/com/cameleer/server/core/storage/StatsStore.java`
|
||||
- Create: `cameleer-server-core/src/main/java/com/cameleer/server/core/storage/SearchIndex.java`
|
||||
- Create: `cameleer-server-core/src/main/java/com/cameleer/server/core/storage/DiagramStore.java`
|
||||
- Create: `cameleer-server-core/src/main/java/com/cameleer/server/core/storage/MetricsStore.java`
|
||||
|
||||
- [ ] **Step 1: Create ExecutionStore interface**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.core.storage;
|
||||
package com.cameleer.server.core.storage;
|
||||
|
||||
import com.cameleer3.server.core.detail.ProcessorNode;
|
||||
import com.cameleer.server.core.detail.ProcessorNode;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
@@ -629,10 +629,10 @@ public interface ExecutionStore {
|
||||
Supports all 4 aggregation levels: global, per-app, per-route, per-processor.
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.core.storage;
|
||||
package com.cameleer.server.core.storage;
|
||||
|
||||
import com.cameleer3.server.core.search.ExecutionStats;
|
||||
import com.cameleer3.server.core.search.StatsTimeseries;
|
||||
import com.cameleer.server.core.search.ExecutionStats;
|
||||
import com.cameleer.server.core.search.StatsTimeseries;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
@@ -670,12 +670,12 @@ public interface StatsStore {
|
||||
- [ ] **Step 3: Create SearchIndex interface**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.core.storage;
|
||||
package com.cameleer.server.core.storage;
|
||||
|
||||
import com.cameleer3.server.core.search.ExecutionSummary;
|
||||
import com.cameleer3.server.core.search.SearchRequest;
|
||||
import com.cameleer3.server.core.search.SearchResult;
|
||||
import com.cameleer3.server.core.storage.model.ExecutionDocument;
|
||||
import com.cameleer.server.core.search.ExecutionSummary;
|
||||
import com.cameleer.server.core.search.SearchRequest;
|
||||
import com.cameleer.server.core.search.SearchResult;
|
||||
import com.cameleer.server.core.storage.model.ExecutionDocument;
|
||||
|
||||
public interface SearchIndex {
|
||||
|
||||
@@ -692,10 +692,10 @@ public interface SearchIndex {
|
||||
- [ ] **Step 4: Create DiagramStore interface**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.core.storage;
|
||||
package com.cameleer.server.core.storage;
|
||||
|
||||
import com.cameleer3.common.graph.RouteGraph;
|
||||
import com.cameleer3.server.core.ingestion.TaggedDiagram;
|
||||
import com.cameleer.common.graph.RouteGraph;
|
||||
import com.cameleer.server.core.ingestion.TaggedDiagram;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@@ -715,9 +715,9 @@ public interface DiagramStore {
|
||||
- [ ] **Step 5: Create MetricsStore interface**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.core.storage;
|
||||
package com.cameleer.server.core.storage;
|
||||
|
||||
import com.cameleer3.server.core.storage.model.MetricsSnapshot;
|
||||
import com.cameleer.server.core.storage.model.MetricsSnapshot;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -730,20 +730,20 @@ public interface MetricsStore {
|
||||
- [ ] **Step 6: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-core/src/main/java/com/cameleer3/server/core/storage/
|
||||
git add cameleer-server-core/src/main/java/com/cameleer/server/core/storage/
|
||||
git commit -m "feat: add new storage interfaces for PostgreSQL/OpenSearch backends"
|
||||
```
|
||||
|
||||
### Task 6: Create ExecutionDocument model and indexing event
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/storage/model/ExecutionDocument.java`
|
||||
- Create: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/indexing/ExecutionUpdatedEvent.java`
|
||||
- Create: `cameleer-server-core/src/main/java/com/cameleer/server/core/storage/model/ExecutionDocument.java`
|
||||
- Create: `cameleer-server-core/src/main/java/com/cameleer/server/core/indexing/ExecutionUpdatedEvent.java`
|
||||
|
||||
- [ ] **Step 1: Create ExecutionDocument**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.core.storage.model;
|
||||
package com.cameleer.server.core.storage.model;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
@@ -767,7 +767,7 @@ public record ExecutionDocument(
|
||||
- [ ] **Step 2: Create ExecutionUpdatedEvent**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.core.indexing;
|
||||
package com.cameleer.server.core.indexing;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
@@ -777,25 +777,25 @@ public record ExecutionUpdatedEvent(String executionId, Instant startTime) {}
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-core/src/main/java/com/cameleer3/server/core/storage/model/ExecutionDocument.java
|
||||
git add cameleer3-server-core/src/main/java/com/cameleer3/server/core/indexing/
|
||||
git add cameleer-server-core/src/main/java/com/cameleer/server/core/storage/model/ExecutionDocument.java
|
||||
git add cameleer-server-core/src/main/java/com/cameleer/server/core/indexing/
|
||||
git commit -m "feat: add ExecutionDocument model and ExecutionUpdatedEvent"
|
||||
```
|
||||
|
||||
### Task 7: Update SearchService to use StatsStore for stats/timeseries
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/search/SearchService.java`
|
||||
- Modify: `cameleer-server-core/src/main/java/com/cameleer/server/core/search/SearchService.java`
|
||||
|
||||
- [ ] **Step 1: Refactor SearchService to accept SearchIndex + StatsStore**
|
||||
|
||||
Replace the single `SearchEngine` dependency with two dependencies:
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.core.search;
|
||||
package com.cameleer.server.core.search;
|
||||
|
||||
import com.cameleer3.server.core.storage.SearchIndex;
|
||||
import com.cameleer3.server.core.storage.StatsStore;
|
||||
import com.cameleer.server.core.storage.SearchIndex;
|
||||
import com.cameleer.server.core.storage.StatsStore;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
@@ -840,24 +840,24 @@ public class SearchService {
|
||||
- [ ] **Step 2: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-core/src/main/java/com/cameleer3/server/core/search/SearchService.java
|
||||
git add cameleer-server-core/src/main/java/com/cameleer/server/core/search/SearchService.java
|
||||
git commit -m "refactor: SearchService uses SearchIndex + StatsStore instead of SearchEngine"
|
||||
```
|
||||
|
||||
### Task 8: Update DetailService to use ExecutionStore
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/detail/DetailService.java`
|
||||
- Modify: `cameleer-server-core/src/main/java/com/cameleer/server/core/detail/DetailService.java`
|
||||
|
||||
- [ ] **Step 1: Rewrite DetailService to use ExecutionStore**
|
||||
|
||||
The tree reconstruction from parallel arrays is no longer needed. Processors are now individual records with `parentProcessorId` for tree structure.
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.core.detail;
|
||||
package com.cameleer.server.core.detail;
|
||||
|
||||
import com.cameleer3.server.core.storage.ExecutionStore;
|
||||
import com.cameleer3.server.core.storage.ExecutionStore.ProcessorRecord;
|
||||
import com.cameleer.server.core.storage.ExecutionStore;
|
||||
import com.cameleer.server.core.storage.ExecutionStore.ProcessorRecord;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -920,30 +920,30 @@ public class DetailService {
|
||||
- [ ] **Step 2: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-core/src/main/java/com/cameleer3/server/core/detail/DetailService.java
|
||||
git add cameleer-server-core/src/main/java/com/cameleer/server/core/detail/DetailService.java
|
||||
git commit -m "refactor: DetailService uses ExecutionStore, tree built from parentProcessorId"
|
||||
```
|
||||
|
||||
### Task 9: Update IngestionService for synchronous writes
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/ingestion/IngestionService.java`
|
||||
- Modify: `cameleer-server-core/src/main/java/com/cameleer/server/core/ingestion/IngestionService.java`
|
||||
|
||||
- [ ] **Step 1: Rewrite IngestionService**
|
||||
|
||||
Executions and diagrams become synchronous writes. Metrics keep the write buffer. Add event publishing for OpenSearch indexing.
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.core.ingestion;
|
||||
package com.cameleer.server.core.ingestion;
|
||||
|
||||
import com.cameleer3.common.model.ProcessorExecution;
|
||||
import com.cameleer3.common.model.RouteExecution;
|
||||
import com.cameleer3.server.core.indexing.ExecutionUpdatedEvent;
|
||||
import com.cameleer3.server.core.storage.DiagramStore;
|
||||
import com.cameleer3.server.core.storage.ExecutionStore;
|
||||
import com.cameleer3.server.core.storage.ExecutionStore.ExecutionRecord;
|
||||
import com.cameleer3.server.core.storage.ExecutionStore.ProcessorRecord;
|
||||
import com.cameleer3.server.core.storage.model.MetricsSnapshot;
|
||||
import com.cameleer.common.model.ProcessorExecution;
|
||||
import com.cameleer.common.model.RouteExecution;
|
||||
import com.cameleer.server.core.indexing.ExecutionUpdatedEvent;
|
||||
import com.cameleer.server.core.storage.DiagramStore;
|
||||
import com.cameleer.server.core.storage.ExecutionStore;
|
||||
import com.cameleer.server.core.storage.ExecutionStore.ExecutionRecord;
|
||||
import com.cameleer.server.core.storage.ExecutionStore.ProcessorRecord;
|
||||
import com.cameleer.server.core.storage.model.MetricsSnapshot;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -1055,7 +1055,7 @@ public class IngestionService {
|
||||
- [ ] **Step 2: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-core/src/main/java/com/cameleer3/server/core/ingestion/IngestionService.java
|
||||
git add cameleer-server-core/src/main/java/com/cameleer/server/core/ingestion/IngestionService.java
|
||||
git commit -m "refactor: IngestionService uses synchronous ExecutionStore writes with event publishing"
|
||||
```
|
||||
|
||||
@@ -1066,18 +1066,18 @@ git commit -m "refactor: IngestionService uses synchronous ExecutionStore writes
|
||||
### Task 10: Implement PostgresExecutionStore
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/PostgresExecutionStore.java`
|
||||
- Create: `cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/PostgresExecutionStoreIT.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/storage/PostgresExecutionStore.java`
|
||||
- Create: `cameleer-server-app/src/test/java/com/cameleer/server/app/storage/PostgresExecutionStoreIT.java`
|
||||
|
||||
- [ ] **Step 1: Write the failing test**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.storage;
|
||||
package com.cameleer.server.app.storage;
|
||||
|
||||
import com.cameleer3.server.app.AbstractPostgresIT;
|
||||
import com.cameleer3.server.core.storage.ExecutionStore;
|
||||
import com.cameleer3.server.core.storage.ExecutionStore.ExecutionRecord;
|
||||
import com.cameleer3.server.core.storage.ExecutionStore.ProcessorRecord;
|
||||
import com.cameleer.server.app.AbstractPostgresIT;
|
||||
import com.cameleer.server.core.storage.ExecutionStore;
|
||||
import com.cameleer.server.core.storage.ExecutionStore.ExecutionRecord;
|
||||
import com.cameleer.server.core.storage.ExecutionStore.ProcessorRecord;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
@@ -1159,15 +1159,15 @@ class PostgresExecutionStoreIT extends AbstractPostgresIT {
|
||||
|
||||
- [ ] **Step 2: Run test to verify it fails**
|
||||
|
||||
Run: `mvn test -pl cameleer3-server-app -Dtest=PostgresExecutionStoreIT -q`
|
||||
Run: `mvn test -pl cameleer-server-app -Dtest=PostgresExecutionStoreIT -q`
|
||||
Expected: FAIL — `ExecutionStore` bean not found
|
||||
|
||||
- [ ] **Step 3: Implement PostgresExecutionStore**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.storage;
|
||||
package com.cameleer.server.app.storage;
|
||||
|
||||
import com.cameleer3.server.core.storage.ExecutionStore;
|
||||
import com.cameleer.server.core.storage.ExecutionStore;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.stereotype.Repository;
|
||||
@@ -1300,34 +1300,34 @@ public class PostgresExecutionStore implements ExecutionStore {
|
||||
|
||||
- [ ] **Step 4: Run tests to verify they pass**
|
||||
|
||||
Run: `mvn test -pl cameleer3-server-app -Dtest=PostgresExecutionStoreIT -q`
|
||||
Run: `mvn test -pl cameleer-server-app -Dtest=PostgresExecutionStoreIT -q`
|
||||
Expected: PASS — all 3 tests green
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/PostgresExecutionStore.java
|
||||
git add cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/PostgresExecutionStoreIT.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/storage/PostgresExecutionStore.java
|
||||
git add cameleer-server-app/src/test/java/com/cameleer/server/app/storage/PostgresExecutionStoreIT.java
|
||||
git commit -m "feat: implement PostgresExecutionStore with upsert and dedup"
|
||||
```
|
||||
|
||||
### Task 11: Implement PostgresStatsStore
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/PostgresStatsStore.java`
|
||||
- Create: `cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/PostgresStatsStoreIT.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/storage/PostgresStatsStore.java`
|
||||
- Create: `cameleer-server-app/src/test/java/com/cameleer/server/app/storage/PostgresStatsStoreIT.java`
|
||||
|
||||
- [ ] **Step 1: Write the failing test**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.storage;
|
||||
package com.cameleer.server.app.storage;
|
||||
|
||||
import com.cameleer3.server.app.AbstractPostgresIT;
|
||||
import com.cameleer3.server.core.search.ExecutionStats;
|
||||
import com.cameleer3.server.core.search.StatsTimeseries;
|
||||
import com.cameleer3.server.core.storage.ExecutionStore;
|
||||
import com.cameleer3.server.core.storage.ExecutionStore.ExecutionRecord;
|
||||
import com.cameleer3.server.core.storage.StatsStore;
|
||||
import com.cameleer.server.app.AbstractPostgresIT;
|
||||
import com.cameleer.server.core.search.ExecutionStats;
|
||||
import com.cameleer.server.core.search.StatsTimeseries;
|
||||
import com.cameleer.server.core.storage.ExecutionStore;
|
||||
import com.cameleer.server.core.storage.ExecutionStore.ExecutionRecord;
|
||||
import com.cameleer.server.core.storage.StatsStore;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
@@ -1385,18 +1385,18 @@ class PostgresStatsStoreIT extends AbstractPostgresIT {
|
||||
|
||||
- [ ] **Step 2: Run test to verify it fails**
|
||||
|
||||
Run: `mvn test -pl cameleer3-server-app -Dtest=PostgresStatsStoreIT -q`
|
||||
Run: `mvn test -pl cameleer-server-app -Dtest=PostgresStatsStoreIT -q`
|
||||
Expected: FAIL — `StatsStore` bean not found
|
||||
|
||||
- [ ] **Step 3: Implement PostgresStatsStore**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.storage;
|
||||
package com.cameleer.server.app.storage;
|
||||
|
||||
import com.cameleer3.server.core.search.ExecutionStats;
|
||||
import com.cameleer3.server.core.search.StatsTimeseries;
|
||||
import com.cameleer3.server.core.search.StatsTimeseries.TimeseriesBucket;
|
||||
import com.cameleer3.server.core.storage.StatsStore;
|
||||
import com.cameleer.server.core.search.ExecutionStats;
|
||||
import com.cameleer.server.core.search.StatsTimeseries;
|
||||
import com.cameleer.server.core.search.StatsTimeseries.TimeseriesBucket;
|
||||
import com.cameleer.server.core.storage.StatsStore;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@@ -1582,24 +1582,24 @@ public class PostgresStatsStore implements StatsStore {
|
||||
|
||||
- [ ] **Step 4: Run tests to verify they pass**
|
||||
|
||||
Run: `mvn test -pl cameleer3-server-app -Dtest=PostgresStatsStoreIT -q`
|
||||
Run: `mvn test -pl cameleer-server-app -Dtest=PostgresStatsStoreIT -q`
|
||||
Expected: PASS
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/PostgresStatsStore.java
|
||||
git add cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/PostgresStatsStoreIT.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/storage/PostgresStatsStore.java
|
||||
git add cameleer-server-app/src/test/java/com/cameleer/server/app/storage/PostgresStatsStoreIT.java
|
||||
git commit -m "feat: implement PostgresStatsStore querying continuous aggregates"
|
||||
```
|
||||
|
||||
### Task 12: Implement PostgresDiagramStore, PostgresUserRepository, PostgresOidcConfigRepository, PostgresMetricsStore
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/PostgresDiagramStore.java`
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/PostgresUserRepository.java`
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/PostgresOidcConfigRepository.java`
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/PostgresMetricsStore.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/storage/PostgresDiagramStore.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/storage/PostgresUserRepository.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/storage/PostgresOidcConfigRepository.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/storage/PostgresMetricsStore.java`
|
||||
|
||||
- [ ] **Step 1: Write failing test for PostgresDiagramStore**
|
||||
|
||||
@@ -1620,10 +1620,10 @@ Straightforward CRUD with `ON CONFLICT (content_hash) DO NOTHING`. Port the SHA-
|
||||
Implements `UserRepository` interface (existing interface in `core.security`, unchanged).
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.storage;
|
||||
package com.cameleer.server.app.storage;
|
||||
|
||||
import com.cameleer3.server.core.security.UserInfo;
|
||||
import com.cameleer3.server.core.security.UserRepository;
|
||||
import com.cameleer.server.core.security.UserInfo;
|
||||
import com.cameleer.server.core.security.UserRepository;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@@ -1696,10 +1696,10 @@ public class PostgresUserRepository implements UserRepository {
|
||||
Implements `OidcConfigRepository` interface (existing interface in `core.security`).
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.storage;
|
||||
package com.cameleer.server.app.storage;
|
||||
|
||||
import com.cameleer3.server.core.security.OidcConfig;
|
||||
import com.cameleer3.server.core.security.OidcConfigRepository;
|
||||
import com.cameleer.server.core.security.OidcConfig;
|
||||
import com.cameleer.server.core.security.OidcConfigRepository;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@@ -1760,10 +1760,10 @@ public class PostgresOidcConfigRepository implements OidcConfigRepository {
|
||||
- [ ] **Step 6: Implement PostgresMetricsStore**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.storage;
|
||||
package com.cameleer.server.app.storage;
|
||||
|
||||
import com.cameleer3.server.core.storage.MetricsStore;
|
||||
import com.cameleer3.server.core.storage.model.MetricsSnapshot;
|
||||
import com.cameleer.server.core.storage.MetricsStore;
|
||||
import com.cameleer.server.core.storage.model.MetricsSnapshot;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
@@ -1806,13 +1806,13 @@ public class PostgresMetricsStore implements MetricsStore {
|
||||
|
||||
- [ ] **Step 7: Run all store tests, verify pass**
|
||||
|
||||
Run: `mvn test -pl cameleer3-server-app -Dtest="Postgres*IT" -q`
|
||||
Run: `mvn test -pl cameleer-server-app -Dtest="Postgres*IT" -q`
|
||||
|
||||
- [ ] **Step 8: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/Postgres*.java
|
||||
git add cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/Postgres*.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/storage/Postgres*.java
|
||||
git add cameleer-server-app/src/test/java/com/cameleer/server/app/storage/Postgres*.java
|
||||
git commit -m "feat: implement PostgresDiagramStore, PostgresUserRepository, PostgresOidcConfigRepository, PostgresMetricsStore"
|
||||
```
|
||||
|
||||
@@ -1823,22 +1823,22 @@ git commit -m "feat: implement PostgresDiagramStore, PostgresUserRepository, Pos
|
||||
### Task 13: Implement OpenSearchIndex
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/OpenSearchConfig.java`
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/search/OpenSearchIndex.java`
|
||||
- Create: `cameleer3-server-app/src/test/java/com/cameleer3/server/app/search/OpenSearchIndexIT.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/config/OpenSearchConfig.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/search/OpenSearchIndex.java`
|
||||
- Create: `cameleer-server-app/src/test/java/com/cameleer/server/app/search/OpenSearchIndexIT.java`
|
||||
|
||||
- [ ] **Step 1: Write failing test**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.search;
|
||||
package com.cameleer.server.app.search;
|
||||
|
||||
import com.cameleer3.server.app.AbstractPostgresIT;
|
||||
import com.cameleer3.server.core.search.ExecutionSummary;
|
||||
import com.cameleer3.server.core.search.SearchRequest;
|
||||
import com.cameleer3.server.core.search.SearchResult;
|
||||
import com.cameleer3.server.core.storage.SearchIndex;
|
||||
import com.cameleer3.server.core.storage.model.ExecutionDocument;
|
||||
import com.cameleer3.server.core.storage.model.ExecutionDocument.ProcessorDoc;
|
||||
import com.cameleer.server.app.AbstractPostgresIT;
|
||||
import com.cameleer.server.core.search.ExecutionSummary;
|
||||
import com.cameleer.server.core.search.SearchRequest;
|
||||
import com.cameleer.server.core.search.SearchResult;
|
||||
import com.cameleer.server.core.storage.SearchIndex;
|
||||
import com.cameleer.server.core.storage.model.ExecutionDocument;
|
||||
import com.cameleer.server.core.storage.model.ExecutionDocument.ProcessorDoc;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.opensearch.testcontainers.OpensearchContainer;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -1922,7 +1922,7 @@ class OpenSearchIndexIT extends AbstractPostgresIT {
|
||||
- [ ] **Step 2: Create OpenSearchConfig**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.config;
|
||||
package com.cameleer.server.app.config;
|
||||
|
||||
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
|
||||
import org.apache.hc.core5.http.HttpHost;
|
||||
@@ -1950,14 +1950,14 @@ public class OpenSearchConfig {
|
||||
- [ ] **Step 3: Implement OpenSearchIndex**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.search;
|
||||
package com.cameleer.server.app.search;
|
||||
|
||||
import com.cameleer3.server.core.search.ExecutionSummary;
|
||||
import com.cameleer3.server.core.search.SearchRequest;
|
||||
import com.cameleer3.server.core.search.SearchResult;
|
||||
import com.cameleer3.server.core.storage.SearchIndex;
|
||||
import com.cameleer3.server.core.storage.model.ExecutionDocument;
|
||||
import com.cameleer3.server.core.storage.model.ExecutionDocument.ProcessorDoc;
|
||||
import com.cameleer.server.core.search.ExecutionSummary;
|
||||
import com.cameleer.server.core.search.SearchRequest;
|
||||
import com.cameleer.server.core.search.SearchResult;
|
||||
import com.cameleer.server.core.storage.SearchIndex;
|
||||
import com.cameleer.server.core.storage.model.ExecutionDocument;
|
||||
import com.cameleer.server.core.storage.model.ExecutionDocument.ProcessorDoc;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import org.opensearch.client.opensearch.OpenSearchClient;
|
||||
import org.opensearch.client.opensearch._types.FieldValue;
|
||||
@@ -2264,34 +2264,34 @@ public class OpenSearchIndex implements SearchIndex {
|
||||
|
||||
- [ ] **Step 4: Run tests to verify they pass**
|
||||
|
||||
Run: `mvn test -pl cameleer3-server-app -Dtest=OpenSearchIndexIT -q`
|
||||
Run: `mvn test -pl cameleer-server-app -Dtest=OpenSearchIndexIT -q`
|
||||
Expected: PASS
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/OpenSearchConfig.java
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/search/OpenSearchIndex.java
|
||||
git add cameleer3-server-app/src/test/java/com/cameleer3/server/app/search/OpenSearchIndexIT.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/config/OpenSearchConfig.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/search/OpenSearchIndex.java
|
||||
git add cameleer-server-app/src/test/java/com/cameleer/server/app/search/OpenSearchIndexIT.java
|
||||
git commit -m "feat: implement OpenSearchIndex with full-text and wildcard search"
|
||||
```
|
||||
|
||||
### Task 14: Implement SearchIndexer (debounced event-driven indexer)
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/indexing/SearchIndexer.java`
|
||||
- Create: `cameleer-server-core/src/main/java/com/cameleer/server/core/indexing/SearchIndexer.java`
|
||||
|
||||
- [ ] **Step 1: Implement SearchIndexer**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.core.indexing;
|
||||
package com.cameleer.server.core.indexing;
|
||||
|
||||
import com.cameleer3.server.core.storage.ExecutionStore;
|
||||
import com.cameleer3.server.core.storage.ExecutionStore.ExecutionRecord;
|
||||
import com.cameleer3.server.core.storage.ExecutionStore.ProcessorRecord;
|
||||
import com.cameleer3.server.core.storage.SearchIndex;
|
||||
import com.cameleer3.server.core.storage.model.ExecutionDocument;
|
||||
import com.cameleer3.server.core.storage.model.ExecutionDocument.ProcessorDoc;
|
||||
import com.cameleer.server.core.storage.ExecutionStore;
|
||||
import com.cameleer.server.core.storage.ExecutionStore.ExecutionRecord;
|
||||
import com.cameleer.server.core.storage.ExecutionStore.ProcessorRecord;
|
||||
import com.cameleer.server.core.storage.SearchIndex;
|
||||
import com.cameleer.server.core.storage.model.ExecutionDocument;
|
||||
import com.cameleer.server.core.storage.model.ExecutionDocument.ProcessorDoc;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -2368,7 +2368,7 @@ public class SearchIndexer {
|
||||
- [ ] **Step 2: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-core/src/main/java/com/cameleer3/server/core/indexing/SearchIndexer.java
|
||||
git add cameleer-server-core/src/main/java/com/cameleer/server/core/indexing/SearchIndexer.java
|
||||
git commit -m "feat: implement debounced SearchIndexer for async OpenSearch indexing"
|
||||
```
|
||||
|
||||
@@ -2379,25 +2379,25 @@ git commit -m "feat: implement debounced SearchIndexer for async OpenSearch inde
|
||||
### Task 15: Create bean configuration and wire everything
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/StorageBeanConfig.java`
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/ingestion/MetricsFlushScheduler.java`
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/retention/RetentionScheduler.java`
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/SearchBeanConfig.java`
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/IngestionBeanConfig.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/config/StorageBeanConfig.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/ingestion/MetricsFlushScheduler.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/retention/RetentionScheduler.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/config/SearchBeanConfig.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/config/IngestionBeanConfig.java`
|
||||
|
||||
- [ ] **Step 1: Create StorageBeanConfig**
|
||||
|
||||
Wire `DetailService`, `SearchIndexer`, `IngestionService` with new store beans:
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.config;
|
||||
package com.cameleer.server.app.config;
|
||||
|
||||
import com.cameleer3.server.core.detail.DetailService;
|
||||
import com.cameleer3.server.core.indexing.SearchIndexer;
|
||||
import com.cameleer3.server.core.ingestion.IngestionService;
|
||||
import com.cameleer3.server.core.ingestion.WriteBuffer;
|
||||
import com.cameleer3.server.core.storage.*;
|
||||
import com.cameleer3.server.core.storage.model.MetricsSnapshot;
|
||||
import com.cameleer.server.core.detail.DetailService;
|
||||
import com.cameleer.server.core.indexing.SearchIndexer;
|
||||
import com.cameleer.server.core.ingestion.IngestionService;
|
||||
import com.cameleer.server.core.ingestion.WriteBuffer;
|
||||
import com.cameleer.server.core.storage.*;
|
||||
import com.cameleer.server.core.storage.model.MetricsSnapshot;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -2453,15 +2453,15 @@ public WriteBuffer<MetricsSnapshot> metricsBuffer(IngestionConfig config) {
|
||||
|
||||
- [ ] **Step 4: Create MetricsFlushScheduler**
|
||||
|
||||
Create `cameleer3-server-app/src/main/java/com/cameleer3/server/app/ingestion/MetricsFlushScheduler.java`:
|
||||
Create `cameleer-server-app/src/main/java/com/cameleer/server/app/ingestion/MetricsFlushScheduler.java`:
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.ingestion;
|
||||
package com.cameleer.server.app.ingestion;
|
||||
|
||||
import com.cameleer3.server.app.config.IngestionConfig;
|
||||
import com.cameleer3.server.core.ingestion.WriteBuffer;
|
||||
import com.cameleer3.server.core.storage.MetricsStore;
|
||||
import com.cameleer3.server.core.storage.model.MetricsSnapshot;
|
||||
import com.cameleer.server.app.config.IngestionConfig;
|
||||
import com.cameleer.server.core.ingestion.WriteBuffer;
|
||||
import com.cameleer.server.core.storage.MetricsStore;
|
||||
import com.cameleer.server.core.storage.model.MetricsSnapshot;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.SmartLifecycle;
|
||||
@@ -2519,10 +2519,10 @@ public class MetricsFlushScheduler implements SmartLifecycle {
|
||||
|
||||
- [ ] **Step 5: Create RetentionScheduler**
|
||||
|
||||
Create `cameleer3-server-app/src/main/java/com/cameleer3/server/app/retention/RetentionScheduler.java`:
|
||||
Create `cameleer-server-app/src/main/java/com/cameleer/server/app/retention/RetentionScheduler.java`:
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.retention;
|
||||
package com.cameleer.server.app.retention;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -2575,11 +2575,11 @@ public class RetentionScheduler {
|
||||
- [ ] **Step 6: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/StorageBeanConfig.java
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/SearchBeanConfig.java
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/IngestionBeanConfig.java
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/ingestion/MetricsFlushScheduler.java
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/retention/RetentionScheduler.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/config/StorageBeanConfig.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/config/SearchBeanConfig.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/config/IngestionBeanConfig.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/ingestion/MetricsFlushScheduler.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/retention/RetentionScheduler.java
|
||||
git commit -m "feat: wire new storage beans, add MetricsFlushScheduler and RetentionScheduler"
|
||||
```
|
||||
|
||||
@@ -2591,10 +2591,10 @@ git commit -m "feat: wire new storage beans, add MetricsFlushScheduler and Reten
|
||||
- [ ] **Step 1: Delete ClickHouse implementations**
|
||||
|
||||
```bash
|
||||
rm cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/ClickHouse*.java
|
||||
rm cameleer3-server-app/src/main/java/com/cameleer3/server/app/search/ClickHouseSearchEngine.java
|
||||
rm cameleer3-server-app/src/main/java/com/cameleer3/server/app/ingestion/ClickHouseFlushScheduler.java
|
||||
rm cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/ClickHouseConfig.java
|
||||
rm cameleer-server-app/src/main/java/com/cameleer/server/app/storage/ClickHouse*.java
|
||||
rm cameleer-server-app/src/main/java/com/cameleer/server/app/search/ClickHouseSearchEngine.java
|
||||
rm cameleer-server-app/src/main/java/com/cameleer/server/app/ingestion/ClickHouseFlushScheduler.java
|
||||
rm cameleer-server-app/src/main/java/com/cameleer/server/app/config/ClickHouseConfig.java
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Delete old core interfaces replaced by new ones**
|
||||
@@ -2602,23 +2602,23 @@ rm cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/ClickHouse
|
||||
`UserRepository` and `OidcConfigRepository` in `core.security` are **kept** — the new Postgres implementations implement them. Only interfaces replaced by new storage interfaces are deleted.
|
||||
|
||||
```bash
|
||||
rm cameleer3-server-core/src/main/java/com/cameleer3/server/core/storage/ExecutionRepository.java
|
||||
rm cameleer3-server-core/src/main/java/com/cameleer3/server/core/storage/DiagramRepository.java
|
||||
rm cameleer3-server-core/src/main/java/com/cameleer3/server/core/storage/MetricsRepository.java
|
||||
rm cameleer3-server-core/src/main/java/com/cameleer3/server/core/search/SearchEngine.java
|
||||
rm cameleer3-server-core/src/main/java/com/cameleer3/server/core/detail/RawExecutionRow.java
|
||||
rm cameleer-server-core/src/main/java/com/cameleer/server/core/storage/ExecutionRepository.java
|
||||
rm cameleer-server-core/src/main/java/com/cameleer/server/core/storage/DiagramRepository.java
|
||||
rm cameleer-server-core/src/main/java/com/cameleer/server/core/storage/MetricsRepository.java
|
||||
rm cameleer-server-core/src/main/java/com/cameleer/server/core/search/SearchEngine.java
|
||||
rm cameleer-server-core/src/main/java/com/cameleer/server/core/detail/RawExecutionRow.java
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Delete ClickHouse SQL migrations**
|
||||
|
||||
```bash
|
||||
rm -r cameleer3-server-app/src/main/resources/clickhouse/
|
||||
rm -r cameleer-server-app/src/main/resources/clickhouse/
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Delete old test base class**
|
||||
|
||||
```bash
|
||||
rm cameleer3-server-app/src/test/java/com/cameleer3/server/app/AbstractClickHouseIT.java
|
||||
rm cameleer-server-app/src/test/java/com/cameleer/server/app/AbstractClickHouseIT.java
|
||||
```
|
||||
|
||||
- [ ] **Step 5: Fix compilation errors in specific files**
|
||||
@@ -2651,7 +2651,7 @@ git commit -m "refactor: remove all ClickHouse code, old interfaces, and SQL mig
|
||||
### Task 17: Update existing integration tests
|
||||
|
||||
**Files:**
|
||||
- Modify: all IT files under `cameleer3-server-app/src/test/`
|
||||
- Modify: all IT files under `cameleer-server-app/src/test/`
|
||||
|
||||
- [ ] **Step 1: Update all ITs to extend AbstractPostgresIT**
|
||||
|
||||
@@ -2689,7 +2689,7 @@ git commit -m "test: migrate all integration tests from ClickHouse to PostgreSQL
|
||||
|
||||
- [ ] **Step 1: Update Dockerfile**
|
||||
|
||||
No JDBC driver changes needed in Dockerfile (drivers are in the fat JAR). Just verify the `REGISTRY_TOKEN` build arg still works for `cameleer3-common` resolution.
|
||||
No JDBC driver changes needed in Dockerfile (drivers are in the fat JAR). Just verify the `REGISTRY_TOKEN` build arg still works for `cameleer-common` resolution.
|
||||
|
||||
- [ ] **Step 2: Update K8s manifests**
|
||||
|
||||
@@ -2717,7 +2717,7 @@ Changes needed:
|
||||
- Docker build: no ClickHouse references in the image (it's a fat JAR, driver is bundled)
|
||||
- Deploy step: update K8s secret names from `clickhouse-credentials` to `postgres-credentials`
|
||||
- Deploy step: add OpenSearch deployment manifests
|
||||
- Verify `REGISTRY_TOKEN` build arg still works for `cameleer3-common`
|
||||
- Verify `REGISTRY_TOKEN` build arg still works for `cameleer-common`
|
||||
- Integration tests still skipped in CI (`-DskipITs`) — Testcontainers needs Docker-in-Docker
|
||||
|
||||
- [ ] **Step 2: Commit**
|
||||
@@ -2738,7 +2738,7 @@ Run: `mvn spring-boot:run` (briefly, to generate spec), then fetch `/api/v1/api-
|
||||
- [ ] **Step 2: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/resources/static/openapi.json
|
||||
git add cameleer-server-app/src/main/resources/static/openapi.json
|
||||
git commit -m "docs: regenerate openapi.json after storage layer refactor"
|
||||
```
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
| `core/.../admin/ThresholdRepository.java` | Interface: find + save |
|
||||
| `core/.../indexing/SearchIndexerStats.java` | Interface: queue depth, failed count, rate, etc. |
|
||||
|
||||
> `core/...` = `cameleer3-server-core/src/main/java/com/cameleer3/server/core`
|
||||
> `core/...` = `cameleer-server-core/src/main/java/com/cameleer/server/core`
|
||||
|
||||
### New Files — Backend (App Module)
|
||||
|
||||
@@ -53,8 +53,8 @@
|
||||
| `resources/db/migration/V9__admin_thresholds.sql` | Flyway: admin_thresholds table |
|
||||
| `resources/db/migration/V10__audit_log.sql` | Flyway: audit_log table |
|
||||
|
||||
> `app/...` = `cameleer3-server-app/src/main/java/com/cameleer3/server/app`
|
||||
> `resources/...` = `cameleer3-server-app/src/main/resources`
|
||||
> `app/...` = `cameleer-server-app/src/main/java/com/cameleer/server/app`
|
||||
> `resources/...` = `cameleer-server-app/src/main/resources`
|
||||
|
||||
### New Files — Backend (Tests)
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
| `test/.../controller/ThresholdAdminControllerIT.java` | Integration test: threshold endpoints |
|
||||
| `test/.../admin/AuditServiceTest.java` | Unit test: audit service logic |
|
||||
|
||||
> `test/...` = `cameleer3-server-app/src/test/java/com/cameleer3/server/app`
|
||||
> `test/...` = `cameleer-server-app/src/test/java/com/cameleer/server/app`
|
||||
|
||||
### New Files — Frontend
|
||||
|
||||
@@ -110,8 +110,8 @@
|
||||
### Task 1: Flyway Migrations
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/main/resources/db/migration/V9__admin_thresholds.sql`
|
||||
- Create: `cameleer3-server-app/src/main/resources/db/migration/V10__audit_log.sql`
|
||||
- Create: `cameleer-server-app/src/main/resources/db/migration/V9__admin_thresholds.sql`
|
||||
- Create: `cameleer-server-app/src/main/resources/db/migration/V10__audit_log.sql`
|
||||
|
||||
- [ ] **Step 1: Create V9 migration**
|
||||
|
||||
@@ -150,14 +150,14 @@ CREATE INDEX idx_audit_log_target ON audit_log (target);
|
||||
|
||||
- [ ] **Step 3: Verify migrations compile**
|
||||
|
||||
Run: `cd cameleer3-server && mvn clean compile -pl cameleer3-server-app`
|
||||
Run: `cd cameleer-server && mvn clean compile -pl cameleer-server-app`
|
||||
Expected: BUILD SUCCESS
|
||||
|
||||
- [ ] **Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/resources/db/migration/V9__admin_thresholds.sql \
|
||||
cameleer3-server-app/src/main/resources/db/migration/V10__audit_log.sql
|
||||
git add cameleer-server-app/src/main/resources/db/migration/V9__admin_thresholds.sql \
|
||||
cameleer-server-app/src/main/resources/db/migration/V10__audit_log.sql
|
||||
git commit -m "feat: add Flyway V9 (thresholds) and V10 (audit_log) migrations"
|
||||
```
|
||||
|
||||
@@ -166,16 +166,16 @@ git commit -m "feat: add Flyway V9 (thresholds) and V10 (audit_log) migrations"
|
||||
### Task 2: Core Module — Audit Domain Model + Repository Interface
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/admin/AuditCategory.java`
|
||||
- Create: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/admin/AuditResult.java`
|
||||
- Create: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/admin/AuditRecord.java`
|
||||
- Create: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/admin/AuditRepository.java`
|
||||
- Create: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/admin/AuditService.java`
|
||||
- Create: `cameleer-server-core/src/main/java/com/cameleer/server/core/admin/AuditCategory.java`
|
||||
- Create: `cameleer-server-core/src/main/java/com/cameleer/server/core/admin/AuditResult.java`
|
||||
- Create: `cameleer-server-core/src/main/java/com/cameleer/server/core/admin/AuditRecord.java`
|
||||
- Create: `cameleer-server-core/src/main/java/com/cameleer/server/core/admin/AuditRepository.java`
|
||||
- Create: `cameleer-server-core/src/main/java/com/cameleer/server/core/admin/AuditService.java`
|
||||
|
||||
- [ ] **Step 1: Create AuditCategory enum**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.core.admin;
|
||||
package com.cameleer.server.core.admin;
|
||||
|
||||
public enum AuditCategory {
|
||||
INFRA, AUTH, USER_MGMT, CONFIG
|
||||
@@ -185,7 +185,7 @@ public enum AuditCategory {
|
||||
- [ ] **Step 2: Create AuditResult enum**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.core.admin;
|
||||
package com.cameleer.server.core.admin;
|
||||
|
||||
public enum AuditResult {
|
||||
SUCCESS, FAILURE
|
||||
@@ -195,7 +195,7 @@ public enum AuditResult {
|
||||
- [ ] **Step 3: Create AuditRecord**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.core.admin;
|
||||
package com.cameleer.server.core.admin;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Map;
|
||||
@@ -224,7 +224,7 @@ public record AuditRecord(
|
||||
- [ ] **Step 4: Create AuditRepository interface**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.core.admin;
|
||||
package com.cameleer.server.core.admin;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
@@ -256,7 +256,7 @@ public interface AuditRepository {
|
||||
The service lives in core so it can be referenced by any controller. It depends on `AuditRepository` (interface) and uses SLF4J for dual logging. It extracts username/IP/user-agent from Spring Security context and servlet request.
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.core.admin;
|
||||
package com.cameleer.server.core.admin;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.slf4j.Logger;
|
||||
@@ -307,7 +307,7 @@ public class AuditService {
|
||||
}
|
||||
```
|
||||
|
||||
**Note:** This class uses `jakarta.servlet` and `org.springframework.security` — the core POM must have these as `provided` scope dependencies if not already present. Check `cameleer3-server-core/pom.xml` and add if needed:
|
||||
**Note:** This class uses `jakarta.servlet` and `org.springframework.security` — the core POM must have these as `provided` scope dependencies if not already present. Check `cameleer-server-core/pom.xml` and add if needed:
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>jakarta.servlet</groupId>
|
||||
@@ -364,14 +364,14 @@ class AuditServiceTest {
|
||||
|
||||
- [ ] **Step 7: Verify core module compiles and test passes**
|
||||
|
||||
Run: `mvn clean compile -pl cameleer3-server-core`
|
||||
Run: `mvn test -pl cameleer3-server-app -Dtest=AuditServiceTest`
|
||||
Run: `mvn clean compile -pl cameleer-server-core`
|
||||
Run: `mvn test -pl cameleer-server-app -Dtest=AuditServiceTest`
|
||||
Expected: BUILD SUCCESS, tests PASS
|
||||
|
||||
- [ ] **Step 8: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-core/ cameleer3-server-app/src/test/
|
||||
git add cameleer-server-core/ cameleer-server-app/src/test/
|
||||
git commit -m "feat: add audit domain model, repository interface, AuditService, and unit test"
|
||||
```
|
||||
|
||||
@@ -380,13 +380,13 @@ git commit -m "feat: add audit domain model, repository interface, AuditService,
|
||||
### Task 3: Core Module — Threshold Model + Repository Interface
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/admin/ThresholdConfig.java`
|
||||
- Create: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/admin/ThresholdRepository.java`
|
||||
- Create: `cameleer-server-core/src/main/java/com/cameleer/server/core/admin/ThresholdConfig.java`
|
||||
- Create: `cameleer-server-core/src/main/java/com/cameleer/server/core/admin/ThresholdRepository.java`
|
||||
|
||||
- [ ] **Step 1: Create ThresholdConfig record**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.core.admin;
|
||||
package com.cameleer.server.core.admin;
|
||||
|
||||
public record ThresholdConfig(
|
||||
DatabaseThresholds database,
|
||||
@@ -427,7 +427,7 @@ public record ThresholdConfig(
|
||||
- [ ] **Step 2: Create ThresholdRepository interface**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.core.admin;
|
||||
package com.cameleer.server.core.admin;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@@ -439,10 +439,10 @@ public interface ThresholdRepository {
|
||||
|
||||
- [ ] **Step 3: Compile and commit**
|
||||
|
||||
Run: `mvn clean compile -pl cameleer3-server-core`
|
||||
Run: `mvn clean compile -pl cameleer-server-core`
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-core/
|
||||
git add cameleer-server-core/
|
||||
git commit -m "feat: add ThresholdConfig model and ThresholdRepository interface"
|
||||
```
|
||||
|
||||
@@ -451,13 +451,13 @@ git commit -m "feat: add ThresholdConfig model and ThresholdRepository interface
|
||||
### Task 4: Core Module — SearchIndexerStats Interface + Instrumentation
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/indexing/SearchIndexerStats.java`
|
||||
- Modify: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/indexing/SearchIndexer.java`
|
||||
- Create: `cameleer-server-core/src/main/java/com/cameleer/server/core/indexing/SearchIndexerStats.java`
|
||||
- Modify: `cameleer-server-core/src/main/java/com/cameleer/server/core/indexing/SearchIndexer.java`
|
||||
|
||||
- [ ] **Step 1: Create SearchIndexerStats interface**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.core.indexing;
|
||||
package com.cameleer.server.core.indexing;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
@@ -518,10 +518,10 @@ private void updateRate() {
|
||||
|
||||
- [ ] **Step 3: Compile and commit**
|
||||
|
||||
Run: `mvn clean compile -pl cameleer3-server-core`
|
||||
Run: `mvn clean compile -pl cameleer-server-core`
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-core/
|
||||
git add cameleer-server-core/
|
||||
git commit -m "feat: add SearchIndexerStats interface and instrument SearchIndexer"
|
||||
```
|
||||
|
||||
@@ -530,8 +530,8 @@ git commit -m "feat: add SearchIndexerStats interface and instrument SearchIndex
|
||||
### Task 5: App Module — Postgres Repository Implementations
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/PostgresAuditRepository.java`
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/PostgresThresholdRepository.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/storage/PostgresAuditRepository.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/storage/PostgresThresholdRepository.java`
|
||||
|
||||
- [ ] **Step 1: Create PostgresAuditRepository**
|
||||
|
||||
@@ -686,10 +686,10 @@ public class PostgresThresholdRepository implements ThresholdRepository {
|
||||
|
||||
- [ ] **Step 3: Compile and commit**
|
||||
|
||||
Run: `mvn clean compile -pl cameleer3-server-app`
|
||||
Run: `mvn clean compile -pl cameleer-server-app`
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/storage/
|
||||
git commit -m "feat: add Postgres implementations for AuditRepository and ThresholdRepository"
|
||||
```
|
||||
|
||||
@@ -698,10 +698,10 @@ git commit -m "feat: add Postgres implementations for AuditRepository and Thresh
|
||||
### Task 6: App Module — Bean Wiring + Security Retrofit
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/StorageBeanConfig.java`
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/SecurityConfig.java`
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/OidcConfigAdminController.java`
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/UserAdminController.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/config/StorageBeanConfig.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/security/SecurityConfig.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/OidcConfigAdminController.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/UserAdminController.java`
|
||||
|
||||
- [ ] **Step 1: Wire AuditService bean in StorageBeanConfig**
|
||||
|
||||
@@ -757,7 +757,7 @@ Log OIDC login:
|
||||
Run: `mvn clean compile`
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/
|
||||
git add cameleer-server-app/
|
||||
git commit -m "feat: wire AuditService, enable method security, retrofit audit logging into existing controllers"
|
||||
```
|
||||
|
||||
@@ -898,10 +898,10 @@ public record ThresholdConfigRequest(
|
||||
|
||||
- [ ] **Step 4: Compile and commit**
|
||||
|
||||
Run: `mvn clean compile -pl cameleer3-server-app`
|
||||
Run: `mvn clean compile -pl cameleer-server-app`
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/dto/
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/dto/
|
||||
git commit -m "feat: add response/request DTOs for admin infrastructure endpoints"
|
||||
```
|
||||
|
||||
@@ -910,8 +910,8 @@ git commit -m "feat: add response/request DTOs for admin infrastructure endpoint
|
||||
### Task 8: App Module — DatabaseAdminController
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/DatabaseAdminController.java`
|
||||
- Create: `cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/DatabaseAdminControllerIT.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/DatabaseAdminController.java`
|
||||
- Create: `cameleer-server-app/src/test/java/com/cameleer/server/app/controller/DatabaseAdminControllerIT.java`
|
||||
|
||||
- [ ] **Step 1: Write integration test**
|
||||
|
||||
@@ -926,7 +926,7 @@ Use `TestRestTemplate` with admin JWT for authentication. Create a helper that g
|
||||
|
||||
- [ ] **Step 2: Run test to verify it fails**
|
||||
|
||||
Run: `mvn test -pl cameleer3-server-app -Dtest=DatabaseAdminControllerIT`
|
||||
Run: `mvn test -pl cameleer-server-app -Dtest=DatabaseAdminControllerIT`
|
||||
Expected: FAIL — controller class does not exist
|
||||
|
||||
- [ ] **Step 3: Implement DatabaseAdminController**
|
||||
@@ -1025,13 +1025,13 @@ public class DatabaseAdminController {
|
||||
|
||||
- [ ] **Step 4: Run integration test**
|
||||
|
||||
Run: `mvn test -pl cameleer3-server-app -Dtest=DatabaseAdminControllerIT`
|
||||
Run: `mvn test -pl cameleer-server-app -Dtest=DatabaseAdminControllerIT`
|
||||
Expected: PASS
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/
|
||||
git add cameleer-server-app/
|
||||
git commit -m "feat: add DatabaseAdminController with status, pool, tables, queries, and kill endpoints"
|
||||
```
|
||||
|
||||
@@ -1040,8 +1040,8 @@ git commit -m "feat: add DatabaseAdminController with status, pool, tables, quer
|
||||
### Task 9: App Module — OpenSearchAdminController
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/OpenSearchAdminController.java`
|
||||
- Create: `cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/OpenSearchAdminControllerIT.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/OpenSearchAdminController.java`
|
||||
- Create: `cameleer-server-app/src/test/java/com/cameleer/server/app/controller/OpenSearchAdminControllerIT.java`
|
||||
|
||||
- [ ] **Step 1: Write integration test**
|
||||
|
||||
@@ -1054,7 +1054,7 @@ Extend `AbstractPostgresIT` (which starts both PG and OpenSearch containers). Te
|
||||
|
||||
- [ ] **Step 2: Run test to verify it fails**
|
||||
|
||||
Run: `mvn test -pl cameleer3-server-app -Dtest=OpenSearchAdminControllerIT`
|
||||
Run: `mvn test -pl cameleer-server-app -Dtest=OpenSearchAdminControllerIT`
|
||||
Expected: FAIL
|
||||
|
||||
- [ ] **Step 3: Implement OpenSearchAdminController**
|
||||
@@ -1242,13 +1242,13 @@ public class OpenSearchAdminController {
|
||||
|
||||
- [ ] **Step 4: Run integration test**
|
||||
|
||||
Run: `mvn test -pl cameleer3-server-app -Dtest=OpenSearchAdminControllerIT`
|
||||
Run: `mvn test -pl cameleer-server-app -Dtest=OpenSearchAdminControllerIT`
|
||||
Expected: PASS
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/
|
||||
git add cameleer-server-app/
|
||||
git commit -m "feat: add OpenSearchAdminController with status, pipeline, indices, performance, and delete endpoints"
|
||||
```
|
||||
|
||||
@@ -1257,10 +1257,10 @@ git commit -m "feat: add OpenSearchAdminController with status, pipeline, indice
|
||||
### Task 10: App Module — ThresholdAdminController + AuditLogController
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/ThresholdAdminController.java`
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/AuditLogController.java`
|
||||
- Create: `cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/ThresholdAdminControllerIT.java`
|
||||
- Create: `cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/AuditLogControllerIT.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/ThresholdAdminController.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/AuditLogController.java`
|
||||
- Create: `cameleer-server-app/src/test/java/com/cameleer/server/app/controller/ThresholdAdminControllerIT.java`
|
||||
- Create: `cameleer-server-app/src/test/java/com/cameleer/server/app/controller/AuditLogControllerIT.java`
|
||||
|
||||
- [ ] **Step 1: Write ThresholdAdminController integration test**
|
||||
|
||||
@@ -1351,13 +1351,13 @@ public class AuditLogController {
|
||||
|
||||
- [ ] **Step 5: Run tests**
|
||||
|
||||
Run: `mvn test -pl cameleer3-server-app -Dtest="ThresholdAdminControllerIT,AuditLogControllerIT"`
|
||||
Run: `mvn test -pl cameleer-server-app -Dtest="ThresholdAdminControllerIT,AuditLogControllerIT"`
|
||||
Expected: PASS
|
||||
|
||||
- [ ] **Step 6: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/
|
||||
git add cameleer-server-app/
|
||||
git commit -m "feat: add ThresholdAdminController and AuditLogController with integration tests"
|
||||
```
|
||||
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
### Backend
|
||||
| File | Change |
|
||||
|---|---|
|
||||
| Create: `cameleer3-server-app/src/main/resources/db/migration/V2__admin_group_seed.sql` | Seed Admins group + ADMIN role assignment |
|
||||
| Modify: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/rbac/SystemRole.java` | Add `ADMINS_GROUP_ID` |
|
||||
| Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/UiAuthController.java` | Add admin user to Admins group on login |
|
||||
| Create: `cameleer-server-app/src/main/resources/db/migration/V2__admin_group_seed.sql` | Seed Admins group + ADMIN role assignment |
|
||||
| Modify: `cameleer-server-core/src/main/java/com/cameleer/server/core/rbac/SystemRole.java` | Add `ADMINS_GROUP_ID` |
|
||||
| Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/security/UiAuthController.java` | Add admin user to Admins group on login |
|
||||
|
||||
### Frontend
|
||||
| File | Change |
|
||||
@@ -38,9 +38,9 @@
|
||||
### Task 1: Backend — Admins Group Seed + SystemRole Constant + Auth
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/main/resources/db/migration/V2__admin_group_seed.sql`
|
||||
- Modify: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/rbac/SystemRole.java`
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/UiAuthController.java`
|
||||
- Create: `cameleer-server-app/src/main/resources/db/migration/V2__admin_group_seed.sql`
|
||||
- Modify: `cameleer-server-core/src/main/java/com/cameleer/server/core/rbac/SystemRole.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/security/UiAuthController.java`
|
||||
|
||||
- [ ] **Step 1: Create V2 migration**
|
||||
|
||||
@@ -56,7 +56,7 @@ INSERT INTO group_roles (group_id, role_id) VALUES
|
||||
|
||||
- [ ] **Step 2: Add ADMINS_GROUP_ID to SystemRole.java**
|
||||
|
||||
Read `cameleer3-server-core/src/main/java/com/cameleer3/server/core/rbac/SystemRole.java` and add after the existing UUID constants:
|
||||
Read `cameleer-server-core/src/main/java/com/cameleer/server/core/rbac/SystemRole.java` and add after the existing UUID constants:
|
||||
|
||||
```java
|
||||
public static final UUID ADMINS_GROUP_ID = UUID.fromString("00000000-0000-0000-0000-000000000010");
|
||||
@@ -64,7 +64,7 @@ public static final UUID ADMINS_GROUP_ID = UUID.fromString("00000000-0000-0000-0
|
||||
|
||||
- [ ] **Step 3: Update UiAuthController.login()**
|
||||
|
||||
Read `cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/UiAuthController.java`. In the `login()` method, after the line that assigns ADMIN role (`rbacService.assignRoleToUser(subject, SystemRole.ADMIN_ID)`), add:
|
||||
Read `cameleer-server-app/src/main/java/com/cameleer/server/app/security/UiAuthController.java`. In the `login()` method, after the line that assigns ADMIN role (`rbacService.assignRoleToUser(subject, SystemRole.ADMIN_ID)`), add:
|
||||
|
||||
```java
|
||||
rbacService.addUserToGroup(subject, SystemRole.ADMINS_GROUP_ID);
|
||||
@@ -79,7 +79,7 @@ mvn clean compile
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/resources/db/migration/V2__admin_group_seed.sql cameleer3-server-core/ cameleer3-server-app/src/main/java/
|
||||
git add cameleer-server-app/src/main/resources/db/migration/V2__admin_group_seed.sql cameleer-server-core/ cameleer-server-app/src/main/java/
|
||||
git commit -m "feat: seed built-in Admins group and assign admin users on login"
|
||||
```
|
||||
|
||||
|
||||
@@ -17,51 +17,51 @@
|
||||
### Backend — New Files
|
||||
| File | Responsibility |
|
||||
|---|---|
|
||||
| `cameleer3-server-app/src/main/resources/db/migration/V1__init.sql` | Consolidated schema (replaces V1–V10) |
|
||||
| `cameleer3-server-core/src/main/java/com/cameleer3/server/core/rbac/RbacService.java` | Inheritance computation interface |
|
||||
| `cameleer3-server-core/src/main/java/com/cameleer3/server/core/rbac/GroupRepository.java` | Group CRUD interface |
|
||||
| `cameleer3-server-core/src/main/java/com/cameleer3/server/core/rbac/RoleRepository.java` | Role CRUD interface |
|
||||
| `cameleer3-server-core/src/main/java/com/cameleer3/server/core/rbac/UserDetail.java` | Enriched user record |
|
||||
| `cameleer3-server-core/src/main/java/com/cameleer3/server/core/rbac/GroupDetail.java` | Group detail record |
|
||||
| `cameleer3-server-core/src/main/java/com/cameleer3/server/core/rbac/RoleDetail.java` | Role detail record |
|
||||
| `cameleer3-server-core/src/main/java/com/cameleer3/server/core/rbac/UserSummary.java` | Embedded user ref |
|
||||
| `cameleer3-server-core/src/main/java/com/cameleer3/server/core/rbac/GroupSummary.java` | Embedded group ref |
|
||||
| `cameleer3-server-core/src/main/java/com/cameleer3/server/core/rbac/RoleSummary.java` | Embedded role ref |
|
||||
| `cameleer3-server-core/src/main/java/com/cameleer3/server/core/rbac/RbacStats.java` | Dashboard stats record |
|
||||
| `cameleer3-server-core/src/main/java/com/cameleer3/server/core/rbac/SystemRole.java` | System role constants + fixed UUIDs |
|
||||
| `cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/PostgresGroupRepository.java` | Group repository impl |
|
||||
| `cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/PostgresRoleRepository.java` | Role repository impl |
|
||||
| `cameleer3-server-app/src/main/java/com/cameleer3/server/app/rbac/RbacServiceImpl.java` | Inheritance computation impl |
|
||||
| `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/GroupAdminController.java` | Group CRUD endpoints |
|
||||
| `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/RoleAdminController.java` | Role CRUD endpoints |
|
||||
| `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/RbacStatsController.java` | Dashboard stats endpoint |
|
||||
| `cameleer-server-app/src/main/resources/db/migration/V1__init.sql` | Consolidated schema (replaces V1–V10) |
|
||||
| `cameleer-server-core/src/main/java/com/cameleer/server/core/rbac/RbacService.java` | Inheritance computation interface |
|
||||
| `cameleer-server-core/src/main/java/com/cameleer/server/core/rbac/GroupRepository.java` | Group CRUD interface |
|
||||
| `cameleer-server-core/src/main/java/com/cameleer/server/core/rbac/RoleRepository.java` | Role CRUD interface |
|
||||
| `cameleer-server-core/src/main/java/com/cameleer/server/core/rbac/UserDetail.java` | Enriched user record |
|
||||
| `cameleer-server-core/src/main/java/com/cameleer/server/core/rbac/GroupDetail.java` | Group detail record |
|
||||
| `cameleer-server-core/src/main/java/com/cameleer/server/core/rbac/RoleDetail.java` | Role detail record |
|
||||
| `cameleer-server-core/src/main/java/com/cameleer/server/core/rbac/UserSummary.java` | Embedded user ref |
|
||||
| `cameleer-server-core/src/main/java/com/cameleer/server/core/rbac/GroupSummary.java` | Embedded group ref |
|
||||
| `cameleer-server-core/src/main/java/com/cameleer/server/core/rbac/RoleSummary.java` | Embedded role ref |
|
||||
| `cameleer-server-core/src/main/java/com/cameleer/server/core/rbac/RbacStats.java` | Dashboard stats record |
|
||||
| `cameleer-server-core/src/main/java/com/cameleer/server/core/rbac/SystemRole.java` | System role constants + fixed UUIDs |
|
||||
| `cameleer-server-app/src/main/java/com/cameleer/server/app/storage/PostgresGroupRepository.java` | Group repository impl |
|
||||
| `cameleer-server-app/src/main/java/com/cameleer/server/app/storage/PostgresRoleRepository.java` | Role repository impl |
|
||||
| `cameleer-server-app/src/main/java/com/cameleer/server/app/rbac/RbacServiceImpl.java` | Inheritance computation impl |
|
||||
| `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/GroupAdminController.java` | Group CRUD endpoints |
|
||||
| `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/RoleAdminController.java` | Role CRUD endpoints |
|
||||
| `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/RbacStatsController.java` | Dashboard stats endpoint |
|
||||
|
||||
### Backend — Modified Files
|
||||
| File | Change |
|
||||
|---|---|
|
||||
| `cameleer3-server-core/.../security/UserInfo.java` | Remove `roles` field |
|
||||
| `cameleer3-server-core/.../security/UserRepository.java` | Remove `updateRoles`, add `findSystemRoles` |
|
||||
| `cameleer3-server-core/.../admin/AuditCategory.java` | Add `RBAC` category |
|
||||
| `cameleer3-server-app/.../storage/PostgresUserRepository.java` | Rewrite for new schema (no roles column, use user_roles join) |
|
||||
| `cameleer3-server-app/.../controller/UserAdminController.java` | Rewrite: use RbacService, new endpoints |
|
||||
| `cameleer3-server-app/.../security/UiAuthController.java` | Use user_roles instead of UserInfo.roles |
|
||||
| `cameleer3-server-app/.../security/OidcAuthController.java` | Use user_roles for role resolution |
|
||||
| `cameleer3-server-app/.../security/JwtAuthenticationFilter.java` | No change (reads roles from JWT, not DB) |
|
||||
| `cameleer3-server-app/.../security/AgentRegistrationController.java` | Use user_roles for AGENT role |
|
||||
| `cameleer3-server-app/src/test/.../TestSecurityHelper.java` | No change (creates JWT directly) |
|
||||
| `cameleer-server-core/.../security/UserInfo.java` | Remove `roles` field |
|
||||
| `cameleer-server-core/.../security/UserRepository.java` | Remove `updateRoles`, add `findSystemRoles` |
|
||||
| `cameleer-server-core/.../admin/AuditCategory.java` | Add `RBAC` category |
|
||||
| `cameleer-server-app/.../storage/PostgresUserRepository.java` | Rewrite for new schema (no roles column, use user_roles join) |
|
||||
| `cameleer-server-app/.../controller/UserAdminController.java` | Rewrite: use RbacService, new endpoints |
|
||||
| `cameleer-server-app/.../security/UiAuthController.java` | Use user_roles instead of UserInfo.roles |
|
||||
| `cameleer-server-app/.../security/OidcAuthController.java` | Use user_roles for role resolution |
|
||||
| `cameleer-server-app/.../security/JwtAuthenticationFilter.java` | No change (reads roles from JWT, not DB) |
|
||||
| `cameleer-server-app/.../security/AgentRegistrationController.java` | Use user_roles for AGENT role |
|
||||
| `cameleer-server-app/src/test/.../TestSecurityHelper.java` | No change (creates JWT directly) |
|
||||
|
||||
### Backend — Deleted Files
|
||||
| File |
|
||||
|---|
|
||||
| `cameleer3-server-app/src/main/resources/db/migration/V2__executions.sql` |
|
||||
| `cameleer3-server-app/src/main/resources/db/migration/V3__processor_executions.sql` |
|
||||
| `cameleer3-server-app/src/main/resources/db/migration/V4__agent_metrics.sql` |
|
||||
| `cameleer3-server-app/src/main/resources/db/migration/V5__route_diagrams.sql` |
|
||||
| `cameleer3-server-app/src/main/resources/db/migration/V6__users.sql` |
|
||||
| `cameleer3-server-app/src/main/resources/db/migration/V7__oidc_config.sql` |
|
||||
| `cameleer3-server-app/src/main/resources/db/migration/V8__continuous_aggregates.sql` |
|
||||
| `cameleer3-server-app/src/main/resources/db/migration/V9__admin_thresholds.sql` |
|
||||
| `cameleer3-server-app/src/main/resources/db/migration/V10__audit_log.sql` |
|
||||
| `cameleer-server-app/src/main/resources/db/migration/V2__executions.sql` |
|
||||
| `cameleer-server-app/src/main/resources/db/migration/V3__processor_executions.sql` |
|
||||
| `cameleer-server-app/src/main/resources/db/migration/V4__agent_metrics.sql` |
|
||||
| `cameleer-server-app/src/main/resources/db/migration/V5__route_diagrams.sql` |
|
||||
| `cameleer-server-app/src/main/resources/db/migration/V6__users.sql` |
|
||||
| `cameleer-server-app/src/main/resources/db/migration/V7__oidc_config.sql` |
|
||||
| `cameleer-server-app/src/main/resources/db/migration/V8__continuous_aggregates.sql` |
|
||||
| `cameleer-server-app/src/main/resources/db/migration/V9__admin_thresholds.sql` |
|
||||
| `cameleer-server-app/src/main/resources/db/migration/V10__audit_log.sql` |
|
||||
|
||||
### Frontend — New Files
|
||||
| File | Responsibility |
|
||||
@@ -98,7 +98,7 @@
|
||||
### Task 1: Consolidate Flyway Migrations
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/main/resources/db/migration/V1__init.sql`
|
||||
- Create: `cameleer-server-app/src/main/resources/db/migration/V1__init.sql`
|
||||
- Delete: `V1__extensions.sql` through `V10__audit_log.sql` (10 files)
|
||||
|
||||
- [ ] **Step 1: Create consolidated V1__init.sql**
|
||||
@@ -106,7 +106,7 @@
|
||||
Combine all existing migration content (V1–V10) into a single file, replacing the `users` table definition to drop `roles TEXT[]`, and adding the new RBAC tables. Order: extensions → users (new) → roles (with seeds) → groups → join tables → executions → processor_executions → agent_metrics → route_diagrams → oidc_config → continuous_aggregates → admin_thresholds → audit_log → indexes.
|
||||
|
||||
```sql
|
||||
-- V1__init.sql — Consolidated schema for Cameleer3
|
||||
-- V1__init.sql — Consolidated schema for Cameleer
|
||||
|
||||
-- Extensions
|
||||
CREATE EXTENSION IF NOT EXISTS timescaledb;
|
||||
@@ -400,7 +400,7 @@ CREATE INDEX idx_audit_log_target ON audit_log (target);
|
||||
- [ ] **Step 2: Delete old migration files**
|
||||
|
||||
```bash
|
||||
cd cameleer3-server-app/src/main/resources/db/migration
|
||||
cd cameleer-server-app/src/main/resources/db/migration
|
||||
rm V2__executions.sql V3__processor_executions.sql V4__agent_metrics.sql V5__route_diagrams.sql V6__users.sql V7__oidc_config.sql V8__continuous_aggregates.sql V9__admin_thresholds.sql V10__audit_log.sql
|
||||
# Keep V1__extensions.sql but it's been replaced by V1__init.sql — rename the old one first
|
||||
mv V1__extensions.sql V1__extensions.sql.bak
|
||||
@@ -417,8 +417,8 @@ rm V1__extensions.sql V2__executions.sql V3__processor_executions.sql V4__agent_
|
||||
- [ ] **Step 3: Verify the migration compiles**
|
||||
|
||||
```bash
|
||||
cd /c/Users/Hendrik/Documents/projects/cameleer3-server
|
||||
mvn clean compile -pl cameleer3-server-app
|
||||
cd /c/Users/Hendrik/Documents/projects/cameleer-server
|
||||
mvn clean compile -pl cameleer-server-app
|
||||
```
|
||||
|
||||
Expected: BUILD SUCCESS (Flyway doesn't run at compile time, just packaging)
|
||||
@@ -426,7 +426,7 @@ Expected: BUILD SUCCESS (Flyway doesn't run at compile time, just packaging)
|
||||
- [ ] **Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add -A cameleer3-server-app/src/main/resources/db/migration/
|
||||
git add -A cameleer-server-app/src/main/resources/db/migration/
|
||||
git commit -m "refactor: consolidate V1-V10 Flyway migrations into single V1__init.sql
|
||||
|
||||
Add RBAC tables (roles, groups, group_roles, user_groups, user_roles)
|
||||
@@ -438,25 +438,25 @@ with system role seeds and join indexes. Drop users.roles TEXT[] column."
|
||||
### Task 2: RBAC Domain Model (core module)
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/rbac/SystemRole.java`
|
||||
- Create: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/rbac/UserDetail.java`
|
||||
- Create: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/rbac/GroupDetail.java`
|
||||
- Create: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/rbac/RoleDetail.java`
|
||||
- Create: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/rbac/UserSummary.java`
|
||||
- Create: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/rbac/GroupSummary.java`
|
||||
- Create: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/rbac/RoleSummary.java`
|
||||
- Create: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/rbac/RbacStats.java`
|
||||
- Create: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/rbac/GroupRepository.java`
|
||||
- Create: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/rbac/RoleRepository.java`
|
||||
- Create: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/rbac/RbacService.java`
|
||||
- Modify: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/security/UserInfo.java`
|
||||
- Modify: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/security/UserRepository.java`
|
||||
- Modify: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/admin/AuditCategory.java`
|
||||
- Create: `cameleer-server-core/src/main/java/com/cameleer/server/core/rbac/SystemRole.java`
|
||||
- Create: `cameleer-server-core/src/main/java/com/cameleer/server/core/rbac/UserDetail.java`
|
||||
- Create: `cameleer-server-core/src/main/java/com/cameleer/server/core/rbac/GroupDetail.java`
|
||||
- Create: `cameleer-server-core/src/main/java/com/cameleer/server/core/rbac/RoleDetail.java`
|
||||
- Create: `cameleer-server-core/src/main/java/com/cameleer/server/core/rbac/UserSummary.java`
|
||||
- Create: `cameleer-server-core/src/main/java/com/cameleer/server/core/rbac/GroupSummary.java`
|
||||
- Create: `cameleer-server-core/src/main/java/com/cameleer/server/core/rbac/RoleSummary.java`
|
||||
- Create: `cameleer-server-core/src/main/java/com/cameleer/server/core/rbac/RbacStats.java`
|
||||
- Create: `cameleer-server-core/src/main/java/com/cameleer/server/core/rbac/GroupRepository.java`
|
||||
- Create: `cameleer-server-core/src/main/java/com/cameleer/server/core/rbac/RoleRepository.java`
|
||||
- Create: `cameleer-server-core/src/main/java/com/cameleer/server/core/rbac/RbacService.java`
|
||||
- Modify: `cameleer-server-core/src/main/java/com/cameleer/server/core/security/UserInfo.java`
|
||||
- Modify: `cameleer-server-core/src/main/java/com/cameleer/server/core/security/UserRepository.java`
|
||||
- Modify: `cameleer-server-core/src/main/java/com/cameleer/server/core/admin/AuditCategory.java`
|
||||
|
||||
- [ ] **Step 1: Create SystemRole constants**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.core.rbac;
|
||||
package com.cameleer.server.core.rbac;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -489,14 +489,14 @@ public final class SystemRole {
|
||||
|
||||
`UserSummary.java`:
|
||||
```java
|
||||
package com.cameleer3.server.core.rbac;
|
||||
package com.cameleer.server.core.rbac;
|
||||
|
||||
public record UserSummary(String userId, String displayName, String provider) {}
|
||||
```
|
||||
|
||||
`GroupSummary.java`:
|
||||
```java
|
||||
package com.cameleer3.server.core.rbac;
|
||||
package com.cameleer.server.core.rbac;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@@ -505,7 +505,7 @@ public record GroupSummary(UUID id, String name) {}
|
||||
|
||||
`RoleSummary.java`:
|
||||
```java
|
||||
package com.cameleer3.server.core.rbac;
|
||||
package com.cameleer.server.core.rbac;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@@ -514,7 +514,7 @@ public record RoleSummary(UUID id, String name, boolean system, String source) {
|
||||
|
||||
`RbacStats.java`:
|
||||
```java
|
||||
package com.cameleer3.server.core.rbac;
|
||||
package com.cameleer.server.core.rbac;
|
||||
|
||||
public record RbacStats(int userCount, int activeUserCount, int groupCount, int maxGroupDepth, int roleCount) {}
|
||||
```
|
||||
@@ -523,7 +523,7 @@ public record RbacStats(int userCount, int activeUserCount, int groupCount, int
|
||||
|
||||
`UserDetail.java`:
|
||||
```java
|
||||
package com.cameleer3.server.core.rbac;
|
||||
package com.cameleer.server.core.rbac;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
@@ -543,7 +543,7 @@ public record UserDetail(
|
||||
|
||||
`GroupDetail.java`:
|
||||
```java
|
||||
package com.cameleer3.server.core.rbac;
|
||||
package com.cameleer.server.core.rbac;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
@@ -563,7 +563,7 @@ public record GroupDetail(
|
||||
|
||||
`RoleDetail.java`:
|
||||
```java
|
||||
package com.cameleer3.server.core.rbac;
|
||||
package com.cameleer.server.core.rbac;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
@@ -586,7 +586,7 @@ public record RoleDetail(
|
||||
|
||||
`GroupRepository.java`:
|
||||
```java
|
||||
package com.cameleer3.server.core.rbac;
|
||||
package com.cameleer.server.core.rbac;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@@ -607,7 +607,7 @@ public interface GroupRepository {
|
||||
|
||||
`RoleRepository.java`:
|
||||
```java
|
||||
package com.cameleer3.server.core.rbac;
|
||||
package com.cameleer.server.core.rbac;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@@ -624,7 +624,7 @@ public interface RoleRepository {
|
||||
|
||||
`RbacService.java`:
|
||||
```java
|
||||
package com.cameleer3.server.core.rbac;
|
||||
package com.cameleer.server.core.rbac;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
@@ -651,10 +651,10 @@ public interface RbacService {
|
||||
|
||||
- [ ] **Step 5: Update UserInfo — remove roles field**
|
||||
|
||||
In `cameleer3-server-core/src/main/java/com/cameleer3/server/core/security/UserInfo.java`, change to:
|
||||
In `cameleer-server-core/src/main/java/com/cameleer/server/core/security/UserInfo.java`, change to:
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.core.security;
|
||||
package com.cameleer.server.core.security;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
@@ -669,10 +669,10 @@ public record UserInfo(
|
||||
|
||||
- [ ] **Step 6: Update UserRepository interface**
|
||||
|
||||
In `cameleer3-server-core/src/main/java/com/cameleer3/server/core/security/UserRepository.java`, change to:
|
||||
In `cameleer-server-core/src/main/java/com/cameleer/server/core/security/UserRepository.java`, change to:
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.core.security;
|
||||
package com.cameleer.server.core.security;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@@ -689,7 +689,7 @@ Remove `updateRoles` method (role management moves to `RbacService`).
|
||||
|
||||
- [ ] **Step 7: Add RBAC audit category**
|
||||
|
||||
In `cameleer3-server-core/src/main/java/com/cameleer3/server/core/admin/AuditCategory.java`, add `RBAC`:
|
||||
In `cameleer-server-core/src/main/java/com/cameleer/server/core/admin/AuditCategory.java`, add `RBAC`:
|
||||
|
||||
```java
|
||||
public enum AuditCategory {
|
||||
@@ -700,7 +700,7 @@ public enum AuditCategory {
|
||||
- [ ] **Step 8: Verify core module compiles**
|
||||
|
||||
```bash
|
||||
mvn clean compile -pl cameleer3-server-core
|
||||
mvn clean compile -pl cameleer-server-core
|
||||
```
|
||||
|
||||
Expected: BUILD SUCCESS
|
||||
@@ -712,17 +712,17 @@ Expected: BUILD SUCCESS
|
||||
### Task 3: PostgresUserRepository — Adapt to New Schema
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/PostgresUserRepository.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/storage/PostgresUserRepository.java`
|
||||
|
||||
- [ ] **Step 1: Rewrite PostgresUserRepository**
|
||||
|
||||
The `upsert` no longer writes roles (no `roles` column). The `mapUser` no longer reads a roles array. Remove `updateRoles` method.
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.storage;
|
||||
package com.cameleer.server.app.storage;
|
||||
|
||||
import com.cameleer3.server.core.security.UserInfo;
|
||||
import com.cameleer3.server.core.security.UserRepository;
|
||||
import com.cameleer.server.core.security.UserInfo;
|
||||
import com.cameleer.server.core.security.UserRepository;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@@ -793,15 +793,15 @@ public class PostgresUserRepository implements UserRepository {
|
||||
### Task 4: PostgresGroupRepository and PostgresRoleRepository
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/PostgresGroupRepository.java`
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/PostgresRoleRepository.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/storage/PostgresGroupRepository.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/storage/PostgresRoleRepository.java`
|
||||
|
||||
- [ ] **Step 1: Implement PostgresGroupRepository**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.storage;
|
||||
package com.cameleer.server.app.storage;
|
||||
|
||||
import com.cameleer3.server.core.rbac.*;
|
||||
import com.cameleer.server.core.rbac.*;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@@ -920,9 +920,9 @@ public class PostgresGroupRepository implements GroupRepository {
|
||||
- [ ] **Step 2: Implement PostgresRoleRepository**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.storage;
|
||||
package com.cameleer.server.app.storage;
|
||||
|
||||
import com.cameleer3.server.core.rbac.*;
|
||||
import com.cameleer.server.core.rbac.*;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@@ -1010,7 +1010,7 @@ public class PostgresRoleRepository implements RoleRepository {
|
||||
- [ ] **Step 3: Verify compile**
|
||||
|
||||
```bash
|
||||
mvn clean compile -pl cameleer3-server-app
|
||||
mvn clean compile -pl cameleer-server-app
|
||||
```
|
||||
|
||||
Expected: May still have errors from files referencing `UserInfo.roles()` — those are fixed in Task 6.
|
||||
@@ -1022,18 +1022,18 @@ Expected: May still have errors from files referencing `UserInfo.roles()` — th
|
||||
### Task 5: RbacServiceImpl — Inheritance Logic
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/rbac/RbacServiceImpl.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/rbac/RbacServiceImpl.java`
|
||||
|
||||
- [ ] **Step 1: Implement RbacServiceImpl**
|
||||
|
||||
This is the core service that computes inheritance. It reads from `user_roles`, `user_groups`, `group_roles`, and `groups` tables to compute effective roles/groups.
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.rbac;
|
||||
package com.cameleer.server.app.rbac;
|
||||
|
||||
import com.cameleer3.server.core.rbac.*;
|
||||
import com.cameleer3.server.core.security.UserInfo;
|
||||
import com.cameleer3.server.core.security.UserRepository;
|
||||
import com.cameleer.server.core.rbac.*;
|
||||
import com.cameleer.server.core.security.UserInfo;
|
||||
import com.cameleer.server.core.security.UserRepository;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@@ -1304,9 +1304,9 @@ public class RbacServiceImpl implements RbacService {
|
||||
### Task 6: Auth Integration — Update Login and OIDC Flows
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/UiAuthController.java`
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/OidcAuthController.java`
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/AgentRegistrationController.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/security/UiAuthController.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/security/OidcAuthController.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/AgentRegistrationController.java`
|
||||
|
||||
These controllers currently embed roles in `UserInfo` and pass them to JWT creation. After the change, they must:
|
||||
1. Create/upsert the `UserInfo` (without roles)
|
||||
@@ -1357,10 +1357,10 @@ Expected: BUILD SUCCESS (all `UserInfo.roles()` references resolved)
|
||||
This is the single commit for the entire backend RBAC model. Tasks 2–6 must all be done before committing since intermediate states don't compile.
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-core/ cameleer3-server-app/src/main/java/
|
||||
git add cameleer-server-core/ cameleer-server-app/src/main/java/
|
||||
git commit -m "feat: replace flat users.roles with relational RBAC model
|
||||
|
||||
New package com.cameleer3.server.core.rbac with SystemRole constants,
|
||||
New package com.cameleer.server.core.rbac with SystemRole constants,
|
||||
detail/summary records, GroupRepository, RoleRepository, RbacService.
|
||||
Remove roles field from UserInfo. Implement PostgresGroupRepository,
|
||||
PostgresRoleRepository, RbacServiceImpl with inheritance computation.
|
||||
@@ -1373,19 +1373,19 @@ to assign roles via user_roles table. JWT populated from effective system roles.
|
||||
### Task 7: Admin Controllers — Users, Groups, Roles, Stats
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/UserAdminController.java`
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/GroupAdminController.java`
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/RoleAdminController.java`
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/RbacStatsController.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/UserAdminController.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/GroupAdminController.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/RoleAdminController.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/RbacStatsController.java`
|
||||
|
||||
- [ ] **Step 1: Rewrite UserAdminController**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.controller;
|
||||
package com.cameleer.server.app.controller;
|
||||
|
||||
import com.cameleer3.server.core.admin.*;
|
||||
import com.cameleer3.server.core.rbac.*;
|
||||
import com.cameleer3.server.core.security.UserRepository;
|
||||
import com.cameleer.server.core.admin.*;
|
||||
import com.cameleer.server.core.rbac.*;
|
||||
import com.cameleer.server.core.security.UserRepository;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
@@ -1485,10 +1485,10 @@ public class UserAdminController {
|
||||
- [ ] **Step 2: Create GroupAdminController**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.controller;
|
||||
package com.cameleer.server.app.controller;
|
||||
|
||||
import com.cameleer3.server.core.admin.*;
|
||||
import com.cameleer3.server.core.rbac.*;
|
||||
import com.cameleer.server.core.admin.*;
|
||||
import com.cameleer.server.core.rbac.*;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
@@ -1608,10 +1608,10 @@ public class GroupAdminController {
|
||||
- [ ] **Step 3: Create RoleAdminController**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.controller;
|
||||
package com.cameleer.server.app.controller;
|
||||
|
||||
import com.cameleer3.server.core.admin.*;
|
||||
import com.cameleer3.server.core.rbac.*;
|
||||
import com.cameleer.server.core.admin.*;
|
||||
import com.cameleer.server.core.rbac.*;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
@@ -1701,10 +1701,10 @@ public class RoleAdminController {
|
||||
- [ ] **Step 4: Create RbacStatsController**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.controller;
|
||||
package com.cameleer.server.app.controller;
|
||||
|
||||
import com.cameleer3.server.core.rbac.RbacService;
|
||||
import com.cameleer3.server.core.rbac.RbacStats;
|
||||
import com.cameleer.server.core.rbac.RbacService;
|
||||
import com.cameleer.server.core.rbac.RbacStats;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
@@ -1742,7 +1742,7 @@ Expected: BUILD SUCCESS
|
||||
- [ ] **Step 6: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/controller/
|
||||
git commit -m "feat: add Group, Role, and RBAC stats admin controllers
|
||||
|
||||
GroupAdminController with cycle detection, RoleAdminController
|
||||
@@ -1763,8 +1763,8 @@ Rewrite UserAdminController to use RbacService."
|
||||
Search for references to `UserInfo` constructor with 6 args (now 5) or `.roles()` calls in test files. Update constructor calls, remove roles parameter.
|
||||
|
||||
```bash
|
||||
grep -rn "UserInfo(" cameleer3-server-app/src/test/
|
||||
grep -rn "\.roles()" cameleer3-server-app/src/test/
|
||||
grep -rn "UserInfo(" cameleer-server-app/src/test/
|
||||
grep -rn "\.roles()" cameleer-server-app/src/test/
|
||||
```
|
||||
|
||||
Fix each reference. `TestSecurityHelper` creates JWT directly with roles — this doesn't change since JWT creation still takes `List<String> roles`.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** Close all visual and functional gaps between the `@cameleer/design-system` v0.0.2 mocks and the cameleer3-server UI.
|
||||
**Goal:** Close all visual and functional gaps between the `@cameleer/design-system` v0.0.2 mocks and the cameleer-server UI.
|
||||
|
||||
**Architecture:** Backend-first (new endpoints + migration), then frontend page-by-page alignment. Each task produces one git commit. Backend tasks use Spring Boot controllers querying TimescaleDB continuous aggregates. Frontend tasks modify React pages consuming design system components with TanStack Query hooks.
|
||||
|
||||
@@ -15,20 +15,20 @@
|
||||
## File Structure
|
||||
|
||||
### New backend files
|
||||
- `cameleer3-server-app/src/main/resources/db/migration/V7__processor_stats_by_id.sql`
|
||||
- `cameleer3-server-app/src/main/java/com/cameleer3/server/app/dto/ProcessorMetrics.java`
|
||||
- `cameleer3-server-app/src/main/java/com/cameleer3/server/app/dto/AgentMetricsResponse.java`
|
||||
- `cameleer3-server-app/src/main/java/com/cameleer3/server/app/dto/MetricBucket.java`
|
||||
- `cameleer3-server-app/src/main/java/com/cameleer3/server/app/dto/SetPasswordRequest.java`
|
||||
- `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/AgentMetricsController.java`
|
||||
- `cameleer-server-app/src/main/resources/db/migration/V7__processor_stats_by_id.sql`
|
||||
- `cameleer-server-app/src/main/java/com/cameleer/server/app/dto/ProcessorMetrics.java`
|
||||
- `cameleer-server-app/src/main/java/com/cameleer/server/app/dto/AgentMetricsResponse.java`
|
||||
- `cameleer-server-app/src/main/java/com/cameleer/server/app/dto/MetricBucket.java`
|
||||
- `cameleer-server-app/src/main/java/com/cameleer/server/app/dto/SetPasswordRequest.java`
|
||||
- `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/AgentMetricsController.java`
|
||||
|
||||
### Modified backend files
|
||||
- `cameleer3-server-app/src/main/java/com/cameleer3/server/app/dto/AgentInstanceResponse.java` — add `version`, `capabilities`
|
||||
- `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/AgentRegistrationController.java` — map new fields
|
||||
- `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/RouteMetricsController.java` — add processor stats method
|
||||
- `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/UserAdminController.java` — add password reset
|
||||
- `cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/SecurityConfig.java` — agent metrics rule
|
||||
- `cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/OpenApiConfig.java` — register new DTOs
|
||||
- `cameleer-server-app/src/main/java/com/cameleer/server/app/dto/AgentInstanceResponse.java` — add `version`, `capabilities`
|
||||
- `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/AgentRegistrationController.java` — map new fields
|
||||
- `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/RouteMetricsController.java` — add processor stats method
|
||||
- `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/UserAdminController.java` — add password reset
|
||||
- `cameleer-server-app/src/main/java/com/cameleer/server/app/security/SecurityConfig.java` — agent metrics rule
|
||||
- `cameleer-server-app/src/main/java/com/cameleer/server/app/config/OpenApiConfig.java` — register new DTOs
|
||||
|
||||
### New frontend files
|
||||
- `ui/src/pages/Routes/RouteDetail.tsx` + `RouteDetail.module.css`
|
||||
@@ -58,7 +58,7 @@
|
||||
## Task 1: V7 Migration — Processor Stats Continuous Aggregate
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/main/resources/db/migration/V7__processor_stats_by_id.sql`
|
||||
- Create: `cameleer-server-app/src/main/resources/db/migration/V7__processor_stats_by_id.sql`
|
||||
|
||||
- [ ] **Step 1: Create migration file**
|
||||
|
||||
@@ -88,13 +88,13 @@ SELECT add_continuous_aggregate_policy('stats_1m_processor_detail',
|
||||
|
||||
- [ ] **Step 2: Verify migration compiles**
|
||||
|
||||
Run: `cd cameleer3-server-app && mvn clean compile -q 2>&1 | tail -5`
|
||||
Run: `cd cameleer-server-app && mvn clean compile -q 2>&1 | tail -5`
|
||||
Expected: BUILD SUCCESS (Flyway picks up migration at runtime)
|
||||
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/resources/db/migration/V7__processor_stats_by_id.sql
|
||||
git add cameleer-server-app/src/main/resources/db/migration/V7__processor_stats_by_id.sql
|
||||
git commit -m "feat: add V7 migration for per-processor-id continuous aggregate"
|
||||
```
|
||||
|
||||
@@ -103,14 +103,14 @@ git commit -m "feat: add V7 migration for per-processor-id continuous aggregate"
|
||||
## Task 2: Backend — Processor Stats Endpoint
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/dto/ProcessorMetrics.java`
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/RouteMetricsController.java`
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/OpenApiConfig.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/dto/ProcessorMetrics.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/RouteMetricsController.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/config/OpenApiConfig.java`
|
||||
|
||||
- [ ] **Step 1: Create ProcessorMetrics DTO**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.dto;
|
||||
package com.cameleer.server.app.dto;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
|
||||
@@ -159,9 +159,9 @@ Expected: BUILD SUCCESS
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/dto/ProcessorMetrics.java \
|
||||
cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/RouteMetricsController.java \
|
||||
cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/OpenApiConfig.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/dto/ProcessorMetrics.java \
|
||||
cameleer-server-app/src/main/java/com/cameleer/server/app/controller/RouteMetricsController.java \
|
||||
cameleer-server-app/src/main/java/com/cameleer/server/app/config/OpenApiConfig.java
|
||||
git commit -m "feat: add GET /routes/metrics/processors endpoint"
|
||||
```
|
||||
|
||||
@@ -170,17 +170,17 @@ git commit -m "feat: add GET /routes/metrics/processors endpoint"
|
||||
## Task 3: Backend — Agent Metrics Query Endpoint
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/dto/AgentMetricsResponse.java`
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/dto/MetricBucket.java`
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/AgentMetricsController.java`
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/SecurityConfig.java`
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/OpenApiConfig.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/dto/AgentMetricsResponse.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/dto/MetricBucket.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/AgentMetricsController.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/security/SecurityConfig.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/config/OpenApiConfig.java`
|
||||
|
||||
- [ ] **Step 1: Create DTOs**
|
||||
|
||||
`MetricBucket.java`:
|
||||
```java
|
||||
package com.cameleer3.server.app.dto;
|
||||
package com.cameleer.server.app.dto;
|
||||
|
||||
import java.time.Instant;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
@@ -193,7 +193,7 @@ public record MetricBucket(
|
||||
|
||||
`AgentMetricsResponse.java`:
|
||||
```java
|
||||
package com.cameleer3.server.app.dto;
|
||||
package com.cameleer.server.app.dto;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -207,10 +207,10 @@ public record AgentMetricsResponse(
|
||||
- [ ] **Step 2: Create AgentMetricsController**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.controller;
|
||||
package com.cameleer.server.app.controller;
|
||||
|
||||
import com.cameleer3.server.app.dto.AgentMetricsResponse;
|
||||
import com.cameleer3.server.app.dto.MetricBucket;
|
||||
import com.cameleer.server.app.dto.AgentMetricsResponse;
|
||||
import com.cameleer.server.app.dto.MetricBucket;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@@ -277,7 +277,7 @@ public class AgentMetricsController {
|
||||
|
||||
- [ ] **Step 3: Add SecurityConfig rule**
|
||||
|
||||
In `SecurityConfig.java` (path: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/SecurityConfig.java`), add a new matcher for the agent metrics path. Find the section with VIEWER role matchers and add:
|
||||
In `SecurityConfig.java` (path: `cameleer-server-app/src/main/java/com/cameleer/server/app/security/SecurityConfig.java`), add a new matcher for the agent metrics path. Find the section with VIEWER role matchers and add:
|
||||
```java
|
||||
.requestMatchers(HttpMethod.GET, "/api/v1/agents/*/metrics").hasAnyRole("VIEWER", "OPERATOR", "ADMIN")
|
||||
```
|
||||
@@ -295,11 +295,11 @@ Expected: BUILD SUCCESS
|
||||
- [ ] **Step 6: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/dto/MetricBucket.java \
|
||||
cameleer3-server-app/src/main/java/com/cameleer3/server/app/dto/AgentMetricsResponse.java \
|
||||
cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/AgentMetricsController.java \
|
||||
cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/SecurityConfig.java \
|
||||
cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/OpenApiConfig.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/dto/MetricBucket.java \
|
||||
cameleer-server-app/src/main/java/com/cameleer/server/app/dto/AgentMetricsResponse.java \
|
||||
cameleer-server-app/src/main/java/com/cameleer/server/app/controller/AgentMetricsController.java \
|
||||
cameleer-server-app/src/main/java/com/cameleer/server/app/security/SecurityConfig.java \
|
||||
cameleer-server-app/src/main/java/com/cameleer/server/app/config/OpenApiConfig.java
|
||||
git commit -m "feat: add GET /agents/{id}/metrics endpoint for JVM metrics"
|
||||
```
|
||||
|
||||
@@ -308,10 +308,10 @@ git commit -m "feat: add GET /agents/{id}/metrics endpoint for JVM metrics"
|
||||
## Task 4: Backend — Enrich AgentInstanceResponse + Password Reset
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/dto/AgentInstanceResponse.java`
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/AgentRegistrationController.java`
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/dto/SetPasswordRequest.java`
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/UserAdminController.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/dto/AgentInstanceResponse.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/AgentRegistrationController.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/dto/SetPasswordRequest.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/UserAdminController.java`
|
||||
|
||||
- [ ] **Step 1: Add fields to AgentInstanceResponse**
|
||||
|
||||
@@ -347,7 +347,7 @@ public AgentInstanceResponse withMetrics(double tps, double errorRate, int activ
|
||||
- [ ] **Step 2: Create SetPasswordRequest DTO**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.dto;
|
||||
package com.cameleer.server.app.dto;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
@@ -400,10 +400,10 @@ Expected: BUILD SUCCESS
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/dto/AgentInstanceResponse.java \
|
||||
cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/AgentRegistrationController.java \
|
||||
cameleer3-server-app/src/main/java/com/cameleer3/server/app/dto/SetPasswordRequest.java \
|
||||
cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/UserAdminController.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/dto/AgentInstanceResponse.java \
|
||||
cameleer-server-app/src/main/java/com/cameleer/server/app/controller/AgentRegistrationController.java \
|
||||
cameleer-server-app/src/main/java/com/cameleer/server/app/dto/SetPasswordRequest.java \
|
||||
cameleer-server-app/src/main/java/com/cameleer/server/app/controller/UserAdminController.java
|
||||
git commit -m "feat: enrich AgentInstanceResponse with version/capabilities, add password reset endpoint"
|
||||
```
|
||||
|
||||
|
||||
@@ -15,26 +15,26 @@
|
||||
## File Map
|
||||
|
||||
### Backend — New Files
|
||||
- `cameleer3-server-app/src/main/resources/db/migration/V5__attributes.sql` — Flyway migration adding `attributes JSONB` to executions and processor_executions tables
|
||||
- `cameleer3-server-app/src/main/java/com/cameleer3/server/app/dto/TestExpressionRequest.java` — Request DTO for test-expression endpoint
|
||||
- `cameleer3-server-app/src/main/java/com/cameleer3/server/app/dto/TestExpressionResponse.java` — Response DTO for test-expression endpoint
|
||||
- `cameleer-server-app/src/main/resources/db/migration/V5__attributes.sql` — Flyway migration adding `attributes JSONB` to executions and processor_executions tables
|
||||
- `cameleer-server-app/src/main/java/com/cameleer/server/app/dto/TestExpressionRequest.java` — Request DTO for test-expression endpoint
|
||||
- `cameleer-server-app/src/main/java/com/cameleer/server/app/dto/TestExpressionResponse.java` — Response DTO for test-expression endpoint
|
||||
|
||||
### Backend — Modified Files
|
||||
- `cameleer3-server-core/src/main/java/com/cameleer3/server/core/agent/CommandType.java` — add TEST_EXPRESSION
|
||||
- `cameleer3-server-core/src/main/java/com/cameleer3/server/core/storage/ExecutionStore.java` — add attributes to ExecutionRecord and ProcessorRecord
|
||||
- `cameleer3-server-core/src/main/java/com/cameleer3/server/core/detail/ExecutionDetail.java` — add attributes field
|
||||
- `cameleer3-server-core/src/main/java/com/cameleer3/server/core/detail/ProcessorNode.java` — add attributes field
|
||||
- `cameleer3-server-core/src/main/java/com/cameleer3/server/core/detail/DetailService.java` — pass attributes through tree reconstruction
|
||||
- `cameleer3-server-core/src/main/java/com/cameleer3/server/core/search/ExecutionSummary.java` — add attributes field
|
||||
- `cameleer3-server-core/src/main/java/com/cameleer3/server/core/ingestion/IngestionService.java` — extract attributes from RouteExecution/ProcessorExecution
|
||||
- `cameleer3-server-core/src/main/java/com/cameleer3/server/core/storage/model/ExecutionDocument.java` — add attributes to ProcessorDoc
|
||||
- `cameleer3-server-core/src/main/java/com/cameleer3/server/core/indexing/SearchIndexer.java` — include attributes in indexing
|
||||
- `cameleer3-server-core/src/main/java/com/cameleer3/server/core/agent/AgentRegistryService.java` — add CompletableFuture-based command reply support
|
||||
- `cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/PostgresExecutionStore.java` — add attributes to INSERT/UPDATE queries
|
||||
- `cameleer3-server-app/src/main/java/com/cameleer3/server/app/search/OpenSearchIndex.java` — add attributes to toMap() and fromSearchHit()
|
||||
- `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/ApplicationConfigController.java` — add test-expression endpoint
|
||||
- `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/AgentCommandController.java` — add test-expression mapping, complete futures on ACK
|
||||
- `cameleer3-server-app/src/main/java/com/cameleer3/server/app/dto/CommandAckRequest.java` — add optional data field
|
||||
- `cameleer-server-core/src/main/java/com/cameleer/server/core/agent/CommandType.java` — add TEST_EXPRESSION
|
||||
- `cameleer-server-core/src/main/java/com/cameleer/server/core/storage/ExecutionStore.java` — add attributes to ExecutionRecord and ProcessorRecord
|
||||
- `cameleer-server-core/src/main/java/com/cameleer/server/core/detail/ExecutionDetail.java` — add attributes field
|
||||
- `cameleer-server-core/src/main/java/com/cameleer/server/core/detail/ProcessorNode.java` — add attributes field
|
||||
- `cameleer-server-core/src/main/java/com/cameleer/server/core/detail/DetailService.java` — pass attributes through tree reconstruction
|
||||
- `cameleer-server-core/src/main/java/com/cameleer/server/core/search/ExecutionSummary.java` — add attributes field
|
||||
- `cameleer-server-core/src/main/java/com/cameleer/server/core/ingestion/IngestionService.java` — extract attributes from RouteExecution/ProcessorExecution
|
||||
- `cameleer-server-core/src/main/java/com/cameleer/server/core/storage/model/ExecutionDocument.java` — add attributes to ProcessorDoc
|
||||
- `cameleer-server-core/src/main/java/com/cameleer/server/core/indexing/SearchIndexer.java` — include attributes in indexing
|
||||
- `cameleer-server-core/src/main/java/com/cameleer/server/core/agent/AgentRegistryService.java` — add CompletableFuture-based command reply support
|
||||
- `cameleer-server-app/src/main/java/com/cameleer/server/app/storage/PostgresExecutionStore.java` — add attributes to INSERT/UPDATE queries
|
||||
- `cameleer-server-app/src/main/java/com/cameleer/server/app/search/OpenSearchIndex.java` — add attributes to toMap() and fromSearchHit()
|
||||
- `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/ApplicationConfigController.java` — add test-expression endpoint
|
||||
- `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/AgentCommandController.java` — add test-expression mapping, complete futures on ACK
|
||||
- `cameleer-server-app/src/main/java/com/cameleer/server/app/dto/CommandAckRequest.java` — add optional data field
|
||||
|
||||
### Frontend — Modified Files
|
||||
- `ui/src/api/schema.d.ts` — add attributes to ExecutionDetail, ProcessorNode, ExecutionSummary
|
||||
@@ -52,13 +52,13 @@
|
||||
## Task 1: Verify Prerequisites and Database Migration
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/main/resources/db/migration/V5__attributes.sql`
|
||||
- Create: `cameleer-server-app/src/main/resources/db/migration/V5__attributes.sql`
|
||||
|
||||
- [ ] **Step 1: Verify cameleer3-common has attributes support**
|
||||
- [ ] **Step 1: Verify cameleer-common has attributes support**
|
||||
|
||||
Confirm the `cameleer3-common` SNAPSHOT dependency includes `RouteExecution.getAttributes()` and `ProcessorExecution.getAttributes()`. Run:
|
||||
Confirm the `cameleer-common` SNAPSHOT dependency includes `RouteExecution.getAttributes()` and `ProcessorExecution.getAttributes()`. Run:
|
||||
```bash
|
||||
mvn dependency:sources -pl cameleer3-server-core -q
|
||||
mvn dependency:sources -pl cameleer-server-core -q
|
||||
```
|
||||
Then inspect the source jar for `RouteExecution.java` to confirm the `attributes` field exists. If it does not, the dependency must be updated first.
|
||||
|
||||
@@ -72,13 +72,13 @@ ALTER TABLE processor_executions ADD COLUMN IF NOT EXISTS attributes JSONB;
|
||||
|
||||
- [ ] **Step 3: Verify migration compiles**
|
||||
|
||||
Run: `cd cameleer3-server-app && mvn compile -pl . -q`
|
||||
Run: `cd cameleer-server-app && mvn compile -pl . -q`
|
||||
Expected: BUILD SUCCESS
|
||||
|
||||
- [ ] **Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/resources/db/migration/V5__attributes.sql
|
||||
git add cameleer-server-app/src/main/resources/db/migration/V5__attributes.sql
|
||||
git commit -m "feat: add attributes JSONB columns to executions and processor_executions"
|
||||
```
|
||||
|
||||
@@ -87,10 +87,10 @@ git commit -m "feat: add attributes JSONB columns to executions and processor_ex
|
||||
## Task 2: Backend — Add Attributes to Storage Records and Detail Models
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/storage/ExecutionStore.java`
|
||||
- Modify: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/detail/ExecutionDetail.java`
|
||||
- Modify: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/detail/ProcessorNode.java`
|
||||
- Modify: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/search/ExecutionSummary.java`
|
||||
- Modify: `cameleer-server-core/src/main/java/com/cameleer/server/core/storage/ExecutionStore.java`
|
||||
- Modify: `cameleer-server-core/src/main/java/com/cameleer/server/core/detail/ExecutionDetail.java`
|
||||
- Modify: `cameleer-server-core/src/main/java/com/cameleer/server/core/detail/ProcessorNode.java`
|
||||
- Modify: `cameleer-server-core/src/main/java/com/cameleer/server/core/search/ExecutionSummary.java`
|
||||
|
||||
- [ ] **Step 1: Add `attributes` field to `ExecutionRecord`**
|
||||
|
||||
@@ -120,7 +120,7 @@ Expected: Compilation errors in files that construct these records — these wil
|
||||
- [ ] **Step 7: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-core/
|
||||
git add cameleer-server-core/
|
||||
git commit -m "feat: add attributes field to ExecutionRecord, ProcessorRecord, ExecutionDetail, ProcessorNode, ExecutionSummary"
|
||||
```
|
||||
|
||||
@@ -129,8 +129,8 @@ git commit -m "feat: add attributes field to ExecutionRecord, ProcessorRecord, E
|
||||
## Task 3: Backend — Attributes Ingestion Pipeline
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/ingestion/IngestionService.java`
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/PostgresExecutionStore.java`
|
||||
- Modify: `cameleer-server-core/src/main/java/com/cameleer/server/core/ingestion/IngestionService.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/storage/PostgresExecutionStore.java`
|
||||
|
||||
- [ ] **Step 1: Extract attributes in `IngestionService.toExecutionRecord()`**
|
||||
|
||||
@@ -169,8 +169,8 @@ Expected: BUILD SUCCESS (or remaining errors from DetailService/SearchIndexer wh
|
||||
- [ ] **Step 6: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-core/src/main/java/com/cameleer3/server/core/ingestion/IngestionService.java
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/PostgresExecutionStore.java
|
||||
git add cameleer-server-core/src/main/java/com/cameleer/server/core/ingestion/IngestionService.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/storage/PostgresExecutionStore.java
|
||||
git commit -m "feat: store execution and processor attributes from agent data"
|
||||
```
|
||||
|
||||
@@ -179,10 +179,10 @@ git commit -m "feat: store execution and processor attributes from agent data"
|
||||
## Task 4: Backend — Attributes in Detail Service and OpenSearch Indexing
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/detail/DetailService.java`
|
||||
- Modify: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/storage/model/ExecutionDocument.java`
|
||||
- Modify: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/indexing/SearchIndexer.java`
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/search/OpenSearchIndex.java`
|
||||
- Modify: `cameleer-server-core/src/main/java/com/cameleer/server/core/detail/DetailService.java`
|
||||
- Modify: `cameleer-server-core/src/main/java/com/cameleer/server/core/storage/model/ExecutionDocument.java`
|
||||
- Modify: `cameleer-server-core/src/main/java/com/cameleer/server/core/indexing/SearchIndexer.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/search/OpenSearchIndex.java`
|
||||
|
||||
- [ ] **Step 1: Pass attributes through `DetailService.buildTree()`**
|
||||
|
||||
@@ -218,7 +218,7 @@ Expected: BUILD SUCCESS
|
||||
- [ ] **Step 8: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-core/ cameleer3-server-app/
|
||||
git add cameleer-server-core/ cameleer-server-app/
|
||||
git commit -m "feat: thread attributes through detail service and OpenSearch indexing"
|
||||
```
|
||||
|
||||
@@ -227,13 +227,13 @@ git commit -m "feat: thread attributes through detail service and OpenSearch ind
|
||||
## Task 5: Backend — TEST_EXPRESSION Command and Request-Reply Infrastructure
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/agent/CommandType.java`
|
||||
- Modify: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/agent/AgentRegistryService.java`
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/dto/CommandAckRequest.java`
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/AgentCommandController.java`
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/dto/TestExpressionRequest.java`
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/dto/TestExpressionResponse.java`
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/ApplicationConfigController.java`
|
||||
- Modify: `cameleer-server-core/src/main/java/com/cameleer/server/core/agent/CommandType.java`
|
||||
- Modify: `cameleer-server-core/src/main/java/com/cameleer/server/core/agent/AgentRegistryService.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/dto/CommandAckRequest.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/AgentCommandController.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/dto/TestExpressionRequest.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/dto/TestExpressionResponse.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/ApplicationConfigController.java`
|
||||
|
||||
- [ ] **Step 1: Add TEST_EXPRESSION to CommandType enum**
|
||||
|
||||
@@ -327,7 +327,7 @@ Expected: BUILD SUCCESS
|
||||
- [ ] **Step 9: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-core/ cameleer3-server-app/
|
||||
git add cameleer-server-core/ cameleer-server-app/
|
||||
git commit -m "feat: add TEST_EXPRESSION command with request-reply infrastructure"
|
||||
```
|
||||
|
||||
|
||||
@@ -18,13 +18,13 @@
|
||||
|
||||
| Action | File | Responsibility |
|
||||
|--------|------|---------------|
|
||||
| Create | `cameleer3-server-app/src/main/resources/db/migration/V8__processor_iteration_fields.sql` | Add iteration columns to processor_executions |
|
||||
| Modify | `cameleer3-server-core/.../storage/ExecutionStore.java` | Extend ProcessorRecord with iteration fields |
|
||||
| Modify | `cameleer3-server-app/.../storage/PostgresExecutionStore.java` | Update SQL queries for new columns |
|
||||
| Modify | `cameleer3-server-core/.../ingestion/IngestionService.java` | Store iteration fields during ingestion |
|
||||
| Modify | `cameleer3-server-core/.../detail/ProcessorNode.java` | Add iteration fields to detail model |
|
||||
| Modify | `cameleer3-server-core/.../detail/DetailService.java` | Pass iteration fields through tree builder |
|
||||
| Modify | `cameleer3-server-app/.../controller/DetailController.java` | Add snapshot-by-processorId endpoint |
|
||||
| Create | `cameleer-server-app/src/main/resources/db/migration/V8__processor_iteration_fields.sql` | Add iteration columns to processor_executions |
|
||||
| Modify | `cameleer-server-core/.../storage/ExecutionStore.java` | Extend ProcessorRecord with iteration fields |
|
||||
| Modify | `cameleer-server-app/.../storage/PostgresExecutionStore.java` | Update SQL queries for new columns |
|
||||
| Modify | `cameleer-server-core/.../ingestion/IngestionService.java` | Store iteration fields during ingestion |
|
||||
| Modify | `cameleer-server-core/.../detail/ProcessorNode.java` | Add iteration fields to detail model |
|
||||
| Modify | `cameleer-server-core/.../detail/DetailService.java` | Pass iteration fields through tree builder |
|
||||
| Modify | `cameleer-server-app/.../controller/DetailController.java` | Add snapshot-by-processorId endpoint |
|
||||
|
||||
### Frontend Changes
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before starting, verify that the `cameleer3-common` dependency (in the agent repo) exposes iteration getters on `ProcessorExecution`: `getLoopIndex()`, `getLoopSize()`, `getSplitIndex()`, `getSplitSize()`, `getMulticastIndex()`. If these methods do not exist in the current published version, they must be added to `cameleer3-common` and a new SNAPSHOT or release published before Task 1 Step 4 can work. Check `cameleer3/cameleer3-common/src/main/java/com/cameleer3/common/model/ProcessorExecution.java`.
|
||||
Before starting, verify that the `cameleer-common` dependency (in the agent repo) exposes iteration getters on `ProcessorExecution`: `getLoopIndex()`, `getLoopSize()`, `getSplitIndex()`, `getSplitSize()`, `getMulticastIndex()`. If these methods do not exist in the current published version, they must be added to `cameleer-common` and a new SNAPSHOT or release published before Task 1 Step 4 can work. Check `cameleer/cameleer-common/src/main/java/com/cameleer/common/model/ProcessorExecution.java`.
|
||||
|
||||
Note on migration versioning: The next migration is V8. If other work merges before this plan executes, bump the version number accordingly.
|
||||
|
||||
@@ -72,12 +72,12 @@ Note on migration versioning: The next migration is V8. If other work merges bef
|
||||
Add `loop_index`, `loop_size`, `split_index`, `split_size`, `multicast_index` columns to the database and thread them through the storage → ingestion → detail pipeline.
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/main/resources/db/migration/V8__processor_iteration_fields.sql`
|
||||
- Modify: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/storage/ExecutionStore.java`
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/PostgresExecutionStore.java`
|
||||
- Modify: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/ingestion/IngestionService.java`
|
||||
- Modify: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/detail/ProcessorNode.java`
|
||||
- Modify: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/detail/DetailService.java`
|
||||
- Create: `cameleer-server-app/src/main/resources/db/migration/V8__processor_iteration_fields.sql`
|
||||
- Modify: `cameleer-server-core/src/main/java/com/cameleer/server/core/storage/ExecutionStore.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/storage/PostgresExecutionStore.java`
|
||||
- Modify: `cameleer-server-core/src/main/java/com/cameleer/server/core/ingestion/IngestionService.java`
|
||||
- Modify: `cameleer-server-core/src/main/java/com/cameleer/server/core/detail/ProcessorNode.java`
|
||||
- Modify: `cameleer-server-core/src/main/java/com/cameleer/server/core/detail/DetailService.java`
|
||||
|
||||
- [ ] **Step 1: Create Flyway migration V8**
|
||||
|
||||
@@ -176,12 +176,12 @@ Expected: BUILD SUCCESS
|
||||
- [ ] **Step 8: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/resources/db/migration/V8__processor_iteration_fields.sql \
|
||||
cameleer3-server-core/src/main/java/com/cameleer3/server/core/storage/ExecutionStore.java \
|
||||
cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/PostgresExecutionStore.java \
|
||||
cameleer3-server-core/src/main/java/com/cameleer3/server/core/ingestion/IngestionService.java \
|
||||
cameleer3-server-core/src/main/java/com/cameleer3/server/core/detail/ProcessorNode.java \
|
||||
cameleer3-server-core/src/main/java/com/cameleer3/server/core/detail/DetailService.java
|
||||
git add cameleer-server-app/src/main/resources/db/migration/V8__processor_iteration_fields.sql \
|
||||
cameleer-server-core/src/main/java/com/cameleer/server/core/storage/ExecutionStore.java \
|
||||
cameleer-server-app/src/main/java/com/cameleer/server/app/storage/PostgresExecutionStore.java \
|
||||
cameleer-server-core/src/main/java/com/cameleer/server/core/ingestion/IngestionService.java \
|
||||
cameleer-server-core/src/main/java/com/cameleer/server/core/detail/ProcessorNode.java \
|
||||
cameleer-server-core/src/main/java/com/cameleer/server/core/detail/DetailService.java
|
||||
git commit -m "feat: add iteration fields to processor storage and detail model"
|
||||
```
|
||||
|
||||
@@ -192,10 +192,10 @@ git commit -m "feat: add iteration fields to processor storage and detail model"
|
||||
Add a REST endpoint that fetches processor snapshot data by processorId instead of positional index.
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/storage/ExecutionStore.java`
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/PostgresExecutionStore.java`
|
||||
- Modify: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/detail/DetailService.java`
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/DetailController.java`
|
||||
- Modify: `cameleer-server-core/src/main/java/com/cameleer/server/core/storage/ExecutionStore.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/storage/PostgresExecutionStore.java`
|
||||
- Modify: `cameleer-server-core/src/main/java/com/cameleer/server/core/detail/DetailService.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/DetailController.java`
|
||||
|
||||
- [ ] **Step 1: Add findProcessorById to ExecutionStore interface**
|
||||
|
||||
@@ -251,10 +251,10 @@ Expected: BUILD SUCCESS
|
||||
- [ ] **Step 6: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-core/src/main/java/com/cameleer3/server/core/storage/ExecutionStore.java \
|
||||
cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/PostgresExecutionStore.java \
|
||||
cameleer3-server-core/src/main/java/com/cameleer3/server/core/detail/DetailService.java \
|
||||
cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/DetailController.java
|
||||
git add cameleer-server-core/src/main/java/com/cameleer/server/core/storage/ExecutionStore.java \
|
||||
cameleer-server-app/src/main/java/com/cameleer/server/app/storage/PostgresExecutionStore.java \
|
||||
cameleer-server-core/src/main/java/com/cameleer/server/core/detail/DetailService.java \
|
||||
cameleer-server-app/src/main/java/com/cameleer/server/app/controller/DetailController.java
|
||||
git commit -m "feat: add snapshot-by-processorId endpoint"
|
||||
```
|
||||
|
||||
@@ -274,7 +274,7 @@ Run the server locally, then fetch the OpenAPI spec:
|
||||
|
||||
```bash
|
||||
# Build and run
|
||||
cd cameleer3-server-app && mvn spring-boot:run -DskipTests &
|
||||
cd cameleer-server-app && mvn spring-boot:run -DskipTests &
|
||||
# Wait for startup, then fetch
|
||||
curl -s http://localhost:8080/v3/api-docs | python3 -m json.tool > ui/src/api/openapi.json
|
||||
```
|
||||
|
||||
@@ -16,20 +16,20 @@
|
||||
|
||||
| Action | File | Responsibility |
|
||||
|--------|------|----------------|
|
||||
| Modify | `cameleer3-server-app/pom.xml` | Add clickhouse-jdbc + testcontainers-clickhouse dependencies |
|
||||
| Modify | `cameleer3-server-app/src/main/resources/application.yml` | Add `clickhouse.*` and `cameleer.storage.metrics` config keys |
|
||||
| Create | `cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/ClickHouseConfig.java` | ClickHouse DataSource + JdbcTemplate beans |
|
||||
| Create | `cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/ClickHouseProperties.java` | Config properties class for `clickhouse.*` prefix |
|
||||
| Create | `cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/ClickHouseSchemaInitializer.java` | Runs idempotent DDL on startup |
|
||||
| Create | `cameleer3-server-app/src/main/resources/clickhouse/V1__agent_metrics.sql` | DDL for `agent_metrics` table |
|
||||
| Create | `cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/ClickHouseMetricsStore.java` | `MetricsStore` impl writing to ClickHouse |
|
||||
| Create | `cameleer3-server-core/src/main/java/com/cameleer3/server/core/storage/MetricsQueryStore.java` | Interface: query metrics time-series |
|
||||
| Create | `cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/PostgresMetricsQueryStore.java` | PG impl of MetricsQueryStore (extracted from controller) |
|
||||
| Create | `cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/ClickHouseMetricsQueryStore.java` | CH impl of MetricsQueryStore |
|
||||
| Modify | `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/AgentMetricsController.java` | Use MetricsQueryStore instead of raw JdbcTemplate |
|
||||
| Modify | `cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/StorageBeanConfig.java` | Conditional beans for PG vs CH metrics stores |
|
||||
| Create | `cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/ClickHouseMetricsStoreTest.java` | Unit test |
|
||||
| Create | `cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/ClickHouseMetricsQueryStoreTest.java` | Unit test |
|
||||
| Modify | `cameleer-server-app/pom.xml` | Add clickhouse-jdbc + testcontainers-clickhouse dependencies |
|
||||
| Modify | `cameleer-server-app/src/main/resources/application.yml` | Add `clickhouse.*` and `cameleer.storage.metrics` config keys |
|
||||
| Create | `cameleer-server-app/src/main/java/com/cameleer/server/app/config/ClickHouseConfig.java` | ClickHouse DataSource + JdbcTemplate beans |
|
||||
| Create | `cameleer-server-app/src/main/java/com/cameleer/server/app/config/ClickHouseProperties.java` | Config properties class for `clickhouse.*` prefix |
|
||||
| Create | `cameleer-server-app/src/main/java/com/cameleer/server/app/config/ClickHouseSchemaInitializer.java` | Runs idempotent DDL on startup |
|
||||
| Create | `cameleer-server-app/src/main/resources/clickhouse/V1__agent_metrics.sql` | DDL for `agent_metrics` table |
|
||||
| Create | `cameleer-server-app/src/main/java/com/cameleer/server/app/storage/ClickHouseMetricsStore.java` | `MetricsStore` impl writing to ClickHouse |
|
||||
| Create | `cameleer-server-core/src/main/java/com/cameleer/server/core/storage/MetricsQueryStore.java` | Interface: query metrics time-series |
|
||||
| Create | `cameleer-server-app/src/main/java/com/cameleer/server/app/storage/PostgresMetricsQueryStore.java` | PG impl of MetricsQueryStore (extracted from controller) |
|
||||
| Create | `cameleer-server-app/src/main/java/com/cameleer/server/app/storage/ClickHouseMetricsQueryStore.java` | CH impl of MetricsQueryStore |
|
||||
| Modify | `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/AgentMetricsController.java` | Use MetricsQueryStore instead of raw JdbcTemplate |
|
||||
| Modify | `cameleer-server-app/src/main/java/com/cameleer/server/app/config/StorageBeanConfig.java` | Conditional beans for PG vs CH metrics stores |
|
||||
| Create | `cameleer-server-app/src/test/java/com/cameleer/server/app/storage/ClickHouseMetricsStoreTest.java` | Unit test |
|
||||
| Create | `cameleer-server-app/src/test/java/com/cameleer/server/app/storage/ClickHouseMetricsQueryStoreTest.java` | Unit test |
|
||||
| Create | `deploy/clickhouse.yaml` | K8s StatefulSet + Service for ClickHouse |
|
||||
| Modify | `deploy/base/server.yaml` | Add CLICKHOUSE_URL env var |
|
||||
|
||||
@@ -38,11 +38,11 @@
|
||||
### Task 1: Add ClickHouse Dependencies
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-app/pom.xml`
|
||||
- Modify: `cameleer-server-app/pom.xml`
|
||||
|
||||
- [ ] **Step 1: Add clickhouse-jdbc and testcontainers-clickhouse to app POM**
|
||||
|
||||
In `cameleer3-server-app/pom.xml`, add these two dependencies. Place the runtime dependency after the opensearch dependencies (around line 59), and the test dependency after the opensearch-testcontainers dependency (around line 128):
|
||||
In `cameleer-server-app/pom.xml`, add these two dependencies. Place the runtime dependency after the opensearch dependencies (around line 59), and the test dependency after the opensearch-testcontainers dependency (around line 128):
|
||||
|
||||
```xml
|
||||
<!-- After opensearch-rest-client dependency, ~line 59 -->
|
||||
@@ -65,13 +65,13 @@ Note: The `all` classifier bundles the HTTP client, avoiding transitive dependen
|
||||
|
||||
- [ ] **Step 2: Verify compilation**
|
||||
|
||||
Run: `mvn clean compile -pl cameleer3-server-app -am`
|
||||
Run: `mvn clean compile -pl cameleer-server-app -am`
|
||||
Expected: BUILD SUCCESS
|
||||
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/pom.xml
|
||||
git add cameleer-server-app/pom.xml
|
||||
git commit -m "build: add clickhouse-jdbc and testcontainers-clickhouse dependencies"
|
||||
```
|
||||
|
||||
@@ -80,14 +80,14 @@ git commit -m "build: add clickhouse-jdbc and testcontainers-clickhouse dependen
|
||||
### Task 2: ClickHouse Configuration
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/ClickHouseProperties.java`
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/ClickHouseConfig.java`
|
||||
- Modify: `cameleer3-server-app/src/main/resources/application.yml`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/config/ClickHouseProperties.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/config/ClickHouseConfig.java`
|
||||
- Modify: `cameleer-server-app/src/main/resources/application.yml`
|
||||
|
||||
- [ ] **Step 1: Create ClickHouseProperties**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.config;
|
||||
package com.cameleer.server.app.config;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
@@ -112,7 +112,7 @@ public class ClickHouseProperties {
|
||||
- [ ] **Step 2: Create ClickHouseConfig**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.config;
|
||||
package com.cameleer.server.app.config;
|
||||
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
@@ -168,15 +168,15 @@ Note: The existing `cameleer:` block already has `body-size-limit` and `retentio
|
||||
|
||||
- [ ] **Step 4: Verify compilation**
|
||||
|
||||
Run: `mvn clean compile -pl cameleer3-server-app -am`
|
||||
Run: `mvn clean compile -pl cameleer-server-app -am`
|
||||
Expected: BUILD SUCCESS
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/ClickHouseProperties.java
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/ClickHouseConfig.java
|
||||
git add cameleer3-server-app/src/main/resources/application.yml
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/config/ClickHouseProperties.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/config/ClickHouseConfig.java
|
||||
git add cameleer-server-app/src/main/resources/application.yml
|
||||
git commit -m "feat: add ClickHouse DataSource and JdbcTemplate configuration"
|
||||
```
|
||||
|
||||
@@ -185,12 +185,12 @@ git commit -m "feat: add ClickHouse DataSource and JdbcTemplate configuration"
|
||||
### Task 3: Schema Initializer + DDL Script
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/main/resources/clickhouse/V1__agent_metrics.sql`
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/ClickHouseSchemaInitializer.java`
|
||||
- Create: `cameleer-server-app/src/main/resources/clickhouse/V1__agent_metrics.sql`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/config/ClickHouseSchemaInitializer.java`
|
||||
|
||||
- [ ] **Step 1: Create DDL script**
|
||||
|
||||
File: `cameleer3-server-app/src/main/resources/clickhouse/V1__agent_metrics.sql`
|
||||
File: `cameleer-server-app/src/main/resources/clickhouse/V1__agent_metrics.sql`
|
||||
|
||||
```sql
|
||||
CREATE TABLE IF NOT EXISTS agent_metrics (
|
||||
@@ -212,7 +212,7 @@ SETTINGS index_granularity = 8192;
|
||||
- [ ] **Step 2: Create ClickHouseSchemaInitializer**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.config;
|
||||
package com.cameleer.server.app.config;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -268,14 +268,14 @@ public class ClickHouseSchemaInitializer {
|
||||
|
||||
- [ ] **Step 3: Verify compilation**
|
||||
|
||||
Run: `mvn clean compile -pl cameleer3-server-app -am`
|
||||
Run: `mvn clean compile -pl cameleer-server-app -am`
|
||||
Expected: BUILD SUCCESS
|
||||
|
||||
- [ ] **Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/resources/clickhouse/V1__agent_metrics.sql
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/ClickHouseSchemaInitializer.java
|
||||
git add cameleer-server-app/src/main/resources/clickhouse/V1__agent_metrics.sql
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/config/ClickHouseSchemaInitializer.java
|
||||
git commit -m "feat: add ClickHouse schema initializer with agent_metrics DDL"
|
||||
```
|
||||
|
||||
@@ -284,15 +284,15 @@ git commit -m "feat: add ClickHouse schema initializer with agent_metrics DDL"
|
||||
### Task 4: ClickHouseMetricsStore (TDD)
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/ClickHouseMetricsStoreTest.java`
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/ClickHouseMetricsStore.java`
|
||||
- Create: `cameleer-server-app/src/test/java/com/cameleer/server/app/storage/ClickHouseMetricsStoreTest.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/storage/ClickHouseMetricsStore.java`
|
||||
|
||||
- [ ] **Step 1: Write the failing test**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.storage;
|
||||
package com.cameleer.server.app.storage;
|
||||
|
||||
import com.cameleer3.server.core.storage.model.MetricsSnapshot;
|
||||
import com.cameleer.server.core.storage.model.MetricsSnapshot;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
@@ -406,16 +406,16 @@ class ClickHouseMetricsStoreTest {
|
||||
|
||||
- [ ] **Step 2: Run test to verify it fails**
|
||||
|
||||
Run: `mvn test -pl cameleer3-server-app -Dtest=ClickHouseMetricsStoreTest -DfailIfNoTests=false`
|
||||
Run: `mvn test -pl cameleer-server-app -Dtest=ClickHouseMetricsStoreTest -DfailIfNoTests=false`
|
||||
Expected: FAIL — `ClickHouseMetricsStore` class does not exist
|
||||
|
||||
- [ ] **Step 3: Write ClickHouseMetricsStore**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.storage;
|
||||
package com.cameleer.server.app.storage;
|
||||
|
||||
import com.cameleer3.server.core.storage.MetricsStore;
|
||||
import com.cameleer3.server.core.storage.model.MetricsSnapshot;
|
||||
import com.cameleer.server.core.storage.MetricsStore;
|
||||
import com.cameleer.server.core.storage.model.MetricsSnapshot;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
@@ -459,7 +459,7 @@ Note: ClickHouse JDBC driver handles `Map<String, String>` natively for `Map(Str
|
||||
|
||||
- [ ] **Step 4: Run test to verify it passes**
|
||||
|
||||
Run: `mvn test -pl cameleer3-server-app -Dtest=ClickHouseMetricsStoreTest`
|
||||
Run: `mvn test -pl cameleer-server-app -Dtest=ClickHouseMetricsStoreTest`
|
||||
Expected: PASS — all 4 tests green
|
||||
|
||||
If the tags test fails due to JDBC Map handling, adjust `tagsToClickHouseMap` to return a `java.util.HashMap` (ClickHouse JDBC requires a mutable map). If needed, wrap: `return new HashMap<>(tags)`.
|
||||
@@ -467,8 +467,8 @@ If the tags test fails due to JDBC Map handling, adjust `tagsToClickHouseMap` to
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/ClickHouseMetricsStoreTest.java
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/ClickHouseMetricsStore.java
|
||||
git add cameleer-server-app/src/test/java/com/cameleer/server/app/storage/ClickHouseMetricsStoreTest.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/storage/ClickHouseMetricsStore.java
|
||||
git commit -m "feat: add ClickHouseMetricsStore with batch insert"
|
||||
```
|
||||
|
||||
@@ -479,16 +479,16 @@ git commit -m "feat: add ClickHouseMetricsStore with batch insert"
|
||||
Extract the query logic from `AgentMetricsController` into an interface.
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/storage/MetricsQueryStore.java`
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/PostgresMetricsQueryStore.java`
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/AgentMetricsController.java`
|
||||
- Create: `cameleer-server-core/src/main/java/com/cameleer/server/core/storage/MetricsQueryStore.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/storage/PostgresMetricsQueryStore.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/AgentMetricsController.java`
|
||||
|
||||
- [ ] **Step 1: Create MetricsQueryStore interface**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.core.storage;
|
||||
package com.cameleer.server.core.storage;
|
||||
|
||||
import com.cameleer3.server.core.storage.model.MetricTimeSeries;
|
||||
import com.cameleer.server.core.storage.model.MetricTimeSeries;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
@@ -515,7 +515,7 @@ public interface MetricsQueryStore {
|
||||
- [ ] **Step 2: Create MetricTimeSeries.Bucket record**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.core.storage.model;
|
||||
package com.cameleer.server.core.storage.model;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
@@ -529,10 +529,10 @@ public record MetricTimeSeries(String metricName, List<Bucket> buckets) {
|
||||
- [ ] **Step 3: Create PostgresMetricsQueryStore (extract from controller)**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.storage;
|
||||
package com.cameleer.server.app.storage;
|
||||
|
||||
import com.cameleer3.server.core.storage.MetricsQueryStore;
|
||||
import com.cameleer3.server.core.storage.model.MetricTimeSeries;
|
||||
import com.cameleer.server.core.storage.MetricsQueryStore;
|
||||
import com.cameleer.server.core.storage.model.MetricTimeSeries;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
@@ -591,12 +591,12 @@ public class PostgresMetricsQueryStore implements MetricsQueryStore {
|
||||
Replace the entire `AgentMetricsController.java` content:
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.controller;
|
||||
package com.cameleer.server.app.controller;
|
||||
|
||||
import com.cameleer3.server.app.dto.AgentMetricsResponse;
|
||||
import com.cameleer3.server.app.dto.MetricBucket;
|
||||
import com.cameleer3.server.core.storage.MetricsQueryStore;
|
||||
import com.cameleer3.server.core.storage.model.MetricTimeSeries;
|
||||
import com.cameleer.server.app.dto.AgentMetricsResponse;
|
||||
import com.cameleer.server.app.dto.MetricBucket;
|
||||
import com.cameleer.server.core.storage.MetricsQueryStore;
|
||||
import com.cameleer.server.core.storage.model.MetricTimeSeries;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.time.Instant;
|
||||
@@ -650,8 +650,8 @@ public class AgentMetricsController {
|
||||
The refactored `AgentMetricsController` needs a `MetricsQueryStore` bean. Add this to `StorageBeanConfig.java`:
|
||||
|
||||
```java
|
||||
import com.cameleer3.server.app.storage.PostgresMetricsQueryStore;
|
||||
import com.cameleer3.server.core.storage.MetricsQueryStore;
|
||||
import com.cameleer.server.app.storage.PostgresMetricsQueryStore;
|
||||
import com.cameleer.server.core.storage.MetricsQueryStore;
|
||||
|
||||
// Add this bean method:
|
||||
@Bean
|
||||
@@ -664,17 +664,17 @@ This creates the PG implementation as the default. Task 7 will replace this with
|
||||
|
||||
- [ ] **Step 6: Verify compilation**
|
||||
|
||||
Run: `mvn clean compile -pl cameleer3-server-app -am`
|
||||
Run: `mvn clean compile -pl cameleer-server-app -am`
|
||||
Expected: BUILD SUCCESS
|
||||
|
||||
- [ ] **Step 7: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-core/src/main/java/com/cameleer3/server/core/storage/MetricsQueryStore.java
|
||||
git add cameleer3-server-core/src/main/java/com/cameleer3/server/core/storage/model/MetricTimeSeries.java
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/PostgresMetricsQueryStore.java
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/AgentMetricsController.java
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/StorageBeanConfig.java
|
||||
git add cameleer-server-core/src/main/java/com/cameleer/server/core/storage/MetricsQueryStore.java
|
||||
git add cameleer-server-core/src/main/java/com/cameleer/server/core/storage/model/MetricTimeSeries.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/storage/PostgresMetricsQueryStore.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/controller/AgentMetricsController.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/config/StorageBeanConfig.java
|
||||
git commit -m "refactor: extract MetricsQueryStore interface from AgentMetricsController"
|
||||
```
|
||||
|
||||
@@ -683,15 +683,15 @@ git commit -m "refactor: extract MetricsQueryStore interface from AgentMetricsCo
|
||||
### Task 6: ClickHouseMetricsQueryStore (TDD)
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/ClickHouseMetricsQueryStoreTest.java`
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/ClickHouseMetricsQueryStore.java`
|
||||
- Create: `cameleer-server-app/src/test/java/com/cameleer/server/app/storage/ClickHouseMetricsQueryStoreTest.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/storage/ClickHouseMetricsQueryStore.java`
|
||||
|
||||
- [ ] **Step 1: Write the failing test**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.storage;
|
||||
package com.cameleer.server.app.storage;
|
||||
|
||||
import com.cameleer3.server.core.storage.model.MetricTimeSeries;
|
||||
import com.cameleer.server.core.storage.model.MetricTimeSeries;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -807,16 +807,16 @@ class ClickHouseMetricsQueryStoreTest {
|
||||
|
||||
- [ ] **Step 2: Run test to verify it fails**
|
||||
|
||||
Run: `mvn test -pl cameleer3-server-app -Dtest=ClickHouseMetricsQueryStoreTest -DfailIfNoTests=false`
|
||||
Run: `mvn test -pl cameleer-server-app -Dtest=ClickHouseMetricsQueryStoreTest -DfailIfNoTests=false`
|
||||
Expected: FAIL — `ClickHouseMetricsQueryStore` class does not exist
|
||||
|
||||
- [ ] **Step 3: Write ClickHouseMetricsQueryStore**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.storage;
|
||||
package com.cameleer.server.app.storage;
|
||||
|
||||
import com.cameleer3.server.core.storage.MetricsQueryStore;
|
||||
import com.cameleer3.server.core.storage.model.MetricTimeSeries;
|
||||
import com.cameleer.server.core.storage.MetricsQueryStore;
|
||||
import com.cameleer.server.core.storage.model.MetricTimeSeries;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
|
||||
import java.time.Instant;
|
||||
@@ -896,14 +896,14 @@ public class ClickHouseMetricsQueryStore implements MetricsQueryStore {
|
||||
|
||||
- [ ] **Step 4: Run test to verify it passes**
|
||||
|
||||
Run: `mvn test -pl cameleer3-server-app -Dtest=ClickHouseMetricsQueryStoreTest`
|
||||
Run: `mvn test -pl cameleer-server-app -Dtest=ClickHouseMetricsQueryStoreTest`
|
||||
Expected: PASS — all 4 tests green
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/ClickHouseMetricsQueryStoreTest.java
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/ClickHouseMetricsQueryStore.java
|
||||
git add cameleer-server-app/src/test/java/com/cameleer/server/app/storage/ClickHouseMetricsQueryStoreTest.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/storage/ClickHouseMetricsQueryStore.java
|
||||
git commit -m "feat: add ClickHouseMetricsQueryStore with time-bucketed queries"
|
||||
```
|
||||
|
||||
@@ -912,17 +912,17 @@ git commit -m "feat: add ClickHouseMetricsQueryStore with time-bucketed queries"
|
||||
### Task 7: Wire Feature Flag in StorageBeanConfig
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/StorageBeanConfig.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/config/StorageBeanConfig.java`
|
||||
|
||||
- [ ] **Step 1: Replace simple beans with conditional MetricsStore and MetricsQueryStore beans**
|
||||
|
||||
In `StorageBeanConfig.java`, **remove** the unconditional `metricsQueryStore` bean added in Task 5. Replace with these conditional bean definitions:
|
||||
|
||||
```java
|
||||
import com.cameleer3.server.app.storage.ClickHouseMetricsStore;
|
||||
import com.cameleer3.server.app.storage.ClickHouseMetricsQueryStore;
|
||||
import com.cameleer3.server.app.storage.PostgresMetricsQueryStore;
|
||||
import com.cameleer3.server.core.storage.MetricsQueryStore;
|
||||
import com.cameleer.server.app.storage.ClickHouseMetricsStore;
|
||||
import com.cameleer.server.app.storage.ClickHouseMetricsQueryStore;
|
||||
import com.cameleer.server.app.storage.PostgresMetricsQueryStore;
|
||||
import com.cameleer.server.core.storage.MetricsQueryStore;
|
||||
|
||||
// ... existing beans ...
|
||||
|
||||
@@ -959,7 +959,7 @@ Add the necessary imports to `StorageBeanConfig.java`:
|
||||
```java
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import com.cameleer3.server.core.storage.MetricsStore;
|
||||
import com.cameleer.server.core.storage.MetricsStore;
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Remove @Repository from PostgresMetricsStore**
|
||||
@@ -968,19 +968,19 @@ In `PostgresMetricsStore.java`, remove the `@Repository` annotation from the cla
|
||||
|
||||
- [ ] **Step 3: Verify compilation**
|
||||
|
||||
Run: `mvn clean compile -pl cameleer3-server-app -am`
|
||||
Run: `mvn clean compile -pl cameleer-server-app -am`
|
||||
Expected: BUILD SUCCESS
|
||||
|
||||
- [ ] **Step 4: Run existing tests to verify no regression**
|
||||
|
||||
Run: `mvn test -pl cameleer3-server-app`
|
||||
Run: `mvn test -pl cameleer-server-app`
|
||||
Expected: All existing tests pass. The default config (`cameleer.storage.metrics=postgres`) means the PG beans are created, ClickHouse beans are not (ClickHouse DataSource not needed).
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/StorageBeanConfig.java
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/PostgresMetricsStore.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/config/StorageBeanConfig.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/storage/PostgresMetricsStore.java
|
||||
git commit -m "feat: wire MetricsStore and MetricsQueryStore with feature flag"
|
||||
```
|
||||
|
||||
@@ -1076,7 +1076,7 @@ spec:
|
||||
|
||||
- [ ] **Step 2: Add ClickHouse env vars to server.yaml**
|
||||
|
||||
Add these env vars to the `cameleer3-server` container in `deploy/base/server.yaml`, after the existing env vars (before `resources:`):
|
||||
Add these env vars to the `cameleer-server` container in `deploy/base/server.yaml`, after the existing env vars (before `resources:`):
|
||||
|
||||
```yaml
|
||||
- name: CLICKHOUSE_ENABLED
|
||||
@@ -1102,7 +1102,7 @@ git commit -m "deploy: add ClickHouse StatefulSet and server env vars"
|
||||
### Task 9: Integration Smoke Test
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-app/src/test/java/com/cameleer3/server/app/AbstractPostgresIT.java` (add ClickHouse container)
|
||||
- Modify: `cameleer-server-app/src/test/java/com/cameleer/server/app/AbstractPostgresIT.java` (add ClickHouse container)
|
||||
|
||||
- [ ] **Step 1: Update AbstractPostgresIT to optionally start ClickHouse**
|
||||
|
||||
@@ -1129,13 +1129,13 @@ registry.add("clickhouse.password", clickhouse::getPassword);
|
||||
|
||||
- [ ] **Step 2: Run all integration tests**
|
||||
|
||||
Run: `mvn verify -pl cameleer3-server-app`
|
||||
Run: `mvn verify -pl cameleer-server-app`
|
||||
Expected: All ITs pass. ClickHouse schema initializer runs and creates the `agent_metrics` table. The `MetricsControllerIT` still uses PG (default storage flag is `postgres`).
|
||||
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/test/java/com/cameleer3/server/app/AbstractPostgresIT.java
|
||||
git add cameleer-server-app/src/test/java/com/cameleer/server/app/AbstractPostgresIT.java
|
||||
git commit -m "test: add ClickHouse testcontainer to integration test base"
|
||||
```
|
||||
|
||||
@@ -1162,7 +1162,7 @@ curl "http://localhost:8123/" --data "CREATE DATABASE IF NOT EXISTS cameleer"
|
||||
|
||||
Start the server with ClickHouse enabled:
|
||||
```bash
|
||||
CLICKHOUSE_ENABLED=true CAMELEER_STORAGE_METRICS=clickhouse java -jar cameleer3-server-app/target/cameleer3-server-app-1.0-SNAPSHOT.jar
|
||||
CLICKHOUSE_ENABLED=true CAMELEER_STORAGE_METRICS=clickhouse java -jar cameleer-server-app/target/cameleer-server-app-1.0-SNAPSHOT.jar
|
||||
```
|
||||
|
||||
Verify schema initialization in the logs: `Executing ClickHouse schema script: V1__agent_metrics.sql`
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
**Design Spec:** `docs/superpowers/specs/2026-03-31-clickhouse-migration-design.md`
|
||||
|
||||
**Note on cameleer3-common:** The agent team is refactoring `cameleer3-common` to add `ExecutionChunk` and `FlatProcessorRecord`. Until that library is published, this plan defines server-side DTOs in `cameleer3-server-core` that mirror the common models. When the common lib is ready, swap the server DTOs for the shared classes (import change only).
|
||||
**Note on cameleer-common:** The agent team is refactoring `cameleer-common` to add `ExecutionChunk` and `FlatProcessorRecord`. Until that library is published, this plan defines server-side DTOs in `cameleer-server-core` that mirror the common models. When the common lib is ready, swap the server DTOs for the shared classes (import change only).
|
||||
|
||||
---
|
||||
|
||||
@@ -18,38 +18,38 @@
|
||||
|
||||
| File | Responsibility |
|
||||
|------|----------------|
|
||||
| `cameleer3-server-app/.../resources/clickhouse/V2__executions.sql` | DDL for `executions` table (ReplacingMergeTree) |
|
||||
| `cameleer3-server-app/.../resources/clickhouse/V3__processor_executions.sql` | DDL for `processor_executions` table (MergeTree) — uses seq/parentSeq/iteration |
|
||||
| `cameleer3-server-core/.../model/ExecutionChunk.java` | Server-side DTO mirroring agent's ExecutionChunk (temporary until common lib ready) |
|
||||
| `cameleer3-server-core/.../model/FlatProcessorRecord.java` | Server-side DTO mirroring agent's FlatProcessorRecord (temporary until common lib ready) |
|
||||
| `cameleer3-server-core/.../ingestion/ChunkAccumulator.java` | Accumulates exchange envelope across chunks, pushes processor records + final execution row to WriteBuffers |
|
||||
| `cameleer3-server-core/.../ingestion/MergedExecution.java` | Record holding merged execution envelope + version + tenant |
|
||||
| `cameleer3-server-app/.../storage/ClickHouseExecutionStore.java` | Batch INSERT for executions + processor_executions to ClickHouse |
|
||||
| `cameleer3-server-app/.../search/ClickHouseSearchIndex.java` | SearchIndex impl using SQL with ngram indexes |
|
||||
| `cameleer3-server-app/.../ingestion/ExecutionFlushScheduler.java` | Drains execution + processor WriteBuffers → ClickHouseExecutionStore |
|
||||
| `cameleer3-server-app/.../controller/ChunkIngestionController.java` | REST endpoint `POST /api/v1/data/chunks` accepting ExecutionChunk |
|
||||
| `cameleer3-server-app/.../config/StorageBeanConfig.java` | Modified: add chunk accumulator + CH search beans |
|
||||
| `cameleer3-server-app/.../config/IngestionBeanConfig.java` | Modified: add execution + processor WriteBuffer beans |
|
||||
| `cameleer3-server-app/.../resources/application.yml` | Modified: add `cameleer.storage.search` flag |
|
||||
| `cameleer3-server-app/...test.../storage/ClickHouseExecutionStoreIT.java` | Integration test for CH execution writes |
|
||||
| `cameleer3-server-app/...test.../search/ClickHouseSearchIndexIT.java` | Integration test for CH search |
|
||||
| `cameleer3-server-core/...test.../ingestion/ChunkAccumulatorTest.java` | Unit test for accumulator logic |
|
||||
| `cameleer-server-app/.../resources/clickhouse/V2__executions.sql` | DDL for `executions` table (ReplacingMergeTree) |
|
||||
| `cameleer-server-app/.../resources/clickhouse/V3__processor_executions.sql` | DDL for `processor_executions` table (MergeTree) — uses seq/parentSeq/iteration |
|
||||
| `cameleer-server-core/.../model/ExecutionChunk.java` | Server-side DTO mirroring agent's ExecutionChunk (temporary until common lib ready) |
|
||||
| `cameleer-server-core/.../model/FlatProcessorRecord.java` | Server-side DTO mirroring agent's FlatProcessorRecord (temporary until common lib ready) |
|
||||
| `cameleer-server-core/.../ingestion/ChunkAccumulator.java` | Accumulates exchange envelope across chunks, pushes processor records + final execution row to WriteBuffers |
|
||||
| `cameleer-server-core/.../ingestion/MergedExecution.java` | Record holding merged execution envelope + version + tenant |
|
||||
| `cameleer-server-app/.../storage/ClickHouseExecutionStore.java` | Batch INSERT for executions + processor_executions to ClickHouse |
|
||||
| `cameleer-server-app/.../search/ClickHouseSearchIndex.java` | SearchIndex impl using SQL with ngram indexes |
|
||||
| `cameleer-server-app/.../ingestion/ExecutionFlushScheduler.java` | Drains execution + processor WriteBuffers → ClickHouseExecutionStore |
|
||||
| `cameleer-server-app/.../controller/ChunkIngestionController.java` | REST endpoint `POST /api/v1/data/chunks` accepting ExecutionChunk |
|
||||
| `cameleer-server-app/.../config/StorageBeanConfig.java` | Modified: add chunk accumulator + CH search beans |
|
||||
| `cameleer-server-app/.../config/IngestionBeanConfig.java` | Modified: add execution + processor WriteBuffer beans |
|
||||
| `cameleer-server-app/.../resources/application.yml` | Modified: add `cameleer.storage.search` flag |
|
||||
| `cameleer-server-app/...test.../storage/ClickHouseExecutionStoreIT.java` | Integration test for CH execution writes |
|
||||
| `cameleer-server-app/...test.../search/ClickHouseSearchIndexIT.java` | Integration test for CH search |
|
||||
| `cameleer-server-core/...test.../ingestion/ChunkAccumulatorTest.java` | Unit test for accumulator logic |
|
||||
|
||||
---
|
||||
|
||||
### Task 1: Server-Side DTOs (ExecutionChunk + FlatProcessorRecord)
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/storage/model/FlatProcessorRecord.java`
|
||||
- Create: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/storage/model/ExecutionChunk.java`
|
||||
- Create: `cameleer-server-core/src/main/java/com/cameleer/server/core/storage/model/FlatProcessorRecord.java`
|
||||
- Create: `cameleer-server-core/src/main/java/com/cameleer/server/core/storage/model/ExecutionChunk.java`
|
||||
|
||||
These mirror the agent's models exactly. When `cameleer3-common` is published with these classes, delete these files and update imports.
|
||||
These mirror the agent's models exactly. When `cameleer-common` is published with these classes, delete these files and update imports.
|
||||
|
||||
- [ ] **Step 1: Create FlatProcessorRecord**
|
||||
|
||||
```java
|
||||
// cameleer3-server-core/src/main/java/com/cameleer3/server/core/storage/model/FlatProcessorRecord.java
|
||||
package com.cameleer3.server.core.storage.model;
|
||||
// cameleer-server-core/src/main/java/com/cameleer/server/core/storage/model/FlatProcessorRecord.java
|
||||
package com.cameleer.server.core.storage.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
@@ -59,7 +59,7 @@ import java.util.Map;
|
||||
|
||||
/**
|
||||
* Flat processor execution record with seq/parentSeq for tree reconstruction.
|
||||
* Mirrors cameleer3-common FlatProcessorRecord — replace with common lib import when available.
|
||||
* Mirrors cameleer-common FlatProcessorRecord — replace with common lib import when available.
|
||||
*/
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
@@ -96,8 +96,8 @@ public record FlatProcessorRecord(
|
||||
- [ ] **Step 2: Create ExecutionChunk**
|
||||
|
||||
```java
|
||||
// cameleer3-server-core/src/main/java/com/cameleer3/server/core/storage/model/ExecutionChunk.java
|
||||
package com.cameleer3.server.core.storage.model;
|
||||
// cameleer-server-core/src/main/java/com/cameleer/server/core/storage/model/ExecutionChunk.java
|
||||
package com.cameleer.server.core.storage.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
@@ -109,7 +109,7 @@ import java.util.Map;
|
||||
|
||||
/**
|
||||
* Chunk document: exchange envelope + list of FlatProcessorRecords.
|
||||
* Mirrors cameleer3-common ExecutionChunk — replace with common lib import when available.
|
||||
* Mirrors cameleer-common ExecutionChunk — replace with common lib import when available.
|
||||
*/
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
@@ -144,8 +144,8 @@ public record ExecutionChunk(
|
||||
- [ ] **Step 3: Write deserialization test**
|
||||
|
||||
```java
|
||||
// cameleer3-server-core/src/test/java/com/cameleer3/server/core/storage/model/ExecutionChunkDeserializationTest.java
|
||||
package com.cameleer3.server.core.storage.model;
|
||||
// cameleer-server-core/src/test/java/com/cameleer/server/core/storage/model/ExecutionChunkDeserializationTest.java
|
||||
package com.cameleer.server.core.storage.model;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
@@ -259,7 +259,7 @@ class ExecutionChunkDeserializationTest {
|
||||
- [ ] **Step 4: Run tests**
|
||||
|
||||
```bash
|
||||
mvn test -pl cameleer3-server-core -Dtest=ExecutionChunkDeserializationTest
|
||||
mvn test -pl cameleer-server-core -Dtest=ExecutionChunkDeserializationTest
|
||||
```
|
||||
|
||||
Expected: PASS (3 tests).
|
||||
@@ -267,9 +267,9 @@ Expected: PASS (3 tests).
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-core/src/main/java/com/cameleer3/server/core/storage/model/FlatProcessorRecord.java \
|
||||
cameleer3-server-core/src/main/java/com/cameleer3/server/core/storage/model/ExecutionChunk.java \
|
||||
cameleer3-server-core/src/test/java/com/cameleer3/server/core/storage/model/ExecutionChunkDeserializationTest.java
|
||||
git add cameleer-server-core/src/main/java/com/cameleer/server/core/storage/model/FlatProcessorRecord.java \
|
||||
cameleer-server-core/src/main/java/com/cameleer/server/core/storage/model/ExecutionChunk.java \
|
||||
cameleer-server-core/src/test/java/com/cameleer/server/core/storage/model/ExecutionChunkDeserializationTest.java
|
||||
git commit -m "feat: add server-side ExecutionChunk and FlatProcessorRecord DTOs"
|
||||
```
|
||||
|
||||
@@ -278,8 +278,8 @@ git commit -m "feat: add server-side ExecutionChunk and FlatProcessorRecord DTOs
|
||||
### Task 2: DDL Scripts for executions and processor_executions
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/main/resources/clickhouse/V2__executions.sql`
|
||||
- Create: `cameleer3-server-app/src/main/resources/clickhouse/V3__processor_executions.sql`
|
||||
- Create: `cameleer-server-app/src/main/resources/clickhouse/V2__executions.sql`
|
||||
- Create: `cameleer-server-app/src/main/resources/clickhouse/V3__processor_executions.sql`
|
||||
|
||||
- [ ] **Step 1: Create executions DDL**
|
||||
|
||||
@@ -395,7 +395,7 @@ SETTINGS index_granularity = 8192;
|
||||
- [ ] **Step 3: Verify DDL loads**
|
||||
|
||||
```bash
|
||||
mvn clean compile -pl cameleer3-server-app
|
||||
mvn clean compile -pl cameleer-server-app
|
||||
```
|
||||
|
||||
`ClickHouseSchemaInitializer` scans `classpath:clickhouse/*.sql` automatically.
|
||||
@@ -403,8 +403,8 @@ mvn clean compile -pl cameleer3-server-app
|
||||
- [ ] **Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/resources/clickhouse/V2__executions.sql \
|
||||
cameleer3-server-app/src/main/resources/clickhouse/V3__processor_executions.sql
|
||||
git add cameleer-server-app/src/main/resources/clickhouse/V2__executions.sql \
|
||||
cameleer-server-app/src/main/resources/clickhouse/V3__processor_executions.sql
|
||||
git commit -m "feat(clickhouse): add executions and processor_executions DDL for chunked transport"
|
||||
```
|
||||
|
||||
@@ -413,17 +413,17 @@ git commit -m "feat(clickhouse): add executions and processor_executions DDL for
|
||||
### Task 3: MergedExecution + ClickHouseExecutionStore
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/ingestion/MergedExecution.java`
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/ClickHouseExecutionStore.java`
|
||||
- Create: `cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/ClickHouseExecutionStoreIT.java`
|
||||
- Create: `cameleer-server-core/src/main/java/com/cameleer/server/core/ingestion/MergedExecution.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/storage/ClickHouseExecutionStore.java`
|
||||
- Create: `cameleer-server-app/src/test/java/com/cameleer/server/app/storage/ClickHouseExecutionStoreIT.java`
|
||||
|
||||
The store handles batch INSERT for both `executions` (from MergedExecution) and `processor_executions` (from FlatProcessorRecord). It does NOT implement the `ExecutionStore` interface — it has its own batch API consumed by the flush scheduler.
|
||||
|
||||
- [ ] **Step 1: Create MergedExecution record**
|
||||
|
||||
```java
|
||||
// cameleer3-server-core/src/main/java/com/cameleer3/server/core/ingestion/MergedExecution.java
|
||||
package com.cameleer3.server.core.ingestion;
|
||||
// cameleer-server-core/src/main/java/com/cameleer/server/core/ingestion/MergedExecution.java
|
||||
package com.cameleer.server.core.ingestion;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Map;
|
||||
@@ -468,11 +468,11 @@ public record MergedExecution(
|
||||
- [ ] **Step 2: Write the failing integration test**
|
||||
|
||||
```java
|
||||
// cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/ClickHouseExecutionStoreIT.java
|
||||
package com.cameleer3.server.app.storage;
|
||||
// cameleer-server-app/src/test/java/com/cameleer/server/app/storage/ClickHouseExecutionStoreIT.java
|
||||
package com.cameleer.server.app.storage;
|
||||
|
||||
import com.cameleer3.server.core.ingestion.MergedExecution;
|
||||
import com.cameleer3.server.core.storage.model.FlatProcessorRecord;
|
||||
import com.cameleer.server.core.ingestion.MergedExecution;
|
||||
import com.cameleer.server.core.storage.model.FlatProcessorRecord;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -654,7 +654,7 @@ class ClickHouseExecutionStoreIT {
|
||||
- [ ] **Step 3: Run test to verify it fails**
|
||||
|
||||
```bash
|
||||
mvn test -pl cameleer3-server-app -Dtest=ClickHouseExecutionStoreIT -Dfailsafe.provider=surefire -DfailIfNoTests=false
|
||||
mvn test -pl cameleer-server-app -Dtest=ClickHouseExecutionStoreIT -Dfailsafe.provider=surefire -DfailIfNoTests=false
|
||||
```
|
||||
|
||||
Expected: compilation error — `ClickHouseExecutionStore` does not exist.
|
||||
@@ -662,11 +662,11 @@ Expected: compilation error — `ClickHouseExecutionStore` does not exist.
|
||||
- [ ] **Step 4: Implement ClickHouseExecutionStore**
|
||||
|
||||
```java
|
||||
// cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/ClickHouseExecutionStore.java
|
||||
package com.cameleer3.server.app.storage;
|
||||
// cameleer-server-app/src/main/java/com/cameleer/server/app/storage/ClickHouseExecutionStore.java
|
||||
package com.cameleer.server.app.storage;
|
||||
|
||||
import com.cameleer3.server.core.ingestion.MergedExecution;
|
||||
import com.cameleer3.server.core.storage.model.FlatProcessorRecord;
|
||||
import com.cameleer.server.core.ingestion.MergedExecution;
|
||||
import com.cameleer.server.core.storage.model.FlatProcessorRecord;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
@@ -840,7 +840,7 @@ public class ClickHouseExecutionStore {
|
||||
- [ ] **Step 5: Run test to verify it passes**
|
||||
|
||||
```bash
|
||||
mvn test -pl cameleer3-server-app -Dtest=ClickHouseExecutionStoreIT -Dfailsafe.provider=surefire
|
||||
mvn test -pl cameleer-server-app -Dtest=ClickHouseExecutionStoreIT -Dfailsafe.provider=surefire
|
||||
```
|
||||
|
||||
Expected: all 5 tests PASS.
|
||||
@@ -848,9 +848,9 @@ Expected: all 5 tests PASS.
|
||||
- [ ] **Step 6: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-core/src/main/java/com/cameleer3/server/core/ingestion/MergedExecution.java \
|
||||
cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/ClickHouseExecutionStore.java \
|
||||
cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/ClickHouseExecutionStoreIT.java
|
||||
git add cameleer-server-core/src/main/java/com/cameleer/server/core/ingestion/MergedExecution.java \
|
||||
cameleer-server-app/src/main/java/com/cameleer/server/app/storage/ClickHouseExecutionStore.java \
|
||||
cameleer-server-app/src/test/java/com/cameleer/server/app/storage/ClickHouseExecutionStoreIT.java
|
||||
git commit -m "feat(clickhouse): add ClickHouseExecutionStore with batch insert for chunked format"
|
||||
```
|
||||
|
||||
@@ -859,8 +859,8 @@ git commit -m "feat(clickhouse): add ClickHouseExecutionStore with batch insert
|
||||
### Task 4: ChunkAccumulator
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-core/src/test/java/com/cameleer3/server/core/ingestion/ChunkAccumulatorTest.java`
|
||||
- Create: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/ingestion/ChunkAccumulator.java`
|
||||
- Create: `cameleer-server-core/src/test/java/com/cameleer/server/core/ingestion/ChunkAccumulatorTest.java`
|
||||
- Create: `cameleer-server-core/src/main/java/com/cameleer/server/core/ingestion/ChunkAccumulator.java`
|
||||
|
||||
The ChunkAccumulator receives `ExecutionChunk` documents. For each chunk:
|
||||
- Processor records are pushed to a sink immediately (they're append-only)
|
||||
@@ -872,11 +872,11 @@ A scheduled sweep flushes stale exchanges (no final chunk received within 5 minu
|
||||
- [ ] **Step 1: Write the failing unit test**
|
||||
|
||||
```java
|
||||
// cameleer3-server-core/src/test/java/com/cameleer3/server/core/ingestion/ChunkAccumulatorTest.java
|
||||
package com.cameleer3.server.core.ingestion;
|
||||
// cameleer-server-core/src/test/java/com/cameleer/server/core/ingestion/ChunkAccumulatorTest.java
|
||||
package com.cameleer.server.core.ingestion;
|
||||
|
||||
import com.cameleer3.server.core.storage.model.ExecutionChunk;
|
||||
import com.cameleer3.server.core.storage.model.FlatProcessorRecord;
|
||||
import com.cameleer.server.core.storage.model.ExecutionChunk;
|
||||
import com.cameleer.server.core.storage.model.FlatProcessorRecord;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -1060,7 +1060,7 @@ class ChunkAccumulatorTest {
|
||||
- [ ] **Step 2: Run test to verify it fails**
|
||||
|
||||
```bash
|
||||
mvn test -pl cameleer3-server-core -Dtest=ChunkAccumulatorTest -DfailIfNoTests=false
|
||||
mvn test -pl cameleer-server-core -Dtest=ChunkAccumulatorTest -DfailIfNoTests=false
|
||||
```
|
||||
|
||||
Expected: compilation error — `ChunkAccumulator` does not exist.
|
||||
@@ -1068,11 +1068,11 @@ Expected: compilation error — `ChunkAccumulator` does not exist.
|
||||
- [ ] **Step 3: Implement ChunkAccumulator**
|
||||
|
||||
```java
|
||||
// cameleer3-server-core/src/main/java/com/cameleer3/server/core/ingestion/ChunkAccumulator.java
|
||||
package com.cameleer3.server.core.ingestion;
|
||||
// cameleer-server-core/src/main/java/com/cameleer/server/core/ingestion/ChunkAccumulator.java
|
||||
package com.cameleer.server.core.ingestion;
|
||||
|
||||
import com.cameleer3.server.core.storage.model.ExecutionChunk;
|
||||
import com.cameleer3.server.core.storage.model.FlatProcessorRecord;
|
||||
import com.cameleer.server.core.storage.model.ExecutionChunk;
|
||||
import com.cameleer.server.core.storage.model.FlatProcessorRecord;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.slf4j.Logger;
|
||||
@@ -1267,7 +1267,7 @@ public class ChunkAccumulator {
|
||||
- [ ] **Step 4: Run test to verify it passes**
|
||||
|
||||
```bash
|
||||
mvn test -pl cameleer3-server-core -Dtest=ChunkAccumulatorTest
|
||||
mvn test -pl cameleer-server-core -Dtest=ChunkAccumulatorTest
|
||||
```
|
||||
|
||||
Expected: all 5 tests PASS.
|
||||
@@ -1275,8 +1275,8 @@ Expected: all 5 tests PASS.
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-core/src/main/java/com/cameleer3/server/core/ingestion/ChunkAccumulator.java \
|
||||
cameleer3-server-core/src/test/java/com/cameleer3/server/core/ingestion/ChunkAccumulatorTest.java
|
||||
git add cameleer-server-core/src/main/java/com/cameleer/server/core/ingestion/ChunkAccumulator.java \
|
||||
cameleer-server-core/src/test/java/com/cameleer/server/core/ingestion/ChunkAccumulatorTest.java
|
||||
git commit -m "feat(clickhouse): add ChunkAccumulator for chunked execution ingestion"
|
||||
```
|
||||
|
||||
@@ -1285,22 +1285,22 @@ git commit -m "feat(clickhouse): add ChunkAccumulator for chunked execution inge
|
||||
### Task 5: ExecutionFlushScheduler + ChunkIngestionController
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/ingestion/ExecutionFlushScheduler.java`
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/ChunkIngestionController.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/ingestion/ExecutionFlushScheduler.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/ChunkIngestionController.java`
|
||||
|
||||
- [ ] **Step 1: Implement ExecutionFlushScheduler**
|
||||
|
||||
Follows `MetricsFlushScheduler` pattern. Drains two WriteBuffers (executions + processor batches) and calls ClickHouseExecutionStore. Also runs the stale sweep.
|
||||
|
||||
```java
|
||||
// cameleer3-server-app/src/main/java/com/cameleer3/server/app/ingestion/ExecutionFlushScheduler.java
|
||||
package com.cameleer3.server.app.ingestion;
|
||||
// cameleer-server-app/src/main/java/com/cameleer/server/app/ingestion/ExecutionFlushScheduler.java
|
||||
package com.cameleer.server.app.ingestion;
|
||||
|
||||
import com.cameleer3.server.app.config.IngestionConfig;
|
||||
import com.cameleer3.server.app.storage.ClickHouseExecutionStore;
|
||||
import com.cameleer3.server.core.ingestion.ChunkAccumulator;
|
||||
import com.cameleer3.server.core.ingestion.MergedExecution;
|
||||
import com.cameleer3.server.core.ingestion.WriteBuffer;
|
||||
import com.cameleer.server.app.config.IngestionConfig;
|
||||
import com.cameleer.server.app.storage.ClickHouseExecutionStore;
|
||||
import com.cameleer.server.core.ingestion.ChunkAccumulator;
|
||||
import com.cameleer.server.core.ingestion.MergedExecution;
|
||||
import com.cameleer.server.core.ingestion.WriteBuffer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.SmartLifecycle;
|
||||
@@ -1395,11 +1395,11 @@ public class ExecutionFlushScheduler implements SmartLifecycle {
|
||||
- [ ] **Step 2: Implement ChunkIngestionController**
|
||||
|
||||
```java
|
||||
// cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/ChunkIngestionController.java
|
||||
package com.cameleer3.server.app.controller;
|
||||
// cameleer-server-app/src/main/java/com/cameleer/server/app/controller/ChunkIngestionController.java
|
||||
package com.cameleer.server.app.controller;
|
||||
|
||||
import com.cameleer3.server.core.ingestion.ChunkAccumulator;
|
||||
import com.cameleer3.server.core.storage.model.ExecutionChunk;
|
||||
import com.cameleer.server.core.ingestion.ChunkAccumulator;
|
||||
import com.cameleer.server.core.storage.model.ExecutionChunk;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
@@ -1450,14 +1450,14 @@ public class ChunkIngestionController {
|
||||
- [ ] **Step 3: Compile**
|
||||
|
||||
```bash
|
||||
mvn clean compile -pl cameleer3-server-app
|
||||
mvn clean compile -pl cameleer-server-app
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/ingestion/ExecutionFlushScheduler.java \
|
||||
cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/ChunkIngestionController.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/ingestion/ExecutionFlushScheduler.java \
|
||||
cameleer-server-app/src/main/java/com/cameleer/server/app/controller/ChunkIngestionController.java
|
||||
git commit -m "feat(clickhouse): add ExecutionFlushScheduler and ChunkIngestionController"
|
||||
```
|
||||
|
||||
@@ -1466,8 +1466,8 @@ git commit -m "feat(clickhouse): add ExecutionFlushScheduler and ChunkIngestionC
|
||||
### Task 6: ClickHouseSearchIndex
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/test/java/com/cameleer3/server/app/search/ClickHouseSearchIndexIT.java`
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/search/ClickHouseSearchIndex.java`
|
||||
- Create: `cameleer-server-app/src/test/java/com/cameleer/server/app/search/ClickHouseSearchIndexIT.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/search/ClickHouseSearchIndex.java`
|
||||
|
||||
Same as the original plan — implements `SearchIndex` using SQL against ClickHouse. The search query patterns are unchanged: `_search_text LIKE '%term%'` on executions, subquery join on processor_executions for body/header/error scoped searches.
|
||||
|
||||
@@ -1480,7 +1480,7 @@ Use the same test class from the original plan's Task 5, Step 1. The test seeds
|
||||
- [ ] **Step 2: Run test to verify it fails**
|
||||
|
||||
```bash
|
||||
mvn test -pl cameleer3-server-app -Dtest=ClickHouseSearchIndexIT -Dfailsafe.provider=surefire -DfailIfNoTests=false
|
||||
mvn test -pl cameleer-server-app -Dtest=ClickHouseSearchIndexIT -Dfailsafe.provider=surefire -DfailIfNoTests=false
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Implement ClickHouseSearchIndex**
|
||||
@@ -1490,14 +1490,14 @@ Use the same implementation from the original plan's Task 5, Step 3. The SQL que
|
||||
- [ ] **Step 4: Run test to verify it passes**
|
||||
|
||||
```bash
|
||||
mvn test -pl cameleer3-server-app -Dtest=ClickHouseSearchIndexIT -Dfailsafe.provider=surefire
|
||||
mvn test -pl cameleer-server-app -Dtest=ClickHouseSearchIndexIT -Dfailsafe.provider=surefire
|
||||
```
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/search/ClickHouseSearchIndex.java \
|
||||
cameleer3-server-app/src/test/java/com/cameleer3/server/app/search/ClickHouseSearchIndexIT.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/search/ClickHouseSearchIndex.java \
|
||||
cameleer-server-app/src/test/java/com/cameleer/server/app/search/ClickHouseSearchIndexIT.java
|
||||
git commit -m "feat(clickhouse): add ClickHouseSearchIndex with ngram-accelerated SQL search"
|
||||
```
|
||||
|
||||
@@ -1506,10 +1506,10 @@ git commit -m "feat(clickhouse): add ClickHouseSearchIndex with ngram-accelerate
|
||||
### Task 7: Feature Flag Wiring
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/StorageBeanConfig.java`
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/IngestionBeanConfig.java`
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/search/OpenSearchIndex.java`
|
||||
- Modify: `cameleer3-server-app/src/main/resources/application.yml`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/config/StorageBeanConfig.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/config/IngestionBeanConfig.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/search/OpenSearchIndex.java`
|
||||
- Modify: `cameleer-server-app/src/main/resources/application.yml`
|
||||
- Modify: `deploy/base/server.yaml`
|
||||
|
||||
Wire up the ChunkAccumulator, WriteBuffers, flush scheduler, and search switching.
|
||||
@@ -1608,10 +1608,10 @@ mvn clean verify -DskipITs
|
||||
- [ ] **Step 7: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/StorageBeanConfig.java \
|
||||
cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/IngestionBeanConfig.java \
|
||||
cameleer3-server-app/src/main/java/com/cameleer3/server/app/search/OpenSearchIndex.java \
|
||||
cameleer3-server-app/src/main/resources/application.yml \
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/config/StorageBeanConfig.java \
|
||||
cameleer-server-app/src/main/java/com/cameleer/server/app/config/IngestionBeanConfig.java \
|
||||
cameleer-server-app/src/main/java/com/cameleer/server/app/search/OpenSearchIndex.java \
|
||||
cameleer-server-app/src/main/resources/application.yml \
|
||||
deploy/base/server.yaml
|
||||
git commit -m "feat(clickhouse): wire ChunkAccumulator, flush scheduler, and search feature flag"
|
||||
```
|
||||
@@ -1621,24 +1621,24 @@ git commit -m "feat(clickhouse): wire ChunkAccumulator, flush scheduler, and sea
|
||||
### Task 8: End-to-End Integration Test
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/ClickHouseChunkPipelineIT.java`
|
||||
- Create: `cameleer-server-app/src/test/java/com/cameleer/server/app/storage/ClickHouseChunkPipelineIT.java`
|
||||
|
||||
Validates the full pipeline: ChunkAccumulator → WriteBuffers → ClickHouseExecutionStore → ClickHouseSearchIndex.
|
||||
|
||||
- [ ] **Step 1: Write the integration test**
|
||||
|
||||
```java
|
||||
// cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/ClickHouseChunkPipelineIT.java
|
||||
package com.cameleer3.server.app.storage;
|
||||
// cameleer-server-app/src/test/java/com/cameleer/server/app/storage/ClickHouseChunkPipelineIT.java
|
||||
package com.cameleer.server.app.storage;
|
||||
|
||||
import com.cameleer3.server.app.search.ClickHouseSearchIndex;
|
||||
import com.cameleer3.server.core.ingestion.ChunkAccumulator;
|
||||
import com.cameleer3.server.core.ingestion.MergedExecution;
|
||||
import com.cameleer3.server.core.search.ExecutionSummary;
|
||||
import com.cameleer3.server.core.search.SearchRequest;
|
||||
import com.cameleer3.server.core.search.SearchResult;
|
||||
import com.cameleer3.server.core.storage.model.ExecutionChunk;
|
||||
import com.cameleer3.server.core.storage.model.FlatProcessorRecord;
|
||||
import com.cameleer.server.app.search.ClickHouseSearchIndex;
|
||||
import com.cameleer.server.core.ingestion.ChunkAccumulator;
|
||||
import com.cameleer.server.core.ingestion.MergedExecution;
|
||||
import com.cameleer.server.core.search.ExecutionSummary;
|
||||
import com.cameleer.server.core.search.SearchRequest;
|
||||
import com.cameleer.server.core.search.SearchResult;
|
||||
import com.cameleer.server.core.storage.model.ExecutionChunk;
|
||||
import com.cameleer.server.core.storage.model.FlatProcessorRecord;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -1797,7 +1797,7 @@ class ClickHouseChunkPipelineIT {
|
||||
- [ ] **Step 2: Run the integration test**
|
||||
|
||||
```bash
|
||||
mvn test -pl cameleer3-server-app -Dtest=ClickHouseChunkPipelineIT -Dfailsafe.provider=surefire
|
||||
mvn test -pl cameleer-server-app -Dtest=ClickHouseChunkPipelineIT -Dfailsafe.provider=surefire
|
||||
```
|
||||
|
||||
Expected: PASS.
|
||||
@@ -1805,7 +1805,7 @@ Expected: PASS.
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/ClickHouseChunkPipelineIT.java
|
||||
git add cameleer-server-app/src/test/java/com/cameleer/server/app/storage/ClickHouseChunkPipelineIT.java
|
||||
git commit -m "test(clickhouse): add end-to-end chunk pipeline integration test"
|
||||
```
|
||||
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
|
||||
| File | Responsibility |
|
||||
|------|----------------|
|
||||
| `cameleer3-server-app/.../resources/clickhouse/V4__stats_tables_and_mvs.sql` | DDL for all 5 stats tables + 5 materialized views |
|
||||
| `cameleer3-server-app/.../storage/ClickHouseStatsStore.java` | StatsStore impl using -Merge functions on AggregatingMergeTree tables |
|
||||
| `cameleer3-server-app/.../config/StorageBeanConfig.java` | Modified: add CH stats store bean with feature flag |
|
||||
| `cameleer3-server-app/.../storage/PostgresStatsStore.java` | Modified: add ConditionalOnProperty |
|
||||
| `cameleer3-server-app/.../resources/application.yml` | Modified: add `cameleer.storage.stats` flag |
|
||||
| `cameleer-server-app/.../resources/clickhouse/V4__stats_tables_and_mvs.sql` | DDL for all 5 stats tables + 5 materialized views |
|
||||
| `cameleer-server-app/.../storage/ClickHouseStatsStore.java` | StatsStore impl using -Merge functions on AggregatingMergeTree tables |
|
||||
| `cameleer-server-app/.../config/StorageBeanConfig.java` | Modified: add CH stats store bean with feature flag |
|
||||
| `cameleer-server-app/.../storage/PostgresStatsStore.java` | Modified: add ConditionalOnProperty |
|
||||
| `cameleer-server-app/.../resources/application.yml` | Modified: add `cameleer.storage.stats` flag |
|
||||
| `deploy/base/server.yaml` | Modified: add `CAMELEER_STORAGE_STATS` env var |
|
||||
| `cameleer3-server-app/...test.../storage/ClickHouseStatsStoreIT.java` | Integration test for CH stats queries |
|
||||
| `cameleer-server-app/...test.../storage/ClickHouseStatsStoreIT.java` | Integration test for CH stats queries |
|
||||
|
||||
---
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
### Task 1: DDL for Stats Tables and Materialized Views
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/main/resources/clickhouse/V4__stats_tables_and_mvs.sql`
|
||||
- Create: `cameleer-server-app/src/main/resources/clickhouse/V4__stats_tables_and_mvs.sql`
|
||||
|
||||
All 5 table+MV pairs in a single DDL file. Tables use `AggregatingMergeTree()`. MVs use `-State` combinators and trigger on INSERT to `executions` or `processor_executions`.
|
||||
|
||||
@@ -229,20 +229,20 @@ Note: The `ClickHouseSchemaInitializer` runs each `.sql` file as a single statem
|
||||
|
||||
- [ ] **Step 2: Check ClickHouseSchemaInitializer handles multi-statement**
|
||||
|
||||
Read `cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/ClickHouseSchemaInitializer.java`. If it runs each file as a single `jdbc.execute()`, modify it to split on `;` and run each statement separately. If it already handles this, proceed.
|
||||
Read `cameleer-server-app/src/main/java/com/cameleer/server/app/config/ClickHouseSchemaInitializer.java`. If it runs each file as a single `jdbc.execute()`, modify it to split on `;` and run each statement separately. If it already handles this, proceed.
|
||||
|
||||
- [ ] **Step 3: Verify DDL loads in Testcontainers**
|
||||
|
||||
Write a quick smoke test or manually verify that all 10 objects (5 tables + 5 MVs) are created:
|
||||
|
||||
```bash
|
||||
mvn clean compile -pl cameleer3-server-app -f pom.xml
|
||||
mvn clean compile -pl cameleer-server-app -f pom.xml
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/resources/clickhouse/V4__stats_tables_and_mvs.sql
|
||||
git add cameleer-server-app/src/main/resources/clickhouse/V4__stats_tables_and_mvs.sql
|
||||
# also add ClickHouseSchemaInitializer if modified
|
||||
git commit -m "feat(clickhouse): add stats materialized views DDL (5 tables + 5 MVs)"
|
||||
```
|
||||
@@ -252,8 +252,8 @@ git commit -m "feat(clickhouse): add stats materialized views DDL (5 tables + 5
|
||||
### Task 2: ClickHouseStatsStore — Aggregate Queries
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/ClickHouseStatsStoreIT.java`
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/ClickHouseStatsStore.java`
|
||||
- Create: `cameleer-server-app/src/test/java/com/cameleer/server/app/storage/ClickHouseStatsStoreIT.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/storage/ClickHouseStatsStore.java`
|
||||
|
||||
The store implements `StatsStore` using ClickHouse `-Merge` functions. It follows the same pattern as `PostgresStatsStore` but with ClickHouse SQL syntax.
|
||||
|
||||
@@ -333,7 +333,7 @@ Create `ClickHouseStatsStoreIT.java` with:
|
||||
- [ ] **Step 2: Run test to verify it fails**
|
||||
|
||||
```bash
|
||||
mvn test -pl cameleer3-server-app -Dtest=ClickHouseStatsStoreIT -Dfailsafe.provider=surefire -DfailIfNoTests=false -f pom.xml
|
||||
mvn test -pl cameleer-server-app -Dtest=ClickHouseStatsStoreIT -Dfailsafe.provider=surefire -DfailIfNoTests=false -f pom.xml
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Implement ClickHouseStatsStore**
|
||||
@@ -343,14 +343,14 @@ Follow the `PostgresStatsStore` structure closely. Same private `Filter` record,
|
||||
- [ ] **Step 4: Run test to verify it passes**
|
||||
|
||||
```bash
|
||||
mvn test -pl cameleer3-server-app -Dtest=ClickHouseStatsStoreIT -Dfailsafe.provider=surefire -f pom.xml
|
||||
mvn test -pl cameleer-server-app -Dtest=ClickHouseStatsStoreIT -Dfailsafe.provider=surefire -f pom.xml
|
||||
```
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/ClickHouseStatsStore.java \
|
||||
cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/ClickHouseStatsStoreIT.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/storage/ClickHouseStatsStore.java \
|
||||
cameleer-server-app/src/test/java/com/cameleer/server/app/storage/ClickHouseStatsStoreIT.java
|
||||
git commit -m "feat(clickhouse): add ClickHouseStatsStore with -Merge aggregate queries"
|
||||
```
|
||||
|
||||
@@ -359,9 +359,9 @@ git commit -m "feat(clickhouse): add ClickHouseStatsStore with -Merge aggregate
|
||||
### Task 3: Feature Flag Wiring
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/StorageBeanConfig.java`
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/PostgresStatsStore.java`
|
||||
- Modify: `cameleer3-server-app/src/main/resources/application.yml`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/config/StorageBeanConfig.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/storage/PostgresStatsStore.java`
|
||||
- Modify: `cameleer-server-app/src/main/resources/application.yml`
|
||||
- Modify: `deploy/base/server.yaml`
|
||||
|
||||
- [ ] **Step 1: Add ConditionalOnProperty to PostgresStatsStore**
|
||||
@@ -407,9 +407,9 @@ mvn clean verify -DskipITs -f pom.xml
|
||||
- [ ] **Step 6: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/StorageBeanConfig.java \
|
||||
cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/PostgresStatsStore.java \
|
||||
cameleer3-server-app/src/main/resources/application.yml \
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/config/StorageBeanConfig.java \
|
||||
cameleer-server-app/src/main/java/com/cameleer/server/app/storage/PostgresStatsStore.java \
|
||||
cameleer-server-app/src/main/resources/application.yml \
|
||||
deploy/base/server.yaml
|
||||
git commit -m "feat(clickhouse): wire ClickHouseStatsStore with cameleer.storage.stats feature flag"
|
||||
```
|
||||
|
||||
@@ -16,17 +16,17 @@
|
||||
|
||||
| File | Responsibility |
|
||||
|------|----------------|
|
||||
| `cameleer3-server-app/.../resources/clickhouse/V5__route_diagrams.sql` | DDL for `route_diagrams` (ReplacingMergeTree) |
|
||||
| `cameleer3-server-app/.../resources/clickhouse/V6__agent_events.sql` | DDL for `agent_events` (MergeTree) |
|
||||
| `cameleer3-server-app/.../resources/clickhouse/V7__logs.sql` | DDL for `logs` (MergeTree with ngram indexes) |
|
||||
| `cameleer3-server-app/.../storage/ClickHouseDiagramStore.java` | DiagramStore impl for ClickHouse |
|
||||
| `cameleer3-server-app/.../storage/ClickHouseAgentEventRepository.java` | AgentEventRepository impl for ClickHouse |
|
||||
| `cameleer3-server-app/.../search/ClickHouseLogStore.java` | Replaces OpenSearchLogIndex |
|
||||
| `cameleer3-server-app/.../config/StorageBeanConfig.java` | Modified: add CH beans with feature flags |
|
||||
| `cameleer3-server-app/.../storage/PostgresDiagramStore.java` | Modified: add ConditionalOnProperty |
|
||||
| `cameleer3-server-app/.../storage/PostgresAgentEventRepository.java` | Modified: add ConditionalOnProperty |
|
||||
| `cameleer3-server-app/.../search/OpenSearchLogIndex.java` | Modified: add ConditionalOnProperty |
|
||||
| `cameleer3-server-app/.../resources/application.yml` | Modified: add feature flags |
|
||||
| `cameleer-server-app/.../resources/clickhouse/V5__route_diagrams.sql` | DDL for `route_diagrams` (ReplacingMergeTree) |
|
||||
| `cameleer-server-app/.../resources/clickhouse/V6__agent_events.sql` | DDL for `agent_events` (MergeTree) |
|
||||
| `cameleer-server-app/.../resources/clickhouse/V7__logs.sql` | DDL for `logs` (MergeTree with ngram indexes) |
|
||||
| `cameleer-server-app/.../storage/ClickHouseDiagramStore.java` | DiagramStore impl for ClickHouse |
|
||||
| `cameleer-server-app/.../storage/ClickHouseAgentEventRepository.java` | AgentEventRepository impl for ClickHouse |
|
||||
| `cameleer-server-app/.../search/ClickHouseLogStore.java` | Replaces OpenSearchLogIndex |
|
||||
| `cameleer-server-app/.../config/StorageBeanConfig.java` | Modified: add CH beans with feature flags |
|
||||
| `cameleer-server-app/.../storage/PostgresDiagramStore.java` | Modified: add ConditionalOnProperty |
|
||||
| `cameleer-server-app/.../storage/PostgresAgentEventRepository.java` | Modified: add ConditionalOnProperty |
|
||||
| `cameleer-server-app/.../search/OpenSearchLogIndex.java` | Modified: add ConditionalOnProperty |
|
||||
| `cameleer-server-app/.../resources/application.yml` | Modified: add feature flags |
|
||||
| `deploy/base/server.yaml` | Modified: add env vars |
|
||||
|
||||
---
|
||||
@@ -34,9 +34,9 @@
|
||||
### Task 1: DDL Scripts
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/main/resources/clickhouse/V5__route_diagrams.sql`
|
||||
- Create: `cameleer3-server-app/src/main/resources/clickhouse/V6__agent_events.sql`
|
||||
- Create: `cameleer3-server-app/src/main/resources/clickhouse/V7__logs.sql`
|
||||
- Create: `cameleer-server-app/src/main/resources/clickhouse/V5__route_diagrams.sql`
|
||||
- Create: `cameleer-server-app/src/main/resources/clickhouse/V6__agent_events.sql`
|
||||
- Create: `cameleer-server-app/src/main/resources/clickhouse/V7__logs.sql`
|
||||
|
||||
- [ ] **Step 1: Create route_diagrams DDL**
|
||||
|
||||
@@ -102,7 +102,7 @@ SETTINGS index_granularity = 8192
|
||||
- [ ] **Step 4: Compile and commit**
|
||||
|
||||
```bash
|
||||
mvn clean compile -pl cameleer3-server-app -f pom.xml
|
||||
mvn clean compile -pl cameleer-server-app -f pom.xml
|
||||
git commit -m "feat(clickhouse): add DDL for route_diagrams, agent_events, and logs tables"
|
||||
```
|
||||
|
||||
@@ -111,8 +111,8 @@ git commit -m "feat(clickhouse): add DDL for route_diagrams, agent_events, and l
|
||||
### Task 2: ClickHouseDiagramStore
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/ClickHouseDiagramStore.java`
|
||||
- Create: `cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/ClickHouseDiagramStoreIT.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/storage/ClickHouseDiagramStore.java`
|
||||
- Create: `cameleer-server-app/src/test/java/com/cameleer/server/app/storage/ClickHouseDiagramStoreIT.java`
|
||||
|
||||
Implements `DiagramStore` interface (5 methods). Read `PostgresDiagramStore.java` first and translate.
|
||||
|
||||
@@ -136,8 +136,8 @@ Implements `DiagramStore` interface (5 methods). Read `PostgresDiagramStore.java
|
||||
### Task 3: ClickHouseAgentEventRepository
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/ClickHouseAgentEventRepository.java`
|
||||
- Create: `cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/ClickHouseAgentEventRepositoryIT.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/storage/ClickHouseAgentEventRepository.java`
|
||||
- Create: `cameleer-server-app/src/test/java/com/cameleer/server/app/storage/ClickHouseAgentEventRepositoryIT.java`
|
||||
|
||||
Implements `AgentEventRepository` interface (2 methods: `insert` + `query`).
|
||||
|
||||
@@ -158,8 +158,8 @@ Implements `AgentEventRepository` interface (2 methods: `insert` + `query`).
|
||||
### Task 4: ClickHouseLogStore
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/search/ClickHouseLogStore.java`
|
||||
- Create: `cameleer3-server-app/src/test/java/com/cameleer3/server/app/search/ClickHouseLogStoreIT.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/search/ClickHouseLogStore.java`
|
||||
- Create: `cameleer-server-app/src/test/java/com/cameleer/server/app/search/ClickHouseLogStoreIT.java`
|
||||
|
||||
Replaces `OpenSearchLogIndex`. Must have the same public API:
|
||||
- `search(application, agentId, level, query, exchangeId, from, to, limit)` → returns `List<LogEntryResponse>`
|
||||
|
||||
@@ -171,7 +171,7 @@ export function writeCollapsed(key: string, value: boolean): void {
|
||||
|
||||
- [ ] **Step 2: Verify it compiles**
|
||||
|
||||
Run: `cd C:/Users/Hendrik/Documents/projects/cameleer3-server/ui && npx tsc --project tsconfig.app.json --noEmit`
|
||||
Run: `cd C:/Users/Hendrik/Documents/projects/cameleer-server/ui && npx tsc --project tsconfig.app.json --noEmit`
|
||||
Expected: No errors.
|
||||
|
||||
- [ ] **Step 3: Commit**
|
||||
@@ -479,7 +479,7 @@ Note: The Admin section renders in two positions — at the top when `isAdminPag
|
||||
|
||||
- [ ] **Step 5: Verify it compiles**
|
||||
|
||||
Run: `cd C:/Users/Hendrik/Documents/projects/cameleer3-server/ui && npx tsc --project tsconfig.app.json --noEmit`
|
||||
Run: `cd C:/Users/Hendrik/Documents/projects/cameleer-server/ui && npx tsc --project tsconfig.app.json --noEmit`
|
||||
Expected: No errors. If `StatusDot` is not exported from the DS, check the exact export name with `grep -r "StatusDot" ui/node_modules/@cameleer/design-system/dist/index.es.d.ts`.
|
||||
|
||||
- [ ] **Step 6: Commit**
|
||||
@@ -516,7 +516,7 @@ export default function AdminLayout() {
|
||||
|
||||
- [ ] **Step 2: Verify it compiles**
|
||||
|
||||
Run: `cd C:/Users/Hendrik/Documents/projects/cameleer3-server/ui && npx tsc --project tsconfig.app.json --noEmit`
|
||||
Run: `cd C:/Users/Hendrik/Documents/projects/cameleer-server/ui && npx tsc --project tsconfig.app.json --noEmit`
|
||||
Expected: No errors.
|
||||
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
@@ -14,13 +14,13 @@
|
||||
|
||||
| File | Action | Responsibility |
|
||||
|------|--------|---------------|
|
||||
| `cameleer3-server-app/pom.xml` | Modify | Add oauth2-resource-server dependency |
|
||||
| `cameleer3-server-app/src/main/resources/application.yml` | Modify | Add OIDC issuer/audience properties |
|
||||
| `cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/SecurityProperties.java` | Modify | Add oidcIssuerUri, oidcAudience fields |
|
||||
| `cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/SecurityConfig.java` | Modify | Build OIDC decoder, pass to filter |
|
||||
| `cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/JwtAuthenticationFilter.java` | Modify | Add OIDC fallback path |
|
||||
| `cameleer3-server-core/src/main/java/com/cameleer3/server/core/security/OidcConfig.java` | Modify | Update default rolesClaim |
|
||||
| `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/OidcConfigAdminController.java` | Modify | Update default rolesClaim |
|
||||
| `cameleer-server-app/pom.xml` | Modify | Add oauth2-resource-server dependency |
|
||||
| `cameleer-server-app/src/main/resources/application.yml` | Modify | Add OIDC issuer/audience properties |
|
||||
| `cameleer-server-app/src/main/java/com/cameleer/server/app/security/SecurityProperties.java` | Modify | Add oidcIssuerUri, oidcAudience fields |
|
||||
| `cameleer-server-app/src/main/java/com/cameleer/server/app/security/SecurityConfig.java` | Modify | Build OIDC decoder, pass to filter |
|
||||
| `cameleer-server-app/src/main/java/com/cameleer/server/app/security/JwtAuthenticationFilter.java` | Modify | Add OIDC fallback path |
|
||||
| `cameleer-server-core/src/main/java/com/cameleer/server/core/security/OidcConfig.java` | Modify | Update default rolesClaim |
|
||||
| `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/OidcConfigAdminController.java` | Modify | Update default rolesClaim |
|
||||
| `deploy/authentik.yaml` | Delete | Remove Authentik deployment |
|
||||
| `deploy/logto.yaml` | Create | Logto server + dedicated PostgreSQL |
|
||||
| `.gitea/workflows/ci.yml` | Modify | Replace Authentik with Logto in CI |
|
||||
@@ -33,11 +33,11 @@
|
||||
### Task 1: Add OAuth2 Resource Server Dependency
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-app/pom.xml:87-97`
|
||||
- Modify: `cameleer-server-app/pom.xml:87-97`
|
||||
|
||||
- [ ] **Step 1: Add the spring-boot-starter-oauth2-resource-server dependency**
|
||||
|
||||
In `cameleer3-server-app/pom.xml`, add after the existing `spring-boot-starter-security` dependency (line 87) and before the `nimbus-jose-jwt` dependency (line 88):
|
||||
In `cameleer-server-app/pom.xml`, add after the existing `spring-boot-starter-security` dependency (line 87) and before the `nimbus-jose-jwt` dependency (line 88):
|
||||
|
||||
```xml
|
||||
<dependency>
|
||||
@@ -66,13 +66,13 @@ The full dependencies section around that area should read:
|
||||
|
||||
- [ ] **Step 2: Verify compilation**
|
||||
|
||||
Run: `mvn clean compile -pl cameleer3-server-app -am -B`
|
||||
Run: `mvn clean compile -pl cameleer-server-app -am -B`
|
||||
Expected: BUILD SUCCESS
|
||||
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/pom.xml
|
||||
git add cameleer-server-app/pom.xml
|
||||
git commit -m "feat: add spring-boot-starter-oauth2-resource-server dependency"
|
||||
```
|
||||
|
||||
@@ -81,8 +81,8 @@ git commit -m "feat: add spring-boot-starter-oauth2-resource-server dependency"
|
||||
### Task 2: Add OIDC Properties
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-app/src/main/resources/application.yml:42-48`
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/SecurityProperties.java`
|
||||
- Modify: `cameleer-server-app/src/main/resources/application.yml:42-48`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/security/SecurityProperties.java`
|
||||
|
||||
- [ ] **Step 1: Add OIDC properties to application.yml**
|
||||
|
||||
@@ -107,7 +107,7 @@ security:
|
||||
Add `oidcIssuerUri` and `oidcAudience` fields with getters/setters. The complete file should be:
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.security;
|
||||
package com.cameleer.server.app.security;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
@@ -154,14 +154,14 @@ public class SecurityProperties {
|
||||
|
||||
- [ ] **Step 3: Verify compilation**
|
||||
|
||||
Run: `mvn clean compile -pl cameleer3-server-app -am -B`
|
||||
Run: `mvn clean compile -pl cameleer-server-app -am -B`
|
||||
Expected: BUILD SUCCESS
|
||||
|
||||
- [ ] **Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/resources/application.yml
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/SecurityProperties.java
|
||||
git add cameleer-server-app/src/main/resources/application.yml
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/security/SecurityProperties.java
|
||||
git commit -m "feat: add OIDC issuer URI and audience security properties"
|
||||
```
|
||||
|
||||
@@ -170,18 +170,18 @@ git commit -m "feat: add OIDC issuer URI and audience security properties"
|
||||
### Task 3: Add OIDC Fallback to JwtAuthenticationFilter
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/JwtAuthenticationFilter.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/security/JwtAuthenticationFilter.java`
|
||||
|
||||
- [ ] **Step 1: Update JwtAuthenticationFilter with OIDC fallback**
|
||||
|
||||
The filter needs a new nullable `oidcDecoder` parameter, a `tryInternalToken` method (wrapping existing logic), a `tryOidcToken` fallback, and scope-based role extraction. The complete updated file:
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.security;
|
||||
package com.cameleer.server.app.security;
|
||||
|
||||
import com.cameleer3.server.core.agent.AgentRegistryService;
|
||||
import com.cameleer3.server.core.security.JwtService;
|
||||
import com.cameleer3.server.core.security.JwtService.JwtValidationResult;
|
||||
import com.cameleer.server.core.agent.AgentRegistryService;
|
||||
import com.cameleer.server.core.security.JwtService;
|
||||
import com.cameleer.server.core.security.JwtService.JwtValidationResult;
|
||||
import jakarta.servlet.FilterChain;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
@@ -323,17 +323,17 @@ This change removes the 2-arg constructor, so `SecurityConfig.java` won't compil
|
||||
### Task 4: Build OIDC Decoder in SecurityConfig
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/SecurityConfig.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/security/SecurityConfig.java`
|
||||
|
||||
- [ ] **Step 1: Update SecurityConfig to build OIDC decoder and pass to filter**
|
||||
|
||||
The `filterChain` method needs an additional `SecurityProperties` parameter, an inline OIDC decoder builder, and must pass the decoder to the `JwtAuthenticationFilter` constructor. The complete updated file:
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.security;
|
||||
package com.cameleer.server.app.security;
|
||||
|
||||
import com.cameleer3.server.core.agent.AgentRegistryService;
|
||||
import com.cameleer3.server.core.security.JwtService;
|
||||
import com.cameleer.server.core.agent.AgentRegistryService;
|
||||
import com.cameleer.server.core.security.JwtService;
|
||||
import com.nimbusds.jose.JWSAlgorithm;
|
||||
import com.nimbusds.jose.jwk.source.JWKSourceBuilder;
|
||||
import com.nimbusds.jose.proc.JWSVerificationKeySelector;
|
||||
@@ -550,19 +550,19 @@ public class SecurityConfig {
|
||||
|
||||
- [ ] **Step 2: Verify compilation**
|
||||
|
||||
Run: `mvn clean compile -pl cameleer3-server-app -am -B`
|
||||
Run: `mvn clean compile -pl cameleer-server-app -am -B`
|
||||
Expected: BUILD SUCCESS
|
||||
|
||||
- [ ] **Step 3: Run tests**
|
||||
|
||||
Run: `mvn test -pl cameleer3-server-app -am -B`
|
||||
Run: `mvn test -pl cameleer-server-app -am -B`
|
||||
Expected: Tests pass (OIDC decoder won't be built since `CAMELEER_OIDC_ISSUER_URI` is empty in test config)
|
||||
|
||||
- [ ] **Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/JwtAuthenticationFilter.java
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/security/SecurityConfig.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/security/JwtAuthenticationFilter.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/security/SecurityConfig.java
|
||||
git commit -m "feat: add OIDC resource server support with JWKS discovery and scope-based roles"
|
||||
```
|
||||
|
||||
@@ -571,8 +571,8 @@ git commit -m "feat: add OIDC resource server support with JWKS discovery and sc
|
||||
### Task 5: Update OidcConfig Default RolesClaim
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/security/OidcConfig.java:28`
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/OidcConfigAdminController.java:101`
|
||||
- Modify: `cameleer-server-core/src/main/java/com/cameleer/server/core/security/OidcConfig.java:28`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/OidcConfigAdminController.java:101`
|
||||
|
||||
- [ ] **Step 1: Update OidcConfig.disabled() default**
|
||||
|
||||
@@ -600,8 +600,8 @@ Expected: BUILD SUCCESS
|
||||
- [ ] **Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-core/src/main/java/com/cameleer3/server/core/security/OidcConfig.java
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/OidcConfigAdminController.java
|
||||
git add cameleer-server-core/src/main/java/com/cameleer/server/core/security/OidcConfig.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/controller/OidcConfigAdminController.java
|
||||
git commit -m "feat: update default rolesClaim to 'roles' for Logto compatibility"
|
||||
```
|
||||
|
||||
|
||||
@@ -12,12 +12,12 @@
|
||||
|
||||
## File Structure
|
||||
|
||||
### New files (core module — `cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/`)
|
||||
### New files (core module — `cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/`)
|
||||
- `ResolvedContainerConfig.java` — typed record with all resolved config fields
|
||||
- `ConfigMerger.java` — pure function, three-layer merge logic
|
||||
- `DeployStage.java` — enum for deployment progress stages
|
||||
|
||||
### New files (app module — `cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/`)
|
||||
### New files (app module — `cameleer-server-app/src/main/java/com/cameleer/server/app/runtime/`)
|
||||
- `TraefikLabelBuilder.java` — generates Traefik Docker labels
|
||||
- `DockerNetworkManager.java` — lazy network creation + container attachment
|
||||
- `DockerEventMonitor.java` — persistent Docker event stream listener
|
||||
@@ -51,7 +51,7 @@
|
||||
### Task 1: Database Migration
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/main/resources/db/migration/V7__deployment_orchestration.sql`
|
||||
- Create: `cameleer-server-app/src/main/resources/db/migration/V7__deployment_orchestration.sql`
|
||||
|
||||
- [ ] **Step 1: Create the migration file**
|
||||
|
||||
@@ -79,7 +79,7 @@ Expected: BUILD SUCCESS
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/resources/db/migration/V7__deployment_orchestration.sql
|
||||
git add cameleer-server-app/src/main/resources/db/migration/V7__deployment_orchestration.sql
|
||||
git commit -m "feat: V7 migration — deployment orchestration columns"
|
||||
```
|
||||
|
||||
@@ -88,15 +88,15 @@ git commit -m "feat: V7 migration — deployment orchestration columns"
|
||||
### Task 2: DeploymentStatus Enum + DeployStage Enum
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/DeploymentStatus.java`
|
||||
- Create: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/DeployStage.java`
|
||||
- Modify: `cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/DeploymentStatus.java`
|
||||
- Create: `cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/DeployStage.java`
|
||||
|
||||
- [ ] **Step 1: Update DeploymentStatus enum**
|
||||
|
||||
Replace the content of `DeploymentStatus.java`:
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.core.runtime;
|
||||
package com.cameleer.server.core.runtime;
|
||||
|
||||
public enum DeploymentStatus {
|
||||
STOPPED, STARTING, RUNNING, DEGRADED, STOPPING, FAILED
|
||||
@@ -106,7 +106,7 @@ public enum DeploymentStatus {
|
||||
- [ ] **Step 2: Create DeployStage enum**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.core.runtime;
|
||||
package com.cameleer.server.core.runtime;
|
||||
|
||||
public enum DeployStage {
|
||||
PRE_FLIGHT, PULL_IMAGE, CREATE_NETWORK, START_REPLICAS, HEALTH_CHECK, SWAP_TRAFFIC, COMPLETE
|
||||
@@ -121,8 +121,8 @@ Expected: BUILD SUCCESS
|
||||
- [ ] **Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/DeploymentStatus.java \
|
||||
cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/DeployStage.java
|
||||
git add cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/DeploymentStatus.java \
|
||||
cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/DeployStage.java
|
||||
git commit -m "feat: add DEGRADED, STOPPING statuses and DeployStage enum"
|
||||
```
|
||||
|
||||
@@ -131,14 +131,14 @@ git commit -m "feat: add DEGRADED, STOPPING statuses and DeployStage enum"
|
||||
### Task 3: Update Deployment Record
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/Deployment.java`
|
||||
- Modify: `cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/Deployment.java`
|
||||
|
||||
- [ ] **Step 1: Update the Deployment record**
|
||||
|
||||
Replace the content of `Deployment.java`:
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.core.runtime;
|
||||
package com.cameleer.server.core.runtime;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
@@ -178,7 +178,7 @@ Expected: Compilation errors in `PostgresDeploymentRepository.java` (wrong const
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/Deployment.java
|
||||
git add cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/Deployment.java
|
||||
git commit -m "feat: add targetState, deploymentStrategy, replicaStates, deployStage to Deployment"
|
||||
```
|
||||
|
||||
@@ -187,18 +187,18 @@ git commit -m "feat: add targetState, deploymentStrategy, replicaStates, deployS
|
||||
### Task 4: Update PostgresDeploymentRepository
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/PostgresDeploymentRepository.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/storage/PostgresDeploymentRepository.java`
|
||||
|
||||
- [ ] **Step 1: Update the repository to handle new columns**
|
||||
|
||||
Replace the full content of `PostgresDeploymentRepository.java`:
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.storage;
|
||||
package com.cameleer.server.app.storage;
|
||||
|
||||
import com.cameleer3.server.core.runtime.Deployment;
|
||||
import com.cameleer3.server.core.runtime.DeploymentRepository;
|
||||
import com.cameleer3.server.core.runtime.DeploymentStatus;
|
||||
import com.cameleer.server.core.runtime.Deployment;
|
||||
import com.cameleer.server.core.runtime.DeploymentRepository;
|
||||
import com.cameleer.server.core.runtime.DeploymentStatus;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
@@ -340,7 +340,7 @@ public class PostgresDeploymentRepository implements DeploymentRepository {
|
||||
|
||||
- [ ] **Step 2: Update RuntimeBeanConfig to pass ObjectMapper to the repository**
|
||||
|
||||
In `cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/RuntimeBeanConfig.java`, change the `deploymentRepository()` bean:
|
||||
In `cameleer-server-app/src/main/java/com/cameleer/server/app/config/RuntimeBeanConfig.java`, change the `deploymentRepository()` bean:
|
||||
|
||||
```java
|
||||
@Bean
|
||||
@@ -357,8 +357,8 @@ Expected: BUILD SUCCESS
|
||||
- [ ] **Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/PostgresDeploymentRepository.java \
|
||||
cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/RuntimeBeanConfig.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/storage/PostgresDeploymentRepository.java \
|
||||
cameleer-server-app/src/main/java/com/cameleer/server/app/config/RuntimeBeanConfig.java
|
||||
git commit -m "feat: update PostgresDeploymentRepository for orchestration columns"
|
||||
```
|
||||
|
||||
@@ -367,13 +367,13 @@ git commit -m "feat: update PostgresDeploymentRepository for orchestration colum
|
||||
### Task 5: ResolvedContainerConfig + ConfigMerger
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/ResolvedContainerConfig.java`
|
||||
- Create: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/ConfigMerger.java`
|
||||
- Create: `cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/ResolvedContainerConfig.java`
|
||||
- Create: `cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/ConfigMerger.java`
|
||||
|
||||
- [ ] **Step 1: Create ResolvedContainerConfig record**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.core.runtime;
|
||||
package com.cameleer.server.core.runtime;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -407,7 +407,7 @@ public record ResolvedContainerConfig(
|
||||
- [ ] **Step 2: Create ConfigMerger**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.core.runtime;
|
||||
package com.cameleer.server.core.runtime;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
@@ -517,8 +517,8 @@ Expected: BUILD SUCCESS
|
||||
- [ ] **Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/ResolvedContainerConfig.java \
|
||||
cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/ConfigMerger.java
|
||||
git add cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/ResolvedContainerConfig.java \
|
||||
cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/ConfigMerger.java
|
||||
git commit -m "feat: ResolvedContainerConfig record and three-layer ConfigMerger"
|
||||
```
|
||||
|
||||
@@ -527,14 +527,14 @@ git commit -m "feat: ResolvedContainerConfig record and three-layer ConfigMerger
|
||||
### Task 6: Update ContainerRequest
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/ContainerRequest.java`
|
||||
- Modify: `cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/ContainerRequest.java`
|
||||
|
||||
- [ ] **Step 1: Expand ContainerRequest with new fields**
|
||||
|
||||
Replace `ContainerRequest.java`:
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.core.runtime;
|
||||
package com.cameleer.server.core.runtime;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -682,9 +682,9 @@ Expected: BUILD SUCCESS
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/ContainerRequest.java \
|
||||
cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/DockerRuntimeOrchestrator.java \
|
||||
cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/DeploymentExecutor.java
|
||||
git add cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/ContainerRequest.java \
|
||||
cameleer-server-app/src/main/java/com/cameleer/server/app/runtime/DockerRuntimeOrchestrator.java \
|
||||
cameleer-server-app/src/main/java/com/cameleer/server/app/runtime/DeploymentExecutor.java
|
||||
git commit -m "feat: expand ContainerRequest with cpuLimit, ports, restart policy, additional networks"
|
||||
```
|
||||
|
||||
@@ -693,14 +693,14 @@ git commit -m "feat: expand ContainerRequest with cpuLimit, ports, restart polic
|
||||
### Task 7: TraefikLabelBuilder
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/TraefikLabelBuilder.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/runtime/TraefikLabelBuilder.java`
|
||||
|
||||
- [ ] **Step 1: Create TraefikLabelBuilder**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.runtime;
|
||||
package com.cameleer.server.app.runtime;
|
||||
|
||||
import com.cameleer3.server.core.runtime.ResolvedContainerConfig;
|
||||
import com.cameleer.server.core.runtime.ResolvedContainerConfig;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
@@ -719,7 +719,7 @@ public final class TraefikLabelBuilder {
|
||||
|
||||
// Core labels
|
||||
labels.put("traefik.enable", "true");
|
||||
labels.put("managed-by", "cameleer3-server");
|
||||
labels.put("managed-by", "cameleer-server");
|
||||
labels.put("cameleer.app", appSlug);
|
||||
labels.put("cameleer.environment", envSlug);
|
||||
|
||||
@@ -767,7 +767,7 @@ Expected: BUILD SUCCESS
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/TraefikLabelBuilder.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/runtime/TraefikLabelBuilder.java
|
||||
git commit -m "feat: TraefikLabelBuilder with path-based and subdomain routing"
|
||||
```
|
||||
|
||||
@@ -776,12 +776,12 @@ git commit -m "feat: TraefikLabelBuilder with path-based and subdomain routing"
|
||||
### Task 8: DockerNetworkManager
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/DockerNetworkManager.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/runtime/DockerNetworkManager.java`
|
||||
|
||||
- [ ] **Step 1: Create DockerNetworkManager**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.runtime;
|
||||
package com.cameleer.server.app.runtime;
|
||||
|
||||
import com.github.dockerjava.api.DockerClient;
|
||||
import com.github.dockerjava.api.model.Network;
|
||||
@@ -912,9 +912,9 @@ Expected: BUILD SUCCESS
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/DockerNetworkManager.java \
|
||||
cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/DockerRuntimeOrchestrator.java \
|
||||
cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/RuntimeOrchestratorAutoConfig.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/runtime/DockerNetworkManager.java \
|
||||
cameleer-server-app/src/main/java/com/cameleer/server/app/runtime/DockerRuntimeOrchestrator.java \
|
||||
cameleer-server-app/src/main/java/com/cameleer/server/app/runtime/RuntimeOrchestratorAutoConfig.java
|
||||
git commit -m "feat: DockerNetworkManager with lazy network creation and container attachment"
|
||||
```
|
||||
|
||||
@@ -923,15 +923,15 @@ git commit -m "feat: DockerNetworkManager with lazy network creation and contain
|
||||
### Task 9: DockerEventMonitor
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/DockerEventMonitor.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/runtime/DockerEventMonitor.java`
|
||||
|
||||
- [ ] **Step 1: Create DockerEventMonitor**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.runtime;
|
||||
package com.cameleer.server.app.runtime;
|
||||
|
||||
import com.cameleer3.server.core.runtime.Deployment;
|
||||
import com.cameleer3.server.core.runtime.DeploymentStatus;
|
||||
import com.cameleer.server.core.runtime.Deployment;
|
||||
import com.cameleer.server.core.runtime.DeploymentStatus;
|
||||
import com.github.dockerjava.api.DockerClient;
|
||||
import com.github.dockerjava.api.async.ResultCallback;
|
||||
import com.github.dockerjava.api.model.Event;
|
||||
@@ -1003,7 +1003,7 @@ public class DockerEventMonitor {
|
||||
|
||||
// Only process containers managed by us
|
||||
Map<String, String> labels = event.getActor() != null ? event.getActor().getAttributes() : null;
|
||||
if (labels == null || !"cameleer3-server".equals(labels.get("managed-by"))) return;
|
||||
if (labels == null || !"cameleer-server".equals(labels.get("managed-by"))) return;
|
||||
|
||||
String action = event.getAction();
|
||||
log.debug("Docker event: {} for container {} ({})", action, containerId.substring(0, 12),
|
||||
@@ -1079,7 +1079,7 @@ Expected: BUILD SUCCESS (may need `PostgresDeploymentRepository` to be injected
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/DockerEventMonitor.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/runtime/DockerEventMonitor.java
|
||||
git commit -m "feat: DockerEventMonitor — persistent event stream for container lifecycle"
|
||||
```
|
||||
|
||||
@@ -1088,7 +1088,7 @@ git commit -m "feat: DockerEventMonitor — persistent event stream for containe
|
||||
### Task 10: Rewrite DeploymentExecutor
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/DeploymentExecutor.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/runtime/DeploymentExecutor.java`
|
||||
|
||||
This is the largest task — the orchestration hub that ties everything together.
|
||||
|
||||
@@ -1097,10 +1097,10 @@ This is the largest task — the orchestration hub that ties everything together
|
||||
Replace the full content of `DeploymentExecutor.java`:
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.runtime;
|
||||
package com.cameleer.server.app.runtime;
|
||||
|
||||
import com.cameleer3.server.app.storage.PostgresDeploymentRepository;
|
||||
import com.cameleer3.server.core.runtime.*;
|
||||
import com.cameleer.server.app.storage.PostgresDeploymentRepository;
|
||||
import com.cameleer.server.core.runtime.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
@@ -1183,7 +1183,7 @@ public class DeploymentExecutor {
|
||||
globalCpuShares,
|
||||
globalRoutingMode,
|
||||
globalRoutingDomain,
|
||||
globalServerUrl.isBlank() ? "http://cameleer3-server:8081" : globalServerUrl
|
||||
globalServerUrl.isBlank() ? "http://cameleer-server:8081" : globalServerUrl
|
||||
);
|
||||
ResolvedContainerConfig config = ConfigMerger.resolve(
|
||||
globalDefaults, env.defaultContainerConfig(), app.containerConfig());
|
||||
@@ -1421,7 +1421,7 @@ Expected: BUILD SUCCESS
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/DeploymentExecutor.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/runtime/DeploymentExecutor.java
|
||||
git commit -m "feat: rewrite DeploymentExecutor with staged deploy, config merge, replicas"
|
||||
```
|
||||
|
||||
@@ -1430,7 +1430,7 @@ git commit -m "feat: rewrite DeploymentExecutor with staged deploy, config merge
|
||||
### Task 11: Update DeploymentController
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/DeploymentController.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/DeploymentController.java`
|
||||
|
||||
- [ ] **Step 1: Update the stop endpoint to use stopDeployment**
|
||||
|
||||
@@ -1460,7 +1460,7 @@ Expected: BUILD SUCCESS
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/DeploymentController.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/controller/DeploymentController.java
|
||||
git commit -m "feat: update stop endpoint to use DeploymentExecutor for replica cleanup"
|
||||
```
|
||||
|
||||
@@ -1469,7 +1469,7 @@ git commit -m "feat: update stop endpoint to use DeploymentExecutor for replica
|
||||
### Task 12: Update application.yml
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-app/src/main/resources/application.yml`
|
||||
- Modify: `cameleer-server-app/src/main/resources/application.yml`
|
||||
|
||||
- [ ] **Step 1: Add the server-url property**
|
||||
|
||||
@@ -1489,7 +1489,7 @@ Expected: BUILD SUCCESS
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/resources/application.yml
|
||||
git add cameleer-server-app/src/main/resources/application.yml
|
||||
git commit -m "feat: add CAMELEER_SERVER_URL config property"
|
||||
```
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ git commit -m "fix: add /deployments redirect and fix GC Pauses chart X-axis"
|
||||
**Spec items:** 1.2
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/UserAdminController.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/UserAdminController.java`
|
||||
- Modify: `ui/src/pages/Admin/UsersTab.tsx`
|
||||
|
||||
- [ ] **Step 1: Run impact analysis on UserAdminController.createUser**
|
||||
@@ -138,7 +138,7 @@ onError: (err: any) => {
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/UserAdminController.java ui/src/pages/Admin/UsersTab.tsx
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/controller/UserAdminController.java ui/src/pages/Admin/UsersTab.tsx
|
||||
git commit -m "fix: show descriptive error when creating local user with OIDC enabled"
|
||||
```
|
||||
|
||||
@@ -1052,7 +1052,7 @@ function shortAgentName(name: string): string {
|
||||
// If name contains multiple dashes (K8s pod name pattern), take the last segment
|
||||
const parts = name.split('-');
|
||||
if (parts.length >= 3) {
|
||||
// Show last 2 segments: "8c0affadb860-1" from "cameleer3-sample-8c0affadb860-1"
|
||||
// Show last 2 segments: "8c0affadb860-1" from "cameleer-sample-8c0affadb860-1"
|
||||
return parts.slice(-2).join('-');
|
||||
}
|
||||
return name;
|
||||
@@ -1458,7 +1458,7 @@ git commit -m "fix: standardize number formatting with consistent unit spacing a
|
||||
|
||||
**Spec items:** 6.4, 6.5
|
||||
|
||||
**Note:** These items are in the `cameleer-saas` repository, not `cameleer3-server`. If the SaaS platform UI code is in a separate repo, this task needs to be executed there. If it's co-located, proceed with these files.
|
||||
**Note:** These items are in the `cameleer-saas` repository, not `cameleer-server`. If the SaaS platform UI code is in a separate repo, this task needs to be executed there. If it's co-located, proceed with these files.
|
||||
|
||||
- [ ] **Step 1: Identify platform component files**
|
||||
|
||||
@@ -1520,7 +1520,7 @@ git commit -m "fix: platform label/value spacing and neutral license badge color
|
||||
|
||||
**Files:**
|
||||
- Modify: `ui/src/pages/Admin/AuditLogPage.tsx`
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/AuditLogController.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/AuditLogController.java`
|
||||
|
||||
- [ ] **Step 1: Add client-side CSV export for current page**
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
**Spec:** `docs/superpowers/specs/2026-04-11-infrastructure-endpoint-visibility-design.md`
|
||||
|
||||
**Cross-repo:** Tasks 1-6 in `cameleer3-server`, Tasks 7-13 in `cameleer-saas`.
|
||||
**Cross-repo:** Tasks 1-6 in `cameleer-server`, Tasks 7-13 in `cameleer-saas`.
|
||||
|
||||
---
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
### Task 1: Add property to application.yml
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-app/src/main/resources/application.yml`
|
||||
- Modify: `cameleer3-server-app/src/test/resources/application-test.yml`
|
||||
- Modify: `cameleer-server-app/src/main/resources/application.yml`
|
||||
- Modify: `cameleer-server-app/src/test/resources/application-test.yml`
|
||||
|
||||
- [ ] **Step 1: Add the property to application.yml**
|
||||
|
||||
@@ -41,7 +41,7 @@ In `application-test.yml`, add under `cameleer.server.security` (after `bootstra
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/resources/application.yml cameleer3-server-app/src/test/resources/application-test.yml
|
||||
git add cameleer-server-app/src/main/resources/application.yml cameleer-server-app/src/test/resources/application-test.yml
|
||||
git commit -m "feat: add infrastructureendpoints property (default true)"
|
||||
```
|
||||
|
||||
@@ -50,7 +50,7 @@ git commit -m "feat: add infrastructureendpoints property (default true)"
|
||||
### Task 2: Add @ConditionalOnProperty to DatabaseAdminController
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/DatabaseAdminController.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/DatabaseAdminController.java`
|
||||
|
||||
- [ ] **Step 1: Add the annotation**
|
||||
|
||||
@@ -73,7 +73,7 @@ Add before `@RestController`:
|
||||
- [ ] **Step 2: Verify compile**
|
||||
|
||||
```bash
|
||||
mvn compile -pl cameleer3-server-app -q
|
||||
mvn compile -pl cameleer-server-app -q
|
||||
```
|
||||
|
||||
Expected: BUILD SUCCESS
|
||||
@@ -81,7 +81,7 @@ Expected: BUILD SUCCESS
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/DatabaseAdminController.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/controller/DatabaseAdminController.java
|
||||
git commit -m "feat: make DatabaseAdminController conditional on infrastructureendpoints"
|
||||
```
|
||||
|
||||
@@ -90,7 +90,7 @@ git commit -m "feat: make DatabaseAdminController conditional on infrastructuree
|
||||
### Task 3: Add @ConditionalOnProperty to ClickHouseAdminController
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/ClickHouseAdminController.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/ClickHouseAdminController.java`
|
||||
|
||||
- [ ] **Step 1: Add the annotation**
|
||||
|
||||
@@ -113,7 +113,7 @@ Add before `@RestController`:
|
||||
- [ ] **Step 2: Verify compile**
|
||||
|
||||
```bash
|
||||
mvn compile -pl cameleer3-server-app -q
|
||||
mvn compile -pl cameleer-server-app -q
|
||||
```
|
||||
|
||||
Expected: BUILD SUCCESS
|
||||
@@ -121,7 +121,7 @@ Expected: BUILD SUCCESS
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/ClickHouseAdminController.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/controller/ClickHouseAdminController.java
|
||||
git commit -m "feat: make ClickHouseAdminController conditional on infrastructureendpoints"
|
||||
```
|
||||
|
||||
@@ -132,12 +132,12 @@ git commit -m "feat: make ClickHouseAdminController conditional on infrastructur
|
||||
The server uses Spring Boot Actuator for `/api/v1/health`. Add a custom `HealthIndicator` that contributes the `infrastructureEndpoints` flag to the health response details.
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/ServerCapabilitiesHealthIndicator.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/config/ServerCapabilitiesHealthIndicator.java`
|
||||
|
||||
- [ ] **Step 1: Create the health indicator**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.config;
|
||||
package com.cameleer.server.app.config;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.actuate.health.Health;
|
||||
@@ -162,7 +162,7 @@ public class ServerCapabilitiesHealthIndicator implements HealthIndicator {
|
||||
- [ ] **Step 2: Verify compile**
|
||||
|
||||
```bash
|
||||
mvn compile -pl cameleer3-server-app -q
|
||||
mvn compile -pl cameleer-server-app -q
|
||||
```
|
||||
|
||||
Expected: BUILD SUCCESS
|
||||
@@ -180,7 +180,7 @@ Expected: `true`
|
||||
- [ ] **Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/ServerCapabilitiesHealthIndicator.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/config/ServerCapabilitiesHealthIndicator.java
|
||||
git commit -m "feat: expose infrastructureEndpoints flag in health endpoint"
|
||||
```
|
||||
|
||||
@@ -1117,8 +1117,8 @@ git commit -m "feat: add Infrastructure to vendor sidebar and router"
|
||||
### Task 14: Update documentation
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server/CLAUDE.md` — mention `CAMELEER_SERVER_SECURITY_INFRASTRUCTUREENDPOINTS` in the Security section and Docker Orchestration section
|
||||
- Modify: `cameleer3-server/HOWTO.md` — add to Configuration table under Security
|
||||
- Modify: `cameleer-server/CLAUDE.md` — mention `CAMELEER_SERVER_SECURITY_INFRASTRUCTUREENDPOINTS` in the Security section and Docker Orchestration section
|
||||
- Modify: `cameleer-server/HOWTO.md` — add to Configuration table under Security
|
||||
- Modify: `cameleer-saas/CLAUDE.md` — mention Infrastructure page in vendor section, add to "Per-tenant server env vars" table
|
||||
|
||||
- [ ] **Step 1: Update server CLAUDE.md**
|
||||
@@ -1152,7 +1152,7 @@ In the Layout.tsx description, add "Infrastructure" to the vendor sidebar list.
|
||||
|
||||
```bash
|
||||
# Server
|
||||
cd cameleer3-server
|
||||
cd cameleer-server
|
||||
git add CLAUDE.md HOWTO.md
|
||||
git commit -m "docs: document infrastructureendpoints flag"
|
||||
|
||||
|
||||
@@ -14,21 +14,21 @@
|
||||
|
||||
| Action | File | Responsibility |
|
||||
|--------|------|----------------|
|
||||
| Create | `cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/RuntimeType.java` | Enum: AUTO, SPRING_BOOT, QUARKUS, PLAIN_JAVA, NATIVE |
|
||||
| Create | `cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/RuntimeDetector.java` | Probes JAR files and returns detected RuntimeType + mainClass |
|
||||
| Create | `cameleer3-server-core/src/test/java/com/cameleer3/server/core/runtime/RuntimeDetectorTest.java` | Unit tests for detection logic |
|
||||
| Create | `cameleer3-server-app/src/main/resources/db/migration/V10__app_version_runtime_detection.sql` | Adds detected_runtime_type and detected_main_class to app_versions |
|
||||
| Modify | `cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/AppVersion.java` | Add detectedRuntimeType, detectedMainClass fields |
|
||||
| Modify | `cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/AppVersionRepository.java` | Add updateDetectedRuntime method |
|
||||
| Modify | `cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/PostgresAppVersionRepository.java` | Persist and read new columns |
|
||||
| Modify | `cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/AppService.java` | Run detection after upload |
|
||||
| Modify | `cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/ResolvedContainerConfig.java` | Add runtimeType, customArgs fields |
|
||||
| Modify | `cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/ConfigMerger.java` | Resolve runtimeType, customArgs |
|
||||
| Modify | `cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/ContainerRequest.java` | Add runtimeType, customArgs, mainClass fields |
|
||||
| Modify | `cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/DockerRuntimeOrchestrator.java` | Build entrypoint per runtime type |
|
||||
| Modify | `cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/DeploymentExecutor.java` | Resolve AUTO, pass runtime fields to ContainerRequest |
|
||||
| Modify | `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/AppController.java` | Validate customArgs on config save |
|
||||
| Modify | `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/EnvironmentAdminController.java` | Validate customArgs on config save |
|
||||
| Create | `cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/RuntimeType.java` | Enum: AUTO, SPRING_BOOT, QUARKUS, PLAIN_JAVA, NATIVE |
|
||||
| Create | `cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/RuntimeDetector.java` | Probes JAR files and returns detected RuntimeType + mainClass |
|
||||
| Create | `cameleer-server-core/src/test/java/com/cameleer/server/core/runtime/RuntimeDetectorTest.java` | Unit tests for detection logic |
|
||||
| Create | `cameleer-server-app/src/main/resources/db/migration/V10__app_version_runtime_detection.sql` | Adds detected_runtime_type and detected_main_class to app_versions |
|
||||
| Modify | `cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/AppVersion.java` | Add detectedRuntimeType, detectedMainClass fields |
|
||||
| Modify | `cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/AppVersionRepository.java` | Add updateDetectedRuntime method |
|
||||
| Modify | `cameleer-server-app/src/main/java/com/cameleer/server/app/storage/PostgresAppVersionRepository.java` | Persist and read new columns |
|
||||
| Modify | `cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/AppService.java` | Run detection after upload |
|
||||
| Modify | `cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/ResolvedContainerConfig.java` | Add runtimeType, customArgs fields |
|
||||
| Modify | `cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/ConfigMerger.java` | Resolve runtimeType, customArgs |
|
||||
| Modify | `cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/ContainerRequest.java` | Add runtimeType, customArgs, mainClass fields |
|
||||
| Modify | `cameleer-server-app/src/main/java/com/cameleer/server/app/runtime/DockerRuntimeOrchestrator.java` | Build entrypoint per runtime type |
|
||||
| Modify | `cameleer-server-app/src/main/java/com/cameleer/server/app/runtime/DeploymentExecutor.java` | Resolve AUTO, pass runtime fields to ContainerRequest |
|
||||
| Modify | `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/AppController.java` | Validate customArgs on config save |
|
||||
| Modify | `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/EnvironmentAdminController.java` | Validate customArgs on config save |
|
||||
| Modify | `ui/src/api/queries/admin/apps.ts` | Add new fields to AppVersion type |
|
||||
| Modify | `ui/src/pages/AppsTab/AppsTab.tsx` | Runtime Type select, Custom Arguments input, detection hint |
|
||||
|
||||
@@ -37,15 +37,15 @@
|
||||
### Task 1: RuntimeType Enum and RuntimeDetector
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/RuntimeType.java`
|
||||
- Create: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/RuntimeDetector.java`
|
||||
- Create: `cameleer3-server-core/src/test/java/com/cameleer3/server/core/runtime/RuntimeDetectorTest.java`
|
||||
- Create: `cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/RuntimeType.java`
|
||||
- Create: `cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/RuntimeDetector.java`
|
||||
- Create: `cameleer-server-core/src/test/java/com/cameleer/server/core/runtime/RuntimeDetectorTest.java`
|
||||
|
||||
- [ ] **Step 1: Create the RuntimeType enum**
|
||||
|
||||
```java
|
||||
// cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/RuntimeType.java
|
||||
package com.cameleer3.server.core.runtime;
|
||||
// cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/RuntimeType.java
|
||||
package com.cameleer.server.core.runtime;
|
||||
|
||||
public enum RuntimeType {
|
||||
AUTO,
|
||||
@@ -77,8 +77,8 @@ public enum RuntimeType {
|
||||
- [ ] **Step 2: Write RuntimeDetector tests**
|
||||
|
||||
```java
|
||||
// cameleer3-server-core/src/test/java/com/cameleer3/server/core/runtime/RuntimeDetectorTest.java
|
||||
package com.cameleer3.server.core.runtime;
|
||||
// cameleer-server-core/src/test/java/com/cameleer/server/core/runtime/RuntimeDetectorTest.java
|
||||
package com.cameleer.server.core.runtime;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
@@ -190,14 +190,14 @@ class RuntimeDetectorTest {
|
||||
|
||||
- [ ] **Step 3: Run tests to verify they fail**
|
||||
|
||||
Run: `mvn test -pl cameleer3-server-core -Dtest=RuntimeDetectorTest -Dsurefire.failIfNoSpecifiedTests=false`
|
||||
Run: `mvn test -pl cameleer-server-core -Dtest=RuntimeDetectorTest -Dsurefire.failIfNoSpecifiedTests=false`
|
||||
Expected: FAIL — `RuntimeDetector` class not found
|
||||
|
||||
- [ ] **Step 4: Implement RuntimeDetector**
|
||||
|
||||
```java
|
||||
// cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/RuntimeDetector.java
|
||||
package com.cameleer3.server.core.runtime;
|
||||
// cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/RuntimeDetector.java
|
||||
package com.cameleer.server.core.runtime;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@@ -278,15 +278,15 @@ public final class RuntimeDetector {
|
||||
|
||||
- [ ] **Step 5: Run tests to verify they pass**
|
||||
|
||||
Run: `mvn test -pl cameleer3-server-core -Dtest=RuntimeDetectorTest`
|
||||
Run: `mvn test -pl cameleer-server-core -Dtest=RuntimeDetectorTest`
|
||||
Expected: All 8 tests PASS
|
||||
|
||||
- [ ] **Step 6: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/RuntimeType.java \
|
||||
cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/RuntimeDetector.java \
|
||||
cameleer3-server-core/src/test/java/com/cameleer3/server/core/runtime/RuntimeDetectorTest.java
|
||||
git add cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/RuntimeType.java \
|
||||
cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/RuntimeDetector.java \
|
||||
cameleer-server-core/src/test/java/com/cameleer/server/core/runtime/RuntimeDetectorTest.java
|
||||
git commit -m "feat: add RuntimeType enum and RuntimeDetector for JAR probing"
|
||||
```
|
||||
|
||||
@@ -295,25 +295,25 @@ git commit -m "feat: add RuntimeType enum and RuntimeDetector for JAR probing"
|
||||
### Task 2: AppVersion + Migration + Repository
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/main/resources/db/migration/V10__app_version_runtime_detection.sql`
|
||||
- Modify: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/AppVersion.java`
|
||||
- Modify: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/AppVersionRepository.java`
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/PostgresAppVersionRepository.java`
|
||||
- Create: `cameleer-server-app/src/main/resources/db/migration/V10__app_version_runtime_detection.sql`
|
||||
- Modify: `cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/AppVersion.java`
|
||||
- Modify: `cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/AppVersionRepository.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/storage/PostgresAppVersionRepository.java`
|
||||
|
||||
- [ ] **Step 1: Create Flyway migration**
|
||||
|
||||
```sql
|
||||
-- cameleer3-server-app/src/main/resources/db/migration/V10__app_version_runtime_detection.sql
|
||||
-- cameleer-server-app/src/main/resources/db/migration/V10__app_version_runtime_detection.sql
|
||||
ALTER TABLE app_versions ADD COLUMN detected_runtime_type VARCHAR;
|
||||
ALTER TABLE app_versions ADD COLUMN detected_main_class VARCHAR;
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Update AppVersion record**
|
||||
|
||||
Replace the entire content of `cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/AppVersion.java`:
|
||||
Replace the entire content of `cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/AppVersion.java`:
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.core.runtime;
|
||||
package com.cameleer.server.core.runtime;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
@@ -325,7 +325,7 @@ public record AppVersion(UUID id, UUID appId, int version, String jarPath, Strin
|
||||
|
||||
- [ ] **Step 3: Add updateDetectedRuntime to AppVersionRepository**
|
||||
|
||||
In `cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/AppVersionRepository.java`, add after the `delete` method (line 12):
|
||||
In `cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/AppVersionRepository.java`, add after the `delete` method (line 12):
|
||||
|
||||
```java
|
||||
void updateDetectedRuntime(UUID id, String detectedRuntimeType, String detectedMainClass);
|
||||
@@ -334,7 +334,7 @@ In `cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/AppVer
|
||||
Full file becomes:
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.core.runtime;
|
||||
package com.cameleer.server.core.runtime;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@@ -352,7 +352,7 @@ public interface AppVersionRepository {
|
||||
|
||||
- [ ] **Step 4: Update PostgresAppVersionRepository**
|
||||
|
||||
In `cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/PostgresAppVersionRepository.java`:
|
||||
In `cameleer-server-app/src/main/java/com/cameleer/server/app/storage/PostgresAppVersionRepository.java`:
|
||||
|
||||
Update the SQL SELECT queries in `findByAppId` (line 24) and `findById` (line 31) to include the new columns:
|
||||
|
||||
@@ -404,10 +404,10 @@ Expected: BUILD SUCCESS
|
||||
- [ ] **Step 6: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/resources/db/migration/V10__app_version_runtime_detection.sql \
|
||||
cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/AppVersion.java \
|
||||
cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/AppVersionRepository.java \
|
||||
cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/PostgresAppVersionRepository.java
|
||||
git add cameleer-server-app/src/main/resources/db/migration/V10__app_version_runtime_detection.sql \
|
||||
cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/AppVersion.java \
|
||||
cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/AppVersionRepository.java \
|
||||
cameleer-server-app/src/main/java/com/cameleer/server/app/storage/PostgresAppVersionRepository.java
|
||||
git commit -m "feat: add detected_runtime_type and detected_main_class to app_versions"
|
||||
```
|
||||
|
||||
@@ -416,11 +416,11 @@ git commit -m "feat: add detected_runtime_type and detected_main_class to app_ve
|
||||
### Task 3: Run Detection on Upload
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/AppService.java`
|
||||
- Modify: `cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/AppService.java`
|
||||
|
||||
- [ ] **Step 1: Update AppService.uploadJar to run detection after saving**
|
||||
|
||||
In `cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/AppService.java`, add an import at the top:
|
||||
In `cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/AppService.java`, add an import at the top:
|
||||
|
||||
```java
|
||||
import java.nio.file.Path;
|
||||
@@ -481,7 +481,7 @@ Expected: BUILD SUCCESS
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/AppService.java
|
||||
git add cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/AppService.java
|
||||
git commit -m "feat: run runtime detection on JAR upload"
|
||||
```
|
||||
|
||||
@@ -490,12 +490,12 @@ git commit -m "feat: run runtime detection on JAR upload"
|
||||
### Task 4: ConfigMerger + ResolvedContainerConfig
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/ResolvedContainerConfig.java`
|
||||
- Modify: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/ConfigMerger.java`
|
||||
- Modify: `cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/ResolvedContainerConfig.java`
|
||||
- Modify: `cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/ConfigMerger.java`
|
||||
|
||||
- [ ] **Step 1: Add runtimeType and customArgs to ResolvedContainerConfig**
|
||||
|
||||
In `cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/ResolvedContainerConfig.java`, add two new fields after `replayEnabled` (line 22):
|
||||
In `cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/ResolvedContainerConfig.java`, add two new fields after `replayEnabled` (line 22):
|
||||
|
||||
```java
|
||||
boolean replayEnabled,
|
||||
@@ -532,7 +532,7 @@ The existing helper methods (`memoryLimitBytes`, `memoryReserveBytes`, `dockerCp
|
||||
|
||||
- [ ] **Step 2: Update ConfigMerger.resolve() to include new fields**
|
||||
|
||||
In `cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/ConfigMerger.java`, add two new lines at the end of the `resolve()` return statement (after line 33, the `replayEnabled` line):
|
||||
In `cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/ConfigMerger.java`, add two new lines at the end of the `resolve()` return statement (after line 33, the `replayEnabled` line):
|
||||
|
||||
```java
|
||||
boolVal(appConfig, envConfig, "routeControlEnabled", true),
|
||||
@@ -550,8 +550,8 @@ Expected: FAIL — `DeploymentExecutor.resolvedConfigToMap()` creates `ResolvedC
|
||||
- [ ] **Step 4: Commit (with compile fix deferred to Task 5)**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/ResolvedContainerConfig.java \
|
||||
cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/ConfigMerger.java
|
||||
git add cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/ResolvedContainerConfig.java \
|
||||
cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/ConfigMerger.java
|
||||
git commit -m "feat: add runtimeType and customArgs to ResolvedContainerConfig and ConfigMerger"
|
||||
```
|
||||
|
||||
@@ -560,16 +560,16 @@ git commit -m "feat: add runtimeType and customArgs to ResolvedContainerConfig a
|
||||
### Task 5: ContainerRequest + DeploymentExecutor + Entrypoint
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/ContainerRequest.java`
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/DeploymentExecutor.java`
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/DockerRuntimeOrchestrator.java`
|
||||
- Modify: `cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/ContainerRequest.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/runtime/DeploymentExecutor.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/runtime/DockerRuntimeOrchestrator.java`
|
||||
|
||||
- [ ] **Step 1: Add runtimeType, customArgs, mainClass to ContainerRequest**
|
||||
|
||||
Replace the full content of `cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/ContainerRequest.java`:
|
||||
Replace the full content of `cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/ContainerRequest.java`:
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.core.runtime;
|
||||
package com.cameleer.server.core.runtime;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -600,12 +600,12 @@ public record ContainerRequest(
|
||||
|
||||
- [ ] **Step 2: Update DeploymentExecutor — resolve AUTO, pass runtime fields, update resolvedConfigToMap**
|
||||
|
||||
In `cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/DeploymentExecutor.java`:
|
||||
In `cameleer-server-app/src/main/java/com/cameleer/server/app/runtime/DeploymentExecutor.java`:
|
||||
|
||||
Add import at top:
|
||||
|
||||
```java
|
||||
import com.cameleer3.server.core.runtime.RuntimeType;
|
||||
import com.cameleer.server.core.runtime.RuntimeType;
|
||||
```
|
||||
|
||||
In `executeAsync()`, after `preFlightChecks(jarPath, config);` (after the PRE_FLIGHT stage comment block), add runtime type resolution:
|
||||
@@ -666,7 +666,7 @@ Update `resolvedConfigToMap()` to include new fields — add at the end before t
|
||||
|
||||
- [ ] **Step 3: Add getVersion method to AppService**
|
||||
|
||||
In `cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/AppService.java`, add after `listVersions` (line 33):
|
||||
In `cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/AppService.java`, add after `listVersions` (line 33):
|
||||
|
||||
```java
|
||||
public AppVersion getVersion(UUID versionId) {
|
||||
@@ -677,7 +677,7 @@ In `cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/AppSer
|
||||
|
||||
- [ ] **Step 4: Update DockerRuntimeOrchestrator entrypoint construction**
|
||||
|
||||
In `cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/DockerRuntimeOrchestrator.java`, replace the entrypoint block (the section starting with `// Resolve the JAR path for the entrypoint` through the `createCmd.withEntrypoint` call) with:
|
||||
In `cameleer-server-app/src/main/java/com/cameleer/server/app/runtime/DockerRuntimeOrchestrator.java`, replace the entrypoint block (the section starting with `// Resolve the JAR path for the entrypoint` through the `createCmd.withEntrypoint` call) with:
|
||||
|
||||
```java
|
||||
// Resolve the JAR path for the entrypoint
|
||||
@@ -707,10 +707,10 @@ In `cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/DockerRu
|
||||
String entrypoint = switch (request.runtimeType()) {
|
||||
case "quarkus" -> "exec java -javaagent:/app/agent.jar" + customArgs + " -jar " + appJarPath;
|
||||
case "plain-java" -> "exec java -javaagent:/app/agent.jar -cp " + appJarPath +
|
||||
":/app/cameleer3-log-appender.jar" + customArgs + " " + request.mainClass();
|
||||
":/app/cameleer-log-appender.jar" + customArgs + " " + request.mainClass();
|
||||
case "native" -> "exec " + appJarPath + customArgs;
|
||||
default -> // spring-boot (default)
|
||||
"exec java -javaagent:/app/agent.jar -Dloader.path=/app/cameleer3-log-appender.jar" +
|
||||
"exec java -javaagent:/app/agent.jar -Dloader.path=/app/cameleer-log-appender.jar" +
|
||||
customArgs + " -cp " + appJarPath + " org.springframework.boot.loader.launch.PropertiesLauncher";
|
||||
};
|
||||
createCmd.withEntrypoint("sh", "-c", entrypoint);
|
||||
@@ -724,10 +724,10 @@ Expected: BUILD SUCCESS
|
||||
- [ ] **Step 6: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/ContainerRequest.java \
|
||||
cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/AppService.java \
|
||||
cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/DeploymentExecutor.java \
|
||||
cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/DockerRuntimeOrchestrator.java
|
||||
git add cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/ContainerRequest.java \
|
||||
cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/AppService.java \
|
||||
cameleer-server-app/src/main/java/com/cameleer/server/app/runtime/DeploymentExecutor.java \
|
||||
cameleer-server-app/src/main/java/com/cameleer/server/app/runtime/DockerRuntimeOrchestrator.java
|
||||
git commit -m "feat: build Docker entrypoint per runtime type with custom args support"
|
||||
```
|
||||
|
||||
@@ -736,12 +736,12 @@ git commit -m "feat: build Docker entrypoint per runtime type with custom args s
|
||||
### Task 6: Input Validation
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/AppController.java`
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/EnvironmentAdminController.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/AppController.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/EnvironmentAdminController.java`
|
||||
|
||||
- [ ] **Step 1: Add validation to AppController.updateContainerConfig**
|
||||
|
||||
In `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/AppController.java`, add a validation constant and helper method at the bottom of the class, before the `CreateAppRequest` record:
|
||||
In `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/AppController.java`, add a validation constant and helper method at the bottom of the class, before the `CreateAppRequest` record:
|
||||
|
||||
```java
|
||||
private static final java.util.regex.Pattern CUSTOM_ARGS_PATTERN =
|
||||
@@ -763,7 +763,7 @@ In `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/AppCo
|
||||
Add import at top:
|
||||
|
||||
```java
|
||||
import com.cameleer3.server.core.runtime.RuntimeType;
|
||||
import com.cameleer.server.core.runtime.RuntimeType;
|
||||
```
|
||||
|
||||
Update the `updateContainerConfig` method to call validation:
|
||||
@@ -792,7 +792,7 @@ Update the `updateContainerConfig` method to call validation:
|
||||
|
||||
- [ ] **Step 2: Add same validation to EnvironmentAdminController.updateDefaultContainerConfig**
|
||||
|
||||
In `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/EnvironmentAdminController.java`, add the same constant, helper, and import. Then call `validateContainerConfig(defaultContainerConfig)` as the first line in the try block of `updateDefaultContainerConfig`.
|
||||
In `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/EnvironmentAdminController.java`, add the same constant, helper, and import. Then call `validateContainerConfig(defaultContainerConfig)` as the first line in the try block of `updateDefaultContainerConfig`.
|
||||
|
||||
- [ ] **Step 3: Verify compilation**
|
||||
|
||||
@@ -802,8 +802,8 @@ Expected: BUILD SUCCESS
|
||||
- [ ] **Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/AppController.java \
|
||||
cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/EnvironmentAdminController.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/controller/AppController.java \
|
||||
cameleer-server-app/src/main/java/com/cameleer/server/app/controller/EnvironmentAdminController.java
|
||||
git commit -m "feat: validate runtimeType and customArgs on container config save"
|
||||
```
|
||||
|
||||
@@ -962,7 +962,7 @@ The `AppVersion` record gained 2 new fields and `ResolvedContainerConfig` gained
|
||||
|
||||
Search for these with:
|
||||
```bash
|
||||
grep -rn "new AppVersion\|new ResolvedContainerConfig\|new ContainerRequest" --include="*.java" cameleer3-server-*/src/test/
|
||||
grep -rn "new AppVersion\|new ResolvedContainerConfig\|new ContainerRequest" --include="*.java" cameleer-server-*/src/test/
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Commit fixes if any**
|
||||
|
||||
1007
docs/superpowers/plans/2026-04-14-claim-mapping-rules-editor.md
Normal file
1007
docs/superpowers/plans/2026-04-14-claim-mapping-rules-editor.md
Normal file
File diff suppressed because it is too large
Load Diff
@@ -18,7 +18,7 @@
|
||||
|
||||
| File | Responsibility |
|
||||
|------|----------------|
|
||||
| `cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/ContainerLogForwarder.java` | Docker log streaming, batching, ClickHouse flush, session lifecycle |
|
||||
| `cameleer-server-app/src/main/java/com/cameleer/server/app/runtime/ContainerLogForwarder.java` | Docker log streaming, batching, ClickHouse flush, session lifecycle |
|
||||
| `ui/src/components/StartupLogPanel.tsx` | Collapsible log panel for deployment startup logs |
|
||||
| `ui/src/components/StartupLogPanel.module.css` | Styles for startup log panel |
|
||||
|
||||
@@ -26,13 +26,13 @@
|
||||
|
||||
| File | Change |
|
||||
|------|--------|
|
||||
| `cameleer3-server-core/.../RuntimeOrchestrator.java` | Add 3 default no-op methods |
|
||||
| `cameleer3-server-app/.../DockerRuntimeOrchestrator.java` | Implement log capture, delegate to forwarder |
|
||||
| `cameleer3-server-app/.../DisabledRuntimeOrchestrator.java` | Override no-ops (explicit) |
|
||||
| `cameleer3-server-app/.../RuntimeOrchestratorAutoConfig.java` | Create and wire `ContainerLogForwarder` bean |
|
||||
| `cameleer3-server-app/.../DeploymentExecutor.java` | Call `startLogCapture()` after container start |
|
||||
| `cameleer3-server-app/.../SseConnectionManager.java` | Call `stopLogCaptureByApp()` on SSE connect |
|
||||
| `cameleer3-server-app/.../DockerEventMonitor.java` | Call `stopLogCapture()` on die/oom |
|
||||
| `cameleer-server-core/.../RuntimeOrchestrator.java` | Add 3 default no-op methods |
|
||||
| `cameleer-server-app/.../DockerRuntimeOrchestrator.java` | Implement log capture, delegate to forwarder |
|
||||
| `cameleer-server-app/.../DisabledRuntimeOrchestrator.java` | Override no-ops (explicit) |
|
||||
| `cameleer-server-app/.../RuntimeOrchestratorAutoConfig.java` | Create and wire `ContainerLogForwarder` bean |
|
||||
| `cameleer-server-app/.../DeploymentExecutor.java` | Call `startLogCapture()` after container start |
|
||||
| `cameleer-server-app/.../SseConnectionManager.java` | Call `stopLogCaptureByApp()` on SSE connect |
|
||||
| `cameleer-server-app/.../DockerEventMonitor.java` | Call `stopLogCapture()` on die/oom |
|
||||
| `ui/src/pages/AppsTab/AppsTab.tsx` | Render `StartupLogPanel` below `DeploymentProgress` |
|
||||
| `ui/src/pages/AgentInstance/AgentInstance.tsx` | Add `container` to `LOG_SOURCE_ITEMS` |
|
||||
| `ui/src/api/queries/logs.ts` | Add `useStartupLogs` hook |
|
||||
@@ -42,15 +42,15 @@
|
||||
### Task 1: Extend RuntimeOrchestrator Interface
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/RuntimeOrchestrator.java`
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/DisabledRuntimeOrchestrator.java`
|
||||
- Modify: `cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/RuntimeOrchestrator.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/runtime/DisabledRuntimeOrchestrator.java`
|
||||
|
||||
- [ ] **Step 1: Add default methods to RuntimeOrchestrator**
|
||||
|
||||
In `cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/RuntimeOrchestrator.java`, add three default no-op methods after the existing `getLogs` method (line 11):
|
||||
In `cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/RuntimeOrchestrator.java`, add three default no-op methods after the existing `getLogs` method (line 11):
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.core.runtime;
|
||||
package com.cameleer.server.core.runtime;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@@ -75,7 +75,7 @@ public interface RuntimeOrchestrator {
|
||||
|
||||
- [ ] **Step 2: Add explicit overrides to DisabledRuntimeOrchestrator**
|
||||
|
||||
In `cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/DisabledRuntimeOrchestrator.java`, add explicit no-op overrides after line 15:
|
||||
In `cameleer-server-app/src/main/java/com/cameleer/server/app/runtime/DisabledRuntimeOrchestrator.java`, add explicit no-op overrides after line 15:
|
||||
|
||||
```java
|
||||
@Override public void startLogCapture(String containerId, String appSlug, String envSlug, String tenantId) {}
|
||||
@@ -85,14 +85,14 @@ In `cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/Disabled
|
||||
|
||||
- [ ] **Step 3: Verify compilation**
|
||||
|
||||
Run: `mvn clean compile -pl cameleer3-server-core,cameleer3-server-app -q`
|
||||
Run: `mvn clean compile -pl cameleer-server-core,cameleer-server-app -q`
|
||||
Expected: BUILD SUCCESS
|
||||
|
||||
- [ ] **Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-core/src/main/java/com/cameleer3/server/core/runtime/RuntimeOrchestrator.java \
|
||||
cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/DisabledRuntimeOrchestrator.java
|
||||
git add cameleer-server-core/src/main/java/com/cameleer/server/core/runtime/RuntimeOrchestrator.java \
|
||||
cameleer-server-app/src/main/java/com/cameleer/server/app/runtime/DisabledRuntimeOrchestrator.java
|
||||
git commit -m "feat: add log capture methods to RuntimeOrchestrator interface"
|
||||
```
|
||||
|
||||
@@ -101,16 +101,16 @@ git commit -m "feat: add log capture methods to RuntimeOrchestrator interface"
|
||||
### Task 2: Create ContainerLogForwarder
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/ContainerLogForwarder.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/runtime/ContainerLogForwarder.java`
|
||||
|
||||
- [ ] **Step 1: Create ContainerLogForwarder class**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.runtime;
|
||||
package com.cameleer.server.app.runtime;
|
||||
|
||||
import com.cameleer3.common.model.LogEntry;
|
||||
import com.cameleer3.server.app.search.ClickHouseLogStore;
|
||||
import com.cameleer3.server.core.ingestion.BufferedLogEntry;
|
||||
import com.cameleer.common.model.LogEntry;
|
||||
import com.cameleer.server.app.search.ClickHouseLogStore;
|
||||
import com.cameleer.server.core.ingestion.BufferedLogEntry;
|
||||
import com.github.dockerjava.api.DockerClient;
|
||||
import com.github.dockerjava.api.async.ResultCallback;
|
||||
import com.github.dockerjava.api.model.Frame;
|
||||
@@ -370,13 +370,13 @@ public class ContainerLogForwarder {
|
||||
|
||||
- [ ] **Step 2: Verify compilation**
|
||||
|
||||
Run: `mvn clean compile -pl cameleer3-server-app -q`
|
||||
Run: `mvn clean compile -pl cameleer-server-app -q`
|
||||
Expected: BUILD SUCCESS
|
||||
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/ContainerLogForwarder.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/runtime/ContainerLogForwarder.java
|
||||
git commit -m "feat: add ContainerLogForwarder for Docker log streaming to ClickHouse"
|
||||
```
|
||||
|
||||
@@ -385,8 +385,8 @@ git commit -m "feat: add ContainerLogForwarder for Docker log streaming to Click
|
||||
### Task 3: Wire ContainerLogForwarder and Implement in DockerRuntimeOrchestrator
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/DockerRuntimeOrchestrator.java`
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/RuntimeOrchestratorAutoConfig.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/runtime/DockerRuntimeOrchestrator.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/runtime/RuntimeOrchestratorAutoConfig.java`
|
||||
|
||||
- [ ] **Step 1: Add ContainerLogForwarder field and log capture methods to DockerRuntimeOrchestrator**
|
||||
|
||||
@@ -467,19 +467,19 @@ Add the `ContainerLogForwarder` bean after `dockerEventMonitor()` (after line 46
|
||||
Add the import at the top:
|
||||
|
||||
```java
|
||||
import com.cameleer3.server.app.search.ClickHouseLogStore;
|
||||
import com.cameleer.server.app.search.ClickHouseLogStore;
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Verify compilation**
|
||||
|
||||
Run: `mvn clean compile -pl cameleer3-server-app -q`
|
||||
Run: `mvn clean compile -pl cameleer-server-app -q`
|
||||
Expected: BUILD SUCCESS
|
||||
|
||||
- [ ] **Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/DockerRuntimeOrchestrator.java \
|
||||
cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/RuntimeOrchestratorAutoConfig.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/runtime/DockerRuntimeOrchestrator.java \
|
||||
cameleer-server-app/src/main/java/com/cameleer/server/app/runtime/RuntimeOrchestratorAutoConfig.java
|
||||
git commit -m "feat: wire ContainerLogForwarder into DockerRuntimeOrchestrator"
|
||||
```
|
||||
|
||||
@@ -488,7 +488,7 @@ git commit -m "feat: wire ContainerLogForwarder into DockerRuntimeOrchestrator"
|
||||
### Task 4: Integrate Start Capture in DeploymentExecutor
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/DeploymentExecutor.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/runtime/DeploymentExecutor.java`
|
||||
|
||||
- [ ] **Step 1: Add startLogCapture call after each replica starts**
|
||||
|
||||
@@ -520,13 +520,13 @@ This goes right between the network connection loop and the `replicaStates.add(M
|
||||
|
||||
- [ ] **Step 2: Verify compilation**
|
||||
|
||||
Run: `mvn clean compile -pl cameleer3-server-app -q`
|
||||
Run: `mvn clean compile -pl cameleer-server-app -q`
|
||||
Expected: BUILD SUCCESS
|
||||
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/DeploymentExecutor.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/runtime/DeploymentExecutor.java
|
||||
git commit -m "feat: start log capture when deployment replicas are created"
|
||||
```
|
||||
|
||||
@@ -535,7 +535,7 @@ git commit -m "feat: start log capture when deployment replicas are created"
|
||||
### Task 5: Integrate Stop Capture in SseConnectionManager
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/agent/SseConnectionManager.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/agent/SseConnectionManager.java`
|
||||
|
||||
- [ ] **Step 1: Inject RuntimeOrchestrator and call stopLogCaptureByApp on SSE connect**
|
||||
|
||||
@@ -558,8 +558,8 @@ In `SseConnectionManager.java`, add the `RuntimeOrchestrator` dependency. Modify
|
||||
Add the import at the top:
|
||||
|
||||
```java
|
||||
import com.cameleer3.server.core.runtime.RuntimeOrchestrator;
|
||||
import com.cameleer3.server.core.agent.AgentInfo;
|
||||
import com.cameleer.server.core.runtime.RuntimeOrchestrator;
|
||||
import com.cameleer.server.core.agent.AgentInfo;
|
||||
```
|
||||
|
||||
In the `connect()` method (line 60), after the `log.info("SSE connection established...")` (line 83), add the stop capture call:
|
||||
@@ -574,13 +574,13 @@ In the `connect()` method (line 60), after the `log.info("SSE connection establi
|
||||
|
||||
- [ ] **Step 2: Verify compilation**
|
||||
|
||||
Run: `mvn clean compile -pl cameleer3-server-app -q`
|
||||
Run: `mvn clean compile -pl cameleer-server-app -q`
|
||||
Expected: BUILD SUCCESS
|
||||
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/agent/SseConnectionManager.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/agent/SseConnectionManager.java
|
||||
git commit -m "feat: stop container log capture when agent SSE connects"
|
||||
```
|
||||
|
||||
@@ -589,7 +589,7 @@ git commit -m "feat: stop container log capture when agent SSE connects"
|
||||
### Task 6: Integrate Stop Capture in DockerEventMonitor
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/DockerEventMonitor.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/runtime/DockerEventMonitor.java`
|
||||
|
||||
- [ ] **Step 1: Call stopLogCapture on die/oom/stop events**
|
||||
|
||||
@@ -606,13 +606,13 @@ Insert after line 101 (`break;`) and before line 102 (`}`):
|
||||
|
||||
- [ ] **Step 2: Verify compilation**
|
||||
|
||||
Run: `mvn clean compile -pl cameleer3-server-app -q`
|
||||
Run: `mvn clean compile -pl cameleer-server-app -q`
|
||||
Expected: BUILD SUCCESS
|
||||
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/DockerEventMonitor.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/runtime/DockerEventMonitor.java
|
||||
git commit -m "feat: stop container log capture on Docker die/oom events"
|
||||
```
|
||||
|
||||
|
||||
@@ -13,12 +13,12 @@
|
||||
## Task 1: Core — SensitiveKeysConfig Record
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/admin/SensitiveKeysConfig.java`
|
||||
- Create: `cameleer-server-core/src/main/java/com/cameleer/server/core/admin/SensitiveKeysConfig.java`
|
||||
|
||||
- [ ] **Step 1: Create the config record**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.core.admin;
|
||||
package com.cameleer.server.core.admin;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -33,7 +33,7 @@ public record SensitiveKeysConfig(List<String> keys) {
|
||||
- [ ] **Step 2: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-core/src/main/java/com/cameleer3/server/core/admin/SensitiveKeysConfig.java
|
||||
git add cameleer-server-core/src/main/java/com/cameleer/server/core/admin/SensitiveKeysConfig.java
|
||||
git commit -m "feat: add SensitiveKeysConfig record"
|
||||
```
|
||||
|
||||
@@ -42,14 +42,14 @@ git commit -m "feat: add SensitiveKeysConfig record"
|
||||
## Task 2: Core — SensitiveKeysRepository Interface
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/admin/SensitiveKeysRepository.java`
|
||||
- Create: `cameleer-server-core/src/main/java/com/cameleer/server/core/admin/SensitiveKeysRepository.java`
|
||||
|
||||
- [ ] **Step 1: Create the repository interface**
|
||||
|
||||
Follow the `ThresholdRepository` pattern exactly.
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.core.admin;
|
||||
package com.cameleer.server.core.admin;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@@ -62,7 +62,7 @@ public interface SensitiveKeysRepository {
|
||||
- [ ] **Step 2: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-core/src/main/java/com/cameleer3/server/core/admin/SensitiveKeysRepository.java
|
||||
git add cameleer-server-core/src/main/java/com/cameleer/server/core/admin/SensitiveKeysRepository.java
|
||||
git commit -m "feat: add SensitiveKeysRepository interface"
|
||||
```
|
||||
|
||||
@@ -71,13 +71,13 @@ git commit -m "feat: add SensitiveKeysRepository interface"
|
||||
## Task 3: Core — SensitiveKeysMerger (TDD)
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-core/src/main/java/com/cameleer3/server/core/admin/SensitiveKeysMerger.java`
|
||||
- Create: `cameleer3-server-core/src/test/java/com/cameleer3/server/core/admin/SensitiveKeysMergerTest.java`
|
||||
- Create: `cameleer-server-core/src/main/java/com/cameleer/server/core/admin/SensitiveKeysMerger.java`
|
||||
- Create: `cameleer-server-core/src/test/java/com/cameleer/server/core/admin/SensitiveKeysMergerTest.java`
|
||||
|
||||
- [ ] **Step 1: Write failing tests**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.core.admin;
|
||||
package com.cameleer.server.core.admin;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -149,13 +149,13 @@ class SensitiveKeysMergerTest {
|
||||
|
||||
- [ ] **Step 2: Run tests to verify they fail**
|
||||
|
||||
Run: `mvn test -pl cameleer3-server-core -Dtest=SensitiveKeysMergerTest -Dsurefire.failIfNoSpecifiedTests=false`
|
||||
Run: `mvn test -pl cameleer-server-core -Dtest=SensitiveKeysMergerTest -Dsurefire.failIfNoSpecifiedTests=false`
|
||||
Expected: compilation error — `SensitiveKeysMerger` does not exist
|
||||
|
||||
- [ ] **Step 3: Write implementation**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.core.admin;
|
||||
package com.cameleer.server.core.admin;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -204,14 +204,14 @@ public final class SensitiveKeysMerger {
|
||||
|
||||
- [ ] **Step 4: Run tests to verify they pass**
|
||||
|
||||
Run: `mvn test -pl cameleer3-server-core -Dtest=SensitiveKeysMergerTest`
|
||||
Run: `mvn test -pl cameleer-server-core -Dtest=SensitiveKeysMergerTest`
|
||||
Expected: all 8 tests PASS
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-core/src/main/java/com/cameleer3/server/core/admin/SensitiveKeysMerger.java
|
||||
git add cameleer3-server-core/src/test/java/com/cameleer3/server/core/admin/SensitiveKeysMergerTest.java
|
||||
git add cameleer-server-core/src/main/java/com/cameleer/server/core/admin/SensitiveKeysMerger.java
|
||||
git add cameleer-server-core/src/test/java/com/cameleer/server/core/admin/SensitiveKeysMergerTest.java
|
||||
git commit -m "feat: add SensitiveKeysMerger with case-insensitive union dedup"
|
||||
```
|
||||
|
||||
@@ -220,17 +220,17 @@ git commit -m "feat: add SensitiveKeysMerger with case-insensitive union dedup"
|
||||
## Task 4: App — PostgresSensitiveKeysRepository
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/PostgresSensitiveKeysRepository.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/storage/PostgresSensitiveKeysRepository.java`
|
||||
|
||||
- [ ] **Step 1: Create the repository**
|
||||
|
||||
Follow `PostgresThresholdRepository` pattern exactly.
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.storage;
|
||||
package com.cameleer.server.app.storage;
|
||||
|
||||
import com.cameleer3.server.core.admin.SensitiveKeysConfig;
|
||||
import com.cameleer3.server.core.admin.SensitiveKeysRepository;
|
||||
import com.cameleer.server.core.admin.SensitiveKeysConfig;
|
||||
import com.cameleer.server.core.admin.SensitiveKeysRepository;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
@@ -290,7 +290,7 @@ public class PostgresSensitiveKeysRepository implements SensitiveKeysRepository
|
||||
- [ ] **Step 2: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/PostgresSensitiveKeysRepository.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/storage/PostgresSensitiveKeysRepository.java
|
||||
git commit -m "feat: add PostgresSensitiveKeysRepository"
|
||||
```
|
||||
|
||||
@@ -299,14 +299,14 @@ git commit -m "feat: add PostgresSensitiveKeysRepository"
|
||||
## Task 5: App — SensitiveKeysAdminController
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/SensitiveKeysAdminController.java`
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/dto/SensitiveKeysRequest.java`
|
||||
- Create: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/dto/SensitiveKeysResponse.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/SensitiveKeysAdminController.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/dto/SensitiveKeysRequest.java`
|
||||
- Create: `cameleer-server-app/src/main/java/com/cameleer/server/app/dto/SensitiveKeysResponse.java`
|
||||
|
||||
- [ ] **Step 1: Create the request DTO**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.dto;
|
||||
package com.cameleer.server.app.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
@@ -324,7 +324,7 @@ public record SensitiveKeysRequest(
|
||||
- [ ] **Step 2: Create the response DTO**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.dto;
|
||||
package com.cameleer.server.app.dto;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -337,24 +337,24 @@ public record SensitiveKeysResponse(
|
||||
- [ ] **Step 3: Create the controller**
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.controller;
|
||||
package com.cameleer.server.app.controller;
|
||||
|
||||
import com.cameleer3.common.model.ApplicationConfig;
|
||||
import com.cameleer3.server.app.dto.CommandGroupResponse;
|
||||
import com.cameleer3.server.app.dto.SensitiveKeysRequest;
|
||||
import com.cameleer3.server.app.dto.SensitiveKeysResponse;
|
||||
import com.cameleer3.server.app.storage.PostgresApplicationConfigRepository;
|
||||
import com.cameleer3.server.core.admin.AuditCategory;
|
||||
import com.cameleer3.server.core.admin.AuditResult;
|
||||
import com.cameleer3.server.core.admin.AuditService;
|
||||
import com.cameleer3.server.core.admin.SensitiveKeysConfig;
|
||||
import com.cameleer3.server.core.admin.SensitiveKeysMerger;
|
||||
import com.cameleer3.server.core.admin.SensitiveKeysRepository;
|
||||
import com.cameleer3.server.core.agent.AgentInfo;
|
||||
import com.cameleer3.server.core.agent.AgentRegistryService;
|
||||
import com.cameleer3.server.core.agent.AgentState;
|
||||
import com.cameleer3.server.core.agent.CommandReply;
|
||||
import com.cameleer3.server.core.agent.CommandType;
|
||||
import com.cameleer.common.model.ApplicationConfig;
|
||||
import com.cameleer.server.app.dto.CommandGroupResponse;
|
||||
import com.cameleer.server.app.dto.SensitiveKeysRequest;
|
||||
import com.cameleer.server.app.dto.SensitiveKeysResponse;
|
||||
import com.cameleer.server.app.storage.PostgresApplicationConfigRepository;
|
||||
import com.cameleer.server.core.admin.AuditCategory;
|
||||
import com.cameleer.server.core.admin.AuditResult;
|
||||
import com.cameleer.server.core.admin.AuditService;
|
||||
import com.cameleer.server.core.admin.SensitiveKeysConfig;
|
||||
import com.cameleer.server.core.admin.SensitiveKeysMerger;
|
||||
import com.cameleer.server.core.admin.SensitiveKeysRepository;
|
||||
import com.cameleer.server.core.agent.AgentInfo;
|
||||
import com.cameleer.server.core.agent.AgentRegistryService;
|
||||
import com.cameleer.server.core.agent.AgentState;
|
||||
import com.cameleer.server.core.agent.CommandReply;
|
||||
import com.cameleer.server.core.agent.CommandType;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
@@ -527,15 +527,15 @@ public class SensitiveKeysAdminController {
|
||||
|
||||
- [ ] **Step 4: Verify compilation**
|
||||
|
||||
Run: `mvn clean compile -pl cameleer3-server-core,cameleer3-server-app`
|
||||
Run: `mvn clean compile -pl cameleer-server-core,cameleer-server-app`
|
||||
Expected: BUILD SUCCESS
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/dto/SensitiveKeysRequest.java
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/dto/SensitiveKeysResponse.java
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/SensitiveKeysAdminController.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/dto/SensitiveKeysRequest.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/dto/SensitiveKeysResponse.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/controller/SensitiveKeysAdminController.java
|
||||
git commit -m "feat: add SensitiveKeysAdminController with fan-out support"
|
||||
```
|
||||
|
||||
@@ -544,18 +544,18 @@ git commit -m "feat: add SensitiveKeysAdminController with fan-out support"
|
||||
## Task 6: Enhance ApplicationConfigController — Merge Global Keys
|
||||
|
||||
**Files:**
|
||||
- Modify: `cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/ApplicationConfigController.java`
|
||||
- Modify: `cameleer-server-app/src/main/java/com/cameleer/server/app/controller/ApplicationConfigController.java`
|
||||
|
||||
The GET endpoint must return `globalSensitiveKeys` and `mergedSensitiveKeys` so the UI can render read-only global pills. The PUT push must merge before sending to agents. Since `ApplicationConfig` lives in `cameleer3-common`, we cannot add fields to it directly. Instead, we wrap the response.
|
||||
The GET endpoint must return `globalSensitiveKeys` and `mergedSensitiveKeys` so the UI can render read-only global pills. The PUT push must merge before sending to agents. Since `ApplicationConfig` lives in `cameleer-common`, we cannot add fields to it directly. Instead, we wrap the response.
|
||||
|
||||
- [ ] **Step 1: Create AppConfigResponse DTO**
|
||||
|
||||
Create `cameleer3-server-app/src/main/java/com/cameleer3/server/app/dto/AppConfigResponse.java`:
|
||||
Create `cameleer-server-app/src/main/java/com/cameleer/server/app/dto/AppConfigResponse.java`:
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.dto;
|
||||
package com.cameleer.server.app.dto;
|
||||
|
||||
import com.cameleer3.common.model.ApplicationConfig;
|
||||
import com.cameleer.common.model.ApplicationConfig;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -653,22 +653,22 @@ private ApplicationConfig cloneWithMergedKeys(ApplicationConfig source, List<Str
|
||||
Also add imports at the top of the file:
|
||||
|
||||
```java
|
||||
import com.cameleer3.server.app.dto.AppConfigResponse;
|
||||
import com.cameleer3.server.core.admin.SensitiveKeysConfig;
|
||||
import com.cameleer3.server.core.admin.SensitiveKeysMerger;
|
||||
import com.cameleer3.server.core.admin.SensitiveKeysRepository;
|
||||
import com.cameleer.server.app.dto.AppConfigResponse;
|
||||
import com.cameleer.server.core.admin.SensitiveKeysConfig;
|
||||
import com.cameleer.server.core.admin.SensitiveKeysMerger;
|
||||
import com.cameleer.server.core.admin.SensitiveKeysRepository;
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Verify compilation**
|
||||
|
||||
Run: `mvn clean compile -pl cameleer3-server-core,cameleer3-server-app`
|
||||
Run: `mvn clean compile -pl cameleer-server-core,cameleer-server-app`
|
||||
Expected: BUILD SUCCESS
|
||||
|
||||
- [ ] **Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/dto/AppConfigResponse.java
|
||||
git add cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/ApplicationConfigController.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/dto/AppConfigResponse.java
|
||||
git add cameleer-server-app/src/main/java/com/cameleer/server/app/controller/ApplicationConfigController.java
|
||||
git commit -m "feat: merge global sensitive keys into app config GET and SSE push"
|
||||
```
|
||||
|
||||
@@ -677,17 +677,17 @@ git commit -m "feat: merge global sensitive keys into app config GET and SSE pus
|
||||
## Task 7: Integration Test — SensitiveKeysAdminController
|
||||
|
||||
**Files:**
|
||||
- Create: `cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/SensitiveKeysAdminControllerIT.java`
|
||||
- Create: `cameleer-server-app/src/test/java/com/cameleer/server/app/controller/SensitiveKeysAdminControllerIT.java`
|
||||
|
||||
- [ ] **Step 1: Write integration tests**
|
||||
|
||||
Follow the `ThresholdAdminControllerIT` pattern.
|
||||
|
||||
```java
|
||||
package com.cameleer3.server.app.controller;
|
||||
package com.cameleer.server.app.controller;
|
||||
|
||||
import com.cameleer3.server.app.AbstractPostgresIT;
|
||||
import com.cameleer3.server.app.TestSecurityHelper;
|
||||
import com.cameleer.server.app.AbstractPostgresIT;
|
||||
import com.cameleer.server.app.TestSecurityHelper;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@@ -816,13 +816,13 @@ class SensitiveKeysAdminControllerIT extends AbstractPostgresIT {
|
||||
|
||||
- [ ] **Step 2: Run tests**
|
||||
|
||||
Run: `mvn verify -pl cameleer3-server-app -Dit.test=SensitiveKeysAdminControllerIT -Dsurefire.skip=true`
|
||||
Run: `mvn verify -pl cameleer-server-app -Dit.test=SensitiveKeysAdminControllerIT -Dsurefire.skip=true`
|
||||
Expected: all 5 tests PASS
|
||||
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/SensitiveKeysAdminControllerIT.java
|
||||
git add cameleer-server-app/src/test/java/com/cameleer/server/app/controller/SensitiveKeysAdminControllerIT.java
|
||||
git commit -m "test: add SensitiveKeysAdminController integration tests"
|
||||
```
|
||||
|
||||
@@ -1367,7 +1367,7 @@ Expected: BUILD SUCCESS
|
||||
|
||||
- [ ] **Step 2: Run unit tests**
|
||||
|
||||
Run: `mvn test -pl cameleer3-server-core`
|
||||
Run: `mvn test -pl cameleer-server-core`
|
||||
Expected: all tests pass, including `SensitiveKeysMergerTest`
|
||||
|
||||
- [ ] **Step 3: Run frontend type check**
|
||||
|
||||
Reference in New Issue
Block a user