diff --git a/app/Http/Controllers/Apis/Protected/Main/OAuth2TagsApiController.php b/app/Http/Controllers/Apis/Protected/Main/OAuth2TagsApiController.php index 2e1f1f2a9..4da5c92a5 100644 --- a/app/Http/Controllers/Apis/Protected/Main/OAuth2TagsApiController.php +++ b/app/Http/Controllers/Apis/Protected/Main/OAuth2TagsApiController.php @@ -1,4 +1,7 @@ -tag_service = $tag_service; } + #[OA\Get( + path: "/api/v1/tags", + operationId: "getAllTags", + summary: "Get all tags", + description: "Returns a paginated list of tags. Allows ordering, filtering and pagination.", + tags: ["Tags"], + security: [ + [ + 'tags_oauth2' => [ + SummitScopes::ReadAllSummitData, + SummitScopes::ReadSummitData, + SummitScopes::ReadTagsData, + ] + ] + ], + parameters: [ + new OA\Parameter( + name: 'page', + in: 'query', + required: false, + schema: new OA\Schema(type: 'integer'), + description: 'The page number' + ), + new OA\Parameter( + name: 'per_page', + in: 'query', + required: false, + schema: new OA\Schema(type: 'integer'), + description: 'The number of pages in each page', + ), + new OA\Parameter( + name: "filter[]", + in: "query", + required: false, + description: "Filter tags. Available filters: tag (=@, ==, @@)", + schema: new OA\Schema(type: "array", items: new OA\Items(type: "string")), + explode: true + ), + new OA\Parameter( + name: "order", + in: "query", + required: false, + description: "Order by field. Valid fields: id, tag", + schema: new OA\Schema(type: "string") + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: "Success", + content: new OA\JsonContent(ref: "#/components/schemas/PaginatedTagsResponse") + ), + new OA\Response(response: Response::HTTP_BAD_REQUEST, description: "Bad Request"), + ] + )] public function getAll(){ return $this->_getAll( function () { @@ -88,6 +150,60 @@ function () { ); } + #[OA\Get( + path: "/api/v1/tags/{id}", + operationId: "getTag", + summary: "Get a specific tag", + description: "Returns detailed information about a specific tag", + tags: ["Tags"], + security: [ + [ + 'tags_oauth2' => [ + SummitScopes::ReadAllSummitData, + SummitScopes::ReadSummitData, + SummitScopes::ReadTagsData, + ] + ] + ], + parameters: [ + new OA\Parameter( + name: "id", + in: "path", + required: true, + description: "Tag ID", + schema: new OA\Schema(type: "integer") + ), + new OA\Parameter( + name: "expand", + in: "query", + required: false, + description: "Expand related entities", + schema: new OA\Schema(type: "string") + ), + new OA\Parameter( + name: "fields", + in: "query", + required: false, + description: "Fields to include in response", + schema: new OA\Schema(type: "string") + ), + new OA\Parameter( + name: "relations", + in: "query", + required: false, + description: "Relations to include", + schema: new OA\Schema(type: "string") + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: "Success", + content: new OA\JsonContent(ref: "#/components/schemas/Tag") + ), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Tag not found"), + ] + )] public function getTag($tag_id){ return $this->processRequest(function () use ($tag_id) { $tag = $this->repository->getById(intval($tag_id)); @@ -104,6 +220,43 @@ public function getTag($tag_id){ }); } + #[OA\Post( + path: "/api/v1/tags", + operationId: "createTag", + summary: "Create a new tag", + description: "Creates a new tag", + tags: ["Tags"], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + ] + ], + security: [ + [ + 'tags_oauth2' => [ + SummitScopes::WriteSummitData, + SummitScopes::WriteTagsData, + ] + ] + ], + requestBody: new OA\RequestBody( + required: true, + content: new OA\JsonContent(ref: "#/components/schemas/TagRequest") + ), + responses: [ + new OA\Response( + response: Response::HTTP_CREATED, + description: "Created", + content: new OA\JsonContent(ref: "#/components/schemas/Tag") + ), + new OA\Response(response: Response::HTTP_BAD_REQUEST, description: "Bad Request"), + new OA\Response(response: Response::HTTP_UNAUTHORIZED, description: "Unauthorized"), + new OA\Response(response: Response::HTTP_FORBIDDEN, description: "Forbidden"), + new OA\Response(response: Response::HTTP_PRECONDITION_FAILED, description: "Validation Error"), + ] + )] public function addTag(){ return $this->processRequest(function () { if(!Request::isJson()) return $this->error400(); @@ -134,6 +287,53 @@ public function addTag(){ }); } + #[OA\Put( + path: "/api/v1/tags/{id}", + operationId: "updateTag", + summary: "Update a tag", + description: "Updates an existing tag", + tags: ["Tags"], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + ] + ], + security: [ + [ + 'tags_oauth2' => [ + SummitScopes::WriteSummitData, + SummitScopes::WriteTagsData, + ] + ] + ], + parameters: [ + new OA\Parameter( + name: "id", + in: "path", + required: true, + description: "Tag ID", + schema: new OA\Schema(type: "integer") + ), + ], + requestBody: new OA\RequestBody( + required: true, + content: new OA\JsonContent(ref: "#/components/schemas/TagRequest") + ), + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: "Success", + content: new OA\JsonContent(ref: "#/components/schemas/Tag") + ), + new OA\Response(response: Response::HTTP_BAD_REQUEST, description: "Bad Request"), + new OA\Response(response: Response::HTTP_UNAUTHORIZED, description: "Unauthorized"), + new OA\Response(response: Response::HTTP_FORBIDDEN, description: "Forbidden"), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Tag not found"), + new OA\Response(response: Response::HTTP_PRECONDITION_FAILED, description: "Validation Error"), + ] + )] public function updateTag($tag_id){ return $this->processRequest(function () use ($tag_id) { if(!Request::isJson()) return $this->error400(); @@ -166,6 +366,43 @@ public function updateTag($tag_id){ }); } + #[OA\Delete( + path: "/api/v1/tags/{id}", + operationId: "deleteTag", + summary: "Delete a tag", + description: "Deletes a tag", + tags: ["Tags"], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + ] + ], + security: [ + [ + 'tags_oauth2' => [ + SummitScopes::WriteSummitData, + SummitScopes::WriteTagsData, + ] + ] + ], + parameters: [ + new OA\Parameter( + name: "id", + in: "path", + required: true, + description: "Tag ID", + schema: new OA\Schema(type: "integer") + ), + ], + responses: [ + new OA\Response(response: Response::HTTP_NO_CONTENT, description: "Deleted successfully"), + new OA\Response(response: Response::HTTP_UNAUTHORIZED, description: "Unauthorized"), + new OA\Response(response: Response::HTTP_FORBIDDEN, description: "Forbidden"), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Tag not found"), + ] + )] public function deleteTag($tag_id){ return $this->processRequest(function () use ($tag_id) { @@ -174,4 +411,4 @@ public function deleteTag($tag_id){ return $this->deleted(); }); } -} \ No newline at end of file +} diff --git a/app/Swagger/Models/TagSchema.php b/app/Swagger/Models/TagSchema.php index 3166becf0..9022b364c 100644 --- a/app/Swagger/Models/TagSchema.php +++ b/app/Swagger/Models/TagSchema.php @@ -9,19 +9,10 @@ type: "object", required: ["id", "tag"], properties: [ - new OA\Property( - property: "id", - type: "integer", - format: "int64", - description: "Tag ID", - example: 1 - ), - new OA\Property( - property: "tag", - type: "string", - description: "Tag name/value", - example: "Beginner" - ), + new OA\Property(property: "id", type: "integer", example: 1), + new OA\Property(property: "created", type: "integer", format: "int64", description: "Creation timestamp (epoch)", example: 1234567890), + new OA\Property(property: "last_edited", type: "integer", format: "int64", description: "Last edit timestamp (epoch)", example: 1234567890), + new OA\Property(property: "tag", type: "string", maxLength: 100, example: "Cloud Computing"), ] )] class TagSchema {} diff --git a/app/Swagger/Security/TagsAuthSchema.php b/app/Swagger/Security/TagsAuthSchema.php new file mode 100644 index 000000000..d6cade4c3 --- /dev/null +++ b/app/Swagger/Security/TagsAuthSchema.php @@ -0,0 +1,27 @@ + 'Read All Summit Data', + SummitScopes::ReadSummitData => 'Read Summit Data', + SummitScopes::ReadTagsData => 'Read Tags Data', + SummitScopes::WriteSummitData => 'Write Summit Data', + SummitScopes::WriteTagsData => 'Write Tags Data', + ], + ), + ], + ) +] +class TagsAuthSchema {} diff --git a/app/Swagger/schemas.php b/app/Swagger/schemas.php index b940875b5..2ff72f38e 100644 --- a/app/Swagger/schemas.php +++ b/app/Swagger/schemas.php @@ -469,6 +469,41 @@ class ChunkedFileUploadRequestSchema { } +// Tag Schemas + +#[OA\Schema( + schema: "PaginatedTagsResponse", + description: "Paginated response for Tags", + properties: [ + new OA\Property(property: "total", type: "integer", example: 100), + new OA\Property(property: "per_page", type: "integer", example: 15), + new OA\Property(property: "current_page", type: "integer", example: 1), + new OA\Property(property: "last_page", type: "integer", example: 7), + new OA\Property( + property: "data", + type: "array", + items: new OA\Items(ref: "#/components/schemas/Tag") + ), + ], + type: "object" +)] +class PaginatedTagsResponseSchema +{ +} + +#[OA\Schema( + schema: "TagRequest", + description: "Request to create or update a Tag", + required: ["tag"], + properties: [ + new OA\Property(property: "tag", type: "string", maxLength: 100, example: "Cloud Computing"), + ], + type: "object" +)] +class TagRequestSchema +{ +} + #[OA\Schema( schema: 'PaginatedOrganizationsResponse', allOf: [ @@ -598,4 +633,6 @@ class PaymentGatewayProfileUpdateRequestSchema ) ] )] -class PaginatedUserStoriesResponseSchema {} +class PaginatedUserStoriesResponseSchema +{ +} \ No newline at end of file