Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Root EditorConfig file
root = true

# -------------------------------------------------------
# Global defaults
# -------------------------------------------------------
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = space
indent_size = 4
max_line_length = 160

# -------------------------------------------------------
# Java files
# -------------------------------------------------------
[*.java]
tab_width = 4
ij_java_line_comment_add_space = true

# Ensure imports are ordered consistently
ij_java_imports_layout = java.**,javax.**,org.springframework.**,*, @*,|,at.shiftcontrol.**,|,$*
ij_java_class_count_to_use_import_on_demand = 9999
ij_java_names_count_to_use_import_on_demand = 9999

# Make sure there is no newline at end/start of class
ij_java_blank_lines_after_class_header = 0
ij_java_blank_lines_before_class_end = 0
ij_java_keep_blank_lines_in_declarations = 1
ij_java_keep_blank_lines_in_code = 0
ij_java_keep_blank_lines_before_right_brace = 0
ij_java_if_brace_force = always
ij_java_binary_operation_wrap = normal
ij_java_binary_operation_sign_on_next_line = true

# -------------------------------------------------------
# YAML / properties (Spring configs)
# -------------------------------------------------------
[*.yml]
indent_size = 2

[*.yaml]
indent_size = 2

# -------------------------------------------------------
# JSON files
# -------------------------------------------------------
[*.json]
indent_size = 2

# -------------------------------------------------------
# Markdown docs
# -------------------------------------------------------
[*.md]
trim_trailing_whitespace = false # keep Markdown formatting intact

# -------------------------------------------------------
# XML files (config, pom.xml, applicationContext, ...)
# -------------------------------------------------------
[*.xml]
indent_size = 2

# -------------------------------------------------------
# Git ignore files
# -------------------------------------------------------
[.gitignore]
trim_trailing_whitespace = false
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,15 @@ jobs:
env:
POSTGRES_USER: shiftcontrol
POSTGRES_PASSWORD: password
POSTGRES_DB: shiftservice
POSTGRES_DB: shiftcontrol
options: >-
--health-cmd="pg_isready -U shiftcontrol"
--health-interval=5s
--health-timeout=5s
--health-retries=5

env:
SPRING_DATASOURCE_URL: jdbc:postgresql://localhost:5432/shiftservice
SPRING_DATASOURCE_URL: jdbc:postgresql://localhost:5432/shiftcontrol
SPRING_DATASOURCE_USERNAME: shiftcontrol
SPRING_DATASOURCE_PASSWORD: password

Expand Down
23 changes: 1 addition & 22 deletions checkstyle.xml
Original file line number Diff line number Diff line change
Expand Up @@ -262,14 +262,6 @@
</module>
<module name="OverloadMethodsDeclarationOrder"/>
<module name="VariableDeclarationUsageDistance"/>
<module name="CustomImportOrder">
<property name="sortImportsInGroupAlphabetically" value="true"/>
<property name="separateLineBetweenGroups" value="true"/>
<property name="customImportOrderRules"
value="STANDARD_JAVA_PACKAGE, SPECIAL_IMPORTS, THIRD_PARTY_PACKAGE, SAME_PACKAGE(2)"/>
<property name="specialImportsRegExp" value="org\.springframework\..*"/>
<property name="tokens" value="IMPORT, STATIC_IMPORT, PACKAGE_DEF"/>
</module>
<module name="MethodParamPad">
<property name="tokens"
value="CTOR_DEF, LITERAL_NEW, METHOD_CALL, METHOD_DEF,
Expand Down Expand Up @@ -327,20 +319,7 @@
<property name="allowedAnnotations" value="Override, Test"/>
<property name="tokens" value="METHOD_DEF, CTOR_DEF, ANNOTATION_FIELD_DEF, COMPACT_CTOR_DEF"/>
</module>
<!-- <module name="MissingJavadocMethod">-->
<!-- <property name="accessModifiers" value="public"/>-->
<!-- <property name="minLineCount" value="2"/>-->
<!-- <property name="allowedAnnotations" value="Override, Test"/>-->
<!-- <property name="tokens" value="METHOD_DEF, CTOR_DEF, ANNOTATION_FIELD_DEF,-->
<!-- COMPACT_CTOR_DEF"/>-->
<!-- </module>-->
<!-- <module name="MissingJavadocType">-->
<!-- <property name="accessModifiers" value="protected"/>-->
<!-- <property name="tokens"-->
<!-- value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF,-->
<!-- RECORD_DEF, ANNOTATION_DEF"/>-->
<!-- <property name="excludeScope" value="nothing"/>-->
<!-- </module>-->

<module name="MethodName">
<property name="format" value="^[a-z][a-zA-Z0-9_]*$"/>
<message key="name.invalidPattern"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package at.shiftcontrol.lib.auth;

