From 2f63a9a4fd74306ae10b8e224340ab72f3615e60 Mon Sep 17 00:00:00 2001 From: DualFroz Date: Tue, 25 Aug 2026 16:36:04 +0200 Subject: [PATCH] feat: add organization REST endpoints --- .../organization/OrganizationController.java | 41 +++++++++++++++++++ .../organization/dto/OrganizationRequest.java | 11 +++++ .../dto/OrganizationResponse.java | 13 ++++++ 3 files changed, 65 insertions(+) create mode 100644 src/main/java/com/slotline/organization/OrganizationController.java create mode 100644 src/main/java/com/slotline/organization/dto/OrganizationRequest.java create mode 100644 src/main/java/com/slotline/organization/dto/OrganizationResponse.java diff --git a/src/main/java/com/slotline/organization/OrganizationController.java b/src/main/java/com/slotline/organization/OrganizationController.java new file mode 100644 index 0000000..8ab0cf0 --- /dev/null +++ b/src/main/java/com/slotline/organization/OrganizationController.java @@ -0,0 +1,41 @@ +package com.slotline.organization; + +import com.slotline.organization.dto.OrganizationRequest; +import com.slotline.organization.dto.OrganizationResponse; +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.web.bind.annotation.GetMapping; +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/organizations") +@Tag(name = "Organizations") +public class OrganizationController { + + private final OrganizationService organizationService; + + public OrganizationController(OrganizationService organizationService) { + this.organizationService = organizationService; + } + + @GetMapping + @Operation(summary = "List tenants (ADMIN only)") + public List list() { + return organizationService.findAll(); + } + + @PostMapping + @ResponseStatus(HttpStatus.CREATED) + @Operation(summary = "Provision a new tenant (ADMIN only)") + public OrganizationResponse create(@Valid @RequestBody OrganizationRequest request) { + return organizationService.create(request); + } +} diff --git a/src/main/java/com/slotline/organization/dto/OrganizationRequest.java b/src/main/java/com/slotline/organization/dto/OrganizationRequest.java new file mode 100644 index 0000000..c7dcf78 --- /dev/null +++ b/src/main/java/com/slotline/organization/dto/OrganizationRequest.java @@ -0,0 +1,11 @@ +package com.slotline.organization.dto; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; + +public record OrganizationRequest( + @NotBlank @Size(max = 128) String name, + @NotBlank @Size(min = 2, max = 64) @Pattern(regexp = "[a-z0-9-]+", + message = "slug must be lowercase letters, digits or hyphens") String slug) { +} diff --git a/src/main/java/com/slotline/organization/dto/OrganizationResponse.java b/src/main/java/com/slotline/organization/dto/OrganizationResponse.java new file mode 100644 index 0000000..fc6cec9 --- /dev/null +++ b/src/main/java/com/slotline/organization/dto/OrganizationResponse.java @@ -0,0 +1,13 @@ +package com.slotline.organization.dto; + +import com.slotline.organization.Organization; + +import java.time.Instant; + +public record OrganizationResponse(Long id, String name, String slug, Instant createdAt) { + + public static OrganizationResponse from(Organization organization) { + return new OrganizationResponse(organization.getId(), organization.getName(), organization.getSlug(), + organization.getCreatedAt()); + } +}