chore: logging
This commit is contained in:
parent
96e35dc21d
commit
6537e96e46
37 changed files with 2497 additions and 51 deletions
|
|
@ -7,6 +7,7 @@ import net.beetechgroup.beetask.entities.organization.Organization;
|
||||||
import net.beetechgroup.beetask.frameworks.persistence.entities.OrganizationEntity;
|
import net.beetechgroup.beetask.frameworks.persistence.entities.OrganizationEntity;
|
||||||
import net.beetechgroup.beetask.frameworks.persistence.mapper.OrganizationEntityMapper;
|
import net.beetechgroup.beetask.frameworks.persistence.mapper.OrganizationEntityMapper;
|
||||||
import net.beetechgroup.beetask.usecase.repository.OrganizationRepository;
|
import net.beetechgroup.beetask.usecase.repository.OrganizationRepository;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
@ -14,6 +15,7 @@ import java.util.Optional;
|
||||||
|
|
||||||
@ApplicationScoped
|
@ApplicationScoped
|
||||||
public class OrganizationRepositoryImpl implements OrganizationRepository, PanacheRepository<OrganizationEntity> {
|
public class OrganizationRepositoryImpl implements OrganizationRepository, PanacheRepository<OrganizationEntity> {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(OrganizationRepositoryImpl.class);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
|
|
@ -24,25 +26,35 @@ public class OrganizationRepositoryImpl implements OrganizationRepository, Panac
|
||||||
} else {
|
} else {
|
||||||
entity = getEntityManager().merge(entity);
|
entity = getEntityManager().merge(entity);
|
||||||
}
|
}
|
||||||
return OrganizationEntityMapper.toDomain(entity);
|
Organization savedOrganization = OrganizationEntityMapper.toDomain(entity);
|
||||||
|
LOGGER.infof("Persisted organization %d with name '%s'", savedOrganization.getId(), savedOrganization.getName());
|
||||||
|
return savedOrganization;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Organization> search(String query) {
|
public List<Organization> search(String query) {
|
||||||
if (Objects.isNull(query) || query.isBlank()) {
|
if (Objects.isNull(query) || query.isBlank()) {
|
||||||
return findAll().list().stream()
|
List<Organization> organizations = findAll().list().stream()
|
||||||
.map(OrganizationEntityMapper::toDomain)
|
.map(OrganizationEntityMapper::toDomain)
|
||||||
.toList();
|
.toList();
|
||||||
|
LOGGER.infof("Loaded %d organizations with empty search query", organizations.size());
|
||||||
|
return organizations;
|
||||||
}
|
}
|
||||||
|
|
||||||
return find("name like ?1", "%" + query + "%").stream()
|
List<Organization> organizations = find("name like ?1", "%" + query + "%").stream()
|
||||||
.map(OrganizationEntityMapper::toDomain)
|
.map(OrganizationEntityMapper::toDomain)
|
||||||
.toList();
|
.toList();
|
||||||
|
LOGGER.infof("Loaded %d organizations for search query '%s'", organizations.size(), query);
|
||||||
|
return organizations;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<Organization> findOrganizationById(Long id) {
|
public Optional<Organization> findOrganizationById(Long id) {
|
||||||
return findByIdOptional(id)
|
Optional<Organization> organization = findByIdOptional(id)
|
||||||
.map(OrganizationEntityMapper::toDomain);
|
.map(OrganizationEntityMapper::toDomain);
|
||||||
|
if (organization.isEmpty()) {
|
||||||
|
LOGGER.warnf("Organization %d was not found", id);
|
||||||
|
}
|
||||||
|
return organization;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -7,6 +7,7 @@ import net.beetechgroup.beetask.entities.Project;
|
||||||
import net.beetechgroup.beetask.frameworks.persistence.entities.ProjectEntity;
|
import net.beetechgroup.beetask.frameworks.persistence.entities.ProjectEntity;
|
||||||
import net.beetechgroup.beetask.frameworks.persistence.mapper.ProjectEntityMapper;
|
import net.beetechgroup.beetask.frameworks.persistence.mapper.ProjectEntityMapper;
|
||||||
import net.beetechgroup.beetask.usecase.repository.ProjectRepository;
|
import net.beetechgroup.beetask.usecase.repository.ProjectRepository;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
@ -14,6 +15,7 @@ import java.util.Optional;
|
||||||
|
|
||||||
@ApplicationScoped
|
@ApplicationScoped
|
||||||
public class ProjectRepositoryImpl implements ProjectRepository, PanacheRepository<ProjectEntity> {
|
public class ProjectRepositoryImpl implements ProjectRepository, PanacheRepository<ProjectEntity> {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(ProjectRepositoryImpl.class);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
|
|
@ -24,19 +26,27 @@ public class ProjectRepositoryImpl implements ProjectRepository, PanacheReposito
|
||||||
} else {
|
} else {
|
||||||
entity = getEntityManager().merge(entity);
|
entity = getEntityManager().merge(entity);
|
||||||
}
|
}
|
||||||
return ProjectEntityMapper.toDomain(entity);
|
Project savedProject = ProjectEntityMapper.toDomain(entity);
|
||||||
|
LOGGER.infof("Persisted project %d for organization %d", savedProject.getId(), savedProject.getOrganization().getId());
|
||||||
|
return savedProject;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<Project> findProjectById(Long id) {
|
public Optional<Project> findProjectById(Long id) {
|
||||||
return findByIdOptional(id)
|
Optional<Project> project = findByIdOptional(id)
|
||||||
.map(ProjectEntityMapper::toDomain);
|
.map(ProjectEntityMapper::toDomain);
|
||||||
|
if (project.isEmpty()) {
|
||||||
|
LOGGER.warnf("Project %d was not found", id);
|
||||||
|
}
|
||||||
|
return project;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Project> findByOrganizationId(Long organizationId) {
|
public List<Project> findByOrganizationId(Long organizationId) {
|
||||||
return find("organization.id", organizationId).stream()
|
List<Project> projects = find("organization.id", organizationId).stream()
|
||||||
.map(ProjectEntityMapper::toDomain)
|
.map(ProjectEntityMapper::toDomain)
|
||||||
.toList();
|
.toList();
|
||||||
|
LOGGER.infof("Loaded %d projects for organization %d from database", projects.size(), organizationId);
|
||||||
|
return projects;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,11 @@ import net.beetechgroup.beetask.frameworks.persistence.entities.TaskEntity;
|
||||||
import net.beetechgroup.beetask.frameworks.persistence.mapper.TaskEntityMapper;
|
import net.beetechgroup.beetask.frameworks.persistence.mapper.TaskEntityMapper;
|
||||||
import net.beetechgroup.beetask.usecase.exceptions.TaskNotFoundException;
|
import net.beetechgroup.beetask.usecase.exceptions.TaskNotFoundException;
|
||||||
import net.beetechgroup.beetask.usecase.repository.TaskRepository;
|
import net.beetechgroup.beetask.usecase.repository.TaskRepository;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
@ApplicationScoped
|
@ApplicationScoped
|
||||||
public class TaskRepositoryImpl implements TaskRepository, PanacheRepository<TaskEntity> {
|
public class TaskRepositoryImpl implements TaskRepository, PanacheRepository<TaskEntity> {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(TaskRepositoryImpl.class);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
|
|
@ -26,19 +28,26 @@ public class TaskRepositoryImpl implements TaskRepository, PanacheRepository<Tas
|
||||||
} else {
|
} else {
|
||||||
entity = getEntityManager().merge(entity);
|
entity = getEntityManager().merge(entity);
|
||||||
}
|
}
|
||||||
return TaskEntityMapper.toDomain(entity);
|
Task savedTask = TaskEntityMapper.toDomain(entity);
|
||||||
|
LOGGER.infof("Persisted task %d with status %s", savedTask.getId(), savedTask.getStatus());
|
||||||
|
return savedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Task findTaskById(Long id) {
|
public Task findTaskById(Long id) {
|
||||||
TaskEntity entity = find("id = ?1", id).firstResultOptional()
|
TaskEntity entity = find("id = ?1", id).firstResultOptional()
|
||||||
.orElseThrow(() -> new TaskNotFoundException(id));
|
.orElseThrow(() -> {
|
||||||
|
LOGGER.warnf("Task %d was not found in repository", id);
|
||||||
|
return new TaskNotFoundException(id);
|
||||||
|
});
|
||||||
return TaskEntityMapper.toDomain(entity);
|
return TaskEntityMapper.toDomain(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Task> findAllTasks() {
|
public List<Task> findAllTasks() {
|
||||||
return findAll().list().stream().map(TaskEntityMapper::toDomain).toList();
|
List<Task> tasks = findAll().list().stream().map(TaskEntityMapper::toDomain).toList();
|
||||||
|
LOGGER.infof("Loaded %d tasks from database", tasks.size());
|
||||||
|
return tasks;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -61,7 +70,9 @@ public class TaskRepositoryImpl implements TaskRepository, PanacheRepository<Tas
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Task> findTasksByUser(String email) {
|
public List<Task> findTasksByUser(String email) {
|
||||||
return find("user.email = ?1", email).list().stream().map(TaskEntityMapper::toDomain).toList();
|
List<Task> tasks = find("user.email = ?1", email).list().stream().map(TaskEntityMapper::toDomain).toList();
|
||||||
|
LOGGER.infof("Loaded %d tasks for user %s", tasks.size(), email);
|
||||||
|
return tasks;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -100,7 +111,10 @@ public class TaskRepositoryImpl implements TaskRepository, PanacheRepository<Tas
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Task> findTasksWorkedByUserEmailsInPeriod(List<String> emails, LocalDateTime start, LocalDateTime end) {
|
public List<Task> findTasksWorkedByUserEmailsInPeriod(List<String> emails, LocalDateTime start, LocalDateTime end) {
|
||||||
if (emails.isEmpty()) return List.of();
|
if (emails.isEmpty()) {
|
||||||
|
LOGGER.warn("Task search by user emails skipped because the email list is empty");
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
return find("user.email in ?1", emails).list().stream()
|
return find("user.email in ?1", emails).list().stream()
|
||||||
.filter(entity -> entity.getHistory().stream().anyMatch(h ->
|
.filter(entity -> entity.getHistory().stream().anyMatch(h ->
|
||||||
Objects.nonNull(h.getStartAt()) &&
|
Objects.nonNull(h.getStartAt()) &&
|
||||||
|
|
@ -112,7 +126,10 @@ public class TaskRepositoryImpl implements TaskRepository, PanacheRepository<Tas
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Task> findTasksFinishedByUserEmailsInPeriod(List<String> emails, LocalDateTime start, LocalDateTime end) {
|
public List<Task> findTasksFinishedByUserEmailsInPeriod(List<String> emails, LocalDateTime start, LocalDateTime end) {
|
||||||
if (emails.isEmpty()) return List.of();
|
if (emails.isEmpty()) {
|
||||||
|
LOGGER.warn("Finished task search by user emails skipped because the email list is empty");
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
return find("user.email in ?1 and status = ?2 and finishedAt >= ?3 and finishedAt <= ?4",
|
return find("user.email in ?1 and status = ?2 and finishedAt >= ?3 and finishedAt <= ?4",
|
||||||
emails, TaskStatus.COMPLETED, start, end)
|
emails, TaskStatus.COMPLETED, start, end)
|
||||||
.list().stream().map(TaskEntityMapper::toDomain).toList();
|
.list().stream().map(TaskEntityMapper::toDomain).toList();
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import net.beetechgroup.beetask.entities.organization.UserOrganizationStatus;
|
||||||
import net.beetechgroup.beetask.frameworks.persistence.entities.UserOrganizationEntity;
|
import net.beetechgroup.beetask.frameworks.persistence.entities.UserOrganizationEntity;
|
||||||
import net.beetechgroup.beetask.frameworks.persistence.mapper.UserOrganizationEntityMapper;
|
import net.beetechgroup.beetask.frameworks.persistence.mapper.UserOrganizationEntityMapper;
|
||||||
import net.beetechgroup.beetask.usecase.repository.UserOrganizationRepository;
|
import net.beetechgroup.beetask.usecase.repository.UserOrganizationRepository;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
@ -15,33 +16,44 @@ import java.util.Optional;
|
||||||
|
|
||||||
@ApplicationScoped
|
@ApplicationScoped
|
||||||
public class UserOrganizationRepositoryImpl implements UserOrganizationRepository, PanacheRepository<UserOrganizationEntity> {
|
public class UserOrganizationRepositoryImpl implements UserOrganizationRepository, PanacheRepository<UserOrganizationEntity> {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(UserOrganizationRepositoryImpl.class);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<UserOrganization> findByUserId(Long userId) {
|
public List<UserOrganization> findByUserId(Long userId) {
|
||||||
return find("user.id", userId).stream()
|
List<UserOrganization> organizations = find("user.id", userId).stream()
|
||||||
.map(UserOrganizationEntityMapper::toDomain)
|
.map(UserOrganizationEntityMapper::toDomain)
|
||||||
.toList();
|
.toList();
|
||||||
|
LOGGER.infof("Loaded %d organization memberships for user %d", organizations.size(), userId);
|
||||||
|
return organizations;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<UserOrganization> findByUserIdAndStatus(Long userId, UserOrganizationStatus status) {
|
public List<UserOrganization> findByUserIdAndStatus(Long userId, UserOrganizationStatus status) {
|
||||||
return find("user.id = ?1 and status = ?2", userId, status).stream()
|
List<UserOrganization> organizations = find("user.id = ?1 and status = ?2", userId, status).stream()
|
||||||
.map(UserOrganizationEntityMapper::toDomain)
|
.map(UserOrganizationEntityMapper::toDomain)
|
||||||
.toList();
|
.toList();
|
||||||
|
LOGGER.infof("Loaded %d organization memberships for user %d with status %s", organizations.size(), userId, status);
|
||||||
|
return organizations;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<UserOrganization> findByOrganizationIdAndStatus(Long organizationId, UserOrganizationStatus status) {
|
public List<UserOrganization> findByOrganizationIdAndStatus(Long organizationId, UserOrganizationStatus status) {
|
||||||
return find("organization.id = ?1 and status = ?2", organizationId, status).stream()
|
List<UserOrganization> organizations = find("organization.id = ?1 and status = ?2", organizationId, status).stream()
|
||||||
.map(UserOrganizationEntityMapper::toDomain)
|
.map(UserOrganizationEntityMapper::toDomain)
|
||||||
.toList();
|
.toList();
|
||||||
|
LOGGER.infof("Loaded %d memberships for organization %d with status %s", organizations.size(), organizationId, status);
|
||||||
|
return organizations;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<UserOrganization> findByUserAndOrganization(Long userId, Long organizationId) {
|
public Optional<UserOrganization> findByUserAndOrganization(Long userId, Long organizationId) {
|
||||||
return find("user.id = ?1 and organization.id = ?2", userId, organizationId)
|
Optional<UserOrganization> association = find("user.id = ?1 and organization.id = ?2", userId, organizationId)
|
||||||
.firstResultOptional()
|
.firstResultOptional()
|
||||||
.map(UserOrganizationEntityMapper::toDomain);
|
.map(UserOrganizationEntityMapper::toDomain);
|
||||||
|
if (association.isEmpty()) {
|
||||||
|
LOGGER.warnf("Membership for user %d and organization %d was not found", userId, organizationId);
|
||||||
|
}
|
||||||
|
return association;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -56,9 +68,13 @@ public class UserOrganizationRepositoryImpl implements UserOrganizationRepositor
|
||||||
existingEntity.setRole(entity.getRole());
|
existingEntity.setRole(entity.getRole());
|
||||||
existingEntity.setStatus(entity.getStatus());
|
existingEntity.setStatus(entity.getStatus());
|
||||||
getEntityManager().merge(existingEntity);
|
getEntityManager().merge(existingEntity);
|
||||||
|
LOGGER.infof("Updated membership for user %d in organization %d to role %s and status %s",
|
||||||
|
entity.getUser().getId(), entity.getOrganization().getId(), entity.getRole(), entity.getStatus());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
persist(entity);
|
persist(entity);
|
||||||
|
LOGGER.infof("Created membership for user %d in organization %d with role %s and status %s",
|
||||||
|
entity.getUser().getId(), entity.getOrganization().getId(), entity.getRole(), entity.getStatus());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,12 +12,14 @@ import net.beetechgroup.beetask.entities.organization.UserOrganization;
|
||||||
import net.beetechgroup.beetask.entities.organization.UserOrganizationStatus;
|
import net.beetechgroup.beetask.entities.organization.UserOrganizationStatus;
|
||||||
import net.beetechgroup.beetask.usecase.repository.UserRepository;
|
import net.beetechgroup.beetask.usecase.repository.UserRepository;
|
||||||
import net.beetechgroup.beetask.usecase.repository.UserOrganizationRepository;
|
import net.beetechgroup.beetask.usecase.repository.UserOrganizationRepository;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@ApplicationScoped
|
@ApplicationScoped
|
||||||
public class UserRepositoryImpl implements UserRepository, PanacheRepository<UserEntity> {
|
public class UserRepositoryImpl implements UserRepository, PanacheRepository<UserEntity> {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(UserRepositoryImpl.class);
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
UserOrganizationRepository userOrganizationRepository;
|
UserOrganizationRepository userOrganizationRepository;
|
||||||
|
|
@ -31,23 +33,35 @@ public class UserRepositoryImpl implements UserRepository, PanacheRepository<Use
|
||||||
} else {
|
} else {
|
||||||
entity = getEntityManager().merge(entity);
|
entity = getEntityManager().merge(entity);
|
||||||
}
|
}
|
||||||
return UserEntityMapper.toDomain(entity);
|
User savedUser = UserEntityMapper.toDomain(entity);
|
||||||
|
LOGGER.infof("Persisted user %d with email %s", savedUser.getId(), savedUser.getEmail());
|
||||||
|
return savedUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<User> findByEmail(String email) {
|
public Optional<User> findByEmail(String email) {
|
||||||
return find("email", email).firstResultOptional()
|
Optional<User> user = find("email", email).firstResultOptional()
|
||||||
.map(UserEntityMapper::toDomain);
|
.map(UserEntityMapper::toDomain);
|
||||||
|
if (user.isEmpty()) {
|
||||||
|
LOGGER.warnf("User with email %s was not found", email);
|
||||||
|
}
|
||||||
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<User> findUserById(Long id) {
|
public Optional<User> findUserById(Long id) {
|
||||||
return findByIdOptional(id)
|
Optional<User> user = findByIdOptional(id)
|
||||||
.map(UserEntityMapper::toDomain);
|
.map(UserEntityMapper::toDomain);
|
||||||
|
if (user.isEmpty()) {
|
||||||
|
LOGGER.warnf("User with id %d was not found", id);
|
||||||
|
}
|
||||||
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<UserOrganization> findUserOrganizations(Long userId) {
|
public List<UserOrganization> findUserOrganizations(Long userId) {
|
||||||
return userOrganizationRepository.findByUserIdAndStatus(userId, UserOrganizationStatus.ACTIVE);
|
List<UserOrganization> organizations = userOrganizationRepository.findByUserIdAndStatus(userId, UserOrganizationStatus.ACTIVE);
|
||||||
|
LOGGER.infof("Loaded %d active organizations for user %d", organizations.size(), userId);
|
||||||
|
return organizations;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,12 +27,14 @@ import io.quarkus.security.identity.SecurityIdentity;
|
||||||
import jakarta.ws.rs.GET;
|
import jakarta.ws.rs.GET;
|
||||||
import net.beetechgroup.beetask.usecase.user.profile.GetUserProfileUseCase;
|
import net.beetechgroup.beetask.usecase.user.profile.GetUserProfileUseCase;
|
||||||
import net.beetechgroup.beetask.usecase.user.profile.UserProfileOutput;
|
import net.beetechgroup.beetask.usecase.user.profile.UserProfileOutput;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
@Path("/auth")
|
@Path("/auth")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
@Tag(name = "Authentication", description = "Authentication operations")
|
@Tag(name = "Authentication", description = "Authentication operations")
|
||||||
public class AuthController {
|
public class AuthController {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(AuthController.class);
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
CreateUserUseCase createUserUseCase;
|
CreateUserUseCase createUserUseCase;
|
||||||
|
|
@ -55,6 +57,7 @@ public class AuthController {
|
||||||
@Operation(summary = "Get current user profile", description = "Returns details of the logged in user")
|
@Operation(summary = "Get current user profile", description = "Returns details of the logged in user")
|
||||||
public UserProfileOutput me() {
|
public UserProfileOutput me() {
|
||||||
String email = securityIdentity.getPrincipal().getName();
|
String email = securityIdentity.getPrincipal().getName();
|
||||||
|
LOGGER.infof("Profile requested for authenticated user %s", email);
|
||||||
return getUserProfileUseCase.execute(email);
|
return getUserProfileUseCase.execute(email);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -62,8 +65,10 @@ public class AuthController {
|
||||||
@POST
|
@POST
|
||||||
@Operation(summary = "Register", description = "Creates a new user account")
|
@Operation(summary = "Register", description = "Creates a new user account")
|
||||||
public CreateAccountResponse register(CreateAccountRequest request) {
|
public CreateAccountResponse register(CreateAccountRequest request) {
|
||||||
|
LOGGER.infof("Registration requested for email %s", request.email());
|
||||||
CreateUserInput input = AuthControllerMapper.toCreateUserInput(request);
|
CreateUserInput input = AuthControllerMapper.toCreateUserInput(request);
|
||||||
CreateUserOutput output = createUserUseCase.execute(input);
|
CreateUserOutput output = createUserUseCase.execute(input);
|
||||||
|
LOGGER.infof("User account created successfully for email %s", output.email());
|
||||||
return AuthControllerMapper.toCreateAccountResponse(output);
|
return AuthControllerMapper.toCreateAccountResponse(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -71,8 +76,10 @@ public class AuthController {
|
||||||
@POST
|
@POST
|
||||||
@Operation(summary = "Login", description = "Login that returns real user data and JWT")
|
@Operation(summary = "Login", description = "Login that returns real user data and JWT")
|
||||||
public LoginResponse login(LoginRequest request) {
|
public LoginResponse login(LoginRequest request) {
|
||||||
|
LOGGER.infof("Login requested for email %s", request.email());
|
||||||
LoginInput input = AuthControllerMapper.toLoginInput(request);
|
LoginInput input = AuthControllerMapper.toLoginInput(request);
|
||||||
LoginOutput output = loginUseCase.execute(input);
|
LoginOutput output = loginUseCase.execute(input);
|
||||||
|
LOGGER.infof("Login succeeded for email %s", output.email());
|
||||||
return AuthControllerMapper.toLoginResponse(output);
|
return AuthControllerMapper.toLoginResponse(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -80,8 +87,10 @@ public class AuthController {
|
||||||
@POST
|
@POST
|
||||||
@Operation(summary = "Refresh token", description = "Token refresh using refresh token")
|
@Operation(summary = "Refresh token", description = "Token refresh using refresh token")
|
||||||
public LoginResponse refresh(RefreshTokenRequest request) {
|
public LoginResponse refresh(RefreshTokenRequest request) {
|
||||||
|
LOGGER.info("Refresh token requested");
|
||||||
RefreshTokenInput input = AuthControllerMapper.toRefreshTokenInput(request);
|
RefreshTokenInput input = AuthControllerMapper.toRefreshTokenInput(request);
|
||||||
LoginOutput output = refreshTokenUseCase.execute(input);
|
LoginOutput output = refreshTokenUseCase.execute(input);
|
||||||
|
LOGGER.infof("Refresh token succeeded for email %s", output.email());
|
||||||
return AuthControllerMapper.toLoginResponse(output);
|
return AuthControllerMapper.toLoginResponse(output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import jakarta.ws.rs.core.MediaType;
|
||||||
import net.beetechgroup.beetask.usecase.dashboard.DashboardInput;
|
import net.beetechgroup.beetask.usecase.dashboard.DashboardInput;
|
||||||
import net.beetechgroup.beetask.usecase.dashboard.DashboardOutput;
|
import net.beetechgroup.beetask.usecase.dashboard.DashboardOutput;
|
||||||
import net.beetechgroup.beetask.usecase.dashboard.DashboardUseCase;
|
import net.beetechgroup.beetask.usecase.dashboard.DashboardUseCase;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
@ -19,6 +20,7 @@ import java.time.format.DateTimeFormatter;
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Authenticated
|
@Authenticated
|
||||||
public class DashboardController {
|
public class DashboardController {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(DashboardController.class);
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
DashboardUseCase dashboardUseCase;
|
DashboardUseCase dashboardUseCase;
|
||||||
|
|
@ -46,6 +48,7 @@ public class DashboardController {
|
||||||
}
|
}
|
||||||
|
|
||||||
DashboardInput input = new DashboardInput(email, start, end);
|
DashboardInput input = new DashboardInput(email, start, end);
|
||||||
|
LOGGER.infof("Dashboard requested by user %s for period %s to %s", email, start, end);
|
||||||
return dashboardUseCase.execute(input);
|
return dashboardUseCase.execute(input);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,11 +21,13 @@ import net.beetechgroup.beetask.usecase.organization.requests.ListUserJoinReques
|
||||||
import net.beetechgroup.beetask.usecase.organization.requests.UserJoinRequestOutput;
|
import net.beetechgroup.beetask.usecase.organization.requests.UserJoinRequestOutput;
|
||||||
import net.beetechgroup.beetask.usecase.organization.requests.JoinRequestOutput;
|
import net.beetechgroup.beetask.usecase.organization.requests.JoinRequestOutput;
|
||||||
import net.beetechgroup.beetask.usecase.organization.requests.HandleJoinRequestUseCase;
|
import net.beetechgroup.beetask.usecase.organization.requests.HandleJoinRequestUseCase;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Path("/organizations")
|
@Path("/organizations")
|
||||||
public class OrganizationController {
|
public class OrganizationController {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(OrganizationController.class);
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
CreateOrganizationUseCase createOrganizationUseCase;
|
CreateOrganizationUseCase createOrganizationUseCase;
|
||||||
|
|
@ -53,8 +55,10 @@ public class OrganizationController {
|
||||||
@Operation(summary = "Create organization", description = "Creates a new organization")
|
@Operation(summary = "Create organization", description = "Creates a new organization")
|
||||||
public CreateOrganizationResponse createOrganization(CreateOrganizationRequest request) {
|
public CreateOrganizationResponse createOrganization(CreateOrganizationRequest request) {
|
||||||
String userEmail = securityIdentity.getPrincipal().getName();
|
String userEmail = securityIdentity.getPrincipal().getName();
|
||||||
|
LOGGER.infof("User %s requested organization creation with name '%s'", userEmail, request.name());
|
||||||
CreateOrganizationInput input = OrganizationControllerMapper.toCreateOrganizationInput(request, userEmail);
|
CreateOrganizationInput input = OrganizationControllerMapper.toCreateOrganizationInput(request, userEmail);
|
||||||
CreateOrganizationOutput output = createOrganizationUseCase.execute(input);
|
CreateOrganizationOutput output = createOrganizationUseCase.execute(input);
|
||||||
|
LOGGER.infof("Organization %d created successfully by user %s", output.id(), userEmail);
|
||||||
return OrganizationControllerMapper.toCreateOrganizationResponse(output);
|
return OrganizationControllerMapper.toCreateOrganizationResponse(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -63,7 +67,9 @@ public class OrganizationController {
|
||||||
@Authenticated
|
@Authenticated
|
||||||
@Operation(summary = "Search organizations", description = "Search for organizations by name")
|
@Operation(summary = "Search organizations", description = "Search for organizations by name")
|
||||||
public List<SearchOrganizationOutput> search(@QueryParam("q") String query) {
|
public List<SearchOrganizationOutput> search(@QueryParam("q") String query) {
|
||||||
return searchOrganizationsUseCase.execute(query);
|
List<SearchOrganizationOutput> organizations = searchOrganizationsUseCase.execute(query);
|
||||||
|
LOGGER.infof("Organization search executed with query '%s' and returned %d results", query, organizations.size());
|
||||||
|
return organizations;
|
||||||
}
|
}
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
|
|
@ -72,7 +78,9 @@ public class OrganizationController {
|
||||||
@Operation(summary = "Request to join", description = "Request to join an organization")
|
@Operation(summary = "Request to join", description = "Request to join an organization")
|
||||||
public void requestJoin(@PathParam("id") Long organizationId) {
|
public void requestJoin(@PathParam("id") Long organizationId) {
|
||||||
String userEmail = securityIdentity.getPrincipal().getName();
|
String userEmail = securityIdentity.getPrincipal().getName();
|
||||||
|
LOGGER.infof("User %s requested to join organization %d", userEmail, organizationId);
|
||||||
requestJoinOrganizationUseCase.execute(organizationId, userEmail);
|
requestJoinOrganizationUseCase.execute(organizationId, userEmail);
|
||||||
|
LOGGER.infof("Join request created for user %s in organization %d", userEmail, organizationId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
|
|
@ -81,7 +89,9 @@ public class OrganizationController {
|
||||||
@Operation(summary = "List pending requests", description = "List all pending join requests for an organization (Owner only)")
|
@Operation(summary = "List pending requests", description = "List all pending join requests for an organization (Owner only)")
|
||||||
public List<JoinRequestOutput> listRequests(@PathParam("id") Long organizationId) {
|
public List<JoinRequestOutput> listRequests(@PathParam("id") Long organizationId) {
|
||||||
String userEmail = securityIdentity.getPrincipal().getName();
|
String userEmail = securityIdentity.getPrincipal().getName();
|
||||||
return listPendingRequestsUseCase.execute(userEmail, organizationId, null);
|
List<JoinRequestOutput> requests = listPendingRequestsUseCase.execute(userEmail, organizationId, null);
|
||||||
|
LOGGER.infof("User %s listed %d pending requests for organization %d", userEmail, requests.size(), organizationId);
|
||||||
|
return requests;
|
||||||
}
|
}
|
||||||
|
|
||||||
@PATCH
|
@PATCH
|
||||||
|
|
@ -90,7 +100,9 @@ public class OrganizationController {
|
||||||
@Operation(summary = "Approve request", description = "Approve a join request (Owner only)")
|
@Operation(summary = "Approve request", description = "Approve a join request (Owner only)")
|
||||||
public void approveRequest(@PathParam("id") Long organizationId, @PathParam("userId") Long userId) {
|
public void approveRequest(@PathParam("id") Long organizationId, @PathParam("userId") Long userId) {
|
||||||
String userEmail = securityIdentity.getPrincipal().getName();
|
String userEmail = securityIdentity.getPrincipal().getName();
|
||||||
|
LOGGER.infof("User %s requested approval for user %d in organization %d", userEmail, userId, organizationId);
|
||||||
handleJoinRequestUseCase.execute(userEmail, organizationId, new HandleJoinRequestUseCase.Input(userId, true));
|
handleJoinRequestUseCase.execute(userEmail, organizationId, new HandleJoinRequestUseCase.Input(userId, true));
|
||||||
|
LOGGER.infof("Join request approved for user %d in organization %d by %s", userId, organizationId, userEmail);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PATCH
|
@PATCH
|
||||||
|
|
@ -99,7 +111,9 @@ public class OrganizationController {
|
||||||
@Operation(summary = "Reject request", description = "Reject a join request (Owner only)")
|
@Operation(summary = "Reject request", description = "Reject a join request (Owner only)")
|
||||||
public void rejectRequest(@PathParam("id") Long organizationId, @PathParam("userId") Long userId) {
|
public void rejectRequest(@PathParam("id") Long organizationId, @PathParam("userId") Long userId) {
|
||||||
String userEmail = securityIdentity.getPrincipal().getName();
|
String userEmail = securityIdentity.getPrincipal().getName();
|
||||||
|
LOGGER.infof("User %s requested rejection for user %d in organization %d", userEmail, userId, organizationId);
|
||||||
handleJoinRequestUseCase.execute(userEmail, organizationId, new HandleJoinRequestUseCase.Input(userId, false));
|
handleJoinRequestUseCase.execute(userEmail, organizationId, new HandleJoinRequestUseCase.Input(userId, false));
|
||||||
|
LOGGER.infof("Join request rejected for user %d in organization %d by %s", userId, organizationId, userEmail);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
|
|
@ -108,6 +122,8 @@ public class OrganizationController {
|
||||||
@Operation(summary = "List my requests", description = "List all join requests made by the current user")
|
@Operation(summary = "List my requests", description = "List all join requests made by the current user")
|
||||||
public List<UserJoinRequestOutput> listMyRequests() {
|
public List<UserJoinRequestOutput> listMyRequests() {
|
||||||
String userEmail = securityIdentity.getPrincipal().getName();
|
String userEmail = securityIdentity.getPrincipal().getName();
|
||||||
return listUserJoinRequestsUseCase.execute(userEmail);
|
List<UserJoinRequestOutput> requests = listUserJoinRequestsUseCase.execute(userEmail);
|
||||||
|
LOGGER.infof("User %s listed %d organization join requests", userEmail, requests.size());
|
||||||
|
return requests;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import jakarta.ws.rs.QueryParam;
|
||||||
import jakarta.ws.rs.core.MediaType;
|
import jakarta.ws.rs.core.MediaType;
|
||||||
import net.beetechgroup.beetask.usecase.orgdashboard.memberdetail.MemberDetailInput;
|
import net.beetechgroup.beetask.usecase.orgdashboard.memberdetail.MemberDetailInput;
|
||||||
import net.beetechgroup.beetask.usecase.orgdashboard.memberdetail.MemberDetailUseCase;
|
import net.beetechgroup.beetask.usecase.orgdashboard.memberdetail.MemberDetailUseCase;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
@ -19,6 +20,7 @@ import java.time.format.DateTimeFormatter;
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Authenticated
|
@Authenticated
|
||||||
public class MemberDetailController {
|
public class MemberDetailController {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(MemberDetailController.class);
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
MemberDetailUseCase memberDetailUseCase;
|
MemberDetailUseCase memberDetailUseCase;
|
||||||
|
|
@ -47,6 +49,8 @@ public class MemberDetailController {
|
||||||
end = end.with(java.time.LocalTime.MAX);
|
end = end.with(java.time.LocalTime.MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOGGER.infof("Member stats requested by user %s for organization %d member %d and period %s to %s",
|
||||||
|
email, organizationId, memberId, start, end);
|
||||||
return MemberDetailControllerMapper.toResponse(
|
return MemberDetailControllerMapper.toResponse(
|
||||||
memberDetailUseCase.execute(new MemberDetailInput(email, organizationId, memberId, start, end))
|
memberDetailUseCase.execute(new MemberDetailInput(email, organizationId, memberId, start, end))
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import jakarta.ws.rs.QueryParam;
|
||||||
import jakarta.ws.rs.core.MediaType;
|
import jakarta.ws.rs.core.MediaType;
|
||||||
import net.beetechgroup.beetask.usecase.orgdashboard.OrgDashboardInput;
|
import net.beetechgroup.beetask.usecase.orgdashboard.OrgDashboardInput;
|
||||||
import net.beetechgroup.beetask.usecase.orgdashboard.OrgDashboardUseCase;
|
import net.beetechgroup.beetask.usecase.orgdashboard.OrgDashboardUseCase;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
@ -19,6 +20,7 @@ import java.time.format.DateTimeFormatter;
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Authenticated
|
@Authenticated
|
||||||
public class OrgDashboardController {
|
public class OrgDashboardController {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(OrgDashboardController.class);
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
OrgDashboardUseCase orgDashboardUseCase;
|
OrgDashboardUseCase orgDashboardUseCase;
|
||||||
|
|
@ -46,6 +48,8 @@ public class OrgDashboardController {
|
||||||
end = end.with(java.time.LocalTime.MAX);
|
end = end.with(java.time.LocalTime.MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOGGER.infof("Organization dashboard requested by user %s for organization %d and period %s to %s",
|
||||||
|
email, organizationId, start, end);
|
||||||
return OrgDashboardControllerMapper.toResponse(
|
return OrgDashboardControllerMapper.toResponse(
|
||||||
orgDashboardUseCase.execute(new OrgDashboardInput(email, organizationId, start, end))
|
orgDashboardUseCase.execute(new OrgDashboardInput(email, organizationId, start, end))
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import jakarta.ws.rs.core.MediaType;
|
||||||
import net.beetechgroup.beetask.entities.Project;
|
import net.beetechgroup.beetask.entities.Project;
|
||||||
import net.beetechgroup.beetask.usecase.project.create.CreateProjectUseCase;
|
import net.beetechgroup.beetask.usecase.project.create.CreateProjectUseCase;
|
||||||
import net.beetechgroup.beetask.usecase.project.list.ListProjectsUseCase;
|
import net.beetechgroup.beetask.usecase.project.list.ListProjectsUseCase;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
@ -19,6 +20,7 @@ import java.util.List;
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
public class ProjectController {
|
public class ProjectController {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(ProjectController.class);
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
CreateProjectUseCase createProjectUseCase;
|
CreateProjectUseCase createProjectUseCase;
|
||||||
|
|
@ -29,15 +31,19 @@ public class ProjectController {
|
||||||
@GET
|
@GET
|
||||||
@Authenticated
|
@Authenticated
|
||||||
public List<ProjectResponse> listProjects(@PathParam("orgId") Long orgId) {
|
public List<ProjectResponse> listProjects(@PathParam("orgId") Long orgId) {
|
||||||
return listProjectsUseCase.execute(orgId).stream()
|
List<ProjectResponse> projects = listProjectsUseCase.execute(orgId).stream()
|
||||||
.map(p -> new ProjectResponse(p.getId(), p.getName()))
|
.map(p -> new ProjectResponse(p.getId(), p.getName()))
|
||||||
.toList();
|
.toList();
|
||||||
|
LOGGER.infof("Listed %d projects for organization %d", projects.size(), orgId);
|
||||||
|
return projects;
|
||||||
}
|
}
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
@Authenticated
|
@Authenticated
|
||||||
public ProjectResponse createProject(@PathParam("orgId") Long orgId, CreateProjectRequest request) {
|
public ProjectResponse createProject(@PathParam("orgId") Long orgId, CreateProjectRequest request) {
|
||||||
|
LOGGER.infof("Project creation requested for organization %d with name '%s'", orgId, request.name());
|
||||||
Project project = createProjectUseCase.execute(orgId, request.name());
|
Project project = createProjectUseCase.execute(orgId, request.name());
|
||||||
|
LOGGER.infof("Project %d created successfully for organization %d", project.getId(), orgId);
|
||||||
return new ProjectResponse(project.getId(), project.getName());
|
return new ProjectResponse(project.getId(), project.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ import java.util.List;
|
||||||
import org.eclipse.microprofile.openapi.annotations.Operation;
|
import org.eclipse.microprofile.openapi.annotations.Operation;
|
||||||
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
|
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
|
||||||
import org.eclipse.microprofile.openapi.annotations.tags.Tag;
|
import org.eclipse.microprofile.openapi.annotations.tags.Tag;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
import net.beetechgroup.beetask.entities.task.TaskStatus;
|
import net.beetechgroup.beetask.entities.task.TaskStatus;
|
||||||
import net.beetechgroup.beetask.usecase.task.create.CreateTaskInput;
|
import net.beetechgroup.beetask.usecase.task.create.CreateTaskInput;
|
||||||
|
|
@ -36,6 +37,7 @@ import net.beetechgroup.beetask.usecase.task.get.GetTaskUseCase;
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
@Tag(name = "Tasks", description = "Task management operations")
|
@Tag(name = "Tasks", description = "Task management operations")
|
||||||
public class TaskController {
|
public class TaskController {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(TaskController.class);
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
CreateTaskUseCase createTaskUseCase;
|
CreateTaskUseCase createTaskUseCase;
|
||||||
|
|
@ -69,8 +71,10 @@ public class TaskController {
|
||||||
@APIResponse(responseCode = "201", description = "Task created successfully")
|
@APIResponse(responseCode = "201", description = "Task created successfully")
|
||||||
public CreateTaskResponse createTask(CreateTaskRequest request) {
|
public CreateTaskResponse createTask(CreateTaskRequest request) {
|
||||||
String email = securityIdentity.getPrincipal().getName();
|
String email = securityIdentity.getPrincipal().getName();
|
||||||
|
LOGGER.infof("User %s requested task creation with title '%s'", email, request.title());
|
||||||
CreateTaskInput input = TaskControllerMapper.toCreateTaskInput(request, email);
|
CreateTaskInput input = TaskControllerMapper.toCreateTaskInput(request, email);
|
||||||
CreateTaskOutput output = createTaskUseCase.execute(input);
|
CreateTaskOutput output = createTaskUseCase.execute(input);
|
||||||
|
LOGGER.infof("Task %d created successfully by user %s", output.id(), email);
|
||||||
return TaskControllerMapper.toCreateTaskResponse(output);
|
return TaskControllerMapper.toCreateTaskResponse(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -80,7 +84,9 @@ public class TaskController {
|
||||||
@APIResponse(responseCode = "200", description = "Task updated successfully")
|
@APIResponse(responseCode = "200", description = "Task updated successfully")
|
||||||
public CreateTaskResponse updateTask(@PathParam("id") Long id, CreateTaskRequest request) {
|
public CreateTaskResponse updateTask(@PathParam("id") Long id, CreateTaskRequest request) {
|
||||||
String email = securityIdentity.getPrincipal().getName();
|
String email = securityIdentity.getPrincipal().getName();
|
||||||
|
LOGGER.infof("User %s requested update for task %d", email, id);
|
||||||
CreateTaskOutput output = updateTaskUseCase.execute(TaskControllerMapper.toUpdateTaskInput(id, request, email));
|
CreateTaskOutput output = updateTaskUseCase.execute(TaskControllerMapper.toUpdateTaskInput(id, request, email));
|
||||||
|
LOGGER.infof("Task %d updated successfully by user %s", id, email);
|
||||||
return TaskControllerMapper.toCreateTaskResponse(output);
|
return TaskControllerMapper.toCreateTaskResponse(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -89,6 +95,7 @@ public class TaskController {
|
||||||
@Operation(summary = "Get a task", description = "Gets a specific task by ID")
|
@Operation(summary = "Get a task", description = "Gets a specific task by ID")
|
||||||
@APIResponse(responseCode = "200", description = "Task retrieved successfully")
|
@APIResponse(responseCode = "200", description = "Task retrieved successfully")
|
||||||
public CreateTaskResponse getTask(@PathParam("id") Long id) {
|
public CreateTaskResponse getTask(@PathParam("id") Long id) {
|
||||||
|
LOGGER.infof("Task details requested for task %d", id);
|
||||||
return TaskControllerMapper.toCreateTaskResponse(getTaskUseCase.execute(id));
|
return TaskControllerMapper.toCreateTaskResponse(getTaskUseCase.execute(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -98,7 +105,9 @@ public class TaskController {
|
||||||
@APIResponse(responseCode = "200", description = "Task started successfully")
|
@APIResponse(responseCode = "200", description = "Task started successfully")
|
||||||
public CreateTaskResponse startTask(@PathParam("id") Long id) {
|
public CreateTaskResponse startTask(@PathParam("id") Long id) {
|
||||||
String email = securityIdentity.getPrincipal().getName();
|
String email = securityIdentity.getPrincipal().getName();
|
||||||
|
LOGGER.infof("User %s requested start for task %d", email, id);
|
||||||
CreateTaskOutput output = startTaskUseCase.execute(new StartTaskInput(id, email));
|
CreateTaskOutput output = startTaskUseCase.execute(new StartTaskInput(id, email));
|
||||||
|
LOGGER.infof("Task %d started successfully by user %s", id, email);
|
||||||
return TaskControllerMapper.toCreateTaskResponse(output);
|
return TaskControllerMapper.toCreateTaskResponse(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -107,7 +116,9 @@ public class TaskController {
|
||||||
@Operation(summary = "Stop a task", description = "Stops a task in the system")
|
@Operation(summary = "Stop a task", description = "Stops a task in the system")
|
||||||
@APIResponse(responseCode = "200", description = "Task stopped successfully")
|
@APIResponse(responseCode = "200", description = "Task stopped successfully")
|
||||||
public CreateTaskResponse stopTask(@PathParam("id") Long id) {
|
public CreateTaskResponse stopTask(@PathParam("id") Long id) {
|
||||||
|
LOGGER.infof("Stop requested for task %d", id);
|
||||||
CreateTaskOutput output = stopTaskUseCase.execute(TaskControllerMapper.toStopTaskInput(id));
|
CreateTaskOutput output = stopTaskUseCase.execute(TaskControllerMapper.toStopTaskInput(id));
|
||||||
|
LOGGER.infof("Task %d stopped successfully", id);
|
||||||
return TaskControllerMapper.toCreateTaskResponse(output);
|
return TaskControllerMapper.toCreateTaskResponse(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -116,7 +127,9 @@ public class TaskController {
|
||||||
@Operation(summary = "Update task status", description = "Updates the status of a task")
|
@Operation(summary = "Update task status", description = "Updates the status of a task")
|
||||||
@APIResponse(responseCode = "200", description = "Task status updated successfully")
|
@APIResponse(responseCode = "200", description = "Task status updated successfully")
|
||||||
public CreateTaskResponse updateTaskStatus(@PathParam("id") Long id, TaskStatus status) {
|
public CreateTaskResponse updateTaskStatus(@PathParam("id") Long id, TaskStatus status) {
|
||||||
|
LOGGER.infof("Status update requested for task %d to %s", id, status);
|
||||||
CreateTaskOutput output = updateTaskStatusUseCase.execute(id, status);
|
CreateTaskOutput output = updateTaskStatusUseCase.execute(id, status);
|
||||||
|
LOGGER.infof("Task %d status updated successfully to %s", id, status);
|
||||||
return TaskControllerMapper.toCreateTaskResponse(output);
|
return TaskControllerMapper.toCreateTaskResponse(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -124,7 +137,9 @@ public class TaskController {
|
||||||
@Operation(summary = "List all tasks", description = "Lists all tasks in the system")
|
@Operation(summary = "List all tasks", description = "Lists all tasks in the system")
|
||||||
@APIResponse(responseCode = "200", description = "Tasks listed successfully")
|
@APIResponse(responseCode = "200", description = "Tasks listed successfully")
|
||||||
public List<CreateTaskResponse> listTasks() {
|
public List<CreateTaskResponse> listTasks() {
|
||||||
return listAllTasksUseCase.execute().stream().map(TaskControllerMapper::toCreateTaskResponse).toList();
|
List<CreateTaskResponse> tasks = listAllTasksUseCase.execute().stream().map(TaskControllerMapper::toCreateTaskResponse).toList();
|
||||||
|
LOGGER.infof("Listed %d tasks", tasks.size());
|
||||||
|
return tasks;
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
|
|
@ -133,7 +148,9 @@ public class TaskController {
|
||||||
@APIResponse(responseCode = "200", description = "Tasks listed successfully")
|
@APIResponse(responseCode = "200", description = "Tasks listed successfully")
|
||||||
public List<CreateTaskResponse> listMyTasks() {
|
public List<CreateTaskResponse> listMyTasks() {
|
||||||
String email = securityIdentity.getPrincipal().getName();
|
String email = securityIdentity.getPrincipal().getName();
|
||||||
return listMyTasksUseCase.execute(email).stream().map(TaskControllerMapper::toCreateTaskResponse).toList();
|
List<CreateTaskResponse> tasks = listMyTasksUseCase.execute(email).stream().map(TaskControllerMapper::toCreateTaskResponse).toList();
|
||||||
|
LOGGER.infof("Listed %d tasks for user %s", tasks.size(), email);
|
||||||
|
return tasks;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,10 @@ import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
public class LoginUseCase {
|
public class LoginUseCase {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(LoginUseCase.class);
|
||||||
|
|
||||||
private final UserRepository userRepository;
|
private final UserRepository userRepository;
|
||||||
private final String issuer;
|
private final String issuer;
|
||||||
|
|
@ -27,6 +29,7 @@ public class LoginUseCase {
|
||||||
Optional<User> userOptional = userRepository.findByEmail(input.email());
|
Optional<User> userOptional = userRepository.findByEmail(input.email());
|
||||||
|
|
||||||
if (userOptional.isEmpty()) {
|
if (userOptional.isEmpty()) {
|
||||||
|
LOGGER.warnf("Login failed because email %s was not found", input.email());
|
||||||
throw new RuntimeException("Invalid credentials");
|
throw new RuntimeException("Invalid credentials");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -34,9 +37,11 @@ public class LoginUseCase {
|
||||||
|
|
||||||
// Simple password check for now (should use Bcrypt)
|
// Simple password check for now (should use Bcrypt)
|
||||||
if (!user.getPassword().equals(input.password())) {
|
if (!user.getPassword().equals(input.password())) {
|
||||||
|
LOGGER.warnf("Login failed because password did not match for email %s", input.email());
|
||||||
throw new RuntimeException("Invalid credentials");
|
throw new RuntimeException("Invalid credentials");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOGGER.infof("Login authenticated for user %s", input.email());
|
||||||
List<UserOrganization> userOrganizations = userRepository.findUserOrganizations(user.getId());
|
List<UserOrganization> userOrganizations = userRepository.findUserOrganizations(user.getId());
|
||||||
|
|
||||||
Set<String> groups = new HashSet<>();
|
Set<String> groups = new HashSet<>();
|
||||||
|
|
@ -67,6 +72,7 @@ public class LoginUseCase {
|
||||||
.expiresIn(86400) // 24 hours
|
.expiresIn(86400) // 24 hours
|
||||||
.sign();
|
.sign();
|
||||||
|
|
||||||
|
LOGGER.infof("Login completed for user %s with %d organizations", user.getEmail(), orgs.size());
|
||||||
return new LoginOutput(
|
return new LoginOutput(
|
||||||
user.getName(),
|
user.getName(),
|
||||||
user.getEmail(),
|
user.getEmail(),
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,10 @@ import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
public class RefreshTokenUseCase {
|
public class RefreshTokenUseCase {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(RefreshTokenUseCase.class);
|
||||||
|
|
||||||
private final UserRepository userRepository;
|
private final UserRepository userRepository;
|
||||||
private final JWTParser jwtParser;
|
private final JWTParser jwtParser;
|
||||||
|
|
@ -35,11 +37,14 @@ public class RefreshTokenUseCase {
|
||||||
String email = token.getSubject(); // Or token.getName() / token.getClaim(Claims.upn.name())
|
String email = token.getSubject(); // Or token.getName() / token.getClaim(Claims.upn.name())
|
||||||
|
|
||||||
if (Objects.isNull(email)) {
|
if (Objects.isNull(email)) {
|
||||||
|
LOGGER.warn("Refresh token rejected because subject/email was not present");
|
||||||
throw new RuntimeException("Invalid refresh token: email not found");
|
throw new RuntimeException("Invalid refresh token: email not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOGGER.infof("Refreshing authentication token for user %s", email);
|
||||||
Optional<User> userOptional = userRepository.findByEmail(email);
|
Optional<User> userOptional = userRepository.findByEmail(email);
|
||||||
if (userOptional.isEmpty()) {
|
if (userOptional.isEmpty()) {
|
||||||
|
LOGGER.warnf("Refresh token rejected because user %s was not found", email);
|
||||||
throw new RuntimeException("User not found for the provided refresh token");
|
throw new RuntimeException("User not found for the provided refresh token");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -75,6 +80,7 @@ public class RefreshTokenUseCase {
|
||||||
})
|
})
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
|
LOGGER.infof("Refresh token completed for user %s with %d organizations", user.getEmail(), orgs.size());
|
||||||
return new LoginOutput(
|
return new LoginOutput(
|
||||||
user.getName(),
|
user.getName(),
|
||||||
user.getEmail(),
|
user.getEmail(),
|
||||||
|
|
@ -86,6 +92,7 @@ public class RefreshTokenUseCase {
|
||||||
orgs
|
orgs
|
||||||
);
|
);
|
||||||
} catch (ParseException e) {
|
} catch (ParseException e) {
|
||||||
|
LOGGER.error("Refresh token parsing failed", e);
|
||||||
throw new RuntimeException("Invalid refresh token: " + e.getMessage());
|
throw new RuntimeException("Invalid refresh token: " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,10 @@ import net.beetechgroup.beetask.entities.task.Task;
|
||||||
import net.beetechgroup.beetask.entities.task.TaskHistoryItem;
|
import net.beetechgroup.beetask.entities.task.TaskHistoryItem;
|
||||||
import net.beetechgroup.beetask.usecase.repository.TaskRepository;
|
import net.beetechgroup.beetask.usecase.repository.TaskRepository;
|
||||||
import net.beetechgroup.beetask.usecase.task.create.CreateTaskMapper;
|
import net.beetechgroup.beetask.usecase.task.create.CreateTaskMapper;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
public class DashboardUseCase {
|
public class DashboardUseCase {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(DashboardUseCase.class);
|
||||||
|
|
||||||
private final TaskRepository taskRepository;
|
private final TaskRepository taskRepository;
|
||||||
|
|
||||||
|
|
@ -23,6 +25,8 @@ public class DashboardUseCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public DashboardOutput execute(DashboardInput input) {
|
public DashboardOutput execute(DashboardInput input) {
|
||||||
|
LOGGER.infof("Calculating dashboard for user %s in period %s to %s",
|
||||||
|
input.userEmail(), input.startDate(), input.endDate());
|
||||||
List<Task> workedTasks = taskRepository.findTasksWorkedByUserInPeriod(
|
List<Task> workedTasks = taskRepository.findTasksWorkedByUserInPeriod(
|
||||||
input.userEmail(), input.startDate(), input.endDate()
|
input.userEmail(), input.startDate(), input.endDate()
|
||||||
);
|
);
|
||||||
|
|
@ -61,12 +65,15 @@ public class DashboardUseCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new DashboardOutput(
|
DashboardOutput output = new DashboardOutput(
|
||||||
totalMinutes,
|
totalMinutes,
|
||||||
new ArrayList<>(projectStatsMap.values()),
|
new ArrayList<>(projectStatsMap.values()),
|
||||||
yesterdayTasks.stream().map(CreateTaskMapper::toCreateTaskOutput).toList(),
|
yesterdayTasks.stream().map(CreateTaskMapper::toCreateTaskOutput).toList(),
|
||||||
finishedTasks.stream().map(CreateTaskMapper::toCreateTaskOutput).toList()
|
finishedTasks.stream().map(CreateTaskMapper::toCreateTaskOutput).toList()
|
||||||
);
|
);
|
||||||
|
LOGGER.infof("Dashboard calculated for user %s with %d worked tasks, %d finished tasks and %d total minutes",
|
||||||
|
input.userEmail(), workedTasks.size(), finishedTasks.size(), totalMinutes);
|
||||||
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isWithinPeriod(TaskHistoryItem item, LocalDateTime start, LocalDateTime end) {
|
private boolean isWithinPeriod(TaskHistoryItem item, LocalDateTime start, LocalDateTime end) {
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,10 @@ import net.beetechgroup.beetask.usecase.repository.UserOrganizationRepository;
|
||||||
import net.beetechgroup.beetask.usecase.repository.UserRepository;
|
import net.beetechgroup.beetask.usecase.repository.UserRepository;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
public class AuthorizeOrganizationAdminUseCase {
|
public class AuthorizeOrganizationAdminUseCase {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(AuthorizeOrganizationAdminUseCase.class);
|
||||||
private final UserRepository userRepository;
|
private final UserRepository userRepository;
|
||||||
private final UserOrganizationRepository userOrganizationRepository;
|
private final UserOrganizationRepository userOrganizationRepository;
|
||||||
|
|
||||||
|
|
@ -21,6 +23,7 @@ public class AuthorizeOrganizationAdminUseCase {
|
||||||
public void execute(String userEmail, Long organizationId) {
|
public void execute(String userEmail, Long organizationId) {
|
||||||
Optional<User> userOptional = userRepository.findByEmail(userEmail);
|
Optional<User> userOptional = userRepository.findByEmail(userEmail);
|
||||||
if (userOptional.isEmpty()) {
|
if (userOptional.isEmpty()) {
|
||||||
|
LOGGER.warnf("Organization admin authorization failed because user %s was not found", userEmail);
|
||||||
throw new RuntimeException("Unauthorized: User not found");
|
throw new RuntimeException("Unauthorized: User not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -28,12 +31,17 @@ public class AuthorizeOrganizationAdminUseCase {
|
||||||
Optional<UserOrganization> association = userOrganizationRepository.findByUserAndOrganization(user.getId(), organizationId);
|
Optional<UserOrganization> association = userOrganizationRepository.findByUserAndOrganization(user.getId(), organizationId);
|
||||||
|
|
||||||
if (association.isEmpty()) {
|
if (association.isEmpty()) {
|
||||||
|
LOGGER.warnf("Organization admin authorization failed because user %s is not a member of organization %d",
|
||||||
|
userEmail, organizationId);
|
||||||
throw new RuntimeException("Forbidden: Not a member of this organization");
|
throw new RuntimeException("Forbidden: Not a member of this organization");
|
||||||
}
|
}
|
||||||
|
|
||||||
UserOrganization uo = association.get();
|
UserOrganization uo = association.get();
|
||||||
if (uo.getRole() != UserOrganizationRole.OWNER && uo.getRole() != UserOrganizationRole.ADMIN) {
|
if (uo.getRole() != UserOrganizationRole.OWNER && uo.getRole() != UserOrganizationRole.ADMIN) {
|
||||||
|
LOGGER.warnf("Organization admin authorization failed because user %s has role %s in organization %d",
|
||||||
|
userEmail, uo.getRole(), organizationId);
|
||||||
throw new RuntimeException("Forbidden: Only owners or admins can perform this action");
|
throw new RuntimeException("Forbidden: Only owners or admins can perform this action");
|
||||||
}
|
}
|
||||||
|
LOGGER.infof("Organization admin authorization granted to user %s for organization %d", userEmail, organizationId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,10 @@ import net.beetechgroup.beetask.usecase.repository.UserOrganizationRepository;
|
||||||
import net.beetechgroup.beetask.usecase.repository.UserRepository;
|
import net.beetechgroup.beetask.usecase.repository.UserRepository;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
public class CreateOrganizationUseCase {
|
public class CreateOrganizationUseCase {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(CreateOrganizationUseCase.class);
|
||||||
private final OrganizationRepository organizationRepository;
|
private final OrganizationRepository organizationRepository;
|
||||||
private final UserRepository userRepository;
|
private final UserRepository userRepository;
|
||||||
private final UserOrganizationRepository userOrganizationRepository;
|
private final UserOrganizationRepository userOrganizationRepository;
|
||||||
|
|
@ -27,10 +29,12 @@ public class CreateOrganizationUseCase {
|
||||||
public CreateOrganizationOutput execute(CreateOrganizationInput input) {
|
public CreateOrganizationOutput execute(CreateOrganizationInput input) {
|
||||||
Optional<User> userOptional = userRepository.findByEmail(input.userEmail());
|
Optional<User> userOptional = userRepository.findByEmail(input.userEmail());
|
||||||
if (userOptional.isEmpty()) {
|
if (userOptional.isEmpty()) {
|
||||||
|
LOGGER.warnf("Organization creation failed because user %s was not found", input.userEmail());
|
||||||
throw new RuntimeException("User not found: " + input.userEmail());
|
throw new RuntimeException("User not found: " + input.userEmail());
|
||||||
}
|
}
|
||||||
User user = userOptional.get();
|
User user = userOptional.get();
|
||||||
|
|
||||||
|
LOGGER.infof("Creating organization '%s' for owner %s", input.name(), input.userEmail());
|
||||||
Organization organization = new Organization();
|
Organization organization = new Organization();
|
||||||
organization.setName(input.name());
|
organization.setName(input.name());
|
||||||
organization = organizationRepository.saveOrganization(organization);
|
organization = organizationRepository.saveOrganization(organization);
|
||||||
|
|
@ -41,6 +45,7 @@ public class CreateOrganizationUseCase {
|
||||||
userOrganization.setRole(UserOrganizationRole.OWNER);
|
userOrganization.setRole(UserOrganizationRole.OWNER);
|
||||||
userOrganization.setStatus(UserOrganizationStatus.ACTIVE);
|
userOrganization.setStatus(UserOrganizationStatus.ACTIVE);
|
||||||
userOrganizationRepository.save(userOrganization);
|
userOrganizationRepository.save(userOrganization);
|
||||||
|
LOGGER.infof("Organization %d created successfully with owner user %d", organization.getId(), user.getId());
|
||||||
|
|
||||||
return CreateOrganizationMapper.toCreateOrganizationOutput(organization);
|
return CreateOrganizationMapper.toCreateOrganizationOutput(organization);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,10 @@ import net.beetechgroup.beetask.usecase.repository.UserOrganizationRepository;
|
||||||
import net.beetechgroup.beetask.usecase.repository.UserRepository;
|
import net.beetechgroup.beetask.usecase.repository.UserRepository;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
public class RequestJoinOrganizationUseCase {
|
public class RequestJoinOrganizationUseCase {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(RequestJoinOrganizationUseCase.class);
|
||||||
private final OrganizationRepository organizationRepository;
|
private final OrganizationRepository organizationRepository;
|
||||||
private final UserRepository userRepository;
|
private final UserRepository userRepository;
|
||||||
private final UserOrganizationRepository userOrganizationRepository;
|
private final UserOrganizationRepository userOrganizationRepository;
|
||||||
|
|
@ -29,6 +31,7 @@ public class RequestJoinOrganizationUseCase {
|
||||||
Optional<Organization> orgOptional = organizationRepository.findOrganizationById(organizationId);
|
Optional<Organization> orgOptional = organizationRepository.findOrganizationById(organizationId);
|
||||||
|
|
||||||
if (userOptional.isEmpty() || orgOptional.isEmpty()) {
|
if (userOptional.isEmpty() || orgOptional.isEmpty()) {
|
||||||
|
LOGGER.warnf("Join request failed because user %s or organization %d was not found", userEmail, organizationId);
|
||||||
throw new RuntimeException("User or Organization not found");
|
throw new RuntimeException("User or Organization not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -38,8 +41,10 @@ public class RequestJoinOrganizationUseCase {
|
||||||
Optional<UserOrganization> existing = userOrganizationRepository.findByUserAndOrganization(user.getId(), organization.getId());
|
Optional<UserOrganization> existing = userOrganizationRepository.findByUserAndOrganization(user.getId(), organization.getId());
|
||||||
if (existing.isPresent()) {
|
if (existing.isPresent()) {
|
||||||
if (existing.get().getStatus() == UserOrganizationStatus.ACTIVE) {
|
if (existing.get().getStatus() == UserOrganizationStatus.ACTIVE) {
|
||||||
|
LOGGER.warnf("Join request ignored because user %s is already active in organization %d", userEmail, organizationId);
|
||||||
throw new RuntimeException("User is already a member of this organization");
|
throw new RuntimeException("User is already a member of this organization");
|
||||||
} else if (existing.get().getStatus() == UserOrganizationStatus.PENDING) {
|
} else if (existing.get().getStatus() == UserOrganizationStatus.PENDING) {
|
||||||
|
LOGGER.warnf("Join request ignored because user %s already has a pending request for organization %d", userEmail, organizationId);
|
||||||
throw new RuntimeException("A join request is already pending for this organization");
|
throw new RuntimeException("A join request is already pending for this organization");
|
||||||
}
|
}
|
||||||
// If REJECTED, we allow a new request (or we could just update the existing one to PENDING)
|
// If REJECTED, we allow a new request (or we could just update the existing one to PENDING)
|
||||||
|
|
@ -52,5 +57,6 @@ public class RequestJoinOrganizationUseCase {
|
||||||
request.setStatus(UserOrganizationStatus.PENDING);
|
request.setStatus(UserOrganizationStatus.PENDING);
|
||||||
|
|
||||||
userOrganizationRepository.save(request);
|
userOrganizationRepository.save(request);
|
||||||
|
LOGGER.infof("Join request created for user %s in organization %d", userEmail, organizationId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,10 @@ import net.beetechgroup.beetask.usecase.organization.auth.AuthorizeOrganizationA
|
||||||
import net.beetechgroup.beetask.usecase.repository.UserOrganizationRepository;
|
import net.beetechgroup.beetask.usecase.repository.UserOrganizationRepository;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
public class HandleJoinRequestUseCase extends AuthenticatedOrganizationUseCase<HandleJoinRequestUseCase.Input, Void> {
|
public class HandleJoinRequestUseCase extends AuthenticatedOrganizationUseCase<HandleJoinRequestUseCase.Input, Void> {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(HandleJoinRequestUseCase.class);
|
||||||
private final UserOrganizationRepository userOrganizationRepository;
|
private final UserOrganizationRepository userOrganizationRepository;
|
||||||
|
|
||||||
public HandleJoinRequestUseCase(AuthorizeOrganizationAdminUseCase authorizer,
|
public HandleJoinRequestUseCase(AuthorizeOrganizationAdminUseCase authorizer,
|
||||||
|
|
@ -22,16 +24,22 @@ public class HandleJoinRequestUseCase extends AuthenticatedOrganizationUseCase<H
|
||||||
Optional<UserOrganization> associationOptional = userOrganizationRepository.findByUserAndOrganization(input.userId(), organizationId);
|
Optional<UserOrganization> associationOptional = userOrganizationRepository.findByUserAndOrganization(input.userId(), organizationId);
|
||||||
|
|
||||||
if (associationOptional.isEmpty()) {
|
if (associationOptional.isEmpty()) {
|
||||||
|
LOGGER.warnf("Join request handling failed because request for user %d in organization %d was not found",
|
||||||
|
input.userId(), organizationId);
|
||||||
throw new RuntimeException("Request not found");
|
throw new RuntimeException("Request not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
UserOrganization association = associationOptional.get();
|
UserOrganization association = associationOptional.get();
|
||||||
if (association.getStatus() != UserOrganizationStatus.PENDING) {
|
if (association.getStatus() != UserOrganizationStatus.PENDING) {
|
||||||
|
LOGGER.warnf("Join request handling failed because request for user %d in organization %d is %s",
|
||||||
|
input.userId(), organizationId, association.getStatus());
|
||||||
throw new RuntimeException("Request is not pending");
|
throw new RuntimeException("Request is not pending");
|
||||||
}
|
}
|
||||||
|
|
||||||
association.setStatus(input.approved() ? UserOrganizationStatus.ACTIVE : UserOrganizationStatus.REJECTED);
|
association.setStatus(input.approved() ? UserOrganizationStatus.ACTIVE : UserOrganizationStatus.REJECTED);
|
||||||
userOrganizationRepository.save(association);
|
userOrganizationRepository.save(association);
|
||||||
|
LOGGER.infof("Join request for user %d in organization %d was %s",
|
||||||
|
input.userId(), organizationId, input.approved() ? "approved" : "rejected");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,10 @@ import net.beetechgroup.beetask.usecase.repository.UserOrganizationRepository;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
public class ListPendingRequestsUseCase extends AuthenticatedOrganizationUseCase<Void, List<JoinRequestOutput>> {
|
public class ListPendingRequestsUseCase extends AuthenticatedOrganizationUseCase<Void, List<JoinRequestOutput>> {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(ListPendingRequestsUseCase.class);
|
||||||
private final UserOrganizationRepository userOrganizationRepository;
|
private final UserOrganizationRepository userOrganizationRepository;
|
||||||
|
|
||||||
public ListPendingRequestsUseCase(AuthorizeOrganizationAdminUseCase authorizer,
|
public ListPendingRequestsUseCase(AuthorizeOrganizationAdminUseCase authorizer,
|
||||||
|
|
@ -21,7 +23,7 @@ public class ListPendingRequestsUseCase extends AuthenticatedOrganizationUseCase
|
||||||
@Override
|
@Override
|
||||||
protected List<JoinRequestOutput> doExecute(Long organizationId, Void input) {
|
protected List<JoinRequestOutput> doExecute(Long organizationId, Void input) {
|
||||||
List<UserOrganization> pending = userOrganizationRepository.findByOrganizationIdAndStatus(organizationId, UserOrganizationStatus.PENDING);
|
List<UserOrganization> pending = userOrganizationRepository.findByOrganizationIdAndStatus(organizationId, UserOrganizationStatus.PENDING);
|
||||||
return pending.stream()
|
List<JoinRequestOutput> requests = pending.stream()
|
||||||
.map(uo -> new JoinRequestOutput(
|
.map(uo -> new JoinRequestOutput(
|
||||||
uo.getUser().getId(),
|
uo.getUser().getId(),
|
||||||
uo.getUser().getName(),
|
uo.getUser().getName(),
|
||||||
|
|
@ -29,5 +31,7 @@ public class ListPendingRequestsUseCase extends AuthenticatedOrganizationUseCase
|
||||||
uo.getUser().getPhoto()
|
uo.getUser().getPhoto()
|
||||||
))
|
))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
LOGGER.infof("Loaded %d pending requests for organization %d", requests.size(), organizationId);
|
||||||
|
return requests;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,10 @@ import net.beetechgroup.beetask.usecase.repository.UserOrganizationRepository;
|
||||||
import net.beetechgroup.beetask.usecase.repository.UserRepository;
|
import net.beetechgroup.beetask.usecase.repository.UserRepository;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
public class ListUserJoinRequestsUseCase {
|
public class ListUserJoinRequestsUseCase {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(ListUserJoinRequestsUseCase.class);
|
||||||
private final UserOrganizationRepository userOrganizationRepository;
|
private final UserOrganizationRepository userOrganizationRepository;
|
||||||
private final UserRepository userRepository;
|
private final UserRepository userRepository;
|
||||||
|
|
||||||
|
|
@ -17,14 +19,19 @@ public class ListUserJoinRequestsUseCase {
|
||||||
|
|
||||||
public List<UserJoinRequestOutput> execute(String userEmail) {
|
public List<UserJoinRequestOutput> execute(String userEmail) {
|
||||||
User user = userRepository.findByEmail(userEmail)
|
User user = userRepository.findByEmail(userEmail)
|
||||||
.orElseThrow(() -> new RuntimeException("User not found"));
|
.orElseThrow(() -> {
|
||||||
|
LOGGER.warnf("Join request listing failed because user %s was not found", userEmail);
|
||||||
|
return new RuntimeException("User not found");
|
||||||
|
});
|
||||||
|
|
||||||
return userOrganizationRepository.findByUserId(user.getId()).stream()
|
List<UserJoinRequestOutput> requests = userOrganizationRepository.findByUserId(user.getId()).stream()
|
||||||
.map(uo -> new UserJoinRequestOutput(
|
.map(uo -> new UserJoinRequestOutput(
|
||||||
uo.getOrganization().getId(),
|
uo.getOrganization().getId(),
|
||||||
uo.getOrganization().getName(),
|
uo.getOrganization().getName(),
|
||||||
uo.getStatus()
|
uo.getStatus()
|
||||||
))
|
))
|
||||||
.toList();
|
.toList();
|
||||||
|
LOGGER.infof("Loaded %d join requests for user %s", requests.size(), userEmail);
|
||||||
|
return requests;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,10 @@ package net.beetechgroup.beetask.usecase.organization.search;
|
||||||
import net.beetechgroup.beetask.usecase.repository.OrganizationRepository;
|
import net.beetechgroup.beetask.usecase.repository.OrganizationRepository;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
public class SearchOrganizationsUseCase {
|
public class SearchOrganizationsUseCase {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(SearchOrganizationsUseCase.class);
|
||||||
private final OrganizationRepository organizationRepository;
|
private final OrganizationRepository organizationRepository;
|
||||||
|
|
||||||
public SearchOrganizationsUseCase(OrganizationRepository organizationRepository) {
|
public SearchOrganizationsUseCase(OrganizationRepository organizationRepository) {
|
||||||
|
|
@ -12,8 +14,10 @@ public class SearchOrganizationsUseCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<SearchOrganizationOutput> execute(String query) {
|
public List<SearchOrganizationOutput> execute(String query) {
|
||||||
return organizationRepository.search(query).stream()
|
List<SearchOrganizationOutput> organizations = organizationRepository.search(query).stream()
|
||||||
.map(org -> new SearchOrganizationOutput(org.getId(), org.getName()))
|
.map(org -> new SearchOrganizationOutput(org.getId(), org.getName()))
|
||||||
.toList();
|
.toList();
|
||||||
|
LOGGER.infof("Organization search for query '%s' returned %d results", query, organizations.size());
|
||||||
|
return organizations;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,10 @@ import net.beetechgroup.beetask.entities.task.TaskHistoryItem;
|
||||||
import net.beetechgroup.beetask.usecase.organization.auth.AuthorizeOrganizationAdminUseCase;
|
import net.beetechgroup.beetask.usecase.organization.auth.AuthorizeOrganizationAdminUseCase;
|
||||||
import net.beetechgroup.beetask.usecase.repository.TaskRepository;
|
import net.beetechgroup.beetask.usecase.repository.TaskRepository;
|
||||||
import net.beetechgroup.beetask.usecase.repository.UserOrganizationRepository;
|
import net.beetechgroup.beetask.usecase.repository.UserOrganizationRepository;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
public class OrgDashboardUseCase {
|
public class OrgDashboardUseCase {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(OrgDashboardUseCase.class);
|
||||||
|
|
||||||
private final TaskRepository taskRepository;
|
private final TaskRepository taskRepository;
|
||||||
private final UserOrganizationRepository userOrganizationRepository;
|
private final UserOrganizationRepository userOrganizationRepository;
|
||||||
|
|
@ -32,6 +34,8 @@ public class OrgDashboardUseCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public OrgDashboardOutput execute(OrgDashboardInput input) {
|
public OrgDashboardOutput execute(OrgDashboardInput input) {
|
||||||
|
LOGGER.infof("Calculating organization dashboard for org %d requested by %s in period %s to %s",
|
||||||
|
input.organizationId(), input.userEmail(), input.startDate(), input.endDate());
|
||||||
authorizer.execute(input.userEmail(), input.organizationId());
|
authorizer.execute(input.userEmail(), input.organizationId());
|
||||||
|
|
||||||
List<UserOrganization> members = userOrganizationRepository.findByOrganizationIdAndStatus(
|
List<UserOrganization> members = userOrganizationRepository.findByOrganizationIdAndStatus(
|
||||||
|
|
@ -98,11 +102,14 @@ public class OrgDashboardUseCase {
|
||||||
.sorted(Comparator.comparingLong(OrgMemberStats::totalMinutesWorked).reversed())
|
.sorted(Comparator.comparingLong(OrgMemberStats::totalMinutesWorked).reversed())
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
return new OrgDashboardOutput(
|
OrgDashboardOutput output = new OrgDashboardOutput(
|
||||||
new ArrayList<>(projectStatsMap.values()),
|
new ArrayList<>(projectStatsMap.values()),
|
||||||
topTasks,
|
topTasks,
|
||||||
memberStats
|
memberStats
|
||||||
);
|
);
|
||||||
|
LOGGER.infof("Organization dashboard calculated for org %d with %d members, %d worked tasks and %d finished tasks",
|
||||||
|
input.organizationId(), members.size(), workedTasks.size(), finishedTasks.size());
|
||||||
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
private long calculateMinutesInPeriod(Task task, LocalDateTime start, LocalDateTime end) {
|
private long calculateMinutesInPeriod(Task task, LocalDateTime start, LocalDateTime end) {
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,10 @@ import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
public class MemberDetailUseCase {
|
public class MemberDetailUseCase {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(MemberDetailUseCase.class);
|
||||||
|
|
||||||
private final TaskRepository taskRepository;
|
private final TaskRepository taskRepository;
|
||||||
private final UserOrganizationRepository userOrganizationRepository;
|
private final UserOrganizationRepository userOrganizationRepository;
|
||||||
|
|
@ -33,11 +35,17 @@ public class MemberDetailUseCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public MemberDetailOutput execute(MemberDetailInput input) {
|
public MemberDetailOutput execute(MemberDetailInput input) {
|
||||||
|
LOGGER.infof("Calculating member detail for member %d in organization %d requested by %s from %s to %s",
|
||||||
|
input.memberId(), input.organizationId(), input.userEmail(), input.startDate(), input.endDate());
|
||||||
authorizer.execute(input.userEmail(), input.organizationId());
|
authorizer.execute(input.userEmail(), input.organizationId());
|
||||||
|
|
||||||
UserOrganization member = userOrganizationRepository
|
UserOrganization member = userOrganizationRepository
|
||||||
.findByUserAndOrganization(input.memberId(), input.organizationId())
|
.findByUserAndOrganization(input.memberId(), input.organizationId())
|
||||||
.orElseThrow(() -> new IllegalArgumentException("Member not found in organization"));
|
.orElseThrow(() -> {
|
||||||
|
LOGGER.warnf("Member detail failed because member %d was not found in organization %d",
|
||||||
|
input.memberId(), input.organizationId());
|
||||||
|
return new IllegalArgumentException("Member not found in organization");
|
||||||
|
});
|
||||||
|
|
||||||
LocalDateTime start = input.startDate();
|
LocalDateTime start = input.startDate();
|
||||||
LocalDateTime end = input.endDate();
|
LocalDateTime end = input.endDate();
|
||||||
|
|
@ -114,8 +122,11 @@ public class MemberDetailUseCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return MemberDetailMapper.toOutput(member, groupByDay ? "DAY" : "MONTH", periodStats,
|
MemberDetailOutput output = MemberDetailMapper.toOutput(member, groupByDay ? "DAY" : "MONTH", periodStats,
|
||||||
new ArrayList<>(projectStatsMap.values()));
|
new ArrayList<>(projectStatsMap.values()));
|
||||||
|
LOGGER.infof("Member detail calculated for member %d in organization %d with %d worked tasks and %d finished tasks",
|
||||||
|
input.memberId(), input.organizationId(), workedTasks.size(), finishedTasks.size());
|
||||||
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isWithinPeriod(TaskHistoryItem item, LocalDateTime start, LocalDateTime end) {
|
private boolean isWithinPeriod(TaskHistoryItem item, LocalDateTime start, LocalDateTime end) {
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,10 @@ import net.beetechgroup.beetask.entities.Project;
|
||||||
import net.beetechgroup.beetask.entities.organization.Organization;
|
import net.beetechgroup.beetask.entities.organization.Organization;
|
||||||
import net.beetechgroup.beetask.usecase.repository.OrganizationRepository;
|
import net.beetechgroup.beetask.usecase.repository.OrganizationRepository;
|
||||||
import net.beetechgroup.beetask.usecase.repository.ProjectRepository;
|
import net.beetechgroup.beetask.usecase.repository.ProjectRepository;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
public class CreateProjectUseCase {
|
public class CreateProjectUseCase {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(CreateProjectUseCase.class);
|
||||||
private final ProjectRepository projectRepository;
|
private final ProjectRepository projectRepository;
|
||||||
private final OrganizationRepository organizationRepository;
|
private final OrganizationRepository organizationRepository;
|
||||||
|
|
||||||
|
|
@ -16,12 +18,18 @@ public class CreateProjectUseCase {
|
||||||
|
|
||||||
public Project execute(Long organizationId, String projectName) {
|
public Project execute(Long organizationId, String projectName) {
|
||||||
Organization organization = organizationRepository.findOrganizationById(organizationId)
|
Organization organization = organizationRepository.findOrganizationById(organizationId)
|
||||||
.orElseThrow(() -> new RuntimeException("Organization not found"));
|
.orElseThrow(() -> {
|
||||||
|
LOGGER.warnf("Project creation failed because organization %d was not found", organizationId);
|
||||||
|
return new RuntimeException("Organization not found");
|
||||||
|
});
|
||||||
|
|
||||||
|
LOGGER.infof("Creating project '%s' in organization %d", projectName, organizationId);
|
||||||
Project project = new Project();
|
Project project = new Project();
|
||||||
project.setName(projectName);
|
project.setName(projectName);
|
||||||
project.setOrganization(organization);
|
project.setOrganization(organization);
|
||||||
|
|
||||||
return projectRepository.saveProject(project);
|
Project savedProject = projectRepository.saveProject(project);
|
||||||
|
LOGGER.infof("Project %d created in organization %d", savedProject.getId(), organizationId);
|
||||||
|
return savedProject;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,10 @@ import net.beetechgroup.beetask.entities.Project;
|
||||||
import net.beetechgroup.beetask.usecase.repository.ProjectRepository;
|
import net.beetechgroup.beetask.usecase.repository.ProjectRepository;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
public class ListProjectsUseCase {
|
public class ListProjectsUseCase {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(ListProjectsUseCase.class);
|
||||||
private final ProjectRepository projectRepository;
|
private final ProjectRepository projectRepository;
|
||||||
|
|
||||||
public ListProjectsUseCase(ProjectRepository projectRepository) {
|
public ListProjectsUseCase(ProjectRepository projectRepository) {
|
||||||
|
|
@ -13,6 +15,8 @@ public class ListProjectsUseCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Project> execute(Long organizationId) {
|
public List<Project> execute(Long organizationId) {
|
||||||
return projectRepository.findByOrganizationId(organizationId);
|
List<Project> projects = projectRepository.findByOrganizationId(organizationId);
|
||||||
|
LOGGER.infof("Loaded %d projects for organization %d", projects.size(), organizationId);
|
||||||
|
return projects;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,10 @@ import net.beetechgroup.beetask.entities.task.Task;
|
||||||
import net.beetechgroup.beetask.usecase.repository.ProjectRepository;
|
import net.beetechgroup.beetask.usecase.repository.ProjectRepository;
|
||||||
import net.beetechgroup.beetask.usecase.repository.TaskRepository;
|
import net.beetechgroup.beetask.usecase.repository.TaskRepository;
|
||||||
import net.beetechgroup.beetask.usecase.repository.UserRepository;
|
import net.beetechgroup.beetask.usecase.repository.UserRepository;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
public class CreateTaskUseCase {
|
public class CreateTaskUseCase {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(CreateTaskUseCase.class);
|
||||||
private final TaskRepository taskRepository;
|
private final TaskRepository taskRepository;
|
||||||
private final ProjectRepository projectRepository;
|
private final ProjectRepository projectRepository;
|
||||||
private final UserRepository userRepository;
|
private final UserRepository userRepository;
|
||||||
|
|
@ -19,6 +21,7 @@ public class CreateTaskUseCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public CreateTaskOutput execute(CreateTaskInput input) {
|
public CreateTaskOutput execute(CreateTaskInput input) {
|
||||||
|
LOGGER.infof("Creating task '%s' for user %s", input.title(), input.userEmail());
|
||||||
Task task = new Task();
|
Task task = new Task();
|
||||||
task.setTitle(input.title());
|
task.setTitle(input.title());
|
||||||
task.setDescription(input.description());
|
task.setDescription(input.description());
|
||||||
|
|
@ -26,13 +29,21 @@ public class CreateTaskUseCase {
|
||||||
|
|
||||||
if (Objects.nonNull(input.projectId())) {
|
if (Objects.nonNull(input.projectId())) {
|
||||||
Project project = projectRepository.findProjectById(input.projectId())
|
Project project = projectRepository.findProjectById(input.projectId())
|
||||||
.orElseThrow(() -> new IllegalArgumentException("Projeto não encontrado com ID: " + input.projectId()));
|
.orElseThrow(() -> {
|
||||||
|
LOGGER.warnf("Task creation failed because project %d was not found", input.projectId());
|
||||||
|
return new IllegalArgumentException("Projeto não encontrado com ID: " + input.projectId());
|
||||||
|
});
|
||||||
task.setProject(project);
|
task.setProject(project);
|
||||||
}
|
}
|
||||||
|
|
||||||
task.setUser(userRepository.findByEmail(input.userEmail())
|
task.setUser(userRepository.findByEmail(input.userEmail())
|
||||||
.orElseThrow(() -> new IllegalArgumentException("Usuário não encontrado: " + input.userEmail())));
|
.orElseThrow(() -> {
|
||||||
|
LOGGER.warnf("Task creation failed because user %s was not found", input.userEmail());
|
||||||
|
return new IllegalArgumentException("Usuário não encontrado: " + input.userEmail());
|
||||||
|
}));
|
||||||
|
|
||||||
return CreateTaskMapper.toCreateTaskOutput(taskRepository.saveTask(task));
|
CreateTaskOutput output = CreateTaskMapper.toCreateTaskOutput(taskRepository.saveTask(task));
|
||||||
|
LOGGER.infof("Task %d created for user %s", output.id(), input.userEmail());
|
||||||
|
return output;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,10 @@ package net.beetechgroup.beetask.usecase.task.get;
|
||||||
import net.beetechgroup.beetask.usecase.repository.TaskRepository;
|
import net.beetechgroup.beetask.usecase.repository.TaskRepository;
|
||||||
import net.beetechgroup.beetask.usecase.task.create.CreateTaskMapper;
|
import net.beetechgroup.beetask.usecase.task.create.CreateTaskMapper;
|
||||||
import net.beetechgroup.beetask.usecase.task.create.CreateTaskOutput;
|
import net.beetechgroup.beetask.usecase.task.create.CreateTaskOutput;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
public class GetTaskUseCase {
|
public class GetTaskUseCase {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(GetTaskUseCase.class);
|
||||||
private final TaskRepository taskRepository;
|
private final TaskRepository taskRepository;
|
||||||
|
|
||||||
public GetTaskUseCase(TaskRepository taskRepository) {
|
public GetTaskUseCase(TaskRepository taskRepository) {
|
||||||
|
|
@ -13,6 +15,7 @@ public class GetTaskUseCase {
|
||||||
|
|
||||||
public CreateTaskOutput execute(Long id) {
|
public CreateTaskOutput execute(Long id) {
|
||||||
//TODO deve validar se o usuario logado é o dono da task
|
//TODO deve validar se o usuario logado é o dono da task
|
||||||
|
LOGGER.infof("Fetching task %d", id);
|
||||||
return CreateTaskMapper.toCreateTaskOutput(taskRepository.findTaskById(id));
|
return CreateTaskMapper.toCreateTaskOutput(taskRepository.findTaskById(id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,12 @@ package net.beetechgroup.beetask.usecase.task.listall;
|
||||||
import net.beetechgroup.beetask.usecase.repository.TaskRepository;
|
import net.beetechgroup.beetask.usecase.repository.TaskRepository;
|
||||||
import net.beetechgroup.beetask.usecase.task.create.CreateTaskMapper;
|
import net.beetechgroup.beetask.usecase.task.create.CreateTaskMapper;
|
||||||
import net.beetechgroup.beetask.usecase.task.create.CreateTaskOutput;
|
import net.beetechgroup.beetask.usecase.task.create.CreateTaskOutput;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class ListAllTasksUseCase {
|
public class ListAllTasksUseCase {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(ListAllTasksUseCase.class);
|
||||||
|
|
||||||
private final TaskRepository taskRepository;
|
private final TaskRepository taskRepository;
|
||||||
|
|
||||||
|
|
@ -15,6 +17,8 @@ public class ListAllTasksUseCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<CreateTaskOutput> execute() {
|
public List<CreateTaskOutput> execute() {
|
||||||
return taskRepository.findAllTasks().stream().map(CreateTaskMapper::toCreateTaskOutput).toList();
|
List<CreateTaskOutput> tasks = taskRepository.findAllTasks().stream().map(CreateTaskMapper::toCreateTaskOutput).toList();
|
||||||
|
LOGGER.infof("Loaded %d tasks from repository", tasks.size());
|
||||||
|
return tasks;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,12 @@ package net.beetechgroup.beetask.usecase.task.listall;
|
||||||
import net.beetechgroup.beetask.usecase.repository.TaskRepository;
|
import net.beetechgroup.beetask.usecase.repository.TaskRepository;
|
||||||
import net.beetechgroup.beetask.usecase.task.create.CreateTaskMapper;
|
import net.beetechgroup.beetask.usecase.task.create.CreateTaskMapper;
|
||||||
import net.beetechgroup.beetask.usecase.task.create.CreateTaskOutput;
|
import net.beetechgroup.beetask.usecase.task.create.CreateTaskOutput;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class ListMyTasksUseCase {
|
public class ListMyTasksUseCase {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(ListMyTasksUseCase.class);
|
||||||
|
|
||||||
private final TaskRepository taskRepository;
|
private final TaskRepository taskRepository;
|
||||||
|
|
||||||
|
|
@ -15,6 +17,8 @@ public class ListMyTasksUseCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<CreateTaskOutput> execute(String email) {
|
public List<CreateTaskOutput> execute(String email) {
|
||||||
return taskRepository.findTasksByUser(email).stream().map(CreateTaskMapper::toCreateTaskOutput).toList();
|
List<CreateTaskOutput> tasks = taskRepository.findTasksByUser(email).stream().map(CreateTaskMapper::toCreateTaskOutput).toList();
|
||||||
|
LOGGER.infof("Loaded %d tasks for user %s", tasks.size(), email);
|
||||||
|
return tasks;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,10 @@ import net.beetechgroup.beetask.usecase.repository.TaskRepository;
|
||||||
import net.beetechgroup.beetask.usecase.repository.UserRepository;
|
import net.beetechgroup.beetask.usecase.repository.UserRepository;
|
||||||
import net.beetechgroup.beetask.usecase.task.create.CreateTaskMapper;
|
import net.beetechgroup.beetask.usecase.task.create.CreateTaskMapper;
|
||||||
import net.beetechgroup.beetask.usecase.task.create.CreateTaskOutput;
|
import net.beetechgroup.beetask.usecase.task.create.CreateTaskOutput;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
public class StartTaskUseCase {
|
public class StartTaskUseCase {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(StartTaskUseCase.class);
|
||||||
|
|
||||||
private final TaskRepository taskRepository;
|
private final TaskRepository taskRepository;
|
||||||
private final UserRepository userRepository;
|
private final UserRepository userRepository;
|
||||||
|
|
@ -18,13 +20,18 @@ public class StartTaskUseCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public CreateTaskOutput execute(StartTaskInput input) {
|
public CreateTaskOutput execute(StartTaskInput input) {
|
||||||
|
LOGGER.infof("Starting task %d for user %s", input.id(), input.userEmail());
|
||||||
Task task = taskRepository.findTaskById(input.id());
|
Task task = taskRepository.findTaskById(input.id());
|
||||||
|
|
||||||
if (Objects.nonNull(task.getUser()) && !task.getUser().getEmail().equals(input.userEmail())) {
|
if (Objects.nonNull(task.getUser()) && !task.getUser().getEmail().equals(input.userEmail())) {
|
||||||
|
LOGGER.warnf("User %s attempted to start task %d owned by %s",
|
||||||
|
input.userEmail(), input.id(), task.getUser().getEmail());
|
||||||
throw new SecurityException("Você não tem permissão para iniciar esta tarefa.");
|
throw new SecurityException("Você não tem permissão para iniciar esta tarefa.");
|
||||||
}
|
}
|
||||||
|
|
||||||
task.start();
|
task.start();
|
||||||
return CreateTaskMapper.toCreateTaskOutput(taskRepository.saveTask(task));
|
CreateTaskOutput output = CreateTaskMapper.toCreateTaskOutput(taskRepository.saveTask(task));
|
||||||
|
LOGGER.infof("Task %d started successfully", input.id());
|
||||||
|
return output;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,10 @@ import net.beetechgroup.beetask.entities.task.Task;
|
||||||
import net.beetechgroup.beetask.usecase.repository.TaskRepository;
|
import net.beetechgroup.beetask.usecase.repository.TaskRepository;
|
||||||
import net.beetechgroup.beetask.usecase.task.create.CreateTaskMapper;
|
import net.beetechgroup.beetask.usecase.task.create.CreateTaskMapper;
|
||||||
import net.beetechgroup.beetask.usecase.task.create.CreateTaskOutput;
|
import net.beetechgroup.beetask.usecase.task.create.CreateTaskOutput;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
public class StopTaskUseCase {
|
public class StopTaskUseCase {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(StopTaskUseCase.class);
|
||||||
|
|
||||||
private final TaskRepository taskRepository;
|
private final TaskRepository taskRepository;
|
||||||
|
|
||||||
|
|
@ -14,8 +16,11 @@ public class StopTaskUseCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public CreateTaskOutput execute(StopTaskInput input) {
|
public CreateTaskOutput execute(StopTaskInput input) {
|
||||||
|
LOGGER.infof("Stopping task %d", input.id());
|
||||||
Task task = taskRepository.findTaskById(input.id());
|
Task task = taskRepository.findTaskById(input.id());
|
||||||
task.stop();
|
task.stop();
|
||||||
return CreateTaskMapper.toCreateTaskOutput(taskRepository.saveTask(task));
|
CreateTaskOutput output = CreateTaskMapper.toCreateTaskOutput(taskRepository.saveTask(task));
|
||||||
|
LOGGER.infof("Task %d stopped successfully", input.id());
|
||||||
|
return output;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,10 @@ import net.beetechgroup.beetask.entities.task.TaskStatus;
|
||||||
import net.beetechgroup.beetask.usecase.repository.TaskRepository;
|
import net.beetechgroup.beetask.usecase.repository.TaskRepository;
|
||||||
import net.beetechgroup.beetask.usecase.task.create.CreateTaskMapper;
|
import net.beetechgroup.beetask.usecase.task.create.CreateTaskMapper;
|
||||||
import net.beetechgroup.beetask.usecase.task.create.CreateTaskOutput;
|
import net.beetechgroup.beetask.usecase.task.create.CreateTaskOutput;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
public class UpdateTaskStatusUseCase {
|
public class UpdateTaskStatusUseCase {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(UpdateTaskStatusUseCase.class);
|
||||||
|
|
||||||
private final TaskRepository taskRepository;
|
private final TaskRepository taskRepository;
|
||||||
|
|
||||||
|
|
@ -17,10 +19,13 @@ public class UpdateTaskStatusUseCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public CreateTaskOutput execute(Long id, TaskStatus newStatus) {
|
public CreateTaskOutput execute(Long id, TaskStatus newStatus) {
|
||||||
|
LOGGER.infof("Updating status for task %d to %s", id, newStatus);
|
||||||
Task task = taskRepository.findTaskById(id);
|
Task task = taskRepository.findTaskById(id);
|
||||||
|
|
||||||
task.setStatus(newStatus);
|
task.setStatus(newStatus);
|
||||||
|
|
||||||
return CreateTaskMapper.toCreateTaskOutput(taskRepository.saveTask(task));
|
CreateTaskOutput output = CreateTaskMapper.toCreateTaskOutput(taskRepository.saveTask(task));
|
||||||
|
LOGGER.infof("Status updated for task %d to %s", id, newStatus);
|
||||||
|
return output;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,10 @@ import net.beetechgroup.beetask.usecase.repository.TaskRepository;
|
||||||
import net.beetechgroup.beetask.usecase.repository.UserRepository;
|
import net.beetechgroup.beetask.usecase.repository.UserRepository;
|
||||||
import net.beetechgroup.beetask.usecase.task.create.CreateTaskMapper;
|
import net.beetechgroup.beetask.usecase.task.create.CreateTaskMapper;
|
||||||
import net.beetechgroup.beetask.usecase.task.create.CreateTaskOutput;
|
import net.beetechgroup.beetask.usecase.task.create.CreateTaskOutput;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
public class UpdateTaskUseCase {
|
public class UpdateTaskUseCase {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(UpdateTaskUseCase.class);
|
||||||
private final TaskRepository taskRepository;
|
private final TaskRepository taskRepository;
|
||||||
private final ProjectRepository projectRepository;
|
private final ProjectRepository projectRepository;
|
||||||
private final UserRepository userRepository;
|
private final UserRepository userRepository;
|
||||||
|
|
@ -23,11 +25,15 @@ public class UpdateTaskUseCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public CreateTaskOutput execute(UpdateTaskInput input) {
|
public CreateTaskOutput execute(UpdateTaskInput input) {
|
||||||
|
LOGGER.infof("Updating task %d requested by user %s", input.id(), input.userEmail());
|
||||||
Task task = taskRepository.findTaskById(input.id());
|
Task task = taskRepository.findTaskById(input.id());
|
||||||
|
|
||||||
if (Objects.isNull(task.getUser())) {
|
if (Objects.isNull(task.getUser())) {
|
||||||
task.setUser(userRepository.findByEmail(input.userEmail())
|
task.setUser(userRepository.findByEmail(input.userEmail())
|
||||||
.orElseThrow(() -> new IllegalArgumentException("Usuário não encontrado: " + input.userEmail())));
|
.orElseThrow(() -> {
|
||||||
|
LOGGER.warnf("Task update failed because user %s was not found", input.userEmail());
|
||||||
|
return new IllegalArgumentException("Usuário não encontrado: " + input.userEmail());
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
task.setTitle(input.title());
|
task.setTitle(input.title());
|
||||||
|
|
@ -36,7 +42,10 @@ public class UpdateTaskUseCase {
|
||||||
|
|
||||||
if (Objects.nonNull(input.projectId())) {
|
if (Objects.nonNull(input.projectId())) {
|
||||||
Project project = projectRepository.findProjectById(input.projectId())
|
Project project = projectRepository.findProjectById(input.projectId())
|
||||||
.orElseThrow(() -> new IllegalArgumentException("Projeto não encontrado com ID: " + input.projectId()));
|
.orElseThrow(() -> {
|
||||||
|
LOGGER.warnf("Task update failed because project %d was not found", input.projectId());
|
||||||
|
return new IllegalArgumentException("Projeto não encontrado com ID: " + input.projectId());
|
||||||
|
});
|
||||||
task.setProject(project);
|
task.setProject(project);
|
||||||
} else {
|
} else {
|
||||||
task.setProject(null);
|
task.setProject(null);
|
||||||
|
|
@ -69,8 +78,11 @@ public class UpdateTaskUseCase {
|
||||||
|
|
||||||
task.getHistory().clear();
|
task.getHistory().clear();
|
||||||
task.getHistory().addAll(updatedHistory);
|
task.getHistory().addAll(updatedHistory);
|
||||||
|
LOGGER.infof("Task %d history updated with %d entries", input.id(), updatedHistory.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
return CreateTaskMapper.toCreateTaskOutput(taskRepository.saveTask(task));
|
CreateTaskOutput output = CreateTaskMapper.toCreateTaskOutput(taskRepository.saveTask(task));
|
||||||
|
LOGGER.infof("Task %d updated successfully", input.id());
|
||||||
|
return output;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,10 @@ package net.beetechgroup.beetask.usecase.user.create;
|
||||||
|
|
||||||
import net.beetechgroup.beetask.entities.User;
|
import net.beetechgroup.beetask.entities.User;
|
||||||
import net.beetechgroup.beetask.usecase.repository.UserRepository;
|
import net.beetechgroup.beetask.usecase.repository.UserRepository;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
public class CreateUserUseCase {
|
public class CreateUserUseCase {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(CreateUserUseCase.class);
|
||||||
|
|
||||||
private final UserRepository userRepository;
|
private final UserRepository userRepository;
|
||||||
|
|
||||||
|
|
@ -13,11 +15,14 @@ public class CreateUserUseCase {
|
||||||
|
|
||||||
public CreateUserOutput execute(CreateUserInput input) {
|
public CreateUserOutput execute(CreateUserInput input) {
|
||||||
if (userRepository.findByEmail(input.email()).isPresent()) {
|
if (userRepository.findByEmail(input.email()).isPresent()) {
|
||||||
|
LOGGER.warnf("User creation rejected because email %s already exists", input.email());
|
||||||
throw new RuntimeException("User already exists with this email");
|
throw new RuntimeException("User already exists with this email");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOGGER.infof("Creating user with email %s", input.email());
|
||||||
User user = CreateUserMapper.toUser(input);
|
User user = CreateUserMapper.toUser(input);
|
||||||
User savedUser = userRepository.save(user);
|
User savedUser = userRepository.save(user);
|
||||||
|
LOGGER.infof("User %d created successfully with email %s", savedUser.getId(), savedUser.getEmail());
|
||||||
|
|
||||||
return CreateUserMapper.toCreateUserOutput(savedUser);
|
return CreateUserMapper.toCreateUserOutput(savedUser);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,10 @@ import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
public class GetUserProfileUseCase {
|
public class GetUserProfileUseCase {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(GetUserProfileUseCase.class);
|
||||||
|
|
||||||
private final UserRepository userRepository;
|
private final UserRepository userRepository;
|
||||||
|
|
||||||
|
|
@ -21,11 +23,13 @@ public class GetUserProfileUseCase {
|
||||||
Optional<User> userOptional = userRepository.findByEmail(email);
|
Optional<User> userOptional = userRepository.findByEmail(email);
|
||||||
|
|
||||||
if (userOptional.isEmpty()) {
|
if (userOptional.isEmpty()) {
|
||||||
|
LOGGER.warnf("Profile lookup failed because user %s was not found", email);
|
||||||
throw new RuntimeException("User not found");
|
throw new RuntimeException("User not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
User user = userOptional.get();
|
User user = userOptional.get();
|
||||||
List<UserOrganization> userOrganizations = userRepository.findUserOrganizations(user.getId());
|
List<UserOrganization> userOrganizations = userRepository.findUserOrganizations(user.getId());
|
||||||
|
LOGGER.infof("Loaded profile for user %s with %d active organizations", email, userOrganizations.size());
|
||||||
|
|
||||||
List<UserProfileOutput.OrganizationProfileOutput> orgs = userOrganizations.stream()
|
List<UserProfileOutput.OrganizationProfileOutput> orgs = userOrganizations.stream()
|
||||||
.collect(Collectors.groupingBy(uo -> uo.getOrganization().getId()))
|
.collect(Collectors.groupingBy(uo -> uo.getOrganization().getId()))
|
||||||
|
|
|
||||||
2166
frontend/pnpm-lock.yaml
Normal file
2166
frontend/pnpm-lock.yaml
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue