Skip to content
Merged
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
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## 2.0.4 (17-08-2026)
- Update profile settings to allow for multiple settings per profile [MODLD-1040](https://folio-org.atlassian.net/browse/MODLD-1040)

## 2.0.3 (02-06-2026)
- Exclude LIGHT_RESOURCE from reindexing [MODLD-1071](https://folio-org.atlassian.net/browse/MODLD-1071)
- Fix Instance loses association with Work when Work profile is changed [MODLD-1072](https://folio-org.atlassian.net/browse/MODLD-1072)
Expand Down
74 changes: 67 additions & 7 deletions descriptors/ModuleDescriptor-template.json
Original file line number Diff line number Diff line change
Expand Up @@ -171,13 +171,43 @@
},
{
"methods": [ "GET" ],
"pathPattern": "/linked-data/profile/settings/{id}",
"permissionsRequired": [ "linked-data.profiles.settings.get" ]
"pathPattern": "/linked-data/profile/{profileId}/settings",
"permissionsRequired": [ "linked-data.profiles.settings.list.get" ]
},
{
"methods": [ "POST" ],
"pathPattern": "/linked-data/profile/settings/{id}",
"pathPattern": "/linked-data/profile/{profileId}/settings",
"permissionsRequired": [ "linked-data.profiles.settings.post" ]
},
{
"methods": [ "GET" ],
"pathPattern": "/linked-data/profile/{profileId}/settings/{id}",
"permissionsRequired": [ "linked-data.profiles.settings.get" ]
},
{
"methods": [ "PUT" ],
"pathPattern": "/linked-data/profile/{profileId}/settings/{id}",
"permissionsRequired": [ "linked-data.profiles.settings.put" ]
},
{
"methods": [ "DELETE" ],
"pathPattern": "/linked-data/profile/{profileId}/settings/{id}",
"permissionsRequired": [ "linked-data.profiles.settings.delete" ]
},
{
"methods": [ "GET" ],
"pathPattern": "/linked-data/profile/{profileId}/preferred",
"permissionsRequired": [ "linked-data.profiles.settings.preferred.get" ]
},
{
"methods": [ "POST" ],
"pathPattern": "/linked-data/profile/{profileId}/preferred",
"permissionsRequired": [ "linked-data.profiles.settings.preferred.post" ]
},
{
"methods": [ "DELETE" ],
"pathPattern": "/linked-data/profile/{profileId}/preferred",
"permissionsRequired": [ "linked-data.profiles.settings.preferred.delete" ]
}
]
},
Expand Down Expand Up @@ -404,15 +434,45 @@
"displayName": "Linked Data: Delete the preferred profile for a resource type for the current user",
"description": "Delete the preferred profile for a resource type for the current user"
},
{
"permissionName": "linked-data.profiles.settings.list.get",
"displayName": "Linked Data: List all of the workspace profile settings for the profile for the current user",
"description": "List all of the workspace profile settings for the profile for the current user"
},
{
"permissionName": "linked-data.profiles.settings.get",
"displayName": "Linked Data: Get the workspace profile settings for the profile for the current user",
"description": "Get the workspace profile settings for the profile for the current user"
"displayName": "Linked Data: Get workspace profile settings for the profile for the current user",
"description": "Get workspace profile settings for the profile for the current user"
},
{
"permissionName": "linked-data.profiles.settings.post",
"displayName": "Linked Data: Create or update the profile settings for the profile for the current user",
"description": "Create or update the profile settings for the profile for the current user"
"displayName": "Linked Data: Create profile settings for the profile for the current user",
"description": "Create profile settings for the profile for the current user"
},
{
"permissionName": "linked-data.profiles.settings.put",
"displayName": "Linked Data: Update workspace profile settings for the profile for the current user",
"description": "Update workspace profile settings for the profile for the current user"
},
{
"permissionName": "linked-data.profiles.settings.delete",
"displayName": "Linked Data: Delete profile settings for the profile for the current user",
"description": "Delete profile settings for the profile for the current user"
},
{
"permissionName": "linked-data.profiles.settings.preferred.get",
"displayName": "Linked Data: Get preferred workspace profile settings for the profile for the current user",
"description": "Get preferred workspace profile settings for the profile for the current user"
},
{
"permissionName": "linked-data.profiles.settings.preferred.post",
"displayName": "Linked Data: Create or update preferred profile settings for the profile for the current user",
"description": "Create or updated preferred profile settings for the profile for the current user"
},
{
"permissionName": "linked-data.profiles.settings.preferred.delete",
"displayName": "Linked Data: Delete preferred profile settings for the profile for the current user",
"description": "Delete preferred profile settings for the profile for the current user"
},
{
"permissionName": "linked-data.resources.rdf.get",
Expand Down
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<name>mod-linked-data</name>
<groupId>org.folio</groupId>
<artifactId>mod-linked-data</artifactId>
<version>2.0.3</version>
<version>2.0.4</version>
<packaging>jar</packaging>

<licenses>
Expand Down Expand Up @@ -686,6 +686,6 @@
<url>https://github.com/folio-org/${project.artifactId}</url>
<connection>scm:git:git://github.com/folio-org/${project.artifactId}.git</connection>
<developerConnection>scm:git:git@github.com:folio-org/${project.artifactId}.git</developerConnection>
<tag>v2.0.3</tag>
<tag>v2.0.4</tag>
</scm>
</project>
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
package org.folio.linked.data.controller;

import static org.springframework.http.HttpStatus.CREATED;

import jakarta.validation.ConstraintViolationException;
import jakarta.validation.Valid;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.folio.linked.data.domain.dto.CustomProfileSettingsMetadata;
import org.folio.linked.data.domain.dto.CustomProfileSettingsRequestDto;
import org.folio.linked.data.domain.dto.CustomProfileSettingsResponseDto;
import org.folio.linked.data.domain.dto.PreferredProfileRequest;
import org.folio.linked.data.domain.dto.PreferredProfileSettingsRequest;
import org.folio.linked.data.domain.dto.ProfileMetadata;
import org.folio.linked.data.model.CreateProfileSettingsRequest;
import org.folio.linked.data.rest.resource.ProfileApi;
import org.folio.linked.data.service.profile.PreferredProfileService;
import org.folio.linked.data.service.profile.PreferredProfileSettingsService;
import org.folio.linked.data.service.profile.ProfileService;
import org.folio.linked.data.service.profile.ProfileSettingsService;
import org.springframework.http.ResponseEntity;
Expand All @@ -20,6 +28,8 @@ public class ProfileController implements ProfileApi {
private final ProfileService profileService;
private final PreferredProfileService preferredProfileService;
private final ProfileSettingsService profileSettingsService;
private final PreferredProfileSettingsService preferredProfileSettingsService;
private final jakarta.validation.Validator validator;

@Override
public ResponseEntity<String> getProfileById(Integer profileId) {
Expand Down Expand Up @@ -49,15 +59,75 @@ public ResponseEntity<Void> deletePreferredProfile(String resourceTypeUri) {
}

@Override
public ResponseEntity<CustomProfileSettingsResponseDto> getProfileSettings(Integer profileId) {
return ResponseEntity.ok(profileSettingsService.getProfileSettings(profileId));
public ResponseEntity<List<CustomProfileSettingsMetadata>> getAllProfileSettings(Integer profileId) {
return ResponseEntity.ok(profileSettingsService.getAllProfileSettings(profileId));
}

@Override
public ResponseEntity<CustomProfileSettingsResponseDto> getProfileSettings(
Integer profileId,
Integer profileSettingsId
) {
return ResponseEntity.ok(profileSettingsService.getProfileSettings(profileId, profileSettingsId));
}

@Override
public ResponseEntity<CustomProfileSettingsMetadata> createProfileSettings(
Integer profileId,
@Valid CustomProfileSettingsRequestDto profileSettingsRequest) {
var wrappedRequest = new CreateProfileSettingsRequest(profileId, profileSettingsRequest);
validateCreateProfileSettingsRequest(wrappedRequest);

return ResponseEntity
.status(CREATED)
.body(profileSettingsService.createProfileSettings(profileId, profileSettingsRequest));
}

@Override
public ResponseEntity<Void> setProfileSettings(
Integer profileId,
Integer profileSettingsId,
CustomProfileSettingsRequestDto profileSettingsRequest) {
profileSettingsService.setProfileSettings(profileId, profileSettingsRequest);
profileSettingsService.setProfileSettings(profileId, profileSettingsId, profileSettingsRequest);
return ResponseEntity.noContent().build();
}

@Override
public ResponseEntity<Void> deleteProfileSettings(
Integer profileId,
Integer profileSettingsId
) {
profileSettingsService.deleteProfileSettings(profileId, profileSettingsId);
return ResponseEntity.noContent().build();
}

private void validateCreateProfileSettingsRequest(CreateProfileSettingsRequest request) {
var violations = validator.validate(request);
if (!violations.isEmpty()) {
throw new ConstraintViolationException(violations);
}
}

@Override
public ResponseEntity<List<CustomProfileSettingsMetadata>> getPreferredProfileSettings(Integer profileId) {
return ResponseEntity.ok(preferredProfileSettingsService.getPreferredProfileSettings(profileId));
}

@Override
public ResponseEntity<Void> setPreferredProfileSettings(
Integer profileId,
PreferredProfileSettingsRequest preferredProfileSettings
) {
preferredProfileSettingsService.setPreferredProfileSettings(
profileId,
preferredProfileSettings.getProfileSettingsId()
);
return ResponseEntity.noContent().build();
}

@Override
public ResponseEntity<Void> deletePreferredProfileSettings(Integer profileId) {
preferredProfileSettingsService.deletePreferredProfileSettings(profileId);
return ResponseEntity.noContent().build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.folio.linked.data.model;

import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.folio.linked.data.domain.dto.CustomProfileSettingsRequestDto;
import org.folio.linked.data.validation.ProfileSettingsNameUniqueConstraint;

@ProfileSettingsNameUniqueConstraint
@AllArgsConstructor
@Data
public class CreateProfileSettingsRequest {
@NotNull
private Integer profileId;

@NotNull
@Valid
private CustomProfileSettingsRequestDto customProfileSettingsRequestDto;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.folio.linked.data.model.entity;

import jakarta.persistence.EmbeddedId;
import jakarta.persistence.Entity;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.MapsId;
import jakarta.persistence.Table;
import lombok.Data;
import lombok.experimental.Accessors;
import org.folio.linked.data.model.entity.pk.PreferredProfileSettingsPk;

@Data
@Entity
@Table(name = "preferred_profile_settings")
@Accessors(chain = true)
public class PreferredProfileSettings {

@EmbeddedId
private PreferredProfileSettingsPk id;

@MapsId("profileId")
@ManyToOne
@JoinColumn(name = "profile_id", nullable = false)
private Profile profile;

@ManyToOne
@JoinColumn(name = "profile_settings_id", nullable = false)
private ProfileSettings profileSettings;
}
Original file line number Diff line number Diff line change
@@ -1,32 +1,54 @@
package org.folio.linked.data.model.entity;

import jakarta.persistence.Column;
import jakarta.persistence.EmbeddedId;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.MapsId;
import jakarta.persistence.SequenceGenerator;
import jakarta.persistence.Table;
import jakarta.persistence.UniqueConstraint;
import java.util.UUID;
import lombok.Data;
import lombok.experimental.Accessors;
import org.folio.linked.data.model.entity.pk.ProfileSettingsPk;
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.type.SqlTypes;

@Data
@Entity
@Table(name = "profile_settings")
@Table(
name = "profile_settings",
uniqueConstraints = {
@UniqueConstraint(
name = "unique_profile_settings_name",
columnNames = {"user_id", "profile_id", "name"}
)
}
)
@Accessors(chain = true)
public class ProfileSettings {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "profile_settings_id_seq_gen")
@SequenceGenerator(
name = "profile_settings_id_seq_gen",
sequenceName = "profile_settings_id_seq",
initialValue = 1,
allocationSize = 1
)
private Integer id;

@EmbeddedId
private ProfileSettingsPk id;
@Column(name = "user_id", nullable = false)
private UUID userId;

@MapsId("profileId")
@ManyToOne
@JoinColumn(name = "profile_id", nullable = false)
private Profile profile;

@Column(name = "name", nullable = false)
private String name;

@JdbcTypeCode(SqlTypes.JSON)
@Column(name = "settings", columnDefinition = "jsonb", nullable = false)
private String settings;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
@Embeddable
@NoArgsConstructor
@AllArgsConstructor
public class ProfileSettingsPk implements Serializable {
public class PreferredProfileSettingsPk implements Serializable {

@Column(name = "user_id", nullable = false)
private UUID userId;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.folio.linked.data.repo;

import java.util.List;
import java.util.UUID;
import org.folio.linked.data.model.entity.PreferredProfileSettings;
import org.folio.linked.data.model.entity.pk.PreferredProfileSettingsPk;
import org.springframework.data.repository.CrudRepository;

public interface PreferredProfileSettingsRepository
extends CrudRepository<PreferredProfileSettings, PreferredProfileSettingsPk> {
List<PreferredProfileSettings> findByIdUserIdAndIdProfileId(UUID userId, Integer profileId);
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
package org.folio.linked.data.repo;

import java.util.List;
import java.util.Optional;
import java.util.UUID;
import org.folio.linked.data.model.entity.ProfileSettings;
import org.folio.linked.data.model.entity.pk.ProfileSettingsPk;
import org.springframework.data.repository.CrudRepository;

public interface ProfileSettingsRepository extends CrudRepository<ProfileSettings, ProfileSettingsPk> {
Optional<ProfileSettings> getByIdUserIdAndIdProfileId(UUID userId, Integer profileId);
public interface ProfileSettingsRepository extends CrudRepository<ProfileSettings, Integer> {
List<ProfileSettings> findByUserIdAndProfileId(UUID userId, Integer profileId);

Optional<ProfileSettings> findByIdAndUserId(Integer id, UUID userId);

Boolean existsByUserIdAndProfileIdAndName(UUID userId, Integer profileId, String name);

void deleteByIdAndProfileIdAndUserId(Integer id, Integer profileId, UUID userId);
}
Loading
Loading