feat: vendor sidebar section, remove example tenant, add Logto link
- 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>
This commit is contained in:
@@ -1,106 +0,0 @@
|
||||
package net.siegeln.cameleer.saas.config;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import net.siegeln.cameleer.saas.tenant.TenantEntity;
|
||||
import net.siegeln.cameleer.saas.tenant.TenantRepository;
|
||||
import net.siegeln.cameleer.saas.tenant.TenantStatus;
|
||||
import net.siegeln.cameleer.saas.tenant.Tier;
|
||||
import net.siegeln.cameleer.saas.license.LicenseEntity;
|
||||
import net.siegeln.cameleer.saas.license.LicenseRepository;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.boot.ApplicationRunner;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.File;
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Map;
|
||||
|
||||
@Component
|
||||
public class BootstrapDataSeeder implements ApplicationRunner {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(BootstrapDataSeeder.class);
|
||||
private static final String BOOTSTRAP_FILE = "/data/bootstrap/logto-bootstrap.json";
|
||||
|
||||
private final TenantRepository tenantRepository;
|
||||
private final LicenseRepository licenseRepository;
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
public BootstrapDataSeeder(TenantRepository tenantRepository,
|
||||
LicenseRepository licenseRepository) {
|
||||
this.tenantRepository = tenantRepository;
|
||||
this.licenseRepository = licenseRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments args) {
|
||||
File file = new File(BOOTSTRAP_FILE);
|
||||
if (!file.exists()) {
|
||||
log.info("No bootstrap file found at {} — skipping data seeding", BOOTSTRAP_FILE);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
JsonNode config = objectMapper.readTree(file);
|
||||
String orgId = getField(config, "organizationId");
|
||||
String tenantName = getField(config, "tenantName");
|
||||
String tenantSlug = getField(config, "tenantSlug");
|
||||
|
||||
if (orgId == null || tenantSlug == null) {
|
||||
log.info("Bootstrap file missing organizationId or tenantSlug — skipping");
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if tenant already exists
|
||||
if (tenantRepository.existsBySlug(tenantSlug)) {
|
||||
log.info("Tenant '{}' already exists — skipping bootstrap seeding", tenantSlug);
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("Seeding bootstrap tenant '{}'...", tenantSlug);
|
||||
|
||||
// Create tenant
|
||||
TenantEntity tenant = new TenantEntity();
|
||||
tenant.setName(tenantName != null ? tenantName : "Example Tenant");
|
||||
tenant.setSlug(tenantSlug);
|
||||
tenant.setTier(Tier.LOW);
|
||||
tenant.setStatus(TenantStatus.ACTIVE);
|
||||
tenant.setLogtoOrgId(orgId);
|
||||
tenant = tenantRepository.save(tenant);
|
||||
log.info("Created tenant: {} ({})", tenant.getSlug(), tenant.getId());
|
||||
|
||||
// Create license
|
||||
LicenseEntity license = new LicenseEntity();
|
||||
license.setTenantId(tenant.getId());
|
||||
license.setTier("LOW");
|
||||
license.setFeatures(Map.of(
|
||||
"topology", true,
|
||||
"lineage", false,
|
||||
"correlation", false,
|
||||
"debugger", false,
|
||||
"replay", false
|
||||
));
|
||||
license.setLimits(Map.of(
|
||||
"max_agents", 3,
|
||||
"retention_days", 7,
|
||||
"max_environments", 1
|
||||
));
|
||||
license.setIssuedAt(Instant.now());
|
||||
license.setExpiresAt(Instant.now().plus(365, ChronoUnit.DAYS));
|
||||
license.setToken("bootstrap-license");
|
||||
licenseRepository.save(license);
|
||||
log.info("Created license for tenant '{}'", tenantSlug);
|
||||
|
||||
log.info("Bootstrap data seeding complete.");
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to seed bootstrap data: {}", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private String getField(JsonNode node, String field) {
|
||||
return node.has(field) ? node.get(field).asText() : null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user