When spring.flyway.url is set independently, Spring Boot does not
inherit credentials from spring.datasource. Add explicit user/password
to both application.yml and K8s deployment to prevent "no password"
failures on feature branch deployments.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Flyway needs public in the search_path to access TimescaleDB extension
functions (create_hypertable). The app datasource must NOT include public
to prevent accidental cross-schema reads from production data.
- spring.flyway.url: currentSchema=<branch>,public (extensions accessible)
- spring.datasource.url: currentSchema=<branch> (strict isolation)
- SPRING_FLYWAY_URL env var added to K8s base manifest
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
OIDC configuration is already fully database-backed (oidc_config table,
admin API, OidcConfigRepository). Remove the redundant env var binding
(SecurityProperties.Oidc), the env-to-DB seeder (oidcConfigSeeder), and
the OIDC section from application.yml.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
OIDC configuration should be managed by the server itself (database-backed),
not injected via K8s secrets. Remove all CAMELEER_OIDC_* env vars from
deployment manifests and the cameleer-oidc secret from CI. The server
defaults to OIDC disabled via application.yml.
This also fixes the Kustomize strategic merge conflict where the feature
overlay tried to set value on an env var that had valueFrom in the base.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Kustomize rejects absolute paths for resource references. Instead of
rewriting ../../base to an absolute path, copy both base and overlay
into a temp directory preserving the relative path structure.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
deploy/server.yaml and deploy/ui.yaml are no longer referenced by CI,
which now uses deploy/base/ + deploy/overlays/main/ via kubectl apply -k.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
bitnami/kubectl lacks a package manager in the Gitea Actions runner,
so tool installation fails. alpine/k8s:1.32.3 ships with kubectl,
kustomize, git, jq, curl, and sed pre-installed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Enable deploying feature branches into isolated environments on the same
k3s cluster. Each branch gets its own namespace (cam-<slug>), PostgreSQL
schema, and OpenSearch index prefix for data isolation while sharing the
underlying infrastructure.
- Make OpenSearch index prefix and DB schema configurable via env vars
(defaults preserve existing behavior)
- Restructure deploy/ into Kustomize base + overlays (main/feature)
- Extend CI to build Docker images for all branches, not just main
- Add deploy-feature job with namespace creation, secret copying,
Traefik Ingress routing (<slug>-api/ui.cameleer.siegeln.net)
- Add cleanup-branch job to remove namespace, PG schema, OS indices
on branch deletion
- Install required tools (git, jq, curl) in CI deploy containers
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Set failsafe reuseForks=true to reuse JVM across IT classes (faster test suite)
- Replace ClickHouse with PostgreSQL+OpenSearch in docker-compose.yml
- Remove redundant docker-compose.dev.yml
- Update CLAUDE.md and HOWTO.md to reflect new storage stack
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Use singleton container pattern for PostgreSQL + OpenSearch testcontainers
(fixes container lifecycle issues with @TestInstance(PER_CLASS))
- Fix table name route_executions → executions in DetailControllerIT and
ExecutionControllerIT
- Serialize processor headers as JSON (ObjectMapper) instead of Map.toString()
for JSONB column compatibility
- Add nested mapping for processors field in OpenSearch index template
- Use .keyword sub-field for term queries on dynamically mapped text fields
- Add wildcard fallback queries for all text searches (substring matching)
- Isolate stats tests with unique route names to prevent data contamination
- Wait for OpenSearch indexing in SearchControllerIT with targeted Awaitility
- Reduce OpenSearch debounce to 100ms in test profile
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- SearchControllerIT: remove @TestInstance(PER_CLASS), use @BeforeEach with
static guard, fix table name (route_executions -> executions), remove
Awaitility polling
- OpenSearchIndexIT: replace Thread.sleep with explicit index refresh via
OpenSearchClient
- DiagramLinkingIT: fix table name, remove Awaitility awaits (writes are
synchronous)
- IngestionSchemaIT: rewrite queries for PostgreSQL relational model
(processor_executions table instead of ClickHouse array columns)
- PostgresStatsStoreIT: use explicit time bounds in
refresh_continuous_aggregate calls
- IngestionService: populate diagramContentHash during execution ingestion
by looking up the latest diagram for the route+agent
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace ClickHouse credentials secret with postgres-credentials and
opensearch-credentials secrets. Update deploy step to apply postgres.yaml
and opensearch.yaml manifests instead of clickhouse.yaml, with appropriate
rollout status checks for each StatefulSet.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Delete all ClickHouse storage implementations and config
- Delete old core interfaces (ExecutionRepository, DiagramRepository, MetricsRepository, SearchEngine, RawExecutionRow)
- Delete ClickHouse SQL migration files
- Delete AbstractClickHouseIT
- Update controllers to use new store interfaces (DiagramStore, ExecutionStore)
- Fix IngestionService calls in controllers for new synchronous API
- Migrate all ITs from AbstractClickHouseIT to AbstractPostgresIT
- Fix count() syntax and remove ClickHouse-specific test assertions
- Update TreeReconstructionTest for new buildTree() method
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Design to replace ClickHouse with PostgreSQL/TimescaleDB + OpenSearch.
PostgreSQL as source of truth with continuous aggregates for analytics,
OpenSearch for full-text wildcard search. 21-task implementation plan.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace disconnected Transactions/Applications pages with a persistent
collapsible sidebar listing apps by health status. Add app-scoped view
(/apps/:group) with filtered stats, route chips, and scoped table.
Merge Processor Tree into diagram detail panel with Inspector/Tree
toggle and resizable divider. Remove max-width constraint for full
viewport usage. All view states are deep-linkable via URL.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The empty servers list caused Swagger UI to construct request URLs
without the /api/v1 prefix, resulting in CORS/fetch failures.
Adding a relative server entry makes paths resolve correctly.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>