Commit Graph

465 Commits

Author SHA1 Message Date
hsiegeln
3c2bf4a9b1 fix: pass self-reference in VendorTenantServiceTest for async proxy
All checks were successful
CI / build (push) Successful in 1m17s
CI / docker (push) Successful in 44s
The @Lazy self-proxy pattern requires a non-null reference in tests.
Construct the instance then re-create with itself as the self param.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 23:33:07 +02:00
hsiegeln
97b2235914 fix: update tests for ProvisioningProperties runtimeBaseImage field
Some checks failed
CI / build (push) Failing after 1m22s
CI / docker (push) Has been skipped
Add missing runtimeBaseImage arg to ProvisioningProperties constructor
calls in tests. Also add missing self-proxy arg to VendorTenantService
constructor (pre-existing from async provisioning commit).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 23:27:53 +02:00
hsiegeln
338db5dcda fix: forward runtime base image to provisioned tenant servers
Some checks failed
CI / build (push) Failing after 59s
CI / docker (push) Has been skipped
CAMELEER_SERVER_RUNTIME_BASEIMAGE was never set on provisioned
per-tenant server containers, causing them to fall back to the
server's hardcoded default. Added CAMELEER_SAAS_PROVISIONING_RUNTIMEBASEIMAGE
as a configurable property that gets forwarded during provisioning.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 23:20:46 +02:00
hsiegeln
fd50a147a2 fix: make tenant provisioning truly async via self-proxy
Some checks failed
CI / build (push) Failing after 41s
CI / docker (push) Has been skipped
@Async on provisionAsync() was bypassed because all call sites were
internal (this.provisionAsync), skipping the Spring proxy. Inject self
via @Lazy to route through the proxy so provisioning runs in a
background thread and the API returns immediately.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 22:32:05 +02:00
hsiegeln
0dd52624b7 fix: use semicolon as COMPOSE_FILE separator on Windows
All checks were successful
CI / build (push) Successful in 1m59s
CI / docker (push) Successful in 46s
Windows Docker Compose uses ; not : as the path separator in COMPOSE_FILE.
The colon was being interpreted as part of the filename, causing CreateFile errors.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 22:11:34 +02:00
hsiegeln
1ce0ea411d chore: update design-system to 0.1.54
Some checks failed
CI / build (push) Successful in 1m25s
CI / docker (push) Has been cancelled
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 22:08:17 +02:00
hsiegeln
81be25198c chore: update design-system to 0.1.53
All checks were successful
CI / build (push) Successful in 1m16s
CI / docker (push) Successful in 1m32s
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 21:56:14 +02:00
hsiegeln
dc4ea33c9b feat: externalize docker-compose templates from installer scripts
All checks were successful
CI / build (push) Successful in 1m16s
CI / docker (push) Successful in 20s
Replace inline heredoc compose generation with static template files.
Templates are copied to the install dir and composed via COMPOSE_FILE in .env.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 21:53:26 +02:00
hsiegeln
186f7639ad docs: update CLAUDE.md with template-based installer architecture
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 21:11:04 +02:00
hsiegeln
6c7895b0d6 chore(installer): remove generated install output, add to gitignore
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 21:09:30 +02:00
hsiegeln
6170f61eeb refactor(installer): replace ps1 compose generation with template copying
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 21:08:34 +02:00
hsiegeln
2ed527ac74 refactor(installer): replace sh compose generation with template copying
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 21:03:01 +02:00
hsiegeln
cb1f6b8ccf feat(installer): add .env.example with documented variables
Reference .env file documenting all configuration variables across both
deployment modes, with section headers for compose assembly, public access,
credentials, TLS, Docker, provisioning, and monitoring.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 20:59:15 +02:00
hsiegeln
758585cc9a feat(installer): add TLS and monitoring overlay templates
Optional compose overlays: TLS overlay mounts user-supplied certs into
traefik, monitoring overlay replaces the noop bridge with an external
Docker network for Prometheus scraping.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 20:59:10 +02:00
hsiegeln
141b44048c feat(installer): add standalone docker-compose and traefik templates
Standalone mode: server + server-ui services with postgres image override
to stock postgres:16-alpine. Includes traefik-dynamic.yml for default TLS
certificate store configuration.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 20:59:05 +02:00
hsiegeln
3c343f9441 feat(installer): add SaaS docker-compose template
Logto identity provider and cameleer-saas management plane services.
Includes Traefik labels, CORS config, bootstrap healthcheck, and all
provisioning env vars parameterized from .env.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 20:59:00 +02:00
hsiegeln
bdb24f8de6 feat(installer): add infra base docker-compose template
Shared infrastructure base (traefik, postgres, clickhouse) always loaded
regardless of deployment mode. Uses parameterized images, fail-if-unset
password variables, and a noop monitoring network bridge.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 20:58:54 +02:00
hsiegeln
933b56f68f docs: add implementation plan for externalizing compose templates
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 20:54:31 +02:00
hsiegeln
19c463051a docs: add design spec for externalizing docker compose templates
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 20:47:14 +02:00
hsiegeln
41052d01e8 fix: replace admin password fallback defaults with fail-if-unset
All checks were successful
CI / build (push) Successful in 1m15s
CI / docker (push) Successful in 16s
Docker compose templates defaulted to admin/admin when .env was missing.
Now uses :? to fail with a clear error instead of silently using weak creds.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 20:17:46 +02:00
hsiegeln
99e75b0a4e fix: update sign-in UI to design-system 0.1.51
All checks were successful
CI / build (push) Successful in 1m15s
CI / docker (push) Successful in 1m31s
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 16:33:00 +02:00
hsiegeln
eb6897bf10 chore: update design-system to 0.1.51 (renamed assets)
Some checks failed
CI / build (push) Failing after 1m9s
CI / docker (push) Has been skipped
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 16:30:50 +02:00
hsiegeln
63c194dab7 chore: rename cameleer3 to cameleer
Some checks failed
CI / build (push) Failing after 18s
CI / docker (push) Has been skipped
Rename Java packages from net.siegeln.cameleer3 to net.siegeln.cameleer,
update all references in workflows, Docker configs, docs, and bootstrap.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 15:28:44 +02:00
hsiegeln
44a0e413e9 fix: include cameleer3-log-appender.jar in runtime base image
All checks were successful
CI / build (push) Successful in 1m20s
CI / docker (push) Successful in 13s
The log appender JAR was missing from the cameleer-runtime-base Docker
image, causing agent log forwarding to silently fail with "No supported
logging framework found, log forwarding disabled". This meant only
container stdout logs (source=container) were captured — no application
or agent logs reached ClickHouse.

CI now downloads the appender JAR from the Maven registry alongside the
agent JAR, and the Dockerfile COPYs it to /app/cameleer3-log-appender.jar
where the server's Docker entrypoint expects it (-Dloader.path for
Spring Boot, -cp for plain Java).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 11:11:04 +02:00
hsiegeln
15306dddc0 fix: force-pull images on install and fix provisioning test assertions
All checks were successful
CI / build (push) Successful in 1m11s
CI / docker (push) Successful in 47s
Installers now use `--pull always --force-recreate` on `docker compose up`
to ensure fresh images are used on every install/reinstall, preventing
stale containers from missing schema changes like db_password.

Fix VendorTenantServiceTest to expect two repository saves in provisioning
tests (one for dbPassword, one for final status).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 08:50:40 +02:00
hsiegeln
6eb848f353 fix: add missing TenantDatabaseService mock to VendorTenantServiceTest
Some checks failed
CI / build (push) Failing after 58s
CI / docker (push) Has been skipped
Constructor gained an 11th parameter (TenantDatabaseService) but the
test was not updated, breaking CI compilation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 08:32:14 +02:00
hsiegeln
d53afe43cc docs: update CLAUDE.md for per-tenant PG isolation and consolidated migrations
Some checks failed
CI / build (push) Failing after 42s
CI / docker (push) Has been skipped
SonarQube Analysis / sonarqube (push) Failing after 33s
- TenantDatabaseService added to key classes
- TenantDataCleanupService now ClickHouse-only
- Per-tenant JDBC URL with currentSchema/ApplicationName in env vars table
- Provisioning flow updated with DB creation step
- Delete flow updated with schema+user drop
- Database migrations section reflects consolidated V001 baseline

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 00:26:36 +02:00
hsiegeln
24a443ef30 refactor: consolidate Flyway migrations into single V001 baseline
Some checks failed
CI / build (push) Failing after 51s
CI / docker (push) Has been skipped
Replace 14 incremental migrations (V001-V015) with a single V001__init.sql
representing the final schema. Tables that were created and later dropped
(environments, api_keys, apps, deployments) are excluded.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 00:24:25 +02:00
hsiegeln
d7eb700860 refactor: move PG cleanup to TenantDatabaseService, keep only ClickHouse
TenantDataCleanupService now handles only ClickHouse GDPR erasure;
the dropPostgresSchema private method is removed and the public method
renamed cleanupClickHouse(). VendorTenantService updated accordingly
with the TODO comment removed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 00:17:00 +02:00
hsiegeln
c1458e4995 feat: create per-tenant PG database during provisioning, drop on delete
Inject TenantDatabaseService; call createTenantDatabase() at the start
of provisionAsync() (stores generated password on TenantEntity), and
dropTenantDatabase() in delete() before GDPR data erasure.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 00:16:06 +02:00
hsiegeln
b79a7fe405 feat: construct per-tenant JDBC URL with currentSchema and ApplicationName
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 00:14:35 +02:00
hsiegeln
6d6c1f3562 feat: add TenantDatabaseService for per-tenant PG user+schema
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 00:13:34 +02:00
hsiegeln
0e3f383cf4 feat: add dbPassword to TenantProvisionRequest 2026-04-15 00:13:27 +02:00
hsiegeln
cd6dd1e5af feat: add dbPassword field to TenantEntity 2026-04-15 00:13:12 +02:00
hsiegeln
dfa2a6bfa2 feat: add db_password column to tenants table (V015) 2026-04-15 00:13:11 +02:00
hsiegeln
a7196ff4c1 docs: per-tenant PostgreSQL isolation implementation plan
8-task plan covering migration, entity change, TenantDatabaseService,
provisioner JDBC URL construction, VendorTenantService integration,
and TenantDataCleanupService refactor.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 00:11:34 +02:00
hsiegeln
17c6723f7e docs: per-tenant PostgreSQL isolation design spec
Per-tenant PG users and schemas for DB-level data isolation.
Each tenant server gets its own credentials and currentSchema/ApplicationName
JDBC parameters, aligned with server team's commit 7a63135.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 00:08:35 +02:00
hsiegeln
91e93696ed fix: improve Infrastructure page readability
All checks were successful
CI / build (push) Successful in 1m11s
CI / docker (push) Successful in 54s
Use Card and KpiStrip design system components, add database icons to
section headers, right-align numeric columns, replace text toggles with
chevron icons, and constrain max width to prevent ultra-wide stretching.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 23:26:43 +02:00
hsiegeln
57e41e407c fix: remove "Open Server Dashboard" link from tenant sidebar
All checks were successful
CI / build (push) Successful in 1m11s
CI / docker (push) Successful in 55s
The server dashboard link in the sidebar footer is premature — tenant
servers may not be provisioned yet and the link target depends on org
context that isn't always available.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 23:16:39 +02:00
hsiegeln
bc46af5cea fix: use configured credentials for tenant schema cleanup
All checks were successful
CI / build (push) Successful in 1m9s
CI / docker (push) Successful in 39s
Same hardcoded dev credentials bug as InfrastructureService —
TenantDataCleanupService.dropPostgresSchema() used "cameleer"/"cameleer_dev"
instead of the provisioning properties, causing schema DROP to fail on
production installs during tenant deletion.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 23:11:16 +02:00
hsiegeln
03fb414981 fix: use configured credentials for infrastructure PostgreSQL queries
All checks were successful
CI / build (push) Successful in 1m8s
CI / docker (push) Successful in 43s
pgConnection() had hardcoded dev credentials ("cameleer"/"cameleer_dev")
instead of using the provisioning properties, causing "password
authentication failed" on production installs where the password is
generated.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 23:01:00 +02:00
hsiegeln
553ecc1490 fix: PowerShell installer fixes for Windows and Logto console login
All checks were successful
CI / build (push) Successful in 1m7s
CI / docker (push) Successful in 18s
Three issues fixed:

1. Docker socket: use /var/run/docker.sock instead of Windows named pipe
   (//./pipe/docker_engine) — Linux containers can't use named pipes.

2. FQDN detection: reverse-DNS lookup on host IPs to find the FQDN
   instead of relying on GetHostEntry which returns bare hostname on
   Windows machines with DNS-registered domain suffixes.

3. Reinstall path duplication: Push-Location/Pop-Location in the
   reinstall handler used try/catch without finally, so Pop-Location
   was skipped when docker compose wrote to stderr under
   ErrorActionPreference=Stop. CWD stayed in the install dir, causing
   the relative ./cameleer default to resolve to cameleer/cameleer.

4. Logto bootstrap: register admin-console redirect URIs and add the
   admin user to Logto's internal organizations (t-default, t-admin)
   with the admin role — both required for console login to work.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 22:46:05 +02:00
hsiegeln
dec1c53d30 docs: track AGENTS.md for GitNexus code intelligence instructions
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 20:04:06 +02:00
hsiegeln
ace6ad0cf2 fix: remove openssl dependency for password generation
All checks were successful
CI / build (push) Successful in 1m18s
CI / docker (push) Successful in 19s
Use /dev/urandom instead of openssl rand for generating random
passwords. Available on all Linux/macOS systems without requiring
openssl to be installed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 19:58:11 +02:00
hsiegeln
4a67677158 fix: use correct compose service names in health checks
All checks were successful
CI / build (push) Successful in 1m19s
CI / docker (push) Successful in 33s
The verify_health functions passed short service names (postgres,
clickhouse, server, logto) but the actual compose services are
prefixed with cameleer-. This caused docker compose ps -q to return
empty, so health was never read and checks always timed out.

Also renamed server/server-ui service definitions to
cameleer-server/cameleer-server-ui for consistency.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 19:17:41 +02:00
hsiegeln
27c3f4d136 refactor: prefix all third-party service names with cameleer-
Some checks failed
CI / build (push) Successful in 1m59s
CI / docker (push) Successful in 1m6s
SonarQube Analysis / sonarqube (push) Failing after 1m55s
Rename all Docker Compose service names, DNS hostnames, volumes,
and Traefik labels to use the cameleer- prefix for clear ownership.

Services renamed:
- postgres → cameleer-postgres
- clickhouse → cameleer-clickhouse
- logto → cameleer-logto
- traefik → cameleer-traefik

Volumes renamed:
- pgdata → cameleer-pgdata
- chdata → cameleer-chdata
- certs → cameleer-certs
- bootstrapdata → cameleer-bootstrapdata

Updated across:
- docker-compose.yml, docker-compose.dev.yml
- installer/cameleer/docker-compose.yml
- installer/install.sh, installer/install.ps1
- application.yml defaults
- DockerTenantProvisioner.java hardcoded URL
- logto-bootstrap.sh defaults
- VendorTenantServiceTest.java
- CLAUDE.md, docs/architecture.md, docs/user-manual.md

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 22:51:33 +02:00
hsiegeln
fe6682e520 docs: update CLAUDE.md for deployment modes and admin merge
All checks were successful
CI / build (push) Successful in 1m59s
CI / docker (push) Successful in 23s
- Document standalone vs multi-tenant deployment modes
- Replace vendor references with SaaS admin
- Update bootstrap phases (Phase 12 always runs, no VENDOR_SEED_ENABLED)
- Update provisioning flow (no separate vendor user)
- Remove VENDOR_SEED_ENABLED from dev compose reference

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 21:04:57 +02:00
hsiegeln
012c866594 refactor: merge vendor user into saas-admin
All checks were successful
CI / build (push) Successful in 1m8s
CI / docker (push) Successful in 17s
The admin user IS the platform admin — no separate vendor user needed.
The saas-vendor role is now always assigned to the admin user during
bootstrap. Removes VENDOR_ENABLED, VENDOR_USER, VENDOR_PASS from all
config, prompts, compose templates, and bootstrap script.

In multi-tenant mode: admin logs in with saas-admin credentials, gets
platform:admin scope via saas-vendor role, manages tenants directly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 20:36:52 +02:00
hsiegeln
4e553a6c42 fix: add BOOTSTRAP_TOKEN to standalone server env
All checks were successful
CI / build (push) Successful in 1m9s
CI / docker (push) Successful in 15s
The cameleer3-server requires CAMELEER_SERVER_SECURITY_BOOTSTRAPTOKEN
at startup. In standalone mode nothing uses it externally, but the
server's SecurityBeanConfig validates it exists. Generate a random
token in the .env and pass it through.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 20:16:10 +02:00
hsiegeln
f254f2700f feat: standalone single-tenant deployment mode
All checks were successful
CI / build (push) Successful in 1m12s
CI / docker (push) Successful in 14s
Single-tenant installations now run the server directly without Logto
or the SaaS management plane. The installer generates a simpler compose
with 5 services: traefik, postgres, clickhouse, cameleer3-server, and
cameleer3-server-ui. Uses local auth (built-in admin), no OIDC.

Multi-tenant (vendor) mode is unchanged — full SaaS stack with Logto.

Changes:
- New DEPLOYMENT_MODE variable (standalone/saas) replaces TENANT_ORG_NAME
- generate_compose_file_standalone() for the 5-service compose
- Standalone traefik-dynamic.yml (no /platform/ redirect)
- Stock postgres:16-alpine (server creates schema via Flyway)
- Standalone health checks (server + UI instead of Logto + SaaS)
- Standalone credentials/docs generation
- Remove Phase 12b from bootstrap (no longer needed)
- Remove setup_single_tenant_record (no longer needed)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 20:12:02 +02:00