11 KiB
Plan 4: SaaS Cleanup — Strip to Vendor Management Plane
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Remove all migrated code from the SaaS layer (environments, apps, deployments, ClickHouse access) and strip it down to a thin vendor management plane: tenant lifecycle, license generation, billing, and Logto organization management.
Architecture: The SaaS retains only vendor-level concerns. All runtime management, observability, and user management is now in the server. The SaaS communicates with server instances exclusively via REST API (ServerApiClient). ClickHouse dependency is removed entirely.
Tech Stack: Java 21, Spring Boot 3.4.3, PostgreSQL 16
Repo: C:\Users\Hendrik\Documents\projects\cameleer-saas
Prerequisite: Plans 1-3 must be implemented in cameleer3-server first.
Summary of Changes
Files to DELETE (migrated to server or no longer needed)
src/main/java/net/siegeln/cameleer/saas/environment/
├── EnvironmentEntity.java
├── EnvironmentService.java
├── EnvironmentController.java
├── EnvironmentRepository.java
├── EnvironmentStatus.java
└── dto/
├── CreateEnvironmentRequest.java
├── UpdateEnvironmentRequest.java
└── EnvironmentResponse.java
src/main/java/net/siegeln/cameleer/saas/app/
├── AppEntity.java
├── AppService.java
├── AppController.java
├── AppRepository.java
└── dto/
├── CreateAppRequest.java
└── AppResponse.java
src/main/java/net/siegeln/cameleer/saas/deployment/
├── DeploymentEntity.java
├── DeploymentService.java
├── DeploymentController.java
├── DeploymentRepository.java
├── DeploymentExecutor.java
├── DesiredStatus.java
├── ObservedStatus.java
└── dto/
└── DeploymentResponse.java
src/main/java/net/siegeln/cameleer/saas/runtime/
├── RuntimeOrchestrator.java
├── DockerRuntimeOrchestrator.java
├── RuntimeConfig.java
├── BuildImageRequest.java
├── StartContainerRequest.java
├── ContainerStatus.java
└── LogConsumer.java
src/main/java/net/siegeln/cameleer/saas/log/
├── ClickHouseConfig.java
├── ClickHouseProperties.java
├── ContainerLogService.java
├── LogController.java
└── dto/
└── LogEntry.java
src/main/java/net/siegeln/cameleer/saas/observability/
├── AgentStatusService.java
├── AgentStatusController.java
└── dto/
├── AgentStatusResponse.java
└── ObservabilityStatusResponse.java
Files to MODIFY
src/main/java/net/siegeln/cameleer/saas/config/AsyncConfig.java — remove deploymentExecutor bean
src/main/java/net/siegeln/cameleer/saas/tenant/TenantService.java — remove createDefaultForTenant() call
src/main/resources/application.yml — remove clickhouse + runtime config sections
docker-compose.yml — remove Docker socket mount from SaaS, update routing
Files to KEEP (vendor management plane)
src/main/java/net/siegeln/cameleer/saas/tenant/ — Tenant CRUD, lifecycle
src/main/java/net/siegeln/cameleer/saas/license/ — License generation
src/main/java/net/siegeln/cameleer/saas/identity/ — Logto org management, ServerApiClient
src/main/java/net/siegeln/cameleer/saas/config/ — SecurityConfig, SpaController
src/main/java/net/siegeln/cameleer/saas/audit/ — Vendor audit logging
src/main/java/net/siegeln/cameleer/saas/apikey/ — API key management (if used)
ui/ — Vendor management dashboard
Flyway Migrations to KEEP
The existing migrations (V001-V009) can remain since they're already applied. Add a new cleanup migration:
src/main/resources/db/migration/V010__drop_migrated_tables.sql
Task 1: Remove ClickHouse Dependency
- Step 1: Delete ClickHouse files
rm -rf src/main/java/net/siegeln/cameleer/saas/log/ClickHouseConfig.java
rm -rf src/main/java/net/siegeln/cameleer/saas/log/ClickHouseProperties.java
rm -rf src/main/java/net/siegeln/cameleer/saas/log/ContainerLogService.java
rm -rf src/main/java/net/siegeln/cameleer/saas/log/LogController.java
rm -rf src/main/java/net/siegeln/cameleer/saas/log/dto/
- Step 2: Remove ClickHouse from AgentStatusService
Delete AgentStatusService.java and AgentStatusController.java entirely (agent status is now a server concern).
rm -rf src/main/java/net/siegeln/cameleer/saas/observability/
- Step 3: Remove ClickHouse config from application.yml
Remove the entire cameleer.clickhouse: section.
- Step 4: Remove ClickHouse JDBC dependency from pom.xml
Remove:
<dependency>
<groupId>com.clickhouse</groupId>
<artifactId>clickhouse-jdbc</artifactId>
</dependency>
- Step 5: Verify build
Run: cd /c/Users/Hendrik/Documents/projects/cameleer-saas && mvn compile
Expected: BUILD SUCCESS. Fix any remaining import errors.
- Step 6: Commit
git add -A
git commit -m "feat: remove all ClickHouse dependencies from SaaS layer"
Task 2: Remove Environment/App/Deployment Code
- Step 1: Delete environment package
rm -rf src/main/java/net/siegeln/cameleer/saas/environment/
- Step 2: Delete app package
rm -rf src/main/java/net/siegeln/cameleer/saas/app/
- Step 3: Delete deployment package
rm -rf src/main/java/net/siegeln/cameleer/saas/deployment/
- Step 4: Delete runtime package
rm -rf src/main/java/net/siegeln/cameleer/saas/runtime/
- Step 5: Remove AsyncConfig deploymentExecutor bean
In AsyncConfig.java, remove the deploymentExecutor bean (or delete AsyncConfig if it only had that bean).
- Step 6: Update TenantService
Remove any calls to EnvironmentService.createDefaultForTenant() from TenantService.java. The server now handles default environment creation.
- Step 7: Remove runtime config from application.yml
Remove the entire cameleer.runtime: section.
- Step 8: Verify build
Run: cd /c/Users/Hendrik/Documents/projects/cameleer-saas && mvn compile
Expected: BUILD SUCCESS. Fix any remaining import errors.
- Step 9: Commit
git add -A
git commit -m "feat: remove migrated environment/app/deployment/runtime code from SaaS"
Task 3: Database Cleanup Migration
- Step 1: Create cleanup migration
-- V010__drop_migrated_tables.sql
-- Drop tables that have been migrated to cameleer3-server
DROP TABLE IF EXISTS deployments CASCADE;
DROP TABLE IF EXISTS apps CASCADE;
DROP TABLE IF EXISTS environments CASCADE;
DROP TABLE IF EXISTS api_keys CASCADE;
- Step 2: Commit
git add src/main/resources/db/migration/V010__drop_migrated_tables.sql
git commit -m "feat: drop migrated tables from SaaS database"
Task 4: Remove Docker Socket Dependency
- Step 1: Update docker-compose.yml
Remove from cameleer-saas service:
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- jardata:/data/jars
group_add:
- "0"
The Docker socket mount now belongs to the cameleer3-server service instead.
- Step 2: Remove docker-java dependency from pom.xml
Remove:
<dependency>
<groupId>com.github.docker-java</groupId>
<artifactId>docker-java-core</artifactId>
</dependency>
<dependency>
<groupId>com.github.docker-java</groupId>
<artifactId>docker-java-transport-zerodep</artifactId>
</dependency>
- Step 3: Commit
git add docker-compose.yml pom.xml
git commit -m "feat: remove Docker socket dependency from SaaS layer"
Task 5: Update SaaS UI
- Step 1: Remove environment/app/deployment pages from SaaS frontend
Remove pages that now live in the server UI:
EnvironmentsPageEnvironmentDetailPageAppDetailPage
The SaaS UI retains:
-
DashboardPage— vendor overview (tenant list, status) -
AdminTenantsPage— tenant management -
LicensePage— license management -
Step 2: Update navigation
Remove links to environments/apps/deployments. The SaaS UI should link to the tenant's server instance for those features (e.g., "Open Dashboard" link to https://{tenant-slug}.cameleer.example.com/server/).
- Step 3: Commit
git add ui/
git commit -m "feat: strip SaaS UI to vendor management dashboard"
Task 6: Expand ServerApiClient
- Step 1: Add provisioning-related API calls
The ServerApiClient should gain methods for tenant provisioning:
public void pushLicense(String serverEndpoint, String licenseToken) {
post(serverEndpoint + "/api/v1/admin/license")
.body(Map.of("token", licenseToken))
.retrieve()
.toBodilessEntity();
}
public Map<String, Object> getHealth(String serverEndpoint) {
return get(serverEndpoint + "/api/v1/health")
.retrieve()
.body(Map.class);
}
- Step 2: Commit
git add src/main/java/net/siegeln/cameleer/saas/identity/ServerApiClient.java
git commit -m "feat: expand ServerApiClient with license push and health check methods"
Task 7: Write SAAS-INTEGRATION.md
- Step 1: Create integration contract document
Create docs/SAAS-INTEGRATION.md in the cameleer3-server repo documenting:
-
Which server API endpoints the SaaS calls
-
Required auth (M2M token with
server:adminscope) -
License injection mechanism (
POST /api/v1/admin/license) -
Health check endpoint (
GET /api/v1/health) -
What the server exposes vs what the SaaS must never access directly
-
Env vars the SaaS sets when provisioning a server instance
-
Step 2: Commit
cd /c/Users/Hendrik/Documents/projects/cameleer3-server
git add docs/SAAS-INTEGRATION.md
git commit -m "docs: add SaaS integration contract documentation"
Task 8: Final Verification
- Step 1: Build SaaS
Run: cd /c/Users/Hendrik/Documents/projects/cameleer-saas && mvn clean verify
Expected: BUILD SUCCESS with reduced dependency footprint.
- Step 2: Verify SaaS starts without ClickHouse
The SaaS should start with only PostgreSQL (and Logto). No ClickHouse required.
- Step 3: Verify remaining code footprint
The SaaS source should now contain approximately:
tenant/— ~4 fileslicense/— ~5 filesidentity/— ~3 files (LogtoConfig, ServerApiClient, M2M token)config/— ~3 files (SecurityConfig, SpaController, TLS)audit/— ~3 filesui/— stripped dashboard
Total: ~20 Java files (down from ~75).
- Step 4: Final commit
git add -A
git commit -m "chore: finalize SaaS cleanup — vendor management plane only"