chore: rename cameleer3 to cameleer
Some checks failed
CI / cleanup-branch (push) Has been skipped
CI / build (push) Failing after 18s
CI / docker (push) Has been skipped
CI / deploy (push) Has been skipped
CI / deploy-feature (push) Has been skipped

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:
hsiegeln
2026-04-15 15:28:42 +02:00
parent 1077293343
commit cb3ebfea7c
569 changed files with 4356 additions and 3245 deletions

View File

@@ -6,17 +6,17 @@ wave: 1
depends_on: []
files_modified:
- clickhouse/init/02-search-columns.sql
- cameleer3-server-core/src/main/java/com/cameleer3/server/core/search/SearchRequest.java
- cameleer3-server-core/src/main/java/com/cameleer3/server/core/search/SearchResult.java
- cameleer3-server-core/src/main/java/com/cameleer3/server/core/search/SearchEngine.java
- cameleer3-server-core/src/main/java/com/cameleer3/server/core/search/SearchService.java
- cameleer3-server-core/src/main/java/com/cameleer3/server/core/search/ExecutionSummary.java
- cameleer3-server-core/src/main/java/com/cameleer3/server/core/detail/DetailService.java
- cameleer3-server-core/src/main/java/com/cameleer3/server/core/detail/ExecutionDetail.java
- cameleer3-server-core/src/main/java/com/cameleer3/server/core/detail/ProcessorNode.java
- cameleer3-server-core/src/main/java/com/cameleer3/server/core/storage/ExecutionRepository.java
- cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/ClickHouseExecutionRepository.java
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/AbstractClickHouseIT.java
- cameleer-server-core/src/main/java/com/cameleer/server/core/search/SearchRequest.java
- cameleer-server-core/src/main/java/com/cameleer/server/core/search/SearchResult.java
- cameleer-server-core/src/main/java/com/cameleer/server/core/search/SearchEngine.java
- cameleer-server-core/src/main/java/com/cameleer/server/core/search/SearchService.java
- cameleer-server-core/src/main/java/com/cameleer/server/core/search/ExecutionSummary.java
- cameleer-server-core/src/main/java/com/cameleer/server/core/detail/DetailService.java
- cameleer-server-core/src/main/java/com/cameleer/server/core/detail/ExecutionDetail.java
- cameleer-server-core/src/main/java/com/cameleer/server/core/detail/ProcessorNode.java
- cameleer-server-core/src/main/java/com/cameleer/server/core/storage/ExecutionRepository.java
- cameleer-server-app/src/main/java/com/cameleer/server/app/storage/ClickHouseExecutionRepository.java
- cameleer-server-app/src/test/java/com/cameleer/server/app/AbstractClickHouseIT.java
autonomous: true
requirements:
- SRCH-01
@@ -38,21 +38,21 @@ must_haves:
- path: "clickhouse/init/02-search-columns.sql"
provides: "Schema extension DDL for Phase 2 columns and skip indexes"
contains: "exchange_bodies"
- path: "cameleer3-server-core/src/main/java/com/cameleer3/server/core/search/SearchEngine.java"
- path: "cameleer-server-core/src/main/java/com/cameleer/server/core/search/SearchEngine.java"
provides: "Search backend abstraction interface"
exports: ["SearchEngine"]
- path: "cameleer3-server-core/src/main/java/com/cameleer3/server/core/search/SearchRequest.java"
- path: "cameleer-server-core/src/main/java/com/cameleer/server/core/search/SearchRequest.java"
provides: "Immutable search criteria record"
exports: ["SearchRequest"]
- path: "cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/ClickHouseExecutionRepository.java"
- path: "cameleer-server-app/src/main/java/com/cameleer/server/app/storage/ClickHouseExecutionRepository.java"
provides: "Extended with new columns in INSERT, plus query methods"
min_lines: 100
key_links:
- from: "cameleer3-server-core/src/main/java/com/cameleer3/server/core/search/SearchService.java"
- from: "cameleer-server-core/src/main/java/com/cameleer/server/core/search/SearchService.java"
to: "SearchEngine"
via: "constructor injection"
pattern: "SearchEngine"
- from: "cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/ClickHouseExecutionRepository.java"
- from: "cameleer-server-app/src/main/java/com/cameleer/server/app/storage/ClickHouseExecutionRepository.java"
to: "clickhouse/init/02-search-columns.sql"
via: "INSERT and SELECT SQL matching schema"
pattern: "exchange_bodies|processor_depths|diagram_content_hash"
@@ -79,22 +79,22 @@ Output: Schema migration SQL, updated ingestion INSERT with new columns, core se
@.planning/phases/02-transaction-search-diagrams/02-RESEARCH.md
@clickhouse/init/01-schema.sql
@cameleer3-server-core/src/main/java/com/cameleer3/server/core/storage/ExecutionRepository.java
@cameleer3-server-core/src/main/java/com/cameleer3/server/core/storage/DiagramRepository.java
@cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/ClickHouseExecutionRepository.java
@cameleer3-server-app/src/test/java/com/cameleer3/server/app/AbstractClickHouseIT.java
@cameleer-server-core/src/main/java/com/cameleer/server/core/storage/ExecutionRepository.java
@cameleer-server-core/src/main/java/com/cameleer/server/core/storage/DiagramRepository.java
@cameleer-server-app/src/main/java/com/cameleer/server/app/storage/ClickHouseExecutionRepository.java
@cameleer-server-app/src/test/java/com/cameleer/server/app/AbstractClickHouseIT.java
<interfaces>
<!-- Existing interfaces the executor needs -->
From cameleer3-server-core/.../storage/ExecutionRepository.java:
From cameleer-server-core/.../storage/ExecutionRepository.java:
```java
public interface ExecutionRepository {
void insertBatch(List<RouteExecution> executions);
}
```
From cameleer3-server-core/.../storage/DiagramRepository.java:
From cameleer-server-core/.../storage/DiagramRepository.java:
```java
public interface DiagramRepository {
void store(RouteGraph graph);
@@ -103,7 +103,7 @@ public interface DiagramRepository {
}
```
From cameleer3-common (decompiled — key fields):
From cameleer-common (decompiled — key fields):
```java
// RouteExecution: routeId, status (ExecutionStatus enum: COMPLETED/FAILED/RUNNING),
// startTime (Instant), endTime (Instant), durationMs (long), correlationId, exchangeId,
@@ -145,15 +145,15 @@ Existing ClickHouse schema (01-schema.sql):
<name>Task 1: Schema extension and core domain types</name>
<files>
clickhouse/init/02-search-columns.sql,
cameleer3-server-core/src/main/java/com/cameleer3/server/core/search/SearchRequest.java,
cameleer3-server-core/src/main/java/com/cameleer3/server/core/search/SearchResult.java,
cameleer3-server-core/src/main/java/com/cameleer3/server/core/search/SearchEngine.java,
cameleer3-server-core/src/main/java/com/cameleer3/server/core/search/SearchService.java,
cameleer3-server-core/src/main/java/com/cameleer3/server/core/search/ExecutionSummary.java,
cameleer3-server-core/src/main/java/com/cameleer3/server/core/detail/DetailService.java,
cameleer3-server-core/src/main/java/com/cameleer3/server/core/detail/ExecutionDetail.java,
cameleer3-server-core/src/main/java/com/cameleer3/server/core/detail/ProcessorNode.java,
cameleer3-server-core/src/main/java/com/cameleer3/server/core/storage/ExecutionRepository.java
cameleer-server-core/src/main/java/com/cameleer/server/core/search/SearchRequest.java,
cameleer-server-core/src/main/java/com/cameleer/server/core/search/SearchResult.java,
cameleer-server-core/src/main/java/com/cameleer/server/core/search/SearchEngine.java,
cameleer-server-core/src/main/java/com/cameleer/server/core/search/SearchService.java,
cameleer-server-core/src/main/java/com/cameleer/server/core/search/ExecutionSummary.java,
cameleer-server-core/src/main/java/com/cameleer/server/core/detail/DetailService.java,
cameleer-server-core/src/main/java/com/cameleer/server/core/detail/ExecutionDetail.java,
cameleer-server-core/src/main/java/com/cameleer/server/core/detail/ProcessorNode.java,
cameleer-server-core/src/main/java/com/cameleer/server/core/storage/ExecutionRepository.java
</files>
<action>
1. Create `clickhouse/init/02-search-columns.sql` with ALTER TABLE statements to add Phase 2 columns to route_executions:
@@ -172,14 +172,14 @@ Existing ClickHouse schema (01-schema.sql):
- Add tokenbf_v1 skip indexes on exchange_bodies and exchange_headers (GRANULARITY 4, same as idx_error)
- Add tokenbf_v1 skip index on error_stacktrace (it has no index yet, needed for SRCH-05 full-text search across stack traces)
2. Create core search domain types in `com.cameleer3.server.core.search`:
2. Create core search domain types in `com.cameleer.server.core.search`:
- `SearchRequest` record: status (String, nullable), timeFrom (Instant), timeTo (Instant), durationMin (Long), durationMax (Long), correlationId (String), text (String — global full-text), textInBody (String), textInHeaders (String), textInErrors (String), offset (int), limit (int). Compact constructor validates: limit defaults to 50 if <= 0, capped at 500; offset defaults to 0 if < 0.
- `SearchResult<T>` record: data (List<T>), total (long), offset (int), limit (int). Include static factory `empty(int offset, int limit)`.
- `ExecutionSummary` record: executionId (String), routeId (String), agentId (String), status (String), startTime (Instant), endTime (Instant), durationMs (long), correlationId (String), errorMessage (String), diagramContentHash (String). This is the lightweight list-view DTO — NOT the full processor arrays.
- `SearchEngine` interface with methods: `SearchResult<ExecutionSummary> search(SearchRequest request)` and `long count(SearchRequest request)`. This is the swappable backend (ClickHouse now, OpenSearch later per user decision).
- `SearchService` class: plain class (no Spring annotations, same pattern as IngestionService). Constructor takes SearchEngine. `search(SearchRequest)` delegates to engine.search(). This thin orchestration layer allows adding cross-cutting concerns later.
3. Create core detail domain types in `com.cameleer3.server.core.detail`:
3. Create core detail domain types in `com.cameleer.server.core.detail`:
- `ProcessorNode` record: processorId (String), processorType (String), status (String), startTime (Instant), endTime (Instant), durationMs (long), diagramNodeId (String), errorMessage (String), errorStackTrace (String), children (List<ProcessorNode>). This is the nested tree node.
- `ExecutionDetail` record: executionId (String), routeId (String), agentId (String), status (String), startTime (Instant), endTime (Instant), durationMs (long), correlationId (String), exchangeId (String), errorMessage (String), errorStackTrace (String), diagramContentHash (String), processors (List<ProcessorNode>). This is the full detail response.
- `DetailService` class: plain class (no Spring annotations). Constructor takes ExecutionRepository. Method `getDetail(String executionId)` returns `Optional<ExecutionDetail>`. Calls repository's new `findDetailById` method, then calls `reconstructTree()` to convert flat arrays into nested ProcessorNode tree. The `reconstructTree` method: takes parallel arrays (ids, types, statuses, starts, ends, durations, diagramNodeIds, errorMessages, errorStackTraces, depths, parentIndexes), creates ProcessorNode[] array, then wires children using parentIndexes (parentIndex == -1 means root).
@@ -190,7 +190,7 @@ Existing ClickHouse schema (01-schema.sql):
Actually, use a different approach per the layering: add a `findRawById(String executionId)` method that returns `Optional<RawExecutionRow>` — a new record containing all parallel arrays. DetailService takes this and reconstructs. Create `RawExecutionRow` as a record in the detail package with all fields needed for reconstruction.
</action>
<verify>
<automated>cd C:/Users/Hendrik/Documents/projects/cameleer3-server && mvn compile -pl cameleer3-server-core</automated>
<automated>cd C:/Users/Hendrik/Documents/projects/cameleer-server && mvn compile -pl cameleer-server-core</automated>
</verify>
<done>Schema migration SQL exists, all core domain types compile, SearchEngine interface and SearchService defined, ExecutionRepository extended with query method, DetailService has tree reconstruction logic</done>
</task>
@@ -198,9 +198,9 @@ Existing ClickHouse schema (01-schema.sql):
<task type="auto" tdd="true">
<name>Task 2: Update ingestion to populate new columns and verify with integration test</name>
<files>
cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/ClickHouseExecutionRepository.java,
cameleer3-server-app/src/test/java/com/cameleer3/server/app/AbstractClickHouseIT.java,
cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/IngestionSchemaIT.java
cameleer-server-app/src/main/java/com/cameleer/server/app/storage/ClickHouseExecutionRepository.java,
cameleer-server-app/src/test/java/com/cameleer/server/app/AbstractClickHouseIT.java,
cameleer-server-app/src/test/java/com/cameleer/server/app/storage/IngestionSchemaIT.java
</files>
<behavior>
- Test: After inserting a RouteExecution with processors that have exchange snapshots and nested children, the route_executions row has non-empty exchange_bodies, exchange_headers, processor_depths (correct depth values), processor_parent_indexes (correct parent wiring), processor_input_bodies, processor_output_bodies, processor_input_headers, processor_output_headers, processor_diagram_node_ids, and diagram_content_hash columns
@@ -231,7 +231,7 @@ Existing ClickHouse schema (01-schema.sql):
- Verifies a second insertion with null snapshots succeeds with empty defaults
</action>
<verify>
<automated>cd C:/Users/Hendrik/Documents/projects/cameleer3-server && mvn test -pl cameleer3-server-app -Dtest=IngestionSchemaIT</automated>
<automated>cd C:/Users/Hendrik/Documents/projects/cameleer-server && mvn test -pl cameleer-server-app -Dtest=IngestionSchemaIT</automated>
</verify>
<done>All new columns populated correctly during ingestion, tree metadata (depth/parent) correct for nested processors, exchange data concatenated for search, existing ingestion tests still pass</done>
</task>
@@ -239,9 +239,9 @@ Existing ClickHouse schema (01-schema.sql):
</tasks>
<verification>
- `mvn compile -pl cameleer3-server-core` succeeds (core domain types compile)
- `mvn test -pl cameleer3-server-app -Dtest=IngestionSchemaIT` passes (new columns populated correctly)
- `mvn test -pl cameleer3-server-app` passes (all existing tests still green with schema extension)
- `mvn compile -pl cameleer-server-core` succeeds (core domain types compile)
- `mvn test -pl cameleer-server-app -Dtest=IngestionSchemaIT` passes (new columns populated correctly)
- `mvn test -pl cameleer-server-app` passes (all existing tests still green with schema extension)
</verification>
<success_criteria>

View File

@@ -22,22 +22,22 @@ tech-stack:
key-files:
created:
- clickhouse/init/02-search-columns.sql
- cameleer3-server-core/src/main/java/com/cameleer3/server/core/search/SearchRequest.java
- cameleer3-server-core/src/main/java/com/cameleer3/server/core/search/SearchResult.java
- cameleer3-server-core/src/main/java/com/cameleer3/server/core/search/ExecutionSummary.java
- cameleer3-server-core/src/main/java/com/cameleer3/server/core/search/SearchEngine.java
- cameleer3-server-core/src/main/java/com/cameleer3/server/core/search/SearchService.java
- cameleer3-server-core/src/main/java/com/cameleer3/server/core/detail/DetailService.java
- cameleer3-server-core/src/main/java/com/cameleer3/server/core/detail/ExecutionDetail.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/RawExecutionRow.java
- cameleer3-server-core/src/main/java/com/cameleer3/server/core/diagram/DiagramRenderer.java
- cameleer3-server-core/src/main/java/com/cameleer3/server/core/diagram/DiagramLayout.java
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/IngestionSchemaIT.java
- cameleer-server-core/src/main/java/com/cameleer/server/core/search/SearchRequest.java
- cameleer-server-core/src/main/java/com/cameleer/server/core/search/SearchResult.java
- cameleer-server-core/src/main/java/com/cameleer/server/core/search/ExecutionSummary.java
- cameleer-server-core/src/main/java/com/cameleer/server/core/search/SearchEngine.java
- cameleer-server-core/src/main/java/com/cameleer/server/core/search/SearchService.java
- cameleer-server-core/src/main/java/com/cameleer/server/core/detail/DetailService.java
- cameleer-server-core/src/main/java/com/cameleer/server/core/detail/ExecutionDetail.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/RawExecutionRow.java
- cameleer-server-core/src/main/java/com/cameleer/server/core/diagram/DiagramRenderer.java
- cameleer-server-core/src/main/java/com/cameleer/server/core/diagram/DiagramLayout.java
- cameleer-server-app/src/test/java/com/cameleer/server/app/storage/IngestionSchemaIT.java
modified:
- cameleer3-server-core/src/main/java/com/cameleer3/server/core/storage/ExecutionRepository.java
- cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/ClickHouseExecutionRepository.java
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/AbstractClickHouseIT.java
- cameleer-server-core/src/main/java/com/cameleer/server/core/storage/ExecutionRepository.java
- cameleer-server-app/src/main/java/com/cameleer/server/app/storage/ClickHouseExecutionRepository.java
- cameleer-server-app/src/test/java/com/cameleer/server/app/AbstractClickHouseIT.java
key-decisions:
- "FlatProcessor record captures depth and parentIndex during DFS traversal"
@@ -86,21 +86,21 @@ Each task was committed atomically:
## Files Created/Modified
- `clickhouse/init/02-search-columns.sql` - ALTER TABLE adding 12 columns + 3 skip indexes
- `cameleer3-server-core/.../search/SearchRequest.java` - Immutable search criteria record with validation
- `cameleer3-server-core/.../search/SearchResult.java` - Paginated result envelope
- `cameleer3-server-core/.../search/ExecutionSummary.java` - Lightweight list-view DTO
- `cameleer3-server-core/.../search/SearchEngine.java` - Swappable search backend interface
- `cameleer3-server-core/.../search/SearchService.java` - Search orchestration layer
- `cameleer3-server-core/.../detail/DetailService.java` - Tree reconstruction from flat arrays
- `cameleer3-server-core/.../detail/ExecutionDetail.java` - Full execution detail record
- `cameleer3-server-core/.../detail/ProcessorNode.java` - Nested tree node (mutable children)
- `cameleer3-server-core/.../detail/RawExecutionRow.java` - DB-to-domain intermediate record
- `cameleer3-server-core/.../diagram/DiagramRenderer.java` - Diagram rendering interface (stub)
- `cameleer3-server-core/.../diagram/DiagramLayout.java` - JSON layout record (stub)
- `cameleer3-server-core/.../storage/ExecutionRepository.java` - Extended with findRawById
- `cameleer3-server-app/.../storage/ClickHouseExecutionRepository.java` - INSERT extended with 12 new columns
- `cameleer3-server-app/src/test/.../AbstractClickHouseIT.java` - Loads 02-search-columns.sql
- `cameleer3-server-app/src/test/.../storage/IngestionSchemaIT.java` - 3 integration tests
- `cameleer-server-core/.../search/SearchRequest.java` - Immutable search criteria record with validation
- `cameleer-server-core/.../search/SearchResult.java` - Paginated result envelope
- `cameleer-server-core/.../search/ExecutionSummary.java` - Lightweight list-view DTO
- `cameleer-server-core/.../search/SearchEngine.java` - Swappable search backend interface
- `cameleer-server-core/.../search/SearchService.java` - Search orchestration layer
- `cameleer-server-core/.../detail/DetailService.java` - Tree reconstruction from flat arrays
- `cameleer-server-core/.../detail/ExecutionDetail.java` - Full execution detail record
- `cameleer-server-core/.../detail/ProcessorNode.java` - Nested tree node (mutable children)
- `cameleer-server-core/.../detail/RawExecutionRow.java` - DB-to-domain intermediate record
- `cameleer-server-core/.../diagram/DiagramRenderer.java` - Diagram rendering interface (stub)
- `cameleer-server-core/.../diagram/DiagramLayout.java` - JSON layout record (stub)
- `cameleer-server-core/.../storage/ExecutionRepository.java` - Extended with findRawById
- `cameleer-server-app/.../storage/ClickHouseExecutionRepository.java` - INSERT extended with 12 new columns
- `cameleer-server-app/src/test/.../AbstractClickHouseIT.java` - Loads 02-search-columns.sql
- `cameleer-server-app/src/test/.../storage/IngestionSchemaIT.java` - 3 integration tests
## Decisions Made
- Used FlatProcessor record to carry depth and parentIndex alongside the ProcessorExecution during DFS flattening -- single pass, no separate traversal
@@ -116,9 +116,9 @@ Each task was committed atomically:
**1. [Rule 3 - Blocking] Created DiagramRenderer and DiagramLayout stub interfaces**
- **Found during:** Task 2 (compilation step)
- **Issue:** Pre-existing `ElkDiagramRenderer` in app module referenced `DiagramRenderer` and `DiagramLayout` interfaces that did not exist in core module, causing compilation failure
- **Fix:** Created minimal stub interfaces in `com.cameleer3.server.core.diagram` package
- **Fix:** Created minimal stub interfaces in `com.cameleer.server.core.diagram` package
- **Files created:** DiagramRenderer.java, DiagramLayout.java
- **Verification:** `mvn compile -pl cameleer3-server-core` and `mvn compile -pl cameleer3-server-app` succeed
- **Verification:** `mvn compile -pl cameleer-server-core` and `mvn compile -pl cameleer-server-app` succeed
- **Committed in:** f6ff279 (Task 2 GREEN commit)
**2. [Rule 1 - Bug] Fixed ClickHouse Array type handling in IngestionSchemaIT**

View File

@@ -5,16 +5,16 @@ type: execute
wave: 1
depends_on: []
files_modified:
- cameleer3-server-app/pom.xml
- cameleer3-server-core/src/main/java/com/cameleer3/server/core/diagram/DiagramRenderer.java
- cameleer3-server-core/src/main/java/com/cameleer3/server/core/diagram/DiagramLayout.java
- cameleer3-server-core/src/main/java/com/cameleer3/server/core/diagram/PositionedNode.java
- cameleer3-server-core/src/main/java/com/cameleer3/server/core/diagram/PositionedEdge.java
- cameleer3-server-app/src/main/java/com/cameleer3/server/app/diagram/ElkDiagramRenderer.java
- cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/DiagramRenderController.java
- cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/DiagramBeanConfig.java
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/DiagramRenderControllerIT.java
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/diagram/ElkDiagramRendererTest.java
- cameleer-server-app/pom.xml
- cameleer-server-core/src/main/java/com/cameleer/server/core/diagram/DiagramRenderer.java
- cameleer-server-core/src/main/java/com/cameleer/server/core/diagram/DiagramLayout.java
- cameleer-server-core/src/main/java/com/cameleer/server/core/diagram/PositionedNode.java
- cameleer-server-core/src/main/java/com/cameleer/server/core/diagram/PositionedEdge.java
- cameleer-server-app/src/main/java/com/cameleer/server/app/diagram/ElkDiagramRenderer.java
- cameleer-server-app/src/main/java/com/cameleer/server/app/controller/DiagramRenderController.java
- cameleer-server-app/src/main/java/com/cameleer/server/app/config/DiagramBeanConfig.java
- cameleer-server-app/src/test/java/com/cameleer/server/app/controller/DiagramRenderControllerIT.java
- cameleer-server-app/src/test/java/com/cameleer/server/app/diagram/ElkDiagramRendererTest.java
autonomous: true
requirements:
- DIAG-03
@@ -27,13 +27,13 @@ must_haves:
- "Node colors match the route-diagram-example.html style: blue endpoints, green processors, red error handlers, purple EIPs"
- "Nested processors (inside split, choice, try-catch) are rendered in compound/swimlane groups"
artifacts:
- path: "cameleer3-server-core/src/main/java/com/cameleer3/server/core/diagram/DiagramRenderer.java"
- path: "cameleer-server-core/src/main/java/com/cameleer/server/core/diagram/DiagramRenderer.java"
provides: "Renderer interface for SVG and JSON layout output"
exports: ["DiagramRenderer"]
- path: "cameleer3-server-app/src/main/java/com/cameleer3/server/app/diagram/ElkDiagramRenderer.java"
- path: "cameleer-server-app/src/main/java/com/cameleer/server/app/diagram/ElkDiagramRenderer.java"
provides: "ELK + JFreeSVG implementation of DiagramRenderer"
min_lines: 100
- path: "cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/DiagramRenderController.java"
- path: "cameleer-server-app/src/main/java/com/cameleer/server/app/controller/DiagramRenderController.java"
provides: "GET /api/v1/diagrams/{hash} with content negotiation"
exports: ["DiagramRenderController"]
key_links:
@@ -70,14 +70,14 @@ Output: DiagramRenderer interface in core, ElkDiagramRenderer implementation in
@.planning/phases/02-transaction-search-diagrams/02-CONTEXT.md
@.planning/phases/02-transaction-search-diagrams/02-RESEARCH.md
@cameleer3-server-core/src/main/java/com/cameleer3/server/core/storage/DiagramRepository.java
@cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/ClickHouseDiagramRepository.java
@cameleer3-server-app/pom.xml
@cameleer-server-core/src/main/java/com/cameleer/server/core/storage/DiagramRepository.java
@cameleer-server-app/src/main/java/com/cameleer/server/app/storage/ClickHouseDiagramRepository.java
@cameleer-server-app/pom.xml
<interfaces>
<!-- Existing interfaces needed -->
From cameleer3-server-core/.../storage/DiagramRepository.java:
From cameleer-server-core/.../storage/DiagramRepository.java:
```java
public interface DiagramRepository {
void store(RouteGraph graph);
@@ -86,7 +86,7 @@ public interface DiagramRepository {
}
```
From cameleer3-common (decompiled — diagram models):
From cameleer-common (decompiled — diagram models):
```java
// RouteGraph: routeId (String), nodes (List<RouteNode>), edges (List<RouteEdge>),
// processorNodeMapping (Map<String,String>)
@@ -114,14 +114,14 @@ NodeType color mapping (from CONTEXT.md, matching route-diagram-example.html):
<task type="auto">
<name>Task 1: Add ELK/JFreeSVG dependencies and create core diagram rendering interfaces</name>
<files>
cameleer3-server-app/pom.xml,
cameleer3-server-core/src/main/java/com/cameleer3/server/core/diagram/DiagramRenderer.java,
cameleer3-server-core/src/main/java/com/cameleer3/server/core/diagram/DiagramLayout.java,
cameleer3-server-core/src/main/java/com/cameleer3/server/core/diagram/PositionedNode.java,
cameleer3-server-core/src/main/java/com/cameleer3/server/core/diagram/PositionedEdge.java
cameleer-server-app/pom.xml,
cameleer-server-core/src/main/java/com/cameleer/server/core/diagram/DiagramRenderer.java,
cameleer-server-core/src/main/java/com/cameleer/server/core/diagram/DiagramLayout.java,
cameleer-server-core/src/main/java/com/cameleer/server/core/diagram/PositionedNode.java,
cameleer-server-core/src/main/java/com/cameleer/server/core/diagram/PositionedEdge.java
</files>
<action>
1. Add Maven dependencies to `cameleer3-server-app/pom.xml`:
1. Add Maven dependencies to `cameleer-server-app/pom.xml`:
```xml
<dependency>
<groupId>org.eclipse.elk</groupId>
@@ -140,7 +140,7 @@ NodeType color mapping (from CONTEXT.md, matching route-diagram-example.html):
</dependency>
```
2. Create core diagram rendering interfaces in `com.cameleer3.server.core.diagram`:
2. Create core diagram rendering interfaces in `com.cameleer.server.core.diagram`:
- `PositionedNode` record: id (String), label (String), type (String — NodeType name), x (double), y (double), width (double), height (double), children (List<PositionedNode> — for compound/swimlane groups). JSON-serializable for the JSON layout response.
@@ -154,7 +154,7 @@ NodeType color mapping (from CONTEXT.md, matching route-diagram-example.html):
Both methods take a RouteGraph and produce output. The interface lives in core so it can be swapped (e.g., for a different renderer).
</action>
<verify>
<automated>cd C:/Users/Hendrik/Documents/projects/cameleer3-server && mvn compile -pl cameleer3-server-core && mvn dependency:resolve -pl cameleer3-server-app -q</automated>
<automated>cd C:/Users/Hendrik/Documents/projects/cameleer-server && mvn compile -pl cameleer-server-core && mvn dependency:resolve -pl cameleer-server-app -q</automated>
</verify>
<done>ELK and JFreeSVG dependencies resolve, DiagramRenderer interface and layout DTOs compile in core module</done>
</task>
@@ -162,11 +162,11 @@ NodeType color mapping (from CONTEXT.md, matching route-diagram-example.html):
<task type="auto" tdd="true">
<name>Task 2: Implement ElkDiagramRenderer, DiagramRenderController, and integration tests</name>
<files>
cameleer3-server-app/src/main/java/com/cameleer3/server/app/diagram/ElkDiagramRenderer.java,
cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/DiagramRenderController.java,
cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/DiagramBeanConfig.java,
cameleer3-server-app/src/test/java/com/cameleer3/server/app/diagram/ElkDiagramRendererTest.java,
cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/DiagramRenderControllerIT.java
cameleer-server-app/src/main/java/com/cameleer/server/app/diagram/ElkDiagramRenderer.java,
cameleer-server-app/src/main/java/com/cameleer/server/app/controller/DiagramRenderController.java,
cameleer-server-app/src/main/java/com/cameleer/server/app/config/DiagramBeanConfig.java,
cameleer-server-app/src/test/java/com/cameleer/server/app/diagram/ElkDiagramRendererTest.java,
cameleer-server-app/src/test/java/com/cameleer/server/app/controller/DiagramRenderControllerIT.java
</files>
<behavior>
- Unit test: ElkDiagramRenderer.renderSvg with a simple 3-node graph (from->process->to) produces valid SVG containing svg element, rect elements for nodes, line/path elements for edges
@@ -179,7 +179,7 @@ NodeType color mapping (from CONTEXT.md, matching route-diagram-example.html):
- Integration test: GET /api/v1/diagrams/{hash} with no Accept preference defaults to SVG
</behavior>
<action>
1. Create `ElkDiagramRenderer` implementing `DiagramRenderer` in `com.cameleer3.server.app.diagram`:
1. Create `ElkDiagramRenderer` implementing `DiagramRenderer` in `com.cameleer.server.app.diagram`:
**Layout phase (shared by both SVG and JSON):**
- Convert RouteGraph to ELK graph: create ElkNode root, set properties for LayeredOptions.ALGORITHM_ID, Direction.DOWN (top-to-bottom per user decision), spacing 40px node-node, 20px edge-node.
@@ -206,10 +206,10 @@ NodeType color mapping (from CONTEXT.md, matching route-diagram-example.html):
**JSON layout (layoutJson):**
- Run layout phase, return DiagramLayout directly. Jackson will serialize it to JSON.
2. Create `DiagramBeanConfig` in `com.cameleer3.server.app.config`:
2. Create `DiagramBeanConfig` in `com.cameleer.server.app.config`:
- @Configuration class that creates DiagramRenderer bean (ElkDiagramRenderer) and SearchService bean wiring (prepare for Plan 03).
3. Create `DiagramRenderController` in `com.cameleer3.server.app.controller`:
3. Create `DiagramRenderController` in `com.cameleer.server.app.controller`:
- `GET /api/v1/diagrams/{contentHash}/render` — renders the diagram
- Inject DiagramRepository and DiagramRenderer.
- Look up RouteGraph via `diagramRepository.findByContentHash(contentHash)`. If empty, return 404.
@@ -233,7 +233,7 @@ NodeType color mapping (from CONTEXT.md, matching route-diagram-example.html):
- GET /api/v1/diagrams/{hash}/render with no Accept header -> assert SVG response (default).
</action>
<verify>
<automated>cd C:/Users/Hendrik/Documents/projects/cameleer3-server && mvn test -pl cameleer3-server-app -Dtest="ElkDiagramRendererTest,DiagramRenderControllerIT"</automated>
<automated>cd C:/Users/Hendrik/Documents/projects/cameleer-server && mvn test -pl cameleer-server-app -Dtest="ElkDiagramRendererTest,DiagramRenderControllerIT"</automated>
</verify>
<done>Diagram rendering produces color-coded top-to-bottom SVG and JSON layout, content negotiation works via Accept header, compound nodes group nested processors, all tests pass</done>
</task>
@@ -241,8 +241,8 @@ NodeType color mapping (from CONTEXT.md, matching route-diagram-example.html):
</tasks>
<verification>
- `mvn test -pl cameleer3-server-app -Dtest=ElkDiagramRendererTest` passes (unit tests for layout and SVG)
- `mvn test -pl cameleer3-server-app -Dtest=DiagramRenderControllerIT` passes (integration tests for REST endpoint)
- `mvn test -pl cameleer-server-app -Dtest=ElkDiagramRendererTest` passes (unit tests for layout and SVG)
- `mvn test -pl cameleer-server-app -Dtest=DiagramRenderControllerIT` passes (integration tests for REST endpoint)
- `mvn clean verify` passes (all existing tests still green)
- SVG output contains color-coded nodes matching the NodeType color scheme
</verification>

View File

@@ -21,17 +21,17 @@ tech-stack:
key-files:
created:
- cameleer3-server-core/src/main/java/com/cameleer3/server/core/diagram/DiagramRenderer.java
- cameleer3-server-core/src/main/java/com/cameleer3/server/core/diagram/DiagramLayout.java
- cameleer3-server-core/src/main/java/com/cameleer3/server/core/diagram/PositionedNode.java
- cameleer3-server-core/src/main/java/com/cameleer3/server/core/diagram/PositionedEdge.java
- cameleer3-server-app/src/main/java/com/cameleer3/server/app/diagram/ElkDiagramRenderer.java
- cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/DiagramRenderController.java
- cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/DiagramBeanConfig.java
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/diagram/ElkDiagramRendererTest.java
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/DiagramRenderControllerIT.java
- cameleer-server-core/src/main/java/com/cameleer/server/core/diagram/DiagramRenderer.java
- cameleer-server-core/src/main/java/com/cameleer/server/core/diagram/DiagramLayout.java
- cameleer-server-core/src/main/java/com/cameleer/server/core/diagram/PositionedNode.java
- cameleer-server-core/src/main/java/com/cameleer/server/core/diagram/PositionedEdge.java
- cameleer-server-app/src/main/java/com/cameleer/server/app/diagram/ElkDiagramRenderer.java
- cameleer-server-app/src/main/java/com/cameleer/server/app/controller/DiagramRenderController.java
- cameleer-server-app/src/main/java/com/cameleer/server/app/config/DiagramBeanConfig.java
- cameleer-server-app/src/test/java/com/cameleer/server/app/diagram/ElkDiagramRendererTest.java
- cameleer-server-app/src/test/java/com/cameleer/server/app/controller/DiagramRenderControllerIT.java
modified:
- cameleer3-server-app/pom.xml
- cameleer-server-app/pom.xml
key-decisions:
- "Used ELK layered algorithm with top-to-bottom direction for route diagram layout"
@@ -78,16 +78,16 @@ Each task was committed atomically:
2. **Task 2: Implement ElkDiagramRenderer, DiagramRenderController, and integration tests** - `c1bc32d` (feat, TDD)
## Files Created/Modified
- `cameleer3-server-core/.../diagram/DiagramRenderer.java` - Renderer interface with renderSvg and layoutJson
- `cameleer3-server-core/.../diagram/DiagramLayout.java` - Layout record (width, height, nodes, edges)
- `cameleer3-server-core/.../diagram/PositionedNode.java` - Node record with position, dimensions, children
- `cameleer3-server-core/.../diagram/PositionedEdge.java` - Edge record with waypoints
- `cameleer3-server-app/.../diagram/ElkDiagramRenderer.java` - ELK + JFreeSVG implementation (~400 lines)
- `cameleer3-server-app/.../controller/DiagramRenderController.java` - GET /api/v1/diagrams/{hash}/render
- `cameleer3-server-app/.../config/DiagramBeanConfig.java` - Spring bean wiring for DiagramRenderer
- `cameleer3-server-app/pom.xml` - Added ELK, JFreeSVG, xtext dependencies
- `cameleer3-server-app/.../diagram/ElkDiagramRendererTest.java` - 11 unit tests
- `cameleer3-server-app/.../controller/DiagramRenderControllerIT.java` - 4 integration tests
- `cameleer-server-core/.../diagram/DiagramRenderer.java` - Renderer interface with renderSvg and layoutJson
- `cameleer-server-core/.../diagram/DiagramLayout.java` - Layout record (width, height, nodes, edges)
- `cameleer-server-core/.../diagram/PositionedNode.java` - Node record with position, dimensions, children
- `cameleer-server-core/.../diagram/PositionedEdge.java` - Edge record with waypoints
- `cameleer-server-app/.../diagram/ElkDiagramRenderer.java` - ELK + JFreeSVG implementation (~400 lines)
- `cameleer-server-app/.../controller/DiagramRenderController.java` - GET /api/v1/diagrams/{hash}/render
- `cameleer-server-app/.../config/DiagramBeanConfig.java` - Spring bean wiring for DiagramRenderer
- `cameleer-server-app/pom.xml` - Added ELK, JFreeSVG, xtext dependencies
- `cameleer-server-app/.../diagram/ElkDiagramRendererTest.java` - 11 unit tests
- `cameleer-server-app/.../controller/DiagramRenderControllerIT.java` - 4 integration tests
## Decisions Made
- Used ELK layered algorithm (org.eclipse.elk.alg.layered) -- well-maintained, supports compound nodes natively
@@ -104,7 +104,7 @@ Each task was committed atomically:
- **Found during:** Task 2 (ElkDiagramRenderer implementation)
- **Issue:** ELK 0.11.0 LayeredMetaDataProvider references org.eclipse.xtext.xbase.lib.CollectionLiterals at class initialization, causing NoClassDefFoundError
- **Fix:** Added org.eclipse.xtext:org.eclipse.xtext.xbase.lib:2.37.0 dependency to app pom.xml
- **Files modified:** cameleer3-server-app/pom.xml
- **Files modified:** cameleer-server-app/pom.xml
- **Verification:** All unit tests pass after adding dependency
- **Committed in:** c1bc32d (Task 2 commit)
@@ -119,7 +119,7 @@ Each task was committed atomically:
**3. [Rule 1 - Bug] Adapted to actual NodeType enum naming (EIP_ prefix)**
- **Found during:** Task 2 (ElkDiagramRenderer implementation)
- **Issue:** Plan referenced CHOICE, SPLIT etc. but actual enum values are EIP_CHOICE, EIP_SPLIT etc.
- **Fix:** Used correct enum names from decompiled cameleer3-common jar in all color mapping sets
- **Fix:** Used correct enum names from decompiled cameleer-common jar in all color mapping sets
- **Files modified:** ElkDiagramRenderer.java
- **Verification:** Unit tests verify correct colors for endpoint and processor nodes
- **Committed in:** c1bc32d (Task 2 commit)

View File

@@ -6,14 +6,14 @@ wave: 2
depends_on:
- "02-01"
files_modified:
- cameleer3-server-app/src/main/java/com/cameleer3/server/app/search/ClickHouseSearchEngine.java
- cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/SearchController.java
- cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/DetailController.java
- cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/SearchBeanConfig.java
- cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/ClickHouseExecutionRepository.java
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/SearchControllerIT.java
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/DetailControllerIT.java
- cameleer3-server-core/src/test/java/com/cameleer3/server/core/detail/TreeReconstructionTest.java
- cameleer-server-app/src/main/java/com/cameleer/server/app/search/ClickHouseSearchEngine.java
- cameleer-server-app/src/main/java/com/cameleer/server/app/controller/SearchController.java
- cameleer-server-app/src/main/java/com/cameleer/server/app/controller/DetailController.java
- cameleer-server-app/src/main/java/com/cameleer/server/app/config/SearchBeanConfig.java
- cameleer-server-app/src/main/java/com/cameleer/server/app/storage/ClickHouseExecutionRepository.java
- cameleer-server-app/src/test/java/com/cameleer/server/app/controller/SearchControllerIT.java
- cameleer-server-app/src/test/java/com/cameleer/server/app/controller/DetailControllerIT.java
- cameleer-server-core/src/test/java/com/cameleer/server/core/detail/TreeReconstructionTest.java
autonomous: true
requirements:
- SRCH-01
@@ -35,16 +35,16 @@ must_haves:
- "Detail response includes diagramContentHash for linking to diagram endpoint"
- "Search results are paginated with total count, offset, and limit"
artifacts:
- path: "cameleer3-server-app/src/main/java/com/cameleer3/server/app/search/ClickHouseSearchEngine.java"
- path: "cameleer-server-app/src/main/java/com/cameleer/server/app/search/ClickHouseSearchEngine.java"
provides: "ClickHouse implementation of SearchEngine with dynamic WHERE building"
min_lines: 80
- path: "cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/SearchController.java"
- path: "cameleer-server-app/src/main/java/com/cameleer/server/app/controller/SearchController.java"
provides: "GET + POST /api/v1/search/executions endpoints"
exports: ["SearchController"]
- path: "cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/DetailController.java"
- path: "cameleer-server-app/src/main/java/com/cameleer/server/app/controller/DetailController.java"
provides: "GET /api/v1/executions/{id} endpoint returning nested tree"
exports: ["DetailController"]
- path: "cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/SearchControllerIT.java"
- path: "cameleer-server-app/src/test/java/com/cameleer/server/app/controller/SearchControllerIT.java"
provides: "Integration tests for all search filter combinations"
min_lines: 100
key_links:
@@ -92,13 +92,13 @@ Output: SearchController (GET + POST), DetailController, ClickHouseSearchEngine,
@clickhouse/init/01-schema.sql
@clickhouse/init/02-search-columns.sql
@cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/ClickHouseExecutionRepository.java
@cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/ExecutionController.java
@cameleer-server-app/src/main/java/com/cameleer/server/app/storage/ClickHouseExecutionRepository.java
@cameleer-server-app/src/main/java/com/cameleer/server/app/controller/ExecutionController.java
<interfaces>
<!-- Core types created by Plan 01 — executor reads these from plan 01 SUMMARY -->
From cameleer3-server-core/.../search/SearchEngine.java:
From cameleer-server-core/.../search/SearchEngine.java:
```java
public interface SearchEngine {
SearchResult<ExecutionSummary> search(SearchRequest request);
@@ -106,7 +106,7 @@ public interface SearchEngine {
}
```
From cameleer3-server-core/.../search/SearchRequest.java:
From cameleer-server-core/.../search/SearchRequest.java:
```java
public record SearchRequest(
String status, // nullable, filter by ExecutionStatus name
@@ -124,14 +124,14 @@ public record SearchRequest(
) { /* compact constructor with validation */ }
```
From cameleer3-server-core/.../search/SearchResult.java:
From cameleer-server-core/.../search/SearchResult.java:
```java
public record SearchResult<T>(List<T> data, long total, int offset, int limit) {
public static <T> SearchResult<T> empty(int offset, int limit);
}
```
From cameleer3-server-core/.../search/ExecutionSummary.java:
From cameleer-server-core/.../search/ExecutionSummary.java:
```java
public record ExecutionSummary(
String executionId, String routeId, String agentId, String status,
@@ -140,7 +140,7 @@ public record ExecutionSummary(
) {}
```
From cameleer3-server-core/.../detail/DetailService.java:
From cameleer-server-core/.../detail/DetailService.java:
```java
public class DetailService {
// Constructor takes ExecutionRepository (or a query interface)
@@ -149,7 +149,7 @@ public class DetailService {
}
```
From cameleer3-server-core/.../detail/ExecutionDetail.java:
From cameleer-server-core/.../detail/ExecutionDetail.java:
```java
public record ExecutionDetail(
String executionId, String routeId, String agentId, String status,
@@ -160,7 +160,7 @@ public record ExecutionDetail(
) {}
```
From cameleer3-server-core/.../detail/ProcessorNode.java:
From cameleer-server-core/.../detail/ProcessorNode.java:
```java
public record ProcessorNode(
String processorId, String processorType, String status,
@@ -201,10 +201,10 @@ Established controller pattern (from Phase 1):
<task type="auto" tdd="true">
<name>Task 1: ClickHouseSearchEngine, SearchController, and search integration tests</name>
<files>
cameleer3-server-app/src/main/java/com/cameleer3/server/app/search/ClickHouseSearchEngine.java,
cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/SearchController.java,
cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/SearchBeanConfig.java,
cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/SearchControllerIT.java
cameleer-server-app/src/main/java/com/cameleer/server/app/search/ClickHouseSearchEngine.java,
cameleer-server-app/src/main/java/com/cameleer/server/app/controller/SearchController.java,
cameleer-server-app/src/main/java/com/cameleer/server/app/config/SearchBeanConfig.java,
cameleer-server-app/src/test/java/com/cameleer/server/app/controller/SearchControllerIT.java
</files>
<behavior>
- Test searchByStatus: Insert 3 executions (COMPLETED, FAILED, RUNNING). GET /api/v1/search/executions?status=FAILED returns only the FAILED execution. Response has envelope: {"data":[...],"total":1,"offset":0,"limit":50}
@@ -221,7 +221,7 @@ Established controller pattern (from Phase 1):
- Test emptyResults: Search with no matches returns {"data":[],"total":0,"offset":0,"limit":50}
</behavior>
<action>
1. Create `ClickHouseSearchEngine` in `com.cameleer3.server.app.search`:
1. Create `ClickHouseSearchEngine` in `com.cameleer.server.app.search`:
- Implements SearchEngine interface from core module.
- Constructor takes JdbcTemplate.
- `search(SearchRequest)` method:
@@ -244,13 +244,13 @@ Established controller pattern (from Phase 1):
- `escapeLike(String)` utility: escape `%`, `_`, `\` characters in user input to prevent LIKE injection. Replace `\` with `\\`, `%` with `\%`, `_` with `\_`.
- `count(SearchRequest)` method: same WHERE building, just count query.
2. Create `SearchBeanConfig` in `com.cameleer3.server.app.config`:
2. Create `SearchBeanConfig` in `com.cameleer.server.app.config`:
- @Configuration class that creates:
- `ClickHouseSearchEngine` bean (takes JdbcTemplate)
- `SearchService` bean (takes SearchEngine)
- `DetailService` bean (takes the execution query interface from Plan 01)
3. Create `SearchController` in `com.cameleer3.server.app.controller`:
3. Create `SearchController` in `com.cameleer.server.app.controller`:
- Inject SearchService.
- `GET /api/v1/search/executions` with @RequestParam for basic filters:
- status (optional String)
@@ -274,7 +274,7 @@ Established controller pattern (from Phase 1):
- Assert response structure matches the envelope format.
</action>
<verify>
<automated>cd C:/Users/Hendrik/Documents/projects/cameleer3-server && mvn test -pl cameleer3-server-app -Dtest=SearchControllerIT</automated>
<automated>cd C:/Users/Hendrik/Documents/projects/cameleer-server && mvn test -pl cameleer-server-app -Dtest=SearchControllerIT</automated>
</verify>
<done>All search filter types work independently and in combination, response envelope has correct format, pagination works correctly, full-text search finds matches in all text fields, LIKE patterns are properly escaped</done>
</task>
@@ -282,10 +282,10 @@ Established controller pattern (from Phase 1):
<task type="auto" tdd="true">
<name>Task 2: DetailController, tree reconstruction, exchange snapshot endpoint, and integration tests</name>
<files>
cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/ClickHouseExecutionRepository.java,
cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/DetailController.java,
cameleer3-server-core/src/test/java/com/cameleer3/server/core/detail/TreeReconstructionTest.java,
cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/DetailControllerIT.java
cameleer-server-app/src/main/java/com/cameleer/server/app/storage/ClickHouseExecutionRepository.java,
cameleer-server-app/src/main/java/com/cameleer/server/app/controller/DetailController.java,
cameleer-server-core/src/test/java/com/cameleer/server/core/detail/TreeReconstructionTest.java,
cameleer-server-app/src/test/java/com/cameleer/server/app/controller/DetailControllerIT.java
</files>
<behavior>
- Unit test: reconstructTree with [root, child, grandchild], depths=[0,1,2], parents=[-1,0,1] produces single root with one child that has one grandchild
@@ -308,7 +308,7 @@ Established controller pattern (from Phase 1):
- Add `findRawById(String executionId)` method that queries all columns from route_executions WHERE execution_id = ?. Return Optional<RawExecutionRow> (use the record created in Plan 01 or create it here if needed). The RawExecutionRow should contain ALL columns including the parallel arrays for processors.
- Add `findProcessorSnapshot(String executionId, int processorIndex)` method: queries processor_input_bodies[index+1], processor_output_bodies[index+1], processor_input_headers[index+1], processor_output_headers[index+1] for the given execution. Returns a DTO with inputBody, outputBody, inputHeaders, outputHeaders. ClickHouse arrays are 1-indexed in SQL, so add 1 to the Java 0-based index.
3. Create `DetailController` in `com.cameleer3.server.app.controller`:
3. Create `DetailController` in `com.cameleer.server.app.controller`:
- Inject DetailService.
- `GET /api/v1/executions/{executionId}`: call detailService.getDetail(executionId). If empty, return 404. Otherwise return 200 with ExecutionDetail JSON. The processors field is a nested tree of ProcessorNode objects.
- `GET /api/v1/executions/{executionId}/processors/{index}/snapshot`: call repository's findProcessorSnapshot. If execution not found or index out of bounds, return 404. Return JSON with inputBody, outputBody, inputHeaders, outputHeaders. Per user decision: exchange snapshot data fetched separately per processor, not inlined in detail response.
@@ -323,7 +323,7 @@ Established controller pattern (from Phase 1):
- Test GET /api/v1/executions/{id}/processors/999/snapshot: returns 404 for out-of-bounds index.
</action>
<verify>
<automated>cd C:/Users/Hendrik/Documents/projects/cameleer3-server && mvn test -pl cameleer3-server-core -Dtest=TreeReconstructionTest && mvn test -pl cameleer3-server-app -Dtest=DetailControllerIT</automated>
<automated>cd C:/Users/Hendrik/Documents/projects/cameleer-server && mvn test -pl cameleer-server-core -Dtest=TreeReconstructionTest && mvn test -pl cameleer-server-app -Dtest=DetailControllerIT</automated>
</verify>
<done>Tree reconstruction correctly rebuilds nested processor trees from flat arrays, detail endpoint returns nested tree with all fields, snapshot endpoint returns per-processor exchange data, diagram hash included in detail response, all tests pass</done>
</task>
@@ -331,9 +331,9 @@ Established controller pattern (from Phase 1):
</tasks>
<verification>
- `mvn test -pl cameleer3-server-core -Dtest=TreeReconstructionTest` passes (unit test for tree rebuild)
- `mvn test -pl cameleer3-server-app -Dtest=SearchControllerIT` passes (all search filters)
- `mvn test -pl cameleer3-server-app -Dtest=DetailControllerIT` passes (detail + snapshot)
- `mvn test -pl cameleer-server-core -Dtest=TreeReconstructionTest` passes (unit test for tree rebuild)
- `mvn test -pl cameleer-server-app -Dtest=SearchControllerIT` passes (all search filters)
- `mvn test -pl cameleer-server-app -Dtest=DetailControllerIT` passes (detail + snapshot)
- `mvn clean verify` passes (full suite green)
</verification>

View File

@@ -21,16 +21,16 @@ tech-stack:
key-files:
created:
- cameleer3-server-app/src/main/java/com/cameleer3/server/app/search/ClickHouseSearchEngine.java
- cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/SearchController.java
- cameleer3-server-app/src/main/java/com/cameleer3/server/app/controller/DetailController.java
- cameleer3-server-app/src/main/java/com/cameleer3/server/app/config/SearchBeanConfig.java
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/SearchControllerIT.java
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/DetailControllerIT.java
- cameleer3-server-core/src/test/java/com/cameleer3/server/core/detail/TreeReconstructionTest.java
- cameleer-server-app/src/main/java/com/cameleer/server/app/search/ClickHouseSearchEngine.java
- cameleer-server-app/src/main/java/com/cameleer/server/app/controller/SearchController.java
- cameleer-server-app/src/main/java/com/cameleer/server/app/controller/DetailController.java
- cameleer-server-app/src/main/java/com/cameleer/server/app/config/SearchBeanConfig.java
- cameleer-server-app/src/test/java/com/cameleer/server/app/controller/SearchControllerIT.java
- cameleer-server-app/src/test/java/com/cameleer/server/app/controller/DetailControllerIT.java
- cameleer-server-core/src/test/java/com/cameleer/server/core/detail/TreeReconstructionTest.java
modified:
- cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/ClickHouseExecutionRepository.java
- cameleer3-server-core/pom.xml
- cameleer-server-app/src/main/java/com/cameleer/server/app/storage/ClickHouseExecutionRepository.java
- cameleer-server-core/pom.xml
key-decisions:
- "Search tests use correlationId scoping and >= assertions for shared ClickHouse isolation"
@@ -77,15 +77,15 @@ Each task was committed atomically:
3. **Task 2 fix: Test isolation for shared ClickHouse** - `079dce5` (fix)
## Files Created/Modified
- `cameleer3-server-app/.../search/ClickHouseSearchEngine.java` - Dynamic SQL search with LIKE escape, implements SearchEngine
- `cameleer3-server-app/.../controller/SearchController.java` - GET + POST /api/v1/search/executions endpoints
- `cameleer3-server-app/.../controller/DetailController.java` - GET /api/v1/executions/{id} and processor snapshot endpoints
- `cameleer3-server-app/.../config/SearchBeanConfig.java` - Wires SearchEngine, SearchService, DetailService beans
- `cameleer3-server-app/.../storage/ClickHouseExecutionRepository.java` - Added findRawById, findProcessorSnapshot, array extraction helpers
- `cameleer3-server-app/.../controller/SearchControllerIT.java` - 13 integration tests for search
- `cameleer3-server-app/.../controller/DetailControllerIT.java` - 6 integration tests for detail/snapshot
- `cameleer3-server-core/.../detail/TreeReconstructionTest.java` - 5 unit tests for tree reconstruction
- `cameleer3-server-core/pom.xml` - Added assertj and mockito test dependencies
- `cameleer-server-app/.../search/ClickHouseSearchEngine.java` - Dynamic SQL search with LIKE escape, implements SearchEngine
- `cameleer-server-app/.../controller/SearchController.java` - GET + POST /api/v1/search/executions endpoints
- `cameleer-server-app/.../controller/DetailController.java` - GET /api/v1/executions/{id} and processor snapshot endpoints
- `cameleer-server-app/.../config/SearchBeanConfig.java` - Wires SearchEngine, SearchService, DetailService beans
- `cameleer-server-app/.../storage/ClickHouseExecutionRepository.java` - Added findRawById, findProcessorSnapshot, array extraction helpers
- `cameleer-server-app/.../controller/SearchControllerIT.java` - 13 integration tests for search
- `cameleer-server-app/.../controller/DetailControllerIT.java` - 6 integration tests for detail/snapshot
- `cameleer-server-core/.../detail/TreeReconstructionTest.java` - 5 unit tests for tree reconstruction
- `cameleer-server-core/pom.xml` - Added assertj and mockito test dependencies
## Decisions Made
- Search tests use correlationId scoping and >= assertions to remain stable when other test classes seed data in the shared ClickHouse container
@@ -99,8 +99,8 @@ Each task was committed atomically:
**1. [Rule 3 - Blocking] Added assertj and mockito test dependencies to core module**
- **Found during:** Task 2 (TreeReconstructionTest compilation)
- **Issue:** Core module only had JUnit Jupiter as test dependency, TreeReconstructionTest needed assertj for assertions and mockito for mock(ExecutionRepository.class)
- **Fix:** Added assertj-core and mockito-core test-scoped dependencies to cameleer3-server-core/pom.xml
- **Files modified:** cameleer3-server-core/pom.xml
- **Fix:** Added assertj-core and mockito-core test-scoped dependencies to cameleer-server-core/pom.xml
- **Files modified:** cameleer-server-core/pom.xml
- **Committed in:** 0615a98 (Task 2 commit)
**2. [Rule 1 - Bug] Fixed search tests failing with shared ClickHouse data**

View File

@@ -5,9 +5,9 @@ type: execute
wave: 1
depends_on: ["02-01", "02-02", "02-03"]
files_modified:
- cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/ClickHouseExecutionRepository.java
- cameleer3-server-app/pom.xml
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/DiagramLinkingIT.java
- cameleer-server-app/src/main/java/com/cameleer/server/app/storage/ClickHouseExecutionRepository.java
- cameleer-server-app/pom.xml
- cameleer-server-app/src/test/java/com/cameleer/server/app/storage/DiagramLinkingIT.java
autonomous: true
gap_closure: true
requirements: ["DIAG-02"]
@@ -17,13 +17,13 @@ must_haves:
- "Each transaction links to the RouteGraph version that was active at execution time"
- "Full test suite passes with mvn clean verify (no classloader failures)"
artifacts:
- path: "cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/ClickHouseExecutionRepository.java"
- path: "cameleer-server-app/src/main/java/com/cameleer/server/app/storage/ClickHouseExecutionRepository.java"
provides: "Diagram hash lookup during batch insert"
contains: "findContentHashForRoute"
- path: "cameleer3-server-app/pom.xml"
- path: "cameleer-server-app/pom.xml"
provides: "Surefire fork configuration isolating ELK classloader"
contains: "reuseForks"
- path: "cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/DiagramLinkingIT.java"
- path: "cameleer-server-app/src/test/java/com/cameleer/server/app/storage/DiagramLinkingIT.java"
provides: "Integration test proving diagram hash is stored during ingestion"
key_links:
- from: "ClickHouseExecutionRepository"
@@ -57,18 +57,18 @@ Prior plan summaries (needed — touches same files):
<interfaces>
<!-- Key types and contracts the executor needs. -->
From cameleer3-server-core/.../storage/DiagramRepository.java:
From cameleer-server-core/.../storage/DiagramRepository.java:
```java
Optional<String> findContentHashForRoute(String routeId, String agentId);
```
From cameleer3-server-app/.../storage/ClickHouseExecutionRepository.java (line 141):
From cameleer-server-app/.../storage/ClickHouseExecutionRepository.java (line 141):
```java
ps.setString(col++, ""); // diagram_content_hash (wired later)
```
The class is @Repository annotated, constructor takes JdbcTemplate only. It needs DiagramRepository injected to perform the lookup.
From cameleer3-server-app/.../storage/ClickHouseDiagramRepository.java:
From cameleer-server-app/.../storage/ClickHouseDiagramRepository.java:
```java
@Repository
public class ClickHouseDiagramRepository implements DiagramRepository {
@@ -83,9 +83,9 @@ public class ClickHouseDiagramRepository implements DiagramRepository {
<task type="auto" tdd="true">
<name>Task 1: Populate diagram_content_hash during ingestion and fix Surefire forks</name>
<files>
cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/ClickHouseExecutionRepository.java,
cameleer3-server-app/pom.xml,
cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/DiagramLinkingIT.java
cameleer-server-app/src/main/java/com/cameleer/server/app/storage/ClickHouseExecutionRepository.java,
cameleer-server-app/pom.xml,
cameleer-server-app/src/test/java/com/cameleer/server/app/storage/DiagramLinkingIT.java
</files>
<behavior>
- Test 1: When a RouteGraph is ingested before a RouteExecution for the same routeId+agentId, the execution's diagram_content_hash column contains the SHA-256 hash of the diagram (not empty string)
@@ -117,7 +117,7 @@ public class ClickHouseDiagramRepository implements DiagramRepository {
**Gap 2 — Surefire classloader isolation:**
5. In `cameleer3-server-app/pom.xml`, add a `<build><plugins>` section (after the existing `spring-boot-maven-plugin`) with `maven-surefire-plugin` configuration:
5. In `cameleer-server-app/pom.xml`, add a `<build><plugins>` section (after the existing `spring-boot-maven-plugin`) with `maven-surefire-plugin` configuration:
```xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@@ -131,12 +131,12 @@ public class ClickHouseDiagramRepository implements DiagramRepository {
This forces Surefire to fork a fresh JVM for each test class, isolating ELK's static initializer (LayeredMetaDataProvider + xtext CollectionLiterals) from Spring Boot's classloader. Trade-off: slightly slower test execution, but correct results.
</action>
<verify>
<automated>cd C:/Users/Hendrik/Documents/projects/cameleer3-server && mvn clean verify -pl cameleer3-server-app -am 2>&1 | tail -30</automated>
<automated>cd C:/Users/Hendrik/Documents/projects/cameleer-server && mvn clean verify -pl cameleer-server-app -am 2>&1 | tail -30</automated>
</verify>
<done>
- diagram_content_hash is populated with the active diagram's SHA-256 hash during ingestion (not empty string)
- DiagramLinkingIT passes with both positive and negative cases
- `mvn clean verify` passes for cameleer3-server-app (no classloader failures from ElkDiagramRendererTest)
- `mvn clean verify` passes for cameleer-server-app (no classloader failures from ElkDiagramRendererTest)
</done>
</task>

View File

@@ -20,12 +20,12 @@ tech-stack:
key-files:
created:
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/DiagramLinkingIT.java
- cameleer-server-app/src/test/java/com/cameleer/server/app/storage/DiagramLinkingIT.java
modified:
- cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/ClickHouseExecutionRepository.java
- cameleer3-server-app/pom.xml
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/IngestionSchemaIT.java
- cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/SearchControllerIT.java
- cameleer-server-app/src/main/java/com/cameleer/server/app/storage/ClickHouseExecutionRepository.java
- cameleer-server-app/pom.xml
- cameleer-server-app/src/test/java/com/cameleer/server/app/storage/IngestionSchemaIT.java
- cameleer-server-app/src/test/java/com/cameleer/server/app/controller/SearchControllerIT.java
key-decisions:
- "DiagramRepository injected via constructor into ClickHouseExecutionRepository for diagram hash lookup during batch insert"
@@ -69,11 +69,11 @@ Each task was committed atomically:
**Plan metadata:** (pending)
## Files Created/Modified
- `cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/ClickHouseExecutionRepository.java` - Added DiagramRepository injection, diagram hash lookup in insertBatch
- `cameleer3-server-app/pom.xml` - Added maven-surefire-plugin and maven-failsafe-plugin with reuseForks=false
- `cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/DiagramLinkingIT.java` - Integration test for diagram hash linking
- `cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/IngestionSchemaIT.java` - Added ignoreExceptions + increased timeouts
- `cameleer3-server-app/src/test/java/com/cameleer3/server/app/controller/SearchControllerIT.java` - Adjusted pagination assertion count
- `cameleer-server-app/src/main/java/com/cameleer/server/app/storage/ClickHouseExecutionRepository.java` - Added DiagramRepository injection, diagram hash lookup in insertBatch
- `cameleer-server-app/pom.xml` - Added maven-surefire-plugin and maven-failsafe-plugin with reuseForks=false
- `cameleer-server-app/src/test/java/com/cameleer/server/app/storage/DiagramLinkingIT.java` - Integration test for diagram hash linking
- `cameleer-server-app/src/test/java/com/cameleer/server/app/storage/IngestionSchemaIT.java` - Added ignoreExceptions + increased timeouts
- `cameleer-server-app/src/test/java/com/cameleer/server/app/controller/SearchControllerIT.java` - Adjusted pagination assertion count
## Decisions Made
- DiagramRepository injected via constructor into ClickHouseExecutionRepository -- both are @Repository Spring beans, so constructor injection autowires cleanly

View File

@@ -44,7 +44,7 @@ Users can find any transaction by status, time, duration, correlation ID, or con
- No execution overlay in server-rendered SVG — the UI handles overlay with theme support (dark/light)
- Top-to-bottom node layout flow
- Nested processors (inside for-each, split, try-catch) rendered in swimlanes to highlight nesting/scope
- Reference: cameleer3 agent repo `examples/route-diagram-example.html` for visual style inspiration (color-coded node types, EIP icons)
- Reference: cameleer agent repo `examples/route-diagram-example.html` for visual style inspiration (color-coded node types, EIP icons)
### Claude's Discretion
- Pagination implementation details (offset/limit vs cursor)
@@ -58,7 +58,7 @@ Users can find any transaction by status, time, duration, correlation ID, or con
<specifics>
## Specific Ideas
- "We want a cmd+k type of search in the UI" — see `cameleer3/examples/cmd-k-search-example.html` for the target UX. Key features:
- "We want a cmd+k type of search in the UI" — see `cameleer/examples/cmd-k-search-example.html` for the target UX. Key features:
- Cross-entity search: single query hits Executions, Routes, Exchanges, Agents with scope tabs and counts
- Filter chips in the input (e.g., `route:order` prefix filtering)
- Inline preview pane with JSON syntax highlighting for selected result

View File

@@ -112,7 +112,7 @@ The existing Phase 1 code provides a solid foundation: `ClickHouseExecutionRepos
### Recommended Project Structure (additions for Phase 2)
```
cameleer3-server-core/src/main/java/com/cameleer3/server/core/
cameleer-server-core/src/main/java/com/cameleer/server/core/
├── search/
│ ├── SearchService.java # Orchestrates search, delegates to SearchEngine
│ ├── SearchEngine.java # Interface for search backends (ClickHouse now, OpenSearch later)
@@ -127,7 +127,7 @@ cameleer3-server-core/src/main/java/com/cameleer3/server/core/
├── ExecutionRepository.java # Extended with query methods
└── DiagramRepository.java # Extended with lookup methods
cameleer3-server-app/src/main/java/com/cameleer3/server/app/
cameleer-server-app/src/main/java/com/cameleer/server/app/
├── controller/
│ ├── SearchController.java # GET + POST /api/v1/search/executions
│ ├── DetailController.java # GET /api/v1/executions/{id}
@@ -517,25 +517,25 @@ private void populateExchangeColumns(PreparedStatement ps, List<FlatProcessor> p
| Property | Value |
|----------|-------|
| Framework | JUnit 5 + Spring Boot Test + Testcontainers ClickHouse 25.3 |
| Config file | cameleer3-server-app/pom.xml (testcontainers dep), AbstractClickHouseIT base class |
| Quick run command | `mvn test -pl cameleer3-server-app -Dtest=SearchControllerIT -Dfailsafe.skip=true` |
| Config file | cameleer-server-app/pom.xml (testcontainers dep), AbstractClickHouseIT base class |
| Quick run command | `mvn test -pl cameleer-server-app -Dtest=SearchControllerIT -Dfailsafe.skip=true` |
| Full suite command | `mvn clean verify` |
### Phase Requirements -> Test Map
| Req ID | Behavior | Test Type | Automated Command | File Exists? |
|--------|----------|-----------|-------------------|-------------|
| SRCH-01 | Filter by status returns matching executions | integration | `mvn test -pl cameleer3-server-app -Dtest=SearchControllerIT#searchByStatus` | No -- Wave 0 |
| SRCH-02 | Filter by time range returns matching executions | integration | `mvn test -pl cameleer3-server-app -Dtest=SearchControllerIT#searchByTimeRange` | No -- Wave 0 |
| SRCH-03 | Filter by duration range returns matching | integration | `mvn test -pl cameleer3-server-app -Dtest=SearchControllerIT#searchByDuration` | No -- Wave 0 |
| SRCH-04 | Filter by correlationId returns correlated | integration | `mvn test -pl cameleer3-server-app -Dtest=SearchControllerIT#searchByCorrelationId` | No -- Wave 0 |
| SRCH-05 | Full-text search across bodies/headers/errors | integration | `mvn test -pl cameleer3-server-app -Dtest=SearchControllerIT#fullTextSearch` | No -- Wave 0 |
| SRCH-06 | Detail returns nested processor tree | integration | `mvn test -pl cameleer3-server-app -Dtest=DetailControllerIT#detailReturnsNestedTree` | No -- Wave 0 |
| DIAG-01 | Content-hash dedup stores identical defs once | integration | `mvn test -pl cameleer3-server-app -Dtest=DiagramControllerIT#contentHashDedup` | Partial (ingestion test exists) |
| DIAG-02 | Transaction links to active diagram version | integration | `mvn test -pl cameleer3-server-app -Dtest=DetailControllerIT#detailIncludesDiagramHash` | No -- Wave 0 |
| DIAG-03 | Diagram rendered as SVG or JSON layout | integration | `mvn test -pl cameleer3-server-app -Dtest=DiagramRenderControllerIT#renderSvg` | No -- Wave 0 |
| SRCH-01 | Filter by status returns matching executions | integration | `mvn test -pl cameleer-server-app -Dtest=SearchControllerIT#searchByStatus` | No -- Wave 0 |
| SRCH-02 | Filter by time range returns matching executions | integration | `mvn test -pl cameleer-server-app -Dtest=SearchControllerIT#searchByTimeRange` | No -- Wave 0 |
| SRCH-03 | Filter by duration range returns matching | integration | `mvn test -pl cameleer-server-app -Dtest=SearchControllerIT#searchByDuration` | No -- Wave 0 |
| SRCH-04 | Filter by correlationId returns correlated | integration | `mvn test -pl cameleer-server-app -Dtest=SearchControllerIT#searchByCorrelationId` | No -- Wave 0 |
| SRCH-05 | Full-text search across bodies/headers/errors | integration | `mvn test -pl cameleer-server-app -Dtest=SearchControllerIT#fullTextSearch` | No -- Wave 0 |
| SRCH-06 | Detail returns nested processor tree | integration | `mvn test -pl cameleer-server-app -Dtest=DetailControllerIT#detailReturnsNestedTree` | No -- Wave 0 |
| DIAG-01 | Content-hash dedup stores identical defs once | integration | `mvn test -pl cameleer-server-app -Dtest=DiagramControllerIT#contentHashDedup` | Partial (ingestion test exists) |
| DIAG-02 | Transaction links to active diagram version | integration | `mvn test -pl cameleer-server-app -Dtest=DetailControllerIT#detailIncludesDiagramHash` | No -- Wave 0 |
| DIAG-03 | Diagram rendered as SVG or JSON layout | integration | `mvn test -pl cameleer-server-app -Dtest=DiagramRenderControllerIT#renderSvg` | No -- Wave 0 |
### Sampling Rate
- **Per task commit:** `mvn test -pl cameleer3-server-app -Dtest=<relevant>IT`
- **Per task commit:** `mvn test -pl cameleer-server-app -Dtest=<relevant>IT`
- **Per wave merge:** `mvn clean verify`
- **Phase gate:** Full suite green before `/gsd:verify-work`
@@ -551,7 +551,7 @@ private void populateExchangeColumns(PreparedStatement ps, List<FlatProcessor> p
### Primary (HIGH confidence)
- ClickHouse JDBC 0.9.7, ClickHouse 25.3 -- verified from project pom.xml and AbstractClickHouseIT
- cameleer3-common 1.0-SNAPSHOT JAR -- decompiled to verify RouteGraph, RouteNode, RouteEdge, NodeType, ProcessorExecution, ExchangeSnapshot field structures
- cameleer-common 1.0-SNAPSHOT JAR -- decompiled to verify RouteGraph, RouteNode, RouteEdge, NodeType, ProcessorExecution, ExchangeSnapshot field structures
- Existing Phase 1 codebase -- ClickHouseExecutionRepository, ClickHouseDiagramRepository, schema, test patterns
### Secondary (MEDIUM confidence)

View File

@@ -18,8 +18,8 @@ created: 2026-03-11
| Property | Value |
|----------|-------|
| **Framework** | JUnit 5 + Spring Boot Test + Testcontainers ClickHouse 25.3 |
| **Config file** | cameleer3-server-app/pom.xml (testcontainers dep), AbstractClickHouseIT base class |
| **Quick run command** | `mvn test -pl cameleer3-server-app -Dtest=SearchControllerIT` |
| **Config file** | cameleer-server-app/pom.xml (testcontainers dep), AbstractClickHouseIT base class |
| **Quick run command** | `mvn test -pl cameleer-server-app -Dtest=SearchControllerIT` |
| **Full suite command** | `mvn clean verify` |
| **Estimated runtime** | ~45 seconds |
@@ -27,7 +27,7 @@ created: 2026-03-11
## Sampling Rate
- **After every task commit:** Run `mvn test -pl cameleer3-server-app -Dtest=<relevant>IT`
- **After every task commit:** Run `mvn test -pl cameleer-server-app -Dtest=<relevant>IT`
- **After every plan wave:** Run `mvn clean verify`
- **Before `/gsd:verify-work`:** Full suite must be green
- **Max feedback latency:** 45 seconds
@@ -38,15 +38,15 @@ created: 2026-03-11
| Task ID | Plan | Wave | Requirement | Test Type | Automated Command | File Exists | Status |
|---------|------|------|-------------|-----------|-------------------|-------------|--------|
| 02-01-01 | 01 | 1 | SRCH-01 | integration | `mvn test -pl cameleer3-server-app -Dtest=SearchControllerIT#searchByStatus` | ❌ W0 | ⬜ pending |
| 02-01-02 | 01 | 1 | SRCH-02 | integration | `mvn test -pl cameleer3-server-app -Dtest=SearchControllerIT#searchByTimeRange` | ❌ W0 | ⬜ pending |
| 02-01-03 | 01 | 1 | SRCH-03 | integration | `mvn test -pl cameleer3-server-app -Dtest=SearchControllerIT#searchByDuration` | ❌ W0 | ⬜ pending |
| 02-01-04 | 01 | 1 | SRCH-04 | integration | `mvn test -pl cameleer3-server-app -Dtest=SearchControllerIT#searchByCorrelationId` | ❌ W0 | ⬜ pending |
| 02-01-05 | 01 | 1 | SRCH-05 | integration | `mvn test -pl cameleer3-server-app -Dtest=SearchControllerIT#fullTextSearch` | ❌ W0 | ⬜ pending |
| 02-01-06 | 01 | 1 | SRCH-06 | integration | `mvn test -pl cameleer3-server-app -Dtest=DetailControllerIT#detailReturnsNestedTree` | ❌ W0 | ⬜ pending |
| 02-02-01 | 02 | 1 | DIAG-01 | integration | `mvn test -pl cameleer3-server-app -Dtest=DiagramControllerIT#contentHashDedup` | Partial | ⬜ pending |
| 02-02-02 | 02 | 1 | DIAG-02 | integration | `mvn test -pl cameleer3-server-app -Dtest=DetailControllerIT#detailIncludesDiagramHash` | ❌ W0 | ⬜ pending |
| 02-02-03 | 02 | 1 | DIAG-03 | integration | `mvn test -pl cameleer3-server-app -Dtest=DiagramRenderControllerIT#renderSvg` | ❌ W0 | ⬜ pending |
| 02-01-01 | 01 | 1 | SRCH-01 | integration | `mvn test -pl cameleer-server-app -Dtest=SearchControllerIT#searchByStatus` | ❌ W0 | ⬜ pending |
| 02-01-02 | 01 | 1 | SRCH-02 | integration | `mvn test -pl cameleer-server-app -Dtest=SearchControllerIT#searchByTimeRange` | ❌ W0 | ⬜ pending |
| 02-01-03 | 01 | 1 | SRCH-03 | integration | `mvn test -pl cameleer-server-app -Dtest=SearchControllerIT#searchByDuration` | ❌ W0 | ⬜ pending |
| 02-01-04 | 01 | 1 | SRCH-04 | integration | `mvn test -pl cameleer-server-app -Dtest=SearchControllerIT#searchByCorrelationId` | ❌ W0 | ⬜ pending |
| 02-01-05 | 01 | 1 | SRCH-05 | integration | `mvn test -pl cameleer-server-app -Dtest=SearchControllerIT#fullTextSearch` | ❌ W0 | ⬜ pending |
| 02-01-06 | 01 | 1 | SRCH-06 | integration | `mvn test -pl cameleer-server-app -Dtest=DetailControllerIT#detailReturnsNestedTree` | ❌ W0 | ⬜ pending |
| 02-02-01 | 02 | 1 | DIAG-01 | integration | `mvn test -pl cameleer-server-app -Dtest=DiagramControllerIT#contentHashDedup` | Partial | ⬜ pending |
| 02-02-02 | 02 | 1 | DIAG-02 | integration | `mvn test -pl cameleer-server-app -Dtest=DetailControllerIT#detailIncludesDiagramHash` | ❌ W0 | ⬜ pending |
| 02-02-03 | 02 | 1 | DIAG-03 | integration | `mvn test -pl cameleer-server-app -Dtest=DiagramRenderControllerIT#renderSvg` | ❌ W0 | ⬜ pending |
*Status: ⬜ pending · ✅ green · ❌ red · ⚠️ flaky*

View File

@@ -50,9 +50,9 @@ human_verification:
| Artifact | Status | Notes |
|----------|--------|-------|
| `cameleer3-server-app/src/main/java/com/cameleer3/server/app/storage/ClickHouseExecutionRepository.java` | VERIFIED | DiagramRepository injected via constructor (line 59); `findContentHashForRoute` called in `setValues()` (lines 144147); former `""` placeholder removed |
| `cameleer3-server-app/pom.xml` | VERIFIED | `maven-surefire-plugin` with `forkCount=1` `reuseForks=false` at lines 95100; `maven-failsafe-plugin` same config at lines 103108 |
| `cameleer3-server-app/src/test/java/com/cameleer3/server/app/storage/DiagramLinkingIT.java` | VERIFIED | 152 lines; 2 integration tests; positive case asserts 64-char hex hash; negative case asserts empty string; uses `ignoreExceptions()` for ClickHouse eventual consistency |
| `cameleer-server-app/src/main/java/com/cameleer/server/app/storage/ClickHouseExecutionRepository.java` | VERIFIED | DiagramRepository injected via constructor (line 59); `findContentHashForRoute` called in `setValues()` (lines 144147); former `""` placeholder removed |
| `cameleer-server-app/pom.xml` | VERIFIED | `maven-surefire-plugin` with `forkCount=1` `reuseForks=false` at lines 95100; `maven-failsafe-plugin` same config at lines 103108 |
| `cameleer-server-app/src/test/java/com/cameleer/server/app/storage/DiagramLinkingIT.java` | VERIFIED | 152 lines; 2 integration tests; positive case asserts 64-char hex hash; negative case asserts empty string; uses `ignoreExceptions()` for ClickHouse eventual consistency |
### Key Link Verification
@@ -62,7 +62,7 @@ human_verification:
| `SearchController` | `SearchService` | constructor injection, `searchService.search()` | WIRED | Previously verified; no regression |
| `DetailController` | `DetailService` | constructor injection, `detailService.getDetail()` | WIRED | Previously verified; no regression |
| `DiagramRenderController` | `DiagramRepository` + `DiagramRenderer` | `findByContentHash()` + `renderSvg()`/`layoutJson()` | WIRED | Previously verified; no regression |
| `Surefire/Failsafe` | ELK classloader isolation | `reuseForks=false` forces fresh JVM per test class | WIRED | Lines 95116 in `cameleer3-server-app/pom.xml` |
| `Surefire/Failsafe` | ELK classloader isolation | `reuseForks=false` forces fresh JVM per test class | WIRED | Lines 95116 in `cameleer-server-app/pom.xml` |
### Requirements Coverage
@@ -108,7 +108,7 @@ Two blockers from the initial verification (2026-03-11T16:00:00Z) have been reso
**Gap 1 resolved — DIAG-02 diagram hash linking:** `ClickHouseExecutionRepository` now injects `DiagramRepository` via constructor and calls `findContentHashForRoute(exec.getRouteId(), "")` in `insertBatch()`. Both the diagram store path and the execution ingest path use `agent_id=""` consistently, so the lookup is correct. `DiagramLinkingIT` provides integration test coverage for both the positive case (hash populated when diagram exists) and negative case (empty string when no diagram exists for the route).
**Gap 2 resolved — Test suite stability:** Both `maven-surefire-plugin` and `maven-failsafe-plugin` in `cameleer3-server-app/pom.xml` are now configured with `forkCount=1` `reuseForks=false`. This forces a fresh JVM per test class, isolating ELK's `LayeredMetaDataProvider` static initializer from Spring Boot's classloader. The SUMMARY reports 51 tests, 0 failures. Test count across 16 test files totals 80 `@Test` methods; the difference from 51 reflects how Surefire/Failsafe counts parameterized and nested tests vs. raw annotation count.
**Gap 2 resolved — Test suite stability:** Both `maven-surefire-plugin` and `maven-failsafe-plugin` in `cameleer-server-app/pom.xml` are now configured with `forkCount=1` `reuseForks=false`. This forces a fresh JVM per test class, isolating ELK's `LayeredMetaDataProvider` static initializer from Spring Boot's classloader. The SUMMARY reports 51 tests, 0 failures. Test count across 16 test files totals 80 `@Test` methods; the difference from 51 reflects how Surefire/Failsafe counts parameterized and nested tests vs. raw annotation count.
No regressions were introduced. All 10 observable truths and all 9 phase requirements are now satisfied. Two items remain for human visual verification (SVG rendering correctness).