XuqmGroup-Server/tenant-service/src/main/java/com/xuqm/tenant/config/PrivateTenantBootstrapInitializer.java
XuqmGroup 32aa3c0eef feat(tenant): split update/reset ops, remove bootstrap app auto-creation
- SystemUpdateService: split runUpdate() (pull+recreate) and runReset() (recreate only)
- SystemUpdateController: add POST /api/system/reset endpoint
- SdkAppProvisioningService: remove ensureBootstrapApp/ensureApp/ensureFeatureDefaults; resolveApp now throws 404 instead of auto-creating
- SdkAppInitializer: remove ensureBootstrapApp call; only runs one-time migration marking existing system apps as isDefault=true
- PrivateTenantBootstrapInitializer: remove bootstrap app creation; only ensures admin tenant account exists

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 15:33:20 +08:00

77 行
2.9 KiB
Java

package com.xuqm.tenant.config;
import com.xuqm.tenant.entity.TenantEntity;
import com.xuqm.tenant.repository.TenantRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.UUID;
/**
* Runs only when DEPLOYMENT_MODE=PRIVATE.
* Ensures the bootstrap main tenant and app exist without overwriting existing data.
*/
@Component
@Order(20)
public class PrivateTenantBootstrapInitializer implements ApplicationRunner {
private static final Logger log = LoggerFactory.getLogger(PrivateTenantBootstrapInitializer.class);
private final PrivateDeploymentProperties deployProps;
private final TenantRepository tenantRepository;
private final PasswordEncoder passwordEncoder;
@Value("${tenant.bootstrap.email:admin@customer.com}")
private String bootstrapEmail;
@Value("${tenant.bootstrap.password:ChangeMe@2026}")
private String bootstrapPassword;
@Value("${tenant.bootstrap.username:admin}")
private String bootstrapUsername;
public PrivateTenantBootstrapInitializer(PrivateDeploymentProperties deployProps,
TenantRepository tenantRepository,
PasswordEncoder passwordEncoder) {
this.deployProps = deployProps;
this.tenantRepository = tenantRepository;
this.passwordEncoder = passwordEncoder;
}
@Override
@Transactional
public void run(ApplicationArguments args) {
if (!deployProps.isPrivate() || !deployProps.isTenantBootstrapEnabled()) {
return;
}
TenantEntity tenant = tenantRepository.findByEmail(bootstrapEmail)
.or(() -> tenantRepository.findByUsername(bootstrapUsername))
.orElse(null);
if (tenant == null) {
tenant = new TenantEntity();
tenant.setId(UUID.randomUUID().toString());
tenant.setUsername(bootstrapUsername);
tenant.setPassword(passwordEncoder.encode(bootstrapPassword));
tenant.setEmail(bootstrapEmail);
tenant.setNickname("Admin");
tenant.setType(TenantEntity.Type.MAIN);
tenant.setStatus(TenantEntity.Status.ACTIVE);
tenant.setCreatedAt(LocalDateTime.now());
tenantRepository.save(tenant);
log.info("[PRIVATE] Bootstrap tenant created: {}", bootstrapEmail);
} else {
log.info("[PRIVATE] Bootstrap tenant already exists: {}", bootstrapEmail);
}
}
}