From 36ba1b6a83184c764a30fc6a605088efa2f43589 Mon Sep 17 00:00:00 2001 From: DualFroz Date: Wed, 26 Aug 2026 10:00:45 +0200 Subject: [PATCH] feat: add resource group REST endpoints --- .../resource/ResourceGroupController.java | 60 +++++++++++++++++++ .../resource/dto/ResourceGroupRequest.java | 9 +++ .../resource/dto/ResourceGroupResponse.java | 13 ++++ 3 files changed, 82 insertions(+) create mode 100644 src/main/java/com/slotline/resource/ResourceGroupController.java create mode 100644 src/main/java/com/slotline/resource/dto/ResourceGroupRequest.java create mode 100644 src/main/java/com/slotline/resource/dto/ResourceGroupResponse.java diff --git a/src/main/java/com/slotline/resource/ResourceGroupController.java b/src/main/java/com/slotline/resource/ResourceGroupController.java new file mode 100644 index 0000000..dd31551 --- /dev/null +++ b/src/main/java/com/slotline/resource/ResourceGroupController.java @@ -0,0 +1,60 @@ +package com.slotline.resource; + +import com.slotline.resource.dto.ResourceGroupRequest; +import com.slotline.resource.dto.ResourceGroupResponse; +import com.slotline.resource.dto.ResourceResponse; +import com.slotline.security.AuthenticatedUser; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import org.springframework.http.HttpStatus; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RestController +@RequestMapping("/api/resource-groups") +@Tag(name = "Resource groups") +public class ResourceGroupController { + + private final ResourceGroupService groupService; + + public ResourceGroupController(ResourceGroupService groupService) { + this.groupService = groupService; + } + + @GetMapping + @Operation(summary = "List resource groups in the caller's organization") + public List list(@AuthenticationPrincipal AuthenticatedUser actor) { + return groupService.findAll(actor.organizationId()); + } + + @PostMapping + @ResponseStatus(HttpStatus.CREATED) + @Operation(summary = "Create a resource group, optionally nested (ADMIN only)") + public ResourceGroupResponse create(@AuthenticationPrincipal AuthenticatedUser actor, + @Valid @RequestBody ResourceGroupRequest request) { + return groupService.create(actor.organizationId(), request); + } + + @PostMapping("/{groupId}/resources/{resourceId}") + @Operation(summary = "Assign a resource to a group (ADMIN only)") + public ResourceResponse assign(@AuthenticationPrincipal AuthenticatedUser actor, @PathVariable Long groupId, + @PathVariable Long resourceId) { + return groupService.assignResource(actor.organizationId(), groupId, resourceId); + } + + @GetMapping("/{groupId}/resources") + @Operation(summary = "List resources directly assigned to a group") + public List resources(@AuthenticationPrincipal AuthenticatedUser actor, + @PathVariable Long groupId) { + return groupService.resourcesInGroup(actor.organizationId(), groupId); + } +} diff --git a/src/main/java/com/slotline/resource/dto/ResourceGroupRequest.java b/src/main/java/com/slotline/resource/dto/ResourceGroupRequest.java new file mode 100644 index 0000000..091ed6c --- /dev/null +++ b/src/main/java/com/slotline/resource/dto/ResourceGroupRequest.java @@ -0,0 +1,9 @@ +package com.slotline.resource.dto; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; + +public record ResourceGroupRequest( + @NotBlank @Size(max = 128) String name, + Long parentGroupId) { +} diff --git a/src/main/java/com/slotline/resource/dto/ResourceGroupResponse.java b/src/main/java/com/slotline/resource/dto/ResourceGroupResponse.java new file mode 100644 index 0000000..324ba00 --- /dev/null +++ b/src/main/java/com/slotline/resource/dto/ResourceGroupResponse.java @@ -0,0 +1,13 @@ +package com.slotline.resource.dto; + +import com.slotline.resource.ResourceGroup; + +import java.time.Instant; + +public record ResourceGroupResponse(Long id, String name, Long parentGroupId, Instant createdAt) { + + public static ResourceGroupResponse from(ResourceGroup group) { + return new ResourceGroupResponse(group.getId(), group.getName(), group.getParentGroupId(), + group.getCreatedAt()); + } +}