Commit Graph

190 Commits

Author SHA1 Message Date
hsiegeln
dd8553a8b4 feat: full tenant cleanup on delete — Docker resources, PG schema, CH data (#55)
All checks were successful
CI / build (push) Successful in 2m23s
CI / docker (push) Successful in 1m6s
DockerTenantProvisioner.remove() now cleans up all tenant Docker resources:
containers (by cameleer.tenant label), env networks, tenant network, JAR volume.
TenantDataCleanupService drops the tenant's PostgreSQL schema and deletes all
ClickHouse data for GDPR compliance.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 09:10:47 +02:00
hsiegeln
6f8b84fb1a fix: re-provision containers when restart finds them missing
All checks were successful
CI / build (push) Successful in 1m22s
CI / docker (push) Successful in 39s
When Docker containers have been removed (e.g. manual cleanup or image
update), restart now falls back to full re-provisioning instead of
failing with 404. Applies to both vendor and tenant portal restart.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 08:37:04 +02:00
hsiegeln
4fdf171912 fix: don't show stale CA banner when no CA bundle exists
Some checks failed
CI / build (push) Successful in 1m39s
CI / docker (push) Successful in 37s
SonarQube Analysis / sonarqube (push) Failing after 1m44s
The self-signed bootstrap cert has no CA bundle, so newly created tenants
with ca_applied_at=NULL are not actually stale. Skip the count when the
active cert has hasCa=false.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 22:21:26 +02:00
hsiegeln
d7ce0aaf8c feat: add agent/env counts to vendor tenant list endpoint
Extend VendorTenantSummary with agentCount, environmentCount, and
agentLimit fields. Fetch counts in parallel using CompletableFuture
per tenant, only calling server API for ACTIVE tenants with RUNNING
servers. Agent limit extracted from license limits JSONB.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 22:01:02 +02:00
hsiegeln
a5445e332e fix: fetch actual agent/environment counts from server for tenant dashboard
All checks were successful
CI / build (push) Successful in 1m8s
CI / docker (push) Successful in 43s
The dashboard was showing hardcoded zeroes for agent and environment usage.
Now fetches real counts via M2M API from the tenant's server.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 20:35:24 +02:00
hsiegeln
cab6e409b9 fix: show public endpoint instead of internal Docker URL in tenant settings
All checks were successful
CI / build (push) Successful in 1m21s
CI / docker (push) Successful in 38s
Closes #51

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 20:29:54 +02:00
hsiegeln
0fe084bcb2 fix: restrict key.pem file permissions to 0600 (owner-only)
All checks were successful
CI / build (push) Successful in 1m6s
CI / docker (push) Successful in 34s
All private key writes now use writeAtomicRestricted which sets POSIX
owner-read/write permissions after writing. Gracefully skips on
non-POSIX filesystems (Windows dev).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 19:49:07 +02:00
hsiegeln
3ae8fa18cd feat: support password-protected private keys
All checks were successful
CI / build (push) Successful in 1m8s
CI / docker (push) Successful in 42s
Encrypted PKCS#8 private keys are decrypted during staging using the
provided password. The decrypted key is stored for Traefik (which needs
cleartext PEM). Unencrypted keys continue to work without a password.

- CertificateManager.stage() accepts optional keyPassword
- DockerCertificateManager handles EncryptedPrivateKeyInfo decryption
- UI: password field in upload form (vendor CertificatesPage)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 19:44:09 +02:00
hsiegeln
dd30ee77d4 feat: tenant CA certificate management with staging
Some checks failed
CI / build (push) Successful in 1m7s
CI / docker (push) Has been cancelled
Tenants can upload multiple CA certificates for enterprise SSO providers
that use private certificate authorities.

- New tenant_ca_certs table (V013) with PEM storage in DB
- Stage/activate/delete lifecycle per CA cert
- Aggregated ca.pem rebuild on activate/delete (atomic .wip swap)
- REST API: GET/POST/DELETE on /api/tenant/ca
- UI: CA Certificates section on SSO page with upload, activate, remove

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 19:35:04 +02:00
hsiegeln
45bcc954ac feat: certificate management with stage/activate/restore lifecycle
All checks were successful
CI / build (push) Successful in 1m8s
CI / docker (push) Successful in 45s
Provider-based architecture (Docker now, K8s later):
- CertificateManager interface + DockerCertificateManager (file-based)
- Atomic swap via .wip files for safe cert replacement
- Stage -> Activate -> Archive lifecycle with one-deep rollback
- Bootstrap supports user-supplied certs via CERT_FILE/KEY_FILE/CA_FILE
- CA bundle aggregates platform + tenant CAs, distributed to containers
- Vendor UI: Certificates page with upload, activate, restore, discard
- Stale tenant tracking (ca_applied_at) with restart banner
- Conditional TLS skip removal when CA bundle exists

Includes design spec, migration V012, service + controller tests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 18:29:02 +02:00
hsiegeln
2607ef5dbe fix: resolve actor name from Logto for audit log entries
All checks were successful
CI / build (push) Successful in 50s
CI / docker (push) Successful in 32s
AuditService now looks up username/name/email from Logto Management API
when actorEmail is null, with an in-memory cache to avoid repeated calls.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 17:47:43 +02:00
hsiegeln
0a1e848ef7 fix: return 204 No Content from restart endpoints
All checks were successful
CI / build (push) Successful in 52s
CI / docker (push) Successful in 34s
Empty 200 responses caused JSON parse errors in the API client.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 17:41:17 +02:00
hsiegeln
a3a1643b37 fix: update VendorTenantServiceTest for async provisioning
All checks were successful
CI / build (push) Successful in 50s
CI / docker (push) Successful in 45s
Tests now mock tenantRepository.findById() since provisionAsync re-loads
the tenant entity, and assert on the entity directly rather than the
return value of createAndProvision().

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 17:28:51 +02:00
hsiegeln
4447d79c92 fix: add missing TenantProvisioner mock to TenantPortalServiceTest
Some checks failed
CI / build (push) Failing after 40s
CI / docker (push) Has been skipped
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 17:25:37 +02:00
hsiegeln
7e7a07470b feat: add restart server action for vendor and tenant
Some checks failed
CI / build (push) Failing after 36s
CI / docker (push) Has been skipped
Vendor: POST /api/vendor/tenants/{id}/restart (platform:admin scope)
Tenant: POST /api/tenant/server/restart (tenant:manage scope)

Both call TenantProvisioner.stop() then start() on the server + UI
containers. Restart button on vendor TenantDetailPage (Actions card)
and tenant TenantDashboardPage (Server card). Allowed in any status
including PROVISIONING.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 17:21:14 +02:00
hsiegeln
252c18bcff feat: async tenant provisioning with polling UX
Some checks failed
CI / build (push) Failing after 39s
CI / docker (push) Has been skipped
Backend: extract Docker provisioning into @Async method so the API
returns immediately with status=PROVISIONING. The tenant record, Logto
org, admin user, and license are created synchronously; container
provisioning, health check, license push, and OIDC config happen in a
background thread.

Frontend: navigate to tenant detail page immediately after creation.
Detail page polls every 3s while status=PROVISIONING and shows a
spinner indicator. Toast notification when provisioning completes.
Fixes #52.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 17:14:26 +02:00
hsiegeln
e559267f1e feat: replace tenant OIDC page with Enterprise SSO connector management
All checks were successful
CI / build (push) Successful in 1m3s
CI / docker (push) Successful in 46s
- Add LogtoManagementClient methods for SSO connector CRUD + org JIT
- Add TenantSsoService with tenant isolation (validates connector-org link)
- Add TenantSsoController at /api/tenant/sso with test endpoint
- Create SsoPage with provider selection, dynamic config form, test button
- Remove old OIDC config endpoints from tenant portal (server OIDC is
  now platform-managed, set during provisioning)
- Sidebar: OIDC -> SSO with Shield icon

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 15:48:51 +02:00
hsiegeln
4341656a5e refactor: remove additionalScopes from OIDC config push
All checks were successful
CI / build (push) Successful in 1m34s
CI / docker (push) Successful in 56s
Server now hardcodes Logto org scopes in the auth flow, so the
provisioner no longer needs to push them via OIDC config.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 15:37:53 +02:00
hsiegeln
bcad83cc40 fix: use JdbcTemplate for audit queries (match server pattern)
All checks were successful
CI / build (push) Successful in 53s
CI / docker (push) Successful in 34s
Replace JPQL @Query with dynamic SQL via JdbcTemplate to avoid
Hibernate null parameter type issues (bytea vs text). Conditionally
appends WHERE clauses only for non-null filters, matching the proven
pattern from cameleer3-server's PostgresAuditRepository.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 13:31:02 +02:00
hsiegeln
0d47c2ec7c fix: avoid null bytea in audit search JPQL
All checks were successful
CI / build (push) Successful in 51s
CI / docker (push) Successful in 32s
Hibernate binds null String params as bytea, causing PostgreSQL
lower(bytea) error. Convert null search to empty string in service
layer, use empty-string check in JPQL instead of IS NULL.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 13:26:18 +02:00
hsiegeln
247ec030e5 fix: use COALESCE in audit JPQL to prevent lower(bytea) error
All checks were successful
CI / build (push) Successful in 51s
CI / docker (push) Successful in 31s
Hibernate passes null search param as bytea type, causing PostgreSQL
to fail on LOWER(bytea). COALESCE converts null to empty string.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 13:21:20 +02:00
hsiegeln
a1acc0bc62 fix: permit SPA routes /vendor/** and /tenant/** for direct navigation
All checks were successful
CI / build (push) Successful in 49s
CI / docker (push) Successful in 32s
Without this, hard refresh on SPA routes returns 401 because Spring
Security intercepts before SpaController can forward to index.html.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 13:15:08 +02:00
hsiegeln
8b94937d38 feat: add audit log viewing for vendor and tenant personas
All checks were successful
CI / build (push) Successful in 52s
CI / docker (push) Successful in 40s
Vendor sees all audit events with tenant filter at /vendor/audit.
Tenant admin sees only their own events at /tenant/audit.
Both support pagination, action/result filters, and text search.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 13:07:18 +02:00
hsiegeln
4572a4bb57 fix: mount JAR volume on provisioned server containers
All checks were successful
CI / build (push) Successful in 1m3s
CI / docker (push) Successful in 34s
The server needs a shared Docker volume at /data/jars to store
uploaded JARs that deployed app containers can access. Without this
mount, deployed containers fail with "Unable to access jarfile".

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 12:36:09 +02:00
hsiegeln
9824d06824 fix: include Logto org scopes in OIDC config pushed to servers
All checks were successful
CI / build (push) Successful in 1m1s
CI / docker (push) Successful in 38s
Without urn:logto:scope:organizations and
urn:logto:scope:organization_roles in the additionalScopes, Logto
doesn't include organization role data in the Custom JWT context.
This caused the roles claim to be empty, so all OIDC users got
defaultRoles (VIEWER) instead of their org role (e.g. owner →
server:admin).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 12:10:56 +02:00
hsiegeln
d911fd2201 fix: add traefik.docker.network label to provisioned containers
All checks were successful
CI / build (push) Successful in 53s
CI / docker (push) Successful in 34s
Traefik's Docker provider resolves container IPs using the configured
default network ('cameleer'). For dynamically-created containers not
managed by compose, this network name doesn't match. Adding the
traefik.docker.network label explicitly tells Traefik to use the
cameleer-traefik network for routing, fixing 504 Gateway Timeouts
on /t/{slug}/api/* paths.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 09:40:59 +02:00
hsiegeln
b4f9277220 fix: use CAMELEER_API_URL env var for server-ui container
All checks were successful
CI / build (push) Successful in 53s
CI / docker (push) Successful in 33s
The nginx template in cameleer3-server-ui uses ${CAMELEER_API_URL} for
the upstream proxy target, not API_URL. The wrong env var name caused
the baked-in default (http://cameleer3-server:8081) to be used, which
doesn't resolve in per-tenant networks where the server is named
cameleer-server-{slug}.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 09:16:42 +02:00
hsiegeln
eaf109549d fix: use /api/v1/admin/oidc for server OIDC config push (not /api/admin)
All checks were successful
CI / build (push) Successful in 51s
CI / docker (push) Successful in 36s
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 08:58:34 +02:00
hsiegeln
7ee2985626 feat: push OIDC config to provisioned server for SSO login
All checks were successful
CI / build (push) Successful in 52s
CI / docker (push) Successful in 33s
After provisioning a server, pushes Logto Traditional Web App
credentials (client ID + secret) via the server's OIDC admin API.
This enables SSO: users authenticated via Logto can access the
server dashboard without a separate login.

Reads tradAppSecret from bootstrap JSON via LogtoConfig.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 08:37:01 +02:00
hsiegeln
aa663a9c9e feat: vendor sidebar section, remove example tenant, add Logto link
All checks were successful
CI / build (push) Successful in 1m4s
CI / docker (push) Successful in 48s
- Sidebar: Tenants moved into expandable "Vendor" section with
  sub-items for Tenants and Identity (Logto console link)
- Bootstrap: removed example organization creation (Phase 6 org)
  — tenants are now created exclusively via the vendor console
- Removed BootstrapDataSeeder (no auto-seeded tenant/license)
- Bootstrap log updated to reflect clean-slate approach

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 08:19:46 +02:00
hsiegeln
f5ef8e6488 feat: per-tenant network isolation
All checks were successful
CI / build (push) Successful in 52s
CI / docker (push) Successful in 33s
Each tenant gets an isolated Docker bridge network (cameleer-tenant-{slug}).
Server + UI containers use the tenant network as primary, with additional
connections to the shared services network (postgres/clickhouse/logto) and
Traefik network (routing). Tenant networks are internal (no internet) and
isolated from each other. Apps deployed by the tenant server also join
the tenant network. Network is removed on tenant delete.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 08:04:11 +02:00
hsiegeln
0a43a7dcd1 feat: register OIDC redirect URIs for provisioned tenant servers
All checks were successful
CI / build (push) Successful in 53s
CI / docker (push) Successful in 34s
During tenant provisioning, adds /t/{slug}/oidc/callback to the Logto
Traditional Web App's registered redirect URIs. This enables the
server's OIDC login flow to work when accessed via Traefik routing.

Also reads tradAppId from bootstrap JSON via LogtoConfig.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 07:50:38 +02:00
hsiegeln
2dc75c4361 feat: create initial admin user + add vendor to new tenant orgs
All checks were successful
CI / build (push) Successful in 50s
CI / docker (push) Successful in 41s
When creating a tenant, the vendor can specify adminUsername +
adminPassword. The backend creates the user in Logto and assigns them
the owner org role. The vendor user is also auto-added to every new
org for support access.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 07:35:17 +02:00
hsiegeln
b7a0530466 fix: exclude DELETED tenants from vendor tenant list
All checks were successful
CI / build (push) Successful in 50s
CI / docker (push) Successful in 33s
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 07:28:56 +02:00
hsiegeln
ebdb4f9450 fix: allow slug reuse after tenant soft-delete
All checks were successful
CI / build (push) Successful in 59s
CI / docker (push) Successful in 39s
existsBySlug found DELETED records, blocking slug reuse. Changed to
existsBySlugAndStatusNot(slug, DELETED) so deleted tenant slugs can
be reclaimed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 07:25:49 +02:00
hsiegeln
5ed33807d8 fix: use /api/v1/health for server health checks (not /actuator/health)
Some checks failed
CI / build (push) Successful in 49s
CI / docker (push) Successful in 30s
SonarQube Analysis / sonarqube (push) Failing after 1m24s
The server's /actuator/health requires auth. The public health endpoint
is /api/v1/health (same as compose-managed server's Docker HEALTHCHECK).
Also increased health check retries/timeout and added startPeriod.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 23:43:46 +02:00
hsiegeln
4087ce8f29 fix: provisioned server containers — strip-prefix, Docker socket, env
All checks were successful
CI / build (push) Successful in 1m14s
CI / docker (push) Successful in 34s
- Add Traefik strip-prefix middleware so /t/{slug}/api -> /api on server
- Add priority to routers (server API=10, UI=5) to prevent conflicts
- Mount Docker socket + group_add in server containers for app deployment
- Add JAR storage, Docker network, volume env vars for runtime orchestrator
- Use HashMap for labels (>10 entries exceeds Map.of limit)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 23:26:48 +02:00
hsiegeln
17fbe73e60 test: add 25 tests for vendor + portal services and controllers
Some checks failed
CI / build (push) Failing after 1m16s
CI / docker (push) Has been skipped
VendorTenantServiceTest (8): create/provision, suspend, delete, renew
VendorTenantControllerTest (7): CRUD, auth, conflict handling
TenantPortalServiceTest (5): dashboard, license, settings
TenantPortalControllerTest (5): dashboard, license, settings, auth

Fix TenantIsolationInterceptor bugs found by tests:
- org_id resolution now runs before portal path check
- path matching uses URI minus context path (not getServletPath)
- portal path returns 403 sendError instead of empty 200

Total: 50 tests, 0 failures.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 23:08:47 +02:00
hsiegeln
faac0048c3 fix: add missing server env vars to DockerTenantProvisioner
All checks were successful
CI / build (push) Successful in 50s
CI / docker (push) Successful in 43s
Adds CAMELEER_AUTH_TOKEN, CAMELEER_JWT_SECRET, CAMELEER_OIDC_AUDIENCE,
CLICKHOUSE_URL to provisioned server containers. Also passes PUBLIC_HOST
and PUBLIC_PROTOCOL to SaaS container in dev overlay so provisioner
resolves the correct hostname instead of defaulting to localhost.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 22:53:21 +02:00
hsiegeln
bf3aa57274 feat: restructure frontend routes — vendor/tenant persona split
Splits the flat 3-page UI into /vendor/* (platform:admin) and /tenant/*
(all authenticated users) route trees, with stub pages, new API hooks,
updated Layout with persona-aware sidebar, and SpaController forwarding.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 22:29:59 +02:00
hsiegeln
e56e3fca8a feat: tenant portal API (dashboard, license, OIDC, team, settings)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 22:29:01 +02:00
hsiegeln
127834ce4d feat: vendor tenant API with provisioning, suspend, delete
Adds VendorTenantService orchestrating full tenant lifecycle (create,
provision, license push, activate, suspend, delete, renew license),
VendorTenantController at /api/vendor/tenants with platform:admin guard,
LicenseResponse.from() factory, SecurityConfig vendor/tenant path rules,
and TenantIsolationInterceptor bypasses for vendor and tenant portal paths.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 22:29:01 +02:00
hsiegeln
6bdb02ff5a feat: add per-tenant health, OIDC, team methods to API clients
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 22:29:01 +02:00
hsiegeln
96a5b1d9f1 feat: implement DockerTenantProvisioner with container lifecycle
Replace stub with full Docker implementation using docker-java. Manages
per-tenant server and UI containers with Traefik labels, health checks,
image pull, network attachment, and full lifecycle (provision/start/stop/remove/status).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 22:29:01 +02:00
hsiegeln
771e9d1081 feat: add TenantProvisioner interface with auto-detection
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 22:29:01 +02:00
hsiegeln
ebba021448 feat: add provisioning fields to tenants + license revoke
Adds server_endpoint and provision_error columns to tenants table (V011 migration),
updates TenantEntity and TenantResponse with new fields and a from() factory,
adds revokeLicense() to LicenseService, and updates TenantController to use the factory.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 22:29:01 +02:00
hsiegeln
bad78e26a1 feat: add migration to drop migrated tables from SaaS database
- V010: drop deployments, apps, environments, api_keys tables
- Tables have been migrated to cameleer3-server

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 00:00:32 +02:00
hsiegeln
c254fbf723 feat: remove migrated environment/app/deployment/runtime code from SaaS
- Delete environment/, app/, deployment/, runtime/ packages (source + tests)
- Delete apikey/ package (tied to environments, table will be dropped)
- Strip AsyncConfig to empty @EnableAsync (no more deploymentExecutor bean)
- Remove EnvironmentService dependency from TenantService
- Remove environment/app isolation from TenantIsolationInterceptor
- Remove environment seeding from BootstrapDataSeeder
- Refactor ServerApiClient to use LogtoConfig instead of RuntimeConfig
- Add server-endpoint property to LogtoConfig (was in RuntimeConfig)
- Remove runtime config section and multipart config from application.yml

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 23:59:53 +02:00
hsiegeln
160a989f9f feat: remove all ClickHouse dependencies from SaaS layer
- Delete log/ package (ClickHouseConfig, ContainerLogService, LogController)
- Delete observability/ package (AgentStatusService, AgentStatusController)
- Remove clickhouse-jdbc dependency from pom.xml
- Remove cameleer.clickhouse config section from application.yml
- Delete associated test files

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 23:56:21 +02:00
hsiegeln
30aaacb5b5 fix: correct protocol version header, disable SQL logging, document deployment pipeline
All checks were successful
CI / build (push) Successful in 1m9s
CI / docker (push) Successful in 1m43s
SonarQube Analysis / sonarqube (push) Successful in 1m20s
- ServerApiClient: use X-Cameleer-Protocol-Version: 1 (server expects "1", not "2")
- Disable Hibernate show-sql in dev profile (too verbose)
- CLAUDE.md: document deployment pipeline architecture, M2M server role in bootstrap,
  runtime-base image in CI

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 18:58:27 +02:00