feat: add resource group REST endpoints

This commit is contained in:
dualfroz committed 2026-08-26 10:00:45 +02:00
1 parent aa96be9550
commit 36ba1b6a83
3 files changed
+82

No files matched your search

@@ -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<ResourceGroupResponse> 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<ResourceResponse> resources(@AuthenticationPrincipal AuthenticatedUser actor,
@PathVariable Long groupId) {
return groupService.resourcesInGroup(actor.organizationId(), groupId);
}
}
@@ -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) {
}
@@ -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());
}
}