status page creation for onboarding
This commit is contained in:
parent
1bd167d0ec
commit
22ff1a2efb
@ -10,7 +10,8 @@ import lombok.*;
|
|||||||
@RequiredArgsConstructor @Getter @ToString
|
@RequiredArgsConstructor @Getter @ToString
|
||||||
public enum Feature {
|
public enum Feature {
|
||||||
USER_REGISTRATION_ENABLED("user-registration"),
|
USER_REGISTRATION_ENABLED("user-registration"),
|
||||||
ORG_CREATION_ENABLED("org-creation");
|
ORG_CREATION_ENABLED("org-creation"),
|
||||||
|
STATUS_PAGE_CREATION_ENABLED("status-page-creation");
|
||||||
|
|
||||||
public static final Feature[] VALUES = values();
|
public static final Feature[] VALUES = values();
|
||||||
|
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
package cc.pulseapp.api.repository;
|
||||||
|
|
||||||
|
import cc.pulseapp.api.model.page.StatusPage;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import org.springframework.data.mongodb.repository.MongoRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The repository for interacting with {@link StatusPage}'s.
|
||||||
|
*
|
||||||
|
* @author Braydon
|
||||||
|
*/
|
||||||
|
public interface StatusPageRepository extends MongoRepository<StatusPage, Long> {
|
||||||
|
/**
|
||||||
|
* Find a status page by its name.
|
||||||
|
*
|
||||||
|
* @param name the name of the status page
|
||||||
|
* @return the status page with the name
|
||||||
|
*/
|
||||||
|
StatusPage findByNameIgnoreCase(@NonNull String name);
|
||||||
|
}
|
@ -84,7 +84,7 @@ public final class AuthService {
|
|||||||
byte[] salt = HashUtils.generateSalt();
|
byte[] salt = HashUtils.generateSalt();
|
||||||
Date now = new Date();
|
Date now = new Date();
|
||||||
return generateSession(request, userRepository.save(new User(
|
return generateSession(request, userRepository.save(new User(
|
||||||
snowflakeService.generateSnowflake(), input.getEmail(), input.getUsername(),
|
snowflakeService.generateSnowflake(), input.getEmail(), input.getUsername().toLowerCase(),
|
||||||
HashUtils.hash(salt, input.getPassword()), Base64.getEncoder().encodeToString(salt),
|
HashUtils.hash(salt, input.getPassword()), Base64.getEncoder().encodeToString(salt),
|
||||||
null, UserTier.FREE, 0, now
|
null, UserTier.FREE, 0, now
|
||||||
)));
|
)));
|
||||||
|
@ -8,6 +8,7 @@ import cc.pulseapp.api.model.user.User;
|
|||||||
import cc.pulseapp.api.repository.OrganizationRepository;
|
import cc.pulseapp.api.repository.OrganizationRepository;
|
||||||
import jakarta.annotation.Nonnull;
|
import jakarta.annotation.Nonnull;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -25,7 +26,8 @@ public final class OrganizationService {
|
|||||||
*/
|
*/
|
||||||
@NonNull private final OrganizationRepository orgRepository;
|
@NonNull private final OrganizationRepository orgRepository;
|
||||||
|
|
||||||
private OrganizationService(@NonNull SnowflakeService snowflakeService, @NonNull OrganizationRepository orgRepository) {
|
@Autowired
|
||||||
|
public OrganizationService(@NonNull SnowflakeService snowflakeService, @NonNull OrganizationRepository orgRepository) {
|
||||||
this.snowflakeService = snowflakeService;
|
this.snowflakeService = snowflakeService;
|
||||||
this.orgRepository = orgRepository;
|
this.orgRepository = orgRepository;
|
||||||
}
|
}
|
||||||
|
72
src/main/java/cc/pulseapp/api/service/StatusPageService.java
Normal file
72
src/main/java/cc/pulseapp/api/service/StatusPageService.java
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
package cc.pulseapp.api.service;
|
||||||
|
|
||||||
|
import cc.pulseapp.api.exception.impl.BadRequestException;
|
||||||
|
import cc.pulseapp.api.model.Feature;
|
||||||
|
import cc.pulseapp.api.model.IGenericResponse;
|
||||||
|
import cc.pulseapp.api.model.org.Organization;
|
||||||
|
import cc.pulseapp.api.model.page.StatusPage;
|
||||||
|
import cc.pulseapp.api.model.page.StatusPageTheme;
|
||||||
|
import cc.pulseapp.api.repository.StatusPageRepository;
|
||||||
|
import jakarta.annotation.Nonnull;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Braydon
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public final class StatusPageService {
|
||||||
|
/**
|
||||||
|
* The service to use for snowflake generation.
|
||||||
|
*/
|
||||||
|
@NonNull private final SnowflakeService snowflakeService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The repository to store and retrieve status pages.
|
||||||
|
*/
|
||||||
|
@NonNull private final StatusPageRepository pageRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public StatusPageService(@NonNull SnowflakeService snowflakeService, @NonNull StatusPageRepository pageRepository) {
|
||||||
|
this.snowflakeService = snowflakeService;
|
||||||
|
this.pageRepository = pageRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new status page.
|
||||||
|
*
|
||||||
|
* @param name the status page name
|
||||||
|
* @param owner the owner of the status page
|
||||||
|
* @return the created status page
|
||||||
|
* @throws BadRequestException if the status page creation fails
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public StatusPage createStatusPage(@Nonnull String name, @NonNull Organization owner) throws BadRequestException {
|
||||||
|
// Ensure status page creation is enabled
|
||||||
|
if (!Feature.STATUS_PAGE_CREATION_ENABLED.isEnabled()) {
|
||||||
|
throw new BadRequestException(Error.STATUS_PAGE_CREATION_DISABLED);
|
||||||
|
}
|
||||||
|
// Ensure the status page name isn't taken
|
||||||
|
if (pageRepository.findByNameIgnoreCase(name) != null) {
|
||||||
|
throw new BadRequestException(Error.STATUS_PAGE_NAME_TAKEN);
|
||||||
|
}
|
||||||
|
// Create the status page and return it
|
||||||
|
String slug = name.replace(" ", "-") +
|
||||||
|
"-" + ThreadLocalRandom.current().nextInt(10000, 99999);
|
||||||
|
return pageRepository.save(new StatusPage(
|
||||||
|
snowflakeService.generateSnowflake(), name, null, slug, null,
|
||||||
|
null, StatusPageTheme.AUTO, true, owner.getSnowflake())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Organization errors.
|
||||||
|
*/
|
||||||
|
private enum Error implements IGenericResponse {
|
||||||
|
STATUS_PAGE_CREATION_DISABLED,
|
||||||
|
STATUS_PAGE_NAME_TAKEN
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,7 @@ package cc.pulseapp.api.service;
|
|||||||
import cc.pulseapp.api.common.StringUtils;
|
import cc.pulseapp.api.common.StringUtils;
|
||||||
import cc.pulseapp.api.exception.impl.BadRequestException;
|
import cc.pulseapp.api.exception.impl.BadRequestException;
|
||||||
import cc.pulseapp.api.model.IGenericResponse;
|
import cc.pulseapp.api.model.IGenericResponse;
|
||||||
|
import cc.pulseapp.api.model.org.Organization;
|
||||||
import cc.pulseapp.api.model.user.User;
|
import cc.pulseapp.api.model.user.User;
|
||||||
import cc.pulseapp.api.model.user.UserDTO;
|
import cc.pulseapp.api.model.user.UserDTO;
|
||||||
import cc.pulseapp.api.model.user.UserFlag;
|
import cc.pulseapp.api.model.user.UserFlag;
|
||||||
@ -34,6 +35,11 @@ public final class UserService {
|
|||||||
*/
|
*/
|
||||||
@NonNull private final OrganizationService orgService;
|
@NonNull private final OrganizationService orgService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The status page service to use.
|
||||||
|
*/
|
||||||
|
@NonNull private final StatusPageService statusPageService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The user repository to use.
|
* The user repository to use.
|
||||||
*/
|
*/
|
||||||
@ -41,10 +47,12 @@ public final class UserService {
|
|||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public UserService(@NonNull AuthService authService, @NonNull SnowflakeService snowflakeService,
|
public UserService(@NonNull AuthService authService, @NonNull SnowflakeService snowflakeService,
|
||||||
@NonNull OrganizationService orgService, @NonNull UserRepository userRepository) {
|
@NonNull OrganizationService orgService, @NonNull StatusPageService statusPageService,
|
||||||
|
@NonNull UserRepository userRepository) {
|
||||||
this.authService = authService;
|
this.authService = authService;
|
||||||
this.snowflakeService = snowflakeService;
|
this.snowflakeService = snowflakeService;
|
||||||
this.orgService = orgService;
|
this.orgService = orgService;
|
||||||
|
this.statusPageService = statusPageService;
|
||||||
this.userRepository = userRepository;
|
this.userRepository = userRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,7 +86,8 @@ public final class UserService {
|
|||||||
if (user.hasFlag(UserFlag.COMPLETED_ONBOARDING)) { // Already completed
|
if (user.hasFlag(UserFlag.COMPLETED_ONBOARDING)) { // Already completed
|
||||||
throw new BadRequestException(Error.ALREADY_ONBOARDED);
|
throw new BadRequestException(Error.ALREADY_ONBOARDED);
|
||||||
}
|
}
|
||||||
orgService.createOrganization(input.getOrganizationName(), user); // Create the org
|
Organization org = orgService.createOrganization(input.getOrganizationName(), user); // Create the org
|
||||||
|
statusPageService.createStatusPage(input.getStatusPageName(), org); // Create the status page
|
||||||
user.addFlag(UserFlag.COMPLETED_ONBOARDING); // Flag completed onboarding
|
user.addFlag(UserFlag.COMPLETED_ONBOARDING); // Flag completed onboarding
|
||||||
userRepository.save(user);
|
userRepository.save(user);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user