import org.jspecify.annotations.NonNull;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
Expand All @@ -8,7 +9,7 @@

public class NonDevTestCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
public boolean matches(ConditionContext context, @NonNull AnnotatedTypeMetadata metadata) {
Environment env = context.getEnvironment();

// Check if EITHER profile is active
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package at.shiftcontrol.lib.auth;

import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NonNull;
import org.springframework.security.authentication.AbstractAuthenticationToken;
Expand All @@ -8,6 +9,7 @@
import javax.security.auth.Subject;
import java.util.Collection;

@EqualsAndHashCode(callSuper = true)
@Getter
public class UserAuthenticationToken extends AbstractAuthenticationToken {
private final ApplicationUser principal;
Expand All @@ -21,9 +23,4 @@ public UserAuthenticationToken(@NonNull ApplicationUser principal,
this.credentials = credentials;
super.setAuthenticated(true); // must use super, as we override
}

@Override
public boolean implies(Subject subject) {
return super.implies(subject);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public class Activity {
@Column(nullable = false, length = 255)
private String name;
@Size(max = 1024)
@Column(nullable = true, length = 1024)
@Column(length = 1024)
private String description;
@NotNull
@Column(nullable = false)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import lombok.NoArgsConstructor;
import lombok.NonNull;

import at.shiftcontrol.lib.exception.IllegalArgumentException;

@NoArgsConstructor(access = lombok.AccessLevel.PRIVATE)
public final class RoutingKeys {
private static final Pattern PLACEHOLDER = Pattern.compile("\\{([^}]+)}");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@
import java.util.List;
import java.util.stream.Stream;

import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import at.shiftcontrol.lib.exception.BadRequestException;

@Slf4j
@NoArgsConstructor(access = lombok.AccessLevel.PRIVATE)
public class ConvertUtil {
public static long idToLong(String value) throws BadRequestException {
if (value == null || value.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import at.shiftcontrol.lib.entity.Assignment;
import at.shiftcontrol.lib.entity.PositionSlot;

import lombok.NonNull;

public interface AssignmentDao extends BasicDao<Assignment, Long> {
Optional<Assignment> findBySlotAndUser(long positionSlotId, String assignedUser);

Expand All @@ -28,7 +30,7 @@ public interface AssignmentDao extends BasicDao<Assignment, Long> {

Collection<Assignment> getConflictingAssignmentsExcludingSlot(String volunteerId, PositionSlot slot);

Assignment getAssignmentForPositionSlotAndUser(long positionSlotId, String userId);
@NonNull Assignment getAssignmentForPositionSlotAndUser(long positionSlotId, String userId);

Optional<Assignment> findAssignmentForPositionSlotAndUser(long positionSlotId, String userId);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public Collection<Assignment> getConflictingAssignmentsExcludingSlot(String volu
}

@Override
public Assignment getAssignmentForPositionSlotAndUser(long positionSlotId, String userId) {
public @org.jspecify.annotations.NonNull Assignment getAssignmentForPositionSlotAndUser(long positionSlotId, String userId) {
return assignmentRepository.findAssignmentForPositionSlotAndUser(positionSlotId, userId)
.orElseThrow(() -> new NotFoundException("Not assigned to position slot."));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package at.shiftcontrol.shiftservice.dto.invite;

import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Builder;
import lombok.Data;

@Data
@Builder
public class ShiftPlanJoinRequestDto {
@NotNull
@NotBlank
private String inviteCode;
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import at.shiftcontrol.lib.util.ConvertUtil;
import at.shiftcontrol.shiftservice.dto.role.RoleDto;
import at.shiftcontrol.shiftservice.dto.role.RoleModificationDto;
import at.shiftcontrol.shiftservice.service.role.RoleService;
import at.shiftcontrol.shiftservice.service.RoleService;


@Tag(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import at.shiftcontrol.lib.util.ConvertUtil;
import at.shiftcontrol.shiftservice.dto.role.RoleDto;
import at.shiftcontrol.shiftservice.dto.role.RoleModificationDto;
import at.shiftcontrol.shiftservice.service.role.RoleService;
import at.shiftcontrol.shiftservice.service.RoleService;

@Tag(
name = "role-endpoint"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import at.shiftcontrol.lib.util.ConvertUtil;
import at.shiftcontrol.shiftservice.dto.role.UserRoleAssignmentAssignDto;
import at.shiftcontrol.shiftservice.dto.userprofile.VolunteerDto;
import at.shiftcontrol.shiftservice.service.role.RoleService;
import at.shiftcontrol.shiftservice.service.RoleService;

@Slf4j
@RestController
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import at.shiftcontrol.shiftservice.dto.user.UserEventBulkDto;
import at.shiftcontrol.shiftservice.dto.user.UserEventDto;
import at.shiftcontrol.shiftservice.dto.user.UserSearchDto;
import at.shiftcontrol.shiftservice.service.user.UserAdministrationService;
import at.shiftcontrol.shiftservice.service.UserAdministrationService;

@Tag(
name = "user-event-endpoint"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import at.shiftcontrol.shiftservice.dto.user.LockResetUserDto;
import at.shiftcontrol.shiftservice.dto.user.UserEventDto;
import at.shiftcontrol.shiftservice.dto.user.UserEventUpdateDto;
import at.shiftcontrol.shiftservice.service.user.UserAdministrationService;
import at.shiftcontrol.shiftservice.service.UserAdministrationService;

@Tag(
name = "user-event-endpoint"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import at.shiftcontrol.shiftservice.dto.user.UserPlanBulkDto;
import at.shiftcontrol.shiftservice.dto.user.UserPlanDto;
import at.shiftcontrol.shiftservice.dto.user.UserSearchDto;
import at.shiftcontrol.shiftservice.service.user.UserAdministrationService;
import at.shiftcontrol.shiftservice.service.UserAdministrationService;

@Tag(
name = "user-plan-endpoint"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import at.shiftcontrol.lib.util.ConvertUtil;
import at.shiftcontrol.shiftservice.dto.user.UserPlanDto;
import at.shiftcontrol.shiftservice.dto.user.UserPlanUpdateDto;
import at.shiftcontrol.shiftservice.service.user.UserAdministrationService;
import at.shiftcontrol.shiftservice.service.UserAdministrationService;

@Tag(
name = "user-plan-endpoint"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,64 @@
import at.shiftcontrol.shiftservice.dto.activity.ActivityModificationDto;
import at.shiftcontrol.shiftservice.dto.activity.ActivitySuggestionDto;

import lombok.NonNull;
import org.jspecify.annotations.Nullable;

public interface ActivityService {
ActivityDto getActivity(long activityId);
/**
* Get activity by id
* @param activityId the id of the activity
* @return the activity dto
* @throws at.shiftcontrol.lib.exception.NotFoundException if the activity does not exist
*/
@NonNull ActivityDto getActivity(long activityId);

Collection<ActivityDto> getActivitiesForEvent(long eventId);
/**
* Get all activities for an event
* @param eventId the id of the event
* @return collection of activity dtos
* @throws at.shiftcontrol.lib.exception.NotFoundException if the event does not exist
* @throws at.shiftcontrol.lib.exception.ForbiddenException if the user is not a planner in any plan of the event
*/
@NonNull Collection<ActivityDto> getActivitiesForEvent(long eventId);

ActivityDto createActivity(long eventId, ActivityModificationDto modificationDto);
/**
* Create a new activity for an event
* @param eventId the id of the event
* @param modificationDto the modification dto
* @return the created activity dto
* @throws at.shiftcontrol.lib.exception.NotFoundException if the event does not exist
* @throws at.shiftcontrol.lib.exception.ForbiddenException if the user is not an admin of the event
* @throws at.shiftcontrol.lib.exception.BadRequestException if the activity name is not unique within the event
*/
@NonNull ActivityDto createActivity(long eventId, @NonNull ActivityModificationDto modificationDto);

ActivityDto updateActivity(long activityId, ActivityModificationDto modificationDto);
/**
* Update an existing activity
* @param activityId the id of the activity
* @param modificationDto the modification dto
* @return the updated activity dto
* @throws at.shiftcontrol.lib.exception.NotFoundException if the activity does not exist
* @throws at.shiftcontrol.lib.exception.ForbiddenException if the user is not an admin of the event
* @throws at.shiftcontrol.lib.exception.BadRequestException if the activity name is not unique within the event
*/
@NonNull ActivityDto updateActivity(long activityId, @NonNull ActivityModificationDto modificationDto);

/**
* Delete an activity
* @param activityId the id of the activity
* @throws at.shiftcontrol.lib.exception.NotFoundException if the activity does not exist
* @throws at.shiftcontrol.lib.exception.ForbiddenException if the user is not an admin of the event
*/
void deleteActivity(long activityId);

Collection<ActivityDto> suggestActivitiesForShift(long eventId, ActivitySuggestionDto suggestionDto);
/**
* Suggest activities for a shift based on the given criteria
* @param eventId the id of the event
* @param suggestionDto the suggestion criteria
* @return collection of suggested activity dtos
* @throws at.shiftcontrol.lib.exception.NotFoundException if the event does not exist
* @throws at.shiftcontrol.lib.exception.ForbiddenException if the user is not a planner in any plan of the event
*/
@NonNull Collection<ActivityDto> suggestActivitiesForShift(long eventId, @Nullable ActivitySuggestionDto suggestionDto);
}
Loading