diff --git a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitsEventTypesApiController.php b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitsEventTypesApiController.php index d700c3a41..9693d5b76 100644 --- a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitsEventTypesApiController.php +++ b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitsEventTypesApiController.php @@ -33,11 +33,14 @@ use utils\OrderParser; use utils\PagingInfo; use utils\PagingResponse; +use OpenApi\Attributes as OA; +use Symfony\Component\HttpFoundation\Response; /** * Class OAuth2SummitsEventTypesApiController * @package App\Http\Controllers */ +#[OA\Tag(name: "Event Types", description: "Summit Event Types Management Endpoints")] final class OAuth2SummitsEventTypesApiController extends OAuth2ProtectedController { /** @@ -77,6 +80,81 @@ public function __construct * @param $summit_id * @return mixed */ + #[OA\Get( + path: "/api/v1/summits/{id}/event-types", + operationId: "getAllBySummit", + description: "Get all event types for a summit with pagination and filtering", + tags: ["Event Types"], + parameters: [ + new OA\Parameter( + name: "id", + in: "path", + required: true, + schema: new OA\Schema(type: "string"), + description: "Summit ID or slug" + ), + new OA\Parameter( + name: "page", + in: "query", + required: false, + schema: new OA\Schema(type: "integer", default: 1), + description: "Page number" + ), + new OA\Parameter( + name: "per_page", + in: "query", + required: false, + schema: new OA\Schema(type: "integer", default: 20), + description: "Items per page" + ), + new OA\Parameter( + name: "filter", + in: "query", + required: false, + schema: new OA\Schema(type: "string"), + description: "Filter by: name, class_name, is_default, black_out_times, use_sponsors, are_sponsors_mandatory, allows_attachment, use_speakers, are_speakers_mandatory, use_moderator, is_moderator_mandatory, should_be_available_on_cfp" + ), + new OA\Parameter( + name: "order", + in: "query", + required: false, + schema: new OA\Schema(type: "string"), + description: "Order by: id, name" + ), + new OA\Parameter( + name: "expand", + in: "query", + required: false, + schema: new OA\Schema(type: "string"), + description: "Expand relationships: summit, summit_documents, allowed_ticket_types" + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: "Event types retrieved successfully", + content: new OA\JsonContent( + allOf: [ + new OA\Schema(ref: "#/components/schemas/PaginateDataSchemaResponse"), + new OA\Schema( + type: "object", + properties: [ + new OA\Property( + property: "data", + type: "array", + items: new OA\Items(ref: "#/components/schemas/EventType") + ) + ] + ) + ] + ) + ), + new OA\Response(response: Response::HTTP_BAD_REQUEST, description: "Bad Request"), + new OA\Response(response: Response::HTTP_PRECONDITION_FAILED, description: "Validation Error"), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Summit not found"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error"), + ] + )] public function getAllBySummit($summit_id) { @@ -146,6 +224,60 @@ function ($page, $per_page, $filter, $order, $applyExtraFilters) use ($summit) { * @param $summit_id * @return mixed */ + #[OA\Get( + path: "/api/v1/summits/{id}/event-types/csv", + operationId: "getAllBySummitCSV", + description: "Export event types for a summit as CSV", + tags: ["Event Types"], + parameters: [ + new OA\Parameter( + name: "id", + in: "path", + required: true, + schema: new OA\Schema(type: "string"), + description: "Summit ID or slug" + ), + new OA\Parameter( + name: "page", + in: "query", + required: false, + schema: new OA\Schema(type: "integer", default: 1), + description: "Page number" + ), + new OA\Parameter( + name: "per_page", + in: "query", + required: false, + schema: new OA\Schema(type: "integer"), + description: "Items per page" + ), + new OA\Parameter( + name: "filter", + in: "query", + required: false, + schema: new OA\Schema(type: "string"), + description: "Filter criteria" + ), + new OA\Parameter( + name: "order", + in: "query", + required: false, + schema: new OA\Schema(type: "string"), + description: "Order by: id, name" + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: "CSV file exported successfully", + content: new OA\MediaType(mediaType: "text/csv") + ), + new OA\Response(response: Response::HTTP_BAD_REQUEST, description: "Bad Request"), + new OA\Response(response: Response::HTTP_PRECONDITION_FAILED, description: "Validation Error"), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Summit not found"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error"), + ] + )] public function getAllBySummitCSV($summit_id) { $values = Request::all(); @@ -272,6 +404,44 @@ public function getAllBySummitCSV($summit_id) * @param $event_type_id * @return mixed */ + #[OA\Get( + path: "/api/v1/summits/{id}/event-types/{event_type_id}", + operationId: "getEventTypeBySummit", + description: "Get a specific event type by ID", + tags: ["Event Types"], + parameters: [ + new OA\Parameter( + name: "id", + in: "path", + required: true, + schema: new OA\Schema(type: "string"), + description: "Summit ID or slug" + ), + new OA\Parameter( + name: "event_type_id", + in: "path", + required: true, + schema: new OA\Schema(type: "integer", format: "int64"), + description: "Event type ID" + ), + new OA\Parameter( + name: "expand", + in: "query", + required: false, + schema: new OA\Schema(type: "string"), + description: "Expand relationships" + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: "Event type retrieved successfully", + content: new OA\JsonContent(ref: "#/components/schemas/EventType") + ), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Event type or summit not found"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error"), + ] + )] public function getEventTypeBySummit($summit_id, $event_type_id) { return $this->processRequest(function () use ($summit_id, $event_type_id) { @@ -297,6 +467,116 @@ public function getEventTypeBySummit($summit_id, $event_type_id) * @param $summit_id * @return mixed */ + #[OA\Post( + path: "/api/v1/summits/{id}/event-types", + operationId: "addEventTypeBySummit", + description: "Create a new event type", + tags: ["Event Types"], + parameters: [ + new OA\Parameter( + name: "id", + in: "path", + required: true, + schema: new OA\Schema(type: "string"), + description: "Summit ID or slug" + ), + ], + requestBody: new OA\RequestBody( + required: true, + content: new OA\JsonContent( + type: "object", + required: ["name", "class_name"], + properties: [ + new OA\Property( + property: "name", + type: "string", + maxLength: 255, + description: "Event type name", + example: "Presentation" + ), + new OA\Property( + property: "class_name", + type: "string", + enum: ["Presentation", "Lightning Talk", "Workshop", "Keynote", "Panel"], + description: "Event class type", + example: "Presentation" + ), + new OA\Property( + property: "color", + type: "string", + description: "Display color (hex)", + example: "#FF5733" + ), + new OA\Property( + property: "black_out_times", + type: "string", + enum: ["UNLIMITED", "ONLY_MAIN_EVENTS", "BLACKOUT_TIMES"], + description: "Blackout times setting", + example: "UNLIMITED" + ), + new OA\Property( + property: "use_sponsors", + type: "boolean", + description: "Whether event type uses sponsors", + example: false + ), + new OA\Property( + property: "are_sponsors_mandatory", + type: "boolean", + description: "Whether sponsors are mandatory", + example: false + ), + new OA\Property( + property: "allows_attachment", + type: "boolean", + description: "Whether attachments are allowed", + example: true + ), + new OA\Property( + property: "use_speakers", + type: "boolean", + description: "Whether event type uses speakers", + example: true + ), + new OA\Property( + property: "are_speakers_mandatory", + type: "boolean", + description: "Whether speakers are mandatory", + example: true + ), + new OA\Property( + property: "use_moderator", + type: "boolean", + description: "Whether event type uses moderators", + example: false + ), + new OA\Property( + property: "is_moderator_mandatory", + type: "boolean", + description: "Whether moderator is mandatory", + example: false + ), + new OA\Property( + property: "should_be_available_on_cfp", + type: "boolean", + description: "Whether available on Call for Proposals", + example: true + ), + ] + ) + ), + responses: [ + new OA\Response( + response: Response::HTTP_CREATED, + description: "Event type created successfully", + content: new OA\JsonContent(ref: "#/components/schemas/EventType") + ), + new OA\Response(response: Response::HTTP_BAD_REQUEST, description: "Bad Request"), + new OA\Response(response: Response::HTTP_PRECONDITION_FAILED, description: "Validation Error"), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Summit not found"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error"), + ] + )] public function addEventTypeBySummit($summit_id) { return $this->processRequest(function () use ($summit_id) { @@ -321,6 +601,59 @@ public function addEventTypeBySummit($summit_id) * @param $event_type_id * @return mixed */ + #[OA\Put( + path: "/api/v1/summits/{id}/event-types/{event_type_id}", + operationId: "updateEventTypeBySummit", + description: "Update an existing event type", + tags: ["Event Types"], + parameters: [ + new OA\Parameter( + name: "id", + in: "path", + required: true, + schema: new OA\Schema(type: "string"), + description: "Summit ID or slug" + ), + new OA\Parameter( + name: "event_type_id", + in: "path", + required: true, + schema: new OA\Schema(type: "integer", format: "int64"), + description: "Event type ID" + ), + ], + requestBody: new OA\RequestBody( + required: true, + content: new OA\JsonContent( + type: "object", + properties: [ + new OA\Property(property: "name", type: "string"), + new OA\Property(property: "class_name", type: "string"), + new OA\Property(property: "color", type: "string"), + new OA\Property(property: "black_out_times", type: "string"), + new OA\Property(property: "use_sponsors", type: "boolean"), + new OA\Property(property: "are_sponsors_mandatory", type: "boolean"), + new OA\Property(property: "allows_attachment", type: "boolean"), + new OA\Property(property: "use_speakers", type: "boolean"), + new OA\Property(property: "are_speakers_mandatory", type: "boolean"), + new OA\Property(property: "use_moderator", type: "boolean"), + new OA\Property(property: "is_moderator_mandatory", type: "boolean"), + new OA\Property(property: "should_be_available_on_cfp", type: "boolean"), + ] + ) + ), + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: "Event type updated successfully", + content: new OA\JsonContent(ref: "#/components/schemas/EventType") + ), + new OA\Response(response: Response::HTTP_BAD_REQUEST, description: "Bad Request"), + new OA\Response(response: Response::HTTP_PRECONDITION_FAILED, description: "Validation Error"), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Event type or summit not found"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error"), + ] + )] public function updateEventTypeBySummit($summit_id, $event_type_id) { return $this->processRequest(function () use ($summit_id, $event_type_id) { @@ -345,6 +678,37 @@ public function updateEventTypeBySummit($summit_id, $event_type_id) * @param $event_type_id * @return mixed */ + #[OA\Delete( + path: "/api/v1/summits/{id}/event-types/{event_type_id}", + operationId: "deleteEventTypeBySummit", + description: "Delete an event type", + tags: ["Event Types"], + parameters: [ + new OA\Parameter( + name: "id", + in: "path", + required: true, + schema: new OA\Schema(type: "string"), + description: "Summit ID or slug" + ), + new OA\Parameter( + name: "event_type_id", + in: "path", + required: true, + schema: new OA\Schema(type: "integer", format: "int64"), + description: "Event type ID" + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_NO_CONTENT, + description: "Event type deleted successfully" + ), + new OA\Response(response: Response::HTTP_PRECONDITION_FAILED, description: "Validation Error"), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Event type or summit not found"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error"), + ] + )] public function deleteEventTypeBySummit($summit_id, $event_type_id) { return $this->processRequest(function () use ($summit_id, $event_type_id) { @@ -362,6 +726,45 @@ public function deleteEventTypeBySummit($summit_id, $event_type_id) * @param $summit_id * @return mixed */ + #[OA\Post( + path: "/api/v1/summits/{id}/event-types/seed-defaults", + operationId: "seedDefaultEventTypesBySummit", + description: "Seed default event types for a summit", + tags: ["Event Types"], + parameters: [ + new OA\Parameter( + name: "id", + in: "path", + required: true, + schema: new OA\Schema(type: "string"), + description: "Summit ID or slug" + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_CREATED, + description: "Default event types seeded successfully", + content: new OA\JsonContent( + allOf: [ + new OA\Schema(ref: "#/components/schemas/PaginateDataSchemaResponse"), + new OA\Schema( + type: "object", + properties: [ + new OA\Property( + property: "data", + type: "array", + items: new OA\Items(ref: "#/components/schemas/EventType") + ) + ] + ) + ] + ) + ), + new OA\Response(response: Response::HTTP_PRECONDITION_FAILED, description: "Validation Error"), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Summit not found"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error"), + ] + )] public function seedDefaultEventTypesBySummit($summit_id) { return $this->processRequest(function () use ($summit_id) { @@ -390,6 +793,44 @@ public function seedDefaultEventTypesBySummit($summit_id) * @param $document_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Post( + path: "/api/v1/summits/{id}/event-types/{event_type_id}/summit-documents/{document_id}", + operationId: "addSummitDocument", + description: "Add a document to an event type", + tags: ["Event Types"], + parameters: [ + new OA\Parameter( + name: "id", + in: "path", + required: true, + schema: new OA\Schema(type: "string"), + description: "Summit ID or slug" + ), + new OA\Parameter( + name: "event_type_id", + in: "path", + required: true, + schema: new OA\Schema(type: "integer", format: "int64"), + description: "Event type ID" + ), + new OA\Parameter( + name: "document_id", + in: "path", + required: true, + schema: new OA\Schema(type: "integer", format: "int64"), + description: "Document ID" + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: "Document added to event type successfully", + content: new OA\JsonContent(ref: "#/components/schemas/EventType") + ), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Event type, summit or document not found"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error"), + ] + )] public function addSummitDocument($summit_id, $event_type_id, $document_id) { return $this->processRequest(function () use ($summit_id, $event_type_id, $document_id) { @@ -419,6 +860,44 @@ public function addSummitDocument($summit_id, $event_type_id, $document_id) * @param $document_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Delete( + path: "/api/v1/summits/{id}/event-types/{event_type_id}/summit-documents/{document_id}", + operationId: "removeSummitDocument", + description: "Remove a document from an event type", + tags: ["Event Types"], + parameters: [ + new OA\Parameter( + name: "id", + in: "path", + required: true, + schema: new OA\Schema(type: "string"), + description: "Summit ID or slug" + ), + new OA\Parameter( + name: "event_type_id", + in: "path", + required: true, + schema: new OA\Schema(type: "integer", format: "int64"), + description: "Event type ID" + ), + new OA\Parameter( + name: "document_id", + in: "path", + required: true, + schema: new OA\Schema(type: "integer", format: "int64"), + description: "Document ID" + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: "Document removed from event type successfully", + content: new OA\JsonContent(ref: "#/components/schemas/EventType") + ), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Event type, summit or document not found"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error"), + ] + )] public function removeSummitDocument($summit_id, $event_type_id, $document_id) { return $this->processRequest(function () use ($summit_id, $event_type_id, $document_id) { diff --git a/app/Swagger/EventTypeSchemas.php b/app/Swagger/EventTypeSchemas.php new file mode 100644 index 000000000..a4ce105e5 --- /dev/null +++ b/app/Swagger/EventTypeSchemas.php @@ -0,0 +1,121 @@ +