diff --git a/src/main/java/group/goforward/battlbuilder/cli/BetaInviteCliRunner.java b/src/main/java/group/goforward/battlbuilder/cli/BetaInviteCliRunner.java index 39c02a1..8da605b 100644 --- a/src/main/java/group/goforward/battlbuilder/cli/BetaInviteCliRunner.java +++ b/src/main/java/group/goforward/battlbuilder/cli/BetaInviteCliRunner.java @@ -3,16 +3,21 @@ package group.goforward.battlbuilder.cli; import group.goforward.battlbuilder.services.auth.impl.BetaInviteService; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Component; + @Component +@Profile("!prod") +@ConditionalOnProperty( + name = "app.beta.invite.run", + havingValue = "true" +) public class BetaInviteCliRunner implements CommandLineRunner { private final BetaInviteService inviteService; - @Value("${app.beta.invite.run:false}") - private boolean run; - @Value("${app.beta.invite.limit:0}") private int limit; @@ -28,10 +33,11 @@ public class BetaInviteCliRunner implements CommandLineRunner { @Override public void run(String... args) { - if (!run) return; - int count = inviteService.inviteAllBetaUsers(tokenMinutes, limit, dryRun); - System.out.println("✅ Beta invite runner complete. processed=" + count + " dryRun=" + dryRun); + + System.out.println( + "✅ Beta invite runner complete. processed=" + count + " dryRun=" + dryRun + ); // Exit so it behaves like a CLI command System.exit(0); diff --git a/src/main/java/group/goforward/battlbuilder/configuration/SecurityConfig.java b/src/main/java/group/goforward/battlbuilder/configuration/SecurityConfig.java index 70922aa..0b702d3 100644 --- a/src/main/java/group/goforward/battlbuilder/configuration/SecurityConfig.java +++ b/src/main/java/group/goforward/battlbuilder/configuration/SecurityConfig.java @@ -46,6 +46,7 @@ public class SecurityConfig { // protected .requestMatchers("/api/v1/builds/me/**").authenticated() + .requestMatchers("/api/v1/admin/**").authenticated() // everything else (adjust later as you lock down) .anyRequest().permitAll() diff --git a/src/main/java/group/goforward/battlbuilder/controllers/admin/AdminBetaInviteController.java b/src/main/java/group/goforward/battlbuilder/controllers/admin/AdminBetaInviteController.java new file mode 100644 index 0000000..6394318 --- /dev/null +++ b/src/main/java/group/goforward/battlbuilder/controllers/admin/AdminBetaInviteController.java @@ -0,0 +1,28 @@ +package group.goforward.battlbuilder.controllers.admin; + +import group.goforward.battlbuilder.services.auth.impl.BetaInviteService; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/api/v1/admin/beta") +public class AdminBetaInviteController { + + private final BetaInviteService betaInviteService; + + public AdminBetaInviteController(BetaInviteService betaInviteService) { + this.betaInviteService = betaInviteService; + } + + // POST /api/v1/admin/beta/invites/send?limit=25&dryRun=true&tokenMinutes=30 + @PostMapping("/invites/send") + public InviteBatchResponse sendInvites( + @RequestParam(defaultValue = "0") int limit, + @RequestParam(defaultValue = "true") boolean dryRun, + @RequestParam(defaultValue = "30") int tokenMinutes + ) { + int processed = betaInviteService.inviteAllBetaUsers(tokenMinutes, limit, dryRun); + return new InviteBatchResponse(processed, dryRun, tokenMinutes, limit); + } + + public record InviteBatchResponse(int processed, boolean dryRun, int tokenMinutes, int limit) {} +} \ No newline at end of file diff --git a/src/main/java/group/goforward/battlbuilder/services/utils/impl/EmailServiceImpl.java b/src/main/java/group/goforward/battlbuilder/services/utils/impl/EmailServiceImpl.java index bcb0639..191e707 100644 --- a/src/main/java/group/goforward/battlbuilder/services/utils/impl/EmailServiceImpl.java +++ b/src/main/java/group/goforward/battlbuilder/services/utils/impl/EmailServiceImpl.java @@ -51,7 +51,7 @@ public class EmailServiceImpl implements EmailService { // ✅ Capture-only mode: record it, but don’t send if (!outboundEnabled) { - emailRequest.setStatus(EmailStatus.PENDING); // <-- if you don't have this enum, use PENDING + emailRequest.setStatus(EmailStatus.FAILED); emailRequest.setErrorMessage("Outbound email suppressed by config (app.email.outbound-enabled=false)"); return emailRequestRepository.save(emailRequest); } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index d345f16..258622b 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -60,8 +60,10 @@ app.email.outbound-enabled=false # CLI invite runner (off by default) app.beta.invite.run=false -app.beta.invite.limit=0 # 0 = no limit -app.beta.invite.dryRun=true # true = generate + log, but do NOT send emails +app.beta.invite.limit=0 +# 0 = no limit +app.beta.invite.dryRun=true +# true = generate + log, but do NOT send emails app.beta.invite.tokenMinutes=30 # Ai Enrichment Settings