From df8b0c4c7a6fa45add09a39a8716e0803ae3c372 Mon Sep 17 00:00:00 2001 From: Matias Perrone Date: Tue, 14 Oct 2025 15:19:33 -0300 Subject: [PATCH 1/4] feat: Extend Swagger Coverage for controller `OAuth2SummitSubmissionInvitationApiController` --- ...ummitSubmissionInvitationApiController.php | 420 ++++++++++++++++-- app/Swagger/SummitSpeakersSchemas.php | 127 ++++++ 2 files changed, 517 insertions(+), 30 deletions(-) diff --git a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitSubmissionInvitationApiController.php b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitSubmissionInvitationApiController.php index c1016741b..3503f32c1 100644 --- a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitSubmissionInvitationApiController.php +++ b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitSubmissionInvitationApiController.php @@ -1,4 +1,7 @@ -service = $service; } - /** - * @param LaravelRequest $request - * @param $summit_id - * @return \Illuminate\Http\JsonResponse|mixed - */ + #[OA\Post( + path: "/api/v1/summits/{id}/submission-invitations/csv", + description: "Import submission invitations from CSV file", + summary: "Import submission invitations from CSV", + operationId: "ingestSummitSubmissionInvitations", + tags: ['Summit Submission Invitations'], + security: [['summit_oauth2' => []]], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + schema: new OA\Schema(type: 'integer'), + description: 'The summit id' + ) + ], + requestBody: new OA\RequestBody( + required: true, + content: new OA\MediaType( + mediaType: 'multipart/form-data', + schema: new OA\Schema( + type: 'object', + required: ['file'], + properties: [ + new OA\Property( + property: 'file', + type: 'string', + format: 'binary', + description: 'CSV file to import' + ) + ] + ) + ) + ), + responses: [ + new OA\Response(response: 200, description: 'Success'), + 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: "not found"), + new OA\Response(response: Response::HTTP_PRECONDITION_FAILED, description: "Validation Error"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error") + ] + )] public function ingestInvitations(LaravelRequest $request, $summit_id) { return $this->processRequest(function () use ($request, $summit_id) { @@ -94,11 +155,6 @@ public function ingestInvitations(LaravelRequest $request, $summit_id) }); } - // traits - use ParametrizedGetAll; - - use GetSummitChildElementById; - /** * @return ISummitRepository */ @@ -115,10 +171,77 @@ protected function getChildFromSummit(Summit $summit, $child_id): ?IEntity return $summit->getSubmissionInvitationById($child_id); } - /** - * @param $summit_id - * @return mixed - */ + #[OA\Get( + path: "/api/v1/summits/{id}/submission-invitations", + description: "Get all submission invitations for a summit", + summary: "Get all submission invitations", + operationId: "getAllSummitSubmissionInvitations", + tags: ['Summit Submission Invitations'], + security: [['summit_oauth2' => []]], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + schema: new OA\Schema(type: 'integer'), + description: 'The summit id' + ), + 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: 10), + description: 'Items per page' + ), + new OA\Parameter( + name: 'filter', + in: 'query', + required: false, + schema: new OA\Schema(type: 'string'), + description: 'Filter expression (e.g., email=@john,is_sent==true)' + ), + new OA\Parameter( + name: 'order', + in: 'query', + required: false, + schema: new OA\Schema(type: 'string'), + description: 'Order by field (e.g., +id, -email)' + ), + new OA\Parameter( + name: 'expand', + in: 'query', + required: false, + schema: new OA\Schema(type: 'string'), + description: 'Expand relationships (tags)' + ), + new OA\Parameter( + name: 'relations', + in: 'query', + required: false, + schema: new OA\Schema(type: 'string'), + description: 'Relations to include (tags)' + ) + ], + responses: [ + new OA\Response( + response: 200, + description: 'Success', + content: new OA\JsonContent(ref: '#/components/schemas/PaginatedSummitSubmissionInvitationsResponse') + ), + 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: "not found"), + new OA\Response(response: Response::HTTP_PRECONDITION_FAILED, description: "Validation Error"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error") + ] + )] public function getAllBySummit($summit_id) { @@ -169,10 +292,59 @@ function () { ); } - /** - * @param $summit_id - * @return mixed - */ + #[OA\Get( + path: "/api/v1/summits/{id}/submission-invitations/csv", + description: "Get all submission invitations for a summit in CSV format", + summary: "Get all submission invitations (CSV)", + operationId: "getAllSummitSubmissionInvitationsCSV", + tags: ['Summit Submission Invitations'], + security: [['summit_oauth2' => []]], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + schema: new OA\Schema(type: 'integer'), + description: 'The summit id' + ), + new OA\Parameter( + name: 'filter', + in: 'query', + required: false, + schema: new OA\Schema(type: 'string'), + description: 'Filter expression' + ), + new OA\Parameter( + name: 'order', + in: 'query', + required: false, + schema: new OA\Schema(type: 'string'), + description: 'Order by field' + ), + new OA\Parameter( + name: 'columns', + in: 'query', + required: false, + schema: new OA\Schema(type: 'string'), + description: 'Comma-separated list of columns to include' + ) + ], + responses: [ + new OA\Response( + response: 200, + description: 'Success', + content: new OA\MediaType( + mediaType: 'text/csv', + schema: new OA\Schema(type: 'string', format: 'binary') + ) + ), + 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: "not found"), + new OA\Response(response: Response::HTTP_PRECONDITION_FAILED, description: "Validation Error"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error") + ] + )] public function getAllBySummitCSV($summit_id) { @@ -255,9 +427,6 @@ function () { ); } - - use DeleteSummitChildElement; - /** * @inheritDoc */ @@ -266,8 +435,6 @@ protected function deleteChild(Summit $summit, $child_id): void $this->service->delete($summit, $child_id); } - use AddSummitChildElement; - /** * @inheritDoc */ @@ -284,8 +451,6 @@ function getAddValidationRules(array $payload): array return SummitSubmissionInvitationValidationRulesFactory::buildForAdd($payload); } - use UpdateSummitChildElement; - /** * @inheritDoc */ @@ -302,10 +467,205 @@ protected function updateChild(Summit $summit, int $child_id, array $payload): I return $this->service->update($summit, $child_id, $payload); } - /** - * @param $summit_id - * @return \Illuminate\Http\JsonResponse|mixed - */ + #[OA\Get( + path: "/api/v1/summits/{id}/submission-invitations/{invitation_id}", + description: "Get a specific submission invitation by id", + summary: "Get submission invitation", + operationId: "getSummitSubmissionInvitation", + tags: ['Summit Submission Invitations'], + security: [['summit_oauth2' => []]], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + schema: new OA\Schema(type: 'integer'), + description: 'The summit id' + ), + new OA\Parameter( + name: 'invitation_id', + in: 'path', + required: true, + schema: new OA\Schema(type: 'integer'), + description: 'The invitation id' + ), + new OA\Parameter( + name: 'expand', + in: 'query', + required: false, + schema: new OA\Schema(type: 'string'), + description: 'Expand relationships (tags)' + ), + new OA\Parameter( + name: 'relations', + in: 'query', + required: false, + schema: new OA\Schema(type: 'string'), + description: 'Relations to include (tags)' + ) + ], + responses: [ + new OA\Response( + response: 200, + description: 'Success', + content: new OA\JsonContent(ref: '#/components/schemas/SummitSubmissionInvitation') + ), + 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: "not found"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error") + ] + )] + public function get($summit_id, $invitation_id) + { + return $this->traitGet($summit_id, $invitation_id); + } + + #[OA\Post( + path: "/api/v1/summits/{id}/submission-invitations", + description: "Create a new submission invitation", + summary: "Create submission invitation", + operationId: "createSummitSubmissionInvitation", + tags: ['Summit Submission Invitations'], + security: [['summit_oauth2' => []]], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + schema: new OA\Schema(type: 'integer'), + description: 'The summit id' + ) + ], + requestBody: new OA\RequestBody( + required: true, + content: new OA\JsonContent(ref: '#/components/schemas/SummitSubmissionInvitationCreateRequest') + ), + responses: [ + new OA\Response( + response: 201, + description: 'Created', + content: new OA\JsonContent(ref: '#/components/schemas/SummitSubmissionInvitation') + ), + 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: "not found"), + new OA\Response(response: Response::HTTP_PRECONDITION_FAILED, description: "Validation Error"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error") + ] + )] + public function add($summit_id) + { + return $this->traitAdd($summit_id); + } + + #[OA\Put( + path: "/api/v1/summits/{id}/submission-invitations/{invitation_id}", + description: "Update an existing submission invitation", + summary: "Update submission invitation", + operationId: "updateSummitSubmissionInvitation", + tags: ['Summit Submission Invitations'], + security: [['summit_oauth2' => []]], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + schema: new OA\Schema(type: 'integer'), + description: 'The summit id' + ), + new OA\Parameter( + name: 'invitation_id', + in: 'path', + required: true, + schema: new OA\Schema(type: 'integer'), + description: 'The invitation id' + ) + ], + requestBody: new OA\RequestBody( + required: true, + content: new OA\JsonContent(ref: '#/components/schemas/SummitSubmissionInvitationUpdateRequest') + ), + responses: [ + new OA\Response( + response: 200, + description: 'Success', + content: new OA\JsonContent(ref: '#/components/schemas/SummitSubmissionInvitation') + ), + 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: "not found"), + new OA\Response(response: Response::HTTP_PRECONDITION_FAILED, description: "Validation Error"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error") + ] + )] + public function update($summit_id, $invitation_id) + { + return $this->traitUpdate($summit_id, $invitation_id); + } + + #[OA\Delete( + path: "/api/v1/summits/{id}/submission-invitations/{invitation_id}", + description: "Delete a submission invitation", + summary: "Delete submission invitation", + operationId: "deleteSummitSubmissionInvitation", + tags: ['Summit Submission Invitations'], + security: [['summit_oauth2' => []]], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + schema: new OA\Schema(type: 'integer'), + description: 'The summit id' + ), + new OA\Parameter( + name: 'invitation_id', + in: 'path', + required: true, + schema: new OA\Schema(type: 'integer'), + description: 'The invitation id' + ) + ], + responses: [ + new OA\Response(response: 204, description: 'No Content'), + 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: "not found"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error") + ] + )] + public function delete($summit_id, $invitation_id) + { + return $this->traitDelete($summit_id, $invitation_id); + } + + #[OA\Delete( + path: "/api/v1/summits/{id}/submission-invitations/all", + description: "Delete all submission invitations for a summit", + summary: "Delete all submission invitations", + operationId: "deleteAllSummitSubmissionInvitations", + tags: ['Summit Submission Invitations'], + security: [['summit_oauth2' => []]], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + schema: new OA\Schema(type: 'integer'), + description: 'The summit id' + ) + ], + responses: [ + new OA\Response(response: 204, description: 'No Content'), + 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: "not found"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error") + ] + )] public function deleteAll($summit_id) { return $this->processRequest(function () use ($summit_id) { diff --git a/app/Swagger/SummitSpeakersSchemas.php b/app/Swagger/SummitSpeakersSchemas.php index 5a1a0deac..650d24777 100644 --- a/app/Swagger/SummitSpeakersSchemas.php +++ b/app/Swagger/SummitSpeakersSchemas.php @@ -2,8 +2,135 @@ namespace App\Swagger\schemas; +use App\Jobs\Emails\PresentationSubmissions\Invitations\InviteSubmissionEmail; +use App\Jobs\Emails\PresentationSubmissions\Invitations\ReInviteSubmissionEmail; use OpenApi\Attributes as OA; +#[OA\Schema( + schema: 'SummitSubmissionInvitation', + type: 'object', + properties: [ + new OA\Property(property: 'id', type: 'integer', example: 1), + new OA\Property(property: 'created', type: 'integer', description: 'Unix timestamp', example: 1640995200), + new OA\Property(property: 'last_edited', type: 'integer', description: 'Unix timestamp', example: 1640995200), + new OA\Property(property: 'email', type: 'string', format: 'email', example: 'speaker@example.com'), + new OA\Property(property: 'first_name', type: 'string', example: 'John'), + new OA\Property(property: 'last_name', type: 'string', example: 'Doe'), + new OA\Property(property: 'summit_id', type: 'integer', example: 1), + new OA\Property(property: 'is_sent', type: 'boolean', example: false), + new OA\Property(property: 'sent_date', type: 'integer', description: 'Unix timestamp', example: 1640995200, nullable: true), + new OA\Property( + property: 'tags', + type: 'array', + items: new OA\Items(type: 'integer'), + example: [1, 2, 3] + ) + ] +)] +class SummitSubmissionInvitationSchema {} + +#[OA\Schema( + schema: 'PaginatedSummitSubmissionInvitationsResponse', + 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/SummitSubmissionInvitation') + ) + ] + ) + ] +)] +class PaginatedSummitSubmissionInvitationsResponseSchema {} + +#[OA\Schema( + schema: 'SummitSubmissionInvitationCSV', + type: 'object', + properties: [ + new OA\Property(property: 'id', type: 'integer', example: 1), + new OA\Property(property: 'email', type: 'string', format: 'email', example: 'speaker@example.com'), + new OA\Property(property: 'first_name', type: 'string', example: 'John'), + new OA\Property(property: 'last_name', type: 'string', example: 'Doe'), + new OA\Property(property: 'speaker_id', type: 'integer', nullable: true, example: 123), + new OA\Property(property: 'summit_id', type: 'integer', example: 1), + new OA\Property(property: 'is_sent', type: 'boolean', example: false), + new OA\Property(property: 'sent_date', type: 'integer', description: 'Unix timestamp', nullable: true, example: 1640995200), + new OA\Property(property: 'tags', type: 'string', example: 'tag1,tag2,tag3') + ] +)] +class SummitSubmissionInvitationCSVSchema {} + +#[OA\Schema( + schema: 'SummitSubmissionInvitationCreateRequest', + type: 'object', + required: ['email', 'first_name', 'last_name'], + properties: [ + new OA\Property(property: 'email', type: 'string', format: 'email', example: 'speaker@example.com'), + new OA\Property(property: 'first_name', type: 'string', example: 'John'), + new OA\Property(property: 'last_name', type: 'string', example: 'Doe'), + new OA\Property( + property: 'tags', + type: 'array', + items: new OA\Items(type: 'string'), + example: ['tag1', 'tag2'], + nullable: true + ) + ] +)] +class SummitSubmissionInvitationCreateRequestSchema {} + +#[OA\Schema( + schema: 'SummitSubmissionInvitationUpdateRequest', + type: 'object', + properties: [ + new OA\Property(property: 'email', type: 'string', format: 'email', example: 'speaker@example.com', nullable: true), + new OA\Property(property: 'first_name', type: 'string', example: 'John', nullable: true), + new OA\Property(property: 'last_name', type: 'string', example: 'Doe', nullable: true), + new OA\Property( + property: 'tags', + type: 'array', + items: new OA\Items(type: 'string'), + example: ['tag1', 'tag2'], + nullable: true + ) + ] +)] +class SummitSubmissionInvitationUpdateRequestSchema {} + +#[OA\Schema( + schema: 'SendSummitSubmissionInvitationsRequest', + type: 'object', + required: ['email_flow_event'], + properties: [ + new OA\Property( + property: 'email_flow_event', + type: 'string', + enum: [InviteSubmissionEmail::EVENT_SLUG, ReInviteSubmissionEmail::EVENT_SLUG], + example: InviteSubmissionEmail::EVENT_SLUG + ), + new OA\Property(property: 'selection_plan_id', type: 'integer', example: 1, nullable: true), + new OA\Property( + property: 'invitations_ids', + type: 'array', + items: new OA\Items(type: 'integer'), + example: [1, 2, 3], + nullable: true + ), + new OA\Property( + property: 'excluded_invitations_ids', + type: 'array', + items: new OA\Items(type: 'integer'), + example: [4, 5], + nullable: true + ) + ] +)] +class SendSummitSubmissionInvitationsRequestSchema {} + // #[OA\Schema( From 8cc6c3f043c344ddcaa66796fec5b330d009369e Mon Sep 17 00:00:00 2001 From: Matias Perrone Date: Wed, 26 Nov 2025 16:19:31 +0000 Subject: [PATCH 2/4] chore: Add the correct security and x attributes and fix path with the correct routes --- ...ummitSubmissionInvitationApiController.php | 197 ++++++++++++++++-- .../SummitSubmissionInvitationsAuthSchema.php | 27 +++ app/Swagger/SummitSpeakersSchemas.php | 7 +- 3 files changed, 212 insertions(+), 19 deletions(-) create mode 100644 app/Swagger/Security/SummitSubmissionInvitationsAuthSchema.php diff --git a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitSubmissionInvitationApiController.php b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitSubmissionInvitationApiController.php index 3503f32c1..580db21be 100644 --- a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitSubmissionInvitationApiController.php +++ b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitSubmissionInvitationApiController.php @@ -19,7 +19,9 @@ use App\Http\Utils\EpochCellFormatter; use App\Jobs\Emails\PresentationSubmissions\Invitations\InviteSubmissionEmail; use App\Jobs\Emails\PresentationSubmissions\Invitations\ReInviteSubmissionEmail; +use App\Models\Foundation\Main\IGroup; use App\Models\Foundation\Summit\Repositories\ISummitSubmissionInvitationRepository; +use App\Security\SummitScopes; use App\Services\Model\ISummitSubmissionInvitationService; use Illuminate\Http\Request as LaravelRequest; use Illuminate\Http\Response; @@ -95,11 +97,22 @@ public function __construct #[OA\Post( path: "/api/v1/summits/{id}/submission-invitations/csv", - description: "Import submission invitations from CSV file", + description: "Import submission invitations from CSV file - required-groups " . IGroup::SummitAdministrators . ", " . IGroup::SuperAdmins . ", " . IGroup::Administrators . ", " . IGroup::SummitRegistrationAdmins, summary: "Import submission invitations from CSV", operationId: "ingestSummitSubmissionInvitations", tags: ['Summit Submission Invitations'], - security: [['summit_oauth2' => []]], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + IGroup::SummitRegistrationAdmins + ] + ], + security: [['summit_submission_invitations_oauth2' => [ + SummitScopes::WriteSummitData, + SummitScopes::WriteSubmissionInvitations, + ]]], parameters: [ new OA\Parameter( name: 'id', @@ -173,11 +186,22 @@ protected function getChildFromSummit(Summit $summit, $child_id): ?IEntity #[OA\Get( path: "/api/v1/summits/{id}/submission-invitations", - description: "Get all submission invitations for a summit", + description: "Get all submission invitations for a summit - required-groups " . IGroup::SummitAdministrators . ", " . IGroup::SuperAdmins . ", " . IGroup::Administrators . ", " . IGroup::SummitRegistrationAdmins, summary: "Get all submission invitations", operationId: "getAllSummitSubmissionInvitations", tags: ['Summit Submission Invitations'], - security: [['summit_oauth2' => []]], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + IGroup::SummitRegistrationAdmins + ] + ], + security: [['summit_submission_invitations_oauth2' => [ + SummitScopes::ReadAllSummitData, + SummitScopes::ReadSubmissionInvitations, + ]]], parameters: [ new OA\Parameter( name: 'id', @@ -294,11 +318,22 @@ function () { #[OA\Get( path: "/api/v1/summits/{id}/submission-invitations/csv", - description: "Get all submission invitations for a summit in CSV format", + description: "Get all submission invitations for a summit in CSV format - required-groups " . IGroup::SummitAdministrators . ", " . IGroup::SuperAdmins . ", " . IGroup::Administrators . ", " . IGroup::SummitRegistrationAdmins, summary: "Get all submission invitations (CSV)", operationId: "getAllSummitSubmissionInvitationsCSV", tags: ['Summit Submission Invitations'], - security: [['summit_oauth2' => []]], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + IGroup::SummitRegistrationAdmins + ] + ], + security: [['summit_submission_invitations_oauth2' => [ + SummitScopes::ReadAllSummitData, + SummitScopes::ReadSubmissionInvitations, + ]]], parameters: [ new OA\Parameter( name: 'id', @@ -469,11 +504,22 @@ protected function updateChild(Summit $summit, int $child_id, array $payload): I #[OA\Get( path: "/api/v1/summits/{id}/submission-invitations/{invitation_id}", - description: "Get a specific submission invitation by id", + description: "Get a specific submission invitation by id - required-groups " . IGroup::SummitAdministrators . ", " . IGroup::SuperAdmins . ", " . IGroup::Administrators . ", " . IGroup::SummitRegistrationAdmins, summary: "Get submission invitation", operationId: "getSummitSubmissionInvitation", tags: ['Summit Submission Invitations'], - security: [['summit_oauth2' => []]], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + IGroup::SummitRegistrationAdmins + ] + ], + security: [['summit_submission_invitations_oauth2' => [ + SummitScopes::ReadAllSummitData, + SummitScopes::ReadSubmissionInvitations, + ]]], parameters: [ new OA\Parameter( name: 'id', @@ -523,11 +569,22 @@ public function get($summit_id, $invitation_id) #[OA\Post( path: "/api/v1/summits/{id}/submission-invitations", - description: "Create a new submission invitation", + description: "Create a new submission invitation - required-groups " . IGroup::SummitAdministrators . ", " . IGroup::SuperAdmins . ", " . IGroup::Administrators . ", " . IGroup::SummitRegistrationAdmins, summary: "Create submission invitation", operationId: "createSummitSubmissionInvitation", tags: ['Summit Submission Invitations'], - security: [['summit_oauth2' => []]], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + IGroup::SummitRegistrationAdmins + ] + ], + security: [['summit_submission_invitations_oauth2' => [ + SummitScopes::WriteSummitData, + SummitScopes::WriteSubmissionInvitations, + ]]], parameters: [ new OA\Parameter( name: 'id', @@ -562,11 +619,22 @@ public function add($summit_id) #[OA\Put( path: "/api/v1/summits/{id}/submission-invitations/{invitation_id}", - description: "Update an existing submission invitation", + description: "Update an existing submission invitation - required-groups " . IGroup::SummitAdministrators . ", " . IGroup::SuperAdmins . ", " . IGroup::Administrators . ", " . IGroup::SummitRegistrationAdmins, summary: "Update submission invitation", operationId: "updateSummitSubmissionInvitation", tags: ['Summit Submission Invitations'], - security: [['summit_oauth2' => []]], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + IGroup::SummitRegistrationAdmins + ] + ], + security: [['summit_submission_invitations_oauth2' => [ + SummitScopes::WriteSummitData, + SummitScopes::WriteSubmissionInvitations, + ]]], parameters: [ new OA\Parameter( name: 'id', @@ -608,11 +676,22 @@ public function update($summit_id, $invitation_id) #[OA\Delete( path: "/api/v1/summits/{id}/submission-invitations/{invitation_id}", - description: "Delete a submission invitation", + description: "Delete a submission invitation - required-groups " . IGroup::SummitAdministrators . ", " . IGroup::SuperAdmins . ", " . IGroup::Administrators . ", " . IGroup::SummitRegistrationAdmins, summary: "Delete submission invitation", operationId: "deleteSummitSubmissionInvitation", tags: ['Summit Submission Invitations'], - security: [['summit_oauth2' => []]], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + IGroup::SummitRegistrationAdmins + ] + ], + security: [['summit_submission_invitations_oauth2' => [ + SummitScopes::WriteSummitData, + SummitScopes::WriteSubmissionInvitations, + ]]], parameters: [ new OA\Parameter( name: 'id', @@ -644,11 +723,22 @@ public function delete($summit_id, $invitation_id) #[OA\Delete( path: "/api/v1/summits/{id}/submission-invitations/all", - description: "Delete all submission invitations for a summit", + description: "Delete all submission invitations for a summit - required-groups " . IGroup::SummitAdministrators . ", " . IGroup::SuperAdmins . ", " . IGroup::Administrators . ", " . IGroup::SummitRegistrationAdmins, summary: "Delete all submission invitations", operationId: "deleteAllSummitSubmissionInvitations", tags: ['Summit Submission Invitations'], - security: [['summit_oauth2' => []]], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + IGroup::SummitRegistrationAdmins + ] + ], + security: [['summit_submission_invitations_oauth2' => [ + SummitScopes::WriteSummitData, + SummitScopes::WriteSubmissionInvitations, + ]]], parameters: [ new OA\Parameter( name: 'id', @@ -681,6 +771,81 @@ public function deleteAll($summit_id) * @param $summit_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Put( + path: "/api/v1/summits/{id}/submission-invitations/all/send", + description: "Send submission invitations to selected recipients - required-groups " . IGroup::SummitAdministrators . ", " . IGroup::SuperAdmins . ", " . IGroup::Administrators . ", " . IGroup::SummitRegistrationAdmins, + summary: "Send submission invitations", + operationId: "sendSummitSubmissionInvitations", + tags: ['Summit Submission Invitations'], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + IGroup::SummitRegistrationAdmins + ] + ], + security: [['summit_submission_invitations_oauth2' => [ + SummitScopes::WriteSummitData, + SummitScopes::WriteSubmissionInvitations, + ]]], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + schema: new OA\Schema(type: 'integer'), + description: 'The summit id' + ), + new OA\Parameter( + name: 'filter', + in: 'query', + required: false, + schema: new OA\Schema(type: 'string'), + description: 'Filter expression to select invitations' + ) + ], + requestBody: new OA\RequestBody( + required: true, + content: new OA\JsonContent( + required: ['email_flow_event'], + properties: [ + new OA\Property( + property: 'email_flow_event', + type: 'string', + enum: ['SUMMIT_SUBMISSIONS_INVITE_SUBMISSION', 'SUMMIT_SUBMISSIONS_REINVITE_SUBMISSION'], + description: 'Email flow event type' + ), + new OA\Property( + property: 'selection_plan_id', + type: 'integer', + description: 'Selection plan ID' + ), + new OA\Property( + property: 'invitations_ids', + type: 'array', + items: new OA\Items(type: 'integer'), + description: 'Array of invitation IDs to send' + ), + new OA\Property( + property: 'excluded_invitations_ids', + type: 'array', + items: new OA\Items(type: 'integer'), + description: 'Array of invitation IDs to exclude' + ) + ] + ) + ), + responses: [ + new OA\Response(response: 200, description: 'Success'), + 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: "not found"), + new OA\Response(response: Response::HTTP_PRECONDITION_FAILED, description: "Validation Error"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error") + ] + )] public function send($summit_id) { return $this->processRequest(function () use ($summit_id) { diff --git a/app/Swagger/Security/SummitSubmissionInvitationsAuthSchema.php b/app/Swagger/Security/SummitSubmissionInvitationsAuthSchema.php new file mode 100644 index 000000000..e110026d3 --- /dev/null +++ b/app/Swagger/Security/SummitSubmissionInvitationsAuthSchema.php @@ -0,0 +1,27 @@ + 'Read All Summit Data', + SummitScopes::WriteSummitData => 'Write Summit Data', + SummitScopes::ReadSubmissionInvitations => 'Read Submission Invitations', + SummitScopes::WriteSubmissionInvitations => 'Write Submission Invitations', + ], + ), + ], + ) +] +class SummitSubmissionInvitationsAuthSchema{} diff --git a/app/Swagger/SummitSpeakersSchemas.php b/app/Swagger/SummitSpeakersSchemas.php index 650d24777..db9769e87 100644 --- a/app/Swagger/SummitSpeakersSchemas.php +++ b/app/Swagger/SummitSpeakersSchemas.php @@ -16,14 +16,15 @@ new OA\Property(property: 'email', type: 'string', format: 'email', example: 'speaker@example.com'), new OA\Property(property: 'first_name', type: 'string', example: 'John'), new OA\Property(property: 'last_name', type: 'string', example: 'Doe'), - new OA\Property(property: 'summit_id', type: 'integer', example: 1), + new OA\Property(property: 'summit_id', type: 'integer', example: 1, description: 'Summit ID'), new OA\Property(property: 'is_sent', type: 'boolean', example: false), new OA\Property(property: 'sent_date', type: 'integer', description: 'Unix timestamp', example: 1640995200, nullable: true), new OA\Property( property: 'tags', type: 'array', - items: new OA\Items(type: 'integer'), - example: [1, 2, 3] + items: new OA\Items(type: ['integer', 'string']), + example: [1, 2, 3], + description: 'Array of Tag IDs or names (when expanded) associated with the invitation', ) ] )] From 770d7d2affeecdaa89aef3d3d24767426fab6af4 Mon Sep 17 00:00:00 2001 From: Matias Perrone Date: Wed, 3 Dec 2025 19:51:19 +0000 Subject: [PATCH 3/4] feat: Add changes requested --- app/Swagger/Security/SummitSubmissionInvitationsAuthSchema.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Swagger/Security/SummitSubmissionInvitationsAuthSchema.php b/app/Swagger/Security/SummitSubmissionInvitationsAuthSchema.php index e110026d3..6e6e6b9db 100644 --- a/app/Swagger/Security/SummitSubmissionInvitationsAuthSchema.php +++ b/app/Swagger/Security/SummitSubmissionInvitationsAuthSchema.php @@ -1,6 +1,6 @@ Date: Thu, 4 Dec 2025 20:40:33 +0000 Subject: [PATCH 4/4] feat: Add changes requested in PR --- .env.example | 14 +++ ...ummitSubmissionInvitationApiController.php | 108 ++++++++++++------ .../SummitSubmissionInvitationSchema.php | 29 +++++ app/Swagger/SummitSpeakersSchemas.php | 26 +---- 4 files changed, 116 insertions(+), 61 deletions(-) create mode 100644 app/Swagger/Models/SummitSubmissionInvitationSchema.php diff --git a/.env.example b/.env.example index 0331f9628..a117d6925 100644 --- a/.env.example +++ b/.env.example @@ -265,3 +265,17 @@ PAYMENTS_SERVICE_BASE_URL= PAYMENTS_SERVICE_OAUTH2_CLIENT_ID= PAYMENTS_SERVICE_OAUTH2_CLIENT_SECRET= PAYMENTS_SERVICE_OAUTH2_SCOPES=payment-profile/read + + +# L5_FORMAT_TO_USE_FOR_DOCS=yaml +# L5_SWAGGER_GENERATE_ALWAYS=true # Dev setting +# L5_SWAGGER_GENERATE_YAML_COPY=true +# L5_SWAGGER_UI_DARK_MODE=true + +# Apply a sort to the operation list of each API. It can be 'alpha' (sort by paths alphanumerically), 'method' (sort by HTTP method). Default is the order returned by the server unchanged. +# L5_SWAGGER_OPERATIONS_SORT= +# Controls the default expansion setting for the operations and tags. It can be: 'list' (expands only the tags), 'full' (expands the tags and operations), 'none' (expands nothing -default-). +# L5_SWAGGER_UI_DOC_EXPANSION=none +# L5_SWAGGER_UI_FILTERS=false # Show/Hide filters. default true +# L5_SWAGGER_UI_PERSIST_AUTHORIZATION=false # If set to true, it persists authorization data, and it would not be lost on browser close/refresh +L5_SWAGGER_OPEN_API_SPEC_VERSION=3.1.0 diff --git a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitSubmissionInvitationApiController.php b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitSubmissionInvitationApiController.php index 580db21be..983495e7a 100644 --- a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitSubmissionInvitationApiController.php +++ b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitSubmissionInvitationApiController.php @@ -109,10 +109,14 @@ public function __construct IGroup::SummitRegistrationAdmins ] ], - security: [['summit_submission_invitations_oauth2' => [ - SummitScopes::WriteSummitData, - SummitScopes::WriteSubmissionInvitations, - ]]], + security: [ + [ + 'summit_submission_invitations_oauth2' => [ + SummitScopes::WriteSummitData, + SummitScopes::WriteSubmissionInvitations, + ] + ] + ], parameters: [ new OA\Parameter( name: 'id', @@ -198,10 +202,14 @@ protected function getChildFromSummit(Summit $summit, $child_id): ?IEntity IGroup::SummitRegistrationAdmins ] ], - security: [['summit_submission_invitations_oauth2' => [ - SummitScopes::ReadAllSummitData, - SummitScopes::ReadSubmissionInvitations, - ]]], + security: [ + [ + 'summit_submission_invitations_oauth2' => [ + SummitScopes::ReadAllSummitData, + SummitScopes::ReadSubmissionInvitations, + ] + ] + ], parameters: [ new OA\Parameter( name: 'id', @@ -330,10 +338,14 @@ function () { IGroup::SummitRegistrationAdmins ] ], - security: [['summit_submission_invitations_oauth2' => [ - SummitScopes::ReadAllSummitData, - SummitScopes::ReadSubmissionInvitations, - ]]], + security: [ + [ + 'summit_submission_invitations_oauth2' => [ + SummitScopes::ReadAllSummitData, + SummitScopes::ReadSubmissionInvitations, + ] + ] + ], parameters: [ new OA\Parameter( name: 'id', @@ -516,10 +528,14 @@ protected function updateChild(Summit $summit, int $child_id, array $payload): I IGroup::SummitRegistrationAdmins ] ], - security: [['summit_submission_invitations_oauth2' => [ - SummitScopes::ReadAllSummitData, - SummitScopes::ReadSubmissionInvitations, - ]]], + security: [ + [ + 'summit_submission_invitations_oauth2' => [ + SummitScopes::ReadAllSummitData, + SummitScopes::ReadSubmissionInvitations, + ] + ] + ], parameters: [ new OA\Parameter( name: 'id', @@ -581,10 +597,14 @@ public function get($summit_id, $invitation_id) IGroup::SummitRegistrationAdmins ] ], - security: [['summit_submission_invitations_oauth2' => [ - SummitScopes::WriteSummitData, - SummitScopes::WriteSubmissionInvitations, - ]]], + security: [ + [ + 'summit_submission_invitations_oauth2' => [ + SummitScopes::WriteSummitData, + SummitScopes::WriteSubmissionInvitations, + ] + ] + ], parameters: [ new OA\Parameter( name: 'id', @@ -631,10 +651,14 @@ public function add($summit_id) IGroup::SummitRegistrationAdmins ] ], - security: [['summit_submission_invitations_oauth2' => [ - SummitScopes::WriteSummitData, - SummitScopes::WriteSubmissionInvitations, - ]]], + security: [ + [ + 'summit_submission_invitations_oauth2' => [ + SummitScopes::WriteSummitData, + SummitScopes::WriteSubmissionInvitations, + ] + ] + ], parameters: [ new OA\Parameter( name: 'id', @@ -688,10 +712,14 @@ public function update($summit_id, $invitation_id) IGroup::SummitRegistrationAdmins ] ], - security: [['summit_submission_invitations_oauth2' => [ - SummitScopes::WriteSummitData, - SummitScopes::WriteSubmissionInvitations, - ]]], + security: [ + [ + 'summit_submission_invitations_oauth2' => [ + SummitScopes::WriteSummitData, + SummitScopes::WriteSubmissionInvitations, + ] + ] + ], parameters: [ new OA\Parameter( name: 'id', @@ -735,10 +763,14 @@ public function delete($summit_id, $invitation_id) IGroup::SummitRegistrationAdmins ] ], - security: [['summit_submission_invitations_oauth2' => [ - SummitScopes::WriteSummitData, - SummitScopes::WriteSubmissionInvitations, - ]]], + security: [ + [ + 'summit_submission_invitations_oauth2' => [ + SummitScopes::WriteSummitData, + SummitScopes::WriteSubmissionInvitations, + ] + ] + ], parameters: [ new OA\Parameter( name: 'id', @@ -785,10 +817,14 @@ public function deleteAll($summit_id) IGroup::SummitRegistrationAdmins ] ], - security: [['summit_submission_invitations_oauth2' => [ - SummitScopes::WriteSummitData, - SummitScopes::WriteSubmissionInvitations, - ]]], + security: [ + [ + 'summit_submission_invitations_oauth2' => [ + SummitScopes::WriteSummitData, + SummitScopes::WriteSubmissionInvitations, + ] + ] + ], parameters: [ new OA\Parameter( name: 'id', diff --git a/app/Swagger/Models/SummitSubmissionInvitationSchema.php b/app/Swagger/Models/SummitSubmissionInvitationSchema.php new file mode 100644 index 000000000..fbd2704c2 --- /dev/null +++ b/app/Swagger/Models/SummitSubmissionInvitationSchema.php @@ -0,0 +1,29 @@ +