diff --git a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitSelectionPlansApiController.php b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitSelectionPlansApiController.php index 8ca51eba7..1d122030e 100644 --- a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitSelectionPlansApiController.php +++ b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitSelectionPlansApiController.php @@ -13,6 +13,10 @@ **/ use App\Http\Utils\EpochCellFormatter; +use App\Models\Foundation\Main\IGroup; +use App\Security\SummitScopes; +use OpenApi\Attributes as OA; +use Symfony\Component\HttpFoundation\Response; use App\Models\Foundation\Summit\Repositories\IPresentationActionTypeRepository; use App\Models\Foundation\Summit\Repositories\ISelectionPlanRepository; use App\Models\Foundation\Summit\Repositories\ISummitCategoryChangeRepository; @@ -122,6 +126,67 @@ public function __construct * @param $selection_plan_id * @return mixed */ + #[OA\Get( + path: '/api/v1/summits/{id}/selection-plans/{selection_plan_id}', + operationId: 'getSelectionPlan', + summary: 'Get a selection plan by ID', + description: 'Retrieves a specific selection plan for a summit by its ID.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::ReadAllSummitData, + SummitScopes::ReadSummitData, + ]] + ], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'selection_plan_id', + in: 'path', + required: true, + description: 'Selection Plan ID', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'expand', + in: 'query', + required: false, + description: 'Expand relationships to include as full objects: track_groups, extra_questions, event_types, track_chair_rating_types, allowed_presentation_action_types, allowed_presentation_action_types, allowed_presentation_questions, allowed_presentation_editable_questions, summit', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'fields', + in: 'query', + required: false, + description: 'Fields to return (comma-separated)', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'relations', + in: 'query', + required: false, + description: 'Relations to include: track_groups, extra_questions, event_types, track_chair_rating_types, allowed_presentation_action_types, allowed_presentation_action_types, allowed_presentation_questions, allowed_presentation_editable_questions', + schema: new OA\Schema(type: 'string') + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: 'Selection plan retrieved successfully', + content: new OA\JsonContent(ref: '#/components/schemas/SelectionPlan') + ), + 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: 'Summit or Selection Plan not found'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function getSelectionPlan($summit_id, $selection_plan_id) { return $this->processRequest(function () use ($summit_id, $selection_plan_id) { @@ -146,6 +211,80 @@ public function getSelectionPlan($summit_id, $selection_plan_id) * @param $selection_plan_id * @return mixed */ + #[OA\Put( + path: '/api/v1/summits/{id}/selection-plans/{selection_plan_id}', + operationId: 'updateSelectionPlan', + summary: 'Update a selection plan', + description: 'Updates an existing selection plan for a summit.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::WriteSummitData, + ]] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + ] + ], + requestBody: new OA\RequestBody( + description: 'Selection plan data', + required: true, + content: new OA\JsonContent(ref: '#/components/schemas/UpdateSelectionPlanPayload') + ), + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'selection_plan_id', + in: 'path', + required: true, + description: 'Selection Plan ID', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'expand', + in: 'query', + required: false, + description: 'Expand relationships to include as full objects: track_groups, extra_questions, event_types, track_chair_rating_types, allowed_presentation_action_types, allowed_presentation_action_types, allowed_presentation_questions, allowed_presentation_editable_questions, summit', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'fields', + in: 'query', + required: false, + description: 'Fields to return (comma-separated)', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'relations', + in: 'query', + required: false, + description: 'Relations to include: track_groups, extra_questions, event_types, track_chair_rating_types, allowed_presentation_action_types, allowed_presentation_action_types, allowed_presentation_questions, allowed_presentation_editable_questions', + schema: new OA\Schema(type: 'string') + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: 'Selection plan updated successfully', + content: new OA\JsonContent(ref: '#/components/schemas/SelectionPlan') + ), + 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: 'Summit or Selection Plan not found'), + new OA\Response(response: Response::HTTP_UNPROCESSABLE_ENTITY, description: 'Validation Error'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function updateSelectionPlan($summit_id, $selection_plan_id) { return $this->processRequest(function () use ($summit_id, $selection_plan_id) { @@ -172,6 +311,73 @@ public function updateSelectionPlan($summit_id, $selection_plan_id) * @param $summit_id * @return mixed */ + #[OA\Post( + path: '/api/v1/summits/{id}/selection-plans', + operationId: 'addSelectionPlan', + summary: 'Create a new selection plan', + description: 'Creates a new selection plan for a summit.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::WriteSummitData, + ]] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + ] + ], + requestBody: new OA\RequestBody( + description: 'Selection plan data', + required: true, + content: new OA\JsonContent(ref: '#/components/schemas/AddSelectionPlanPayload') + ), + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'expand', + in: 'query', + required: false, + description: 'Expand relationships to include as full objects: track_groups, extra_questions, event_types, track_chair_rating_types, allowed_presentation_action_types, allowed_presentation_action_types, allowed_presentation_questions, allowed_presentation_editable_questions, summit', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'fields', + in: 'query', + required: false, + description: 'Fields to return (comma-separated)', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'relations', + in: 'query', + required: false, + description: 'Relations to include: track_groups, extra_questions, event_types, track_chair_rating_types, allowed_presentation_action_types, allowed_presentation_action_types, allowed_presentation_questions, allowed_presentation_editable_questions', + schema: new OA\Schema(type: 'string') + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_CREATED, + description: 'Selection plan created successfully', + content: new OA\JsonContent(ref: '#/components/schemas/SelectionPlan') + ), + 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: 'Summit not found'), + new OA\Response(response: Response::HTTP_UNPROCESSABLE_ENTITY, description: 'Validation Error'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function addSelectionPlan($summit_id) { return $this->processRequest(function () use ($summit_id) { @@ -200,6 +406,48 @@ public function addSelectionPlan($summit_id) * @param $selection_plan_id * @return mixed */ + #[OA\Delete( + path: '/api/v1/summits/{id}/selection-plans/{selection_plan_id}', + operationId: 'deleteSelectionPlan', + summary: 'Delete a selection plan', + description: 'Deletes an existing selection plan from a summit.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::WriteSummitData, + ]] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + ] + ], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'selection_plan_id', + in: 'path', + required: true, + description: 'Selection Plan ID', + schema: new OA\Schema(type: 'integer') + ), + ], + responses: [ + new OA\Response(response: Response::HTTP_NO_CONTENT, description: 'Selection plan 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: 'Summit or Selection Plan not found'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function deleteSelectionPlan($summit_id, $selection_plan_id) { return $this->processRequest(function () use ($summit_id, $selection_plan_id) { @@ -219,6 +467,55 @@ public function deleteSelectionPlan($summit_id, $selection_plan_id) * @param $track_group_id * @return mixed */ + #[OA\Put( + path: '/api/v1/summits/{id}/selection-plans/{selection_plan_id}/track-groups/{track_group_id}', + operationId: 'addTrackGroupToSelectionPlan', + summary: 'Add a track group to a selection plan', + description: 'Associates a track group with a selection plan.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::WriteSummitData, + ]] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + ] + ], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'selection_plan_id', + in: 'path', + required: true, + description: 'Selection Plan ID', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'track_group_id', + in: 'path', + required: true, + description: 'Track Group ID', + schema: new OA\Schema(type: 'integer') + ), + ], + responses: [ + new OA\Response(response: Response::HTTP_OK, description: 'Track group added 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: 'Summit, Selection Plan, or Track Group not found'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function addTrackGroupToSelectionPlan($summit_id, $selection_plan_id, $track_group_id) { return $this->processRequest(function () use ($summit_id, $selection_plan_id, $track_group_id) { @@ -238,6 +535,55 @@ public function addTrackGroupToSelectionPlan($summit_id, $selection_plan_id, $tr * @param $track_group_id * @return mixed */ + #[OA\Delete( + path: '/api/v1/summits/{id}/selection-plans/{selection_plan_id}/track-groups/{track_group_id}', + operationId: 'deleteTrackGroupToSelectionPlan', + summary: 'Remove a track group from a selection plan', + description: 'Removes the association between a track group and a selection plan.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::WriteSummitData, + ]] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + ] + ], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'selection_plan_id', + in: 'path', + required: true, + description: 'Selection Plan ID', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'track_group_id', + in: 'path', + required: true, + description: 'Track Group ID', + schema: new OA\Schema(type: 'integer') + ), + ], + responses: [ + new OA\Response(response: Response::HTTP_NO_CONTENT, description: 'Track group removed 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: 'Summit, Selection Plan, or Track Group not found'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function deleteTrackGroupToSelectionPlan($summit_id, $selection_plan_id, $track_group_id) { return $this->processRequest(function () use ($summit_id, $selection_plan_id, $track_group_id) { @@ -256,6 +602,59 @@ public function deleteTrackGroupToSelectionPlan($summit_id, $selection_plan_id, * @param $status * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Get( + path: '/api/public/v1/summits/{id}/selection-plans/current/{status}', + operationId: 'getCurrentSelectionPlanByStatus', + summary: 'Get current selection plan by status (Public)', + description: 'Retrieves the current active selection plan for a summit filtered by status. This is a public endpoint.', + tags: ['Selection Plans (Public)'], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'status', + in: 'path', + required: true, + description: 'Selection plan status: submission, selection, or voting', + schema: new OA\Schema(type: 'string', enum: ['submission', 'selection', 'voting']) + ), + new OA\Parameter( + name: 'expand', + in: 'query', + required: false, + description: 'Expand relationships to include as full objects: track_groups, extra_questions, event_types, track_chair_rating_types, allowed_presentation_action_types, allowed_presentation_action_types, allowed_presentation_questions, allowed_presentation_editable_questions, summit', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'fields', + in: 'query', + required: false, + description: 'Fields to return (comma-separated)', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'relations', + in: 'query', + required: false, + description: 'Relations to include: track_groups, extra_questions, event_types, track_chair_rating_types, allowed_presentation_action_types, allowed_presentation_action_types, allowed_presentation_questions, allowed_presentation_editable_questions', + schema: new OA\Schema(type: 'string') + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: 'Current selection plan retrieved successfully', + content: new OA\JsonContent(ref: '#/components/schemas/SelectionPlan') + ), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: 'Summit or Selection Plan not found'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function getCurrentSelectionPlanByStatus($summit_id, $status) { return $this->processRequest(function () use ($summit_id, $status) { @@ -283,6 +682,93 @@ public function getCurrentSelectionPlanByStatus($summit_id, $status) * @param $summit_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Get( + path: '/api/v1/summits/{id}/selection-plans', + operationId: 'getAllSelectionPlans', + summary: 'Get all selection plans for a summit', + description: 'Retrieves a paginated list of selection plans for a specific summit.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::ReadAllSummitData, + SummitScopes::ReadSummitData, + ]] + ], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'page', + in: 'query', + required: false, + description: 'Page number for pagination', + schema: new OA\Schema(type: 'integer', example: 1) + ), + new OA\Parameter( + name: 'per_page', + in: 'query', + required: false, + description: 'Items per page', + schema: new OA\Schema(type: 'integer', example: 10, maximum: 100) + ), + new OA\Parameter( + name: 'filter[]', + in: 'query', + required: false, + description: 'Filter expressions. Available fields: name (=@, @@, ==), status (==, values: submission, selection, voting)', + style: 'form', + explode: true, + schema: new OA\Schema( + type: 'array', + items: new OA\Items(type: 'string', example: 'status==submission') + ) + ), + new OA\Parameter( + name: 'order', + in: 'query', + required: false, + description: 'Order by field(s). Available fields: id, created, last_edited. Use + for asc, - for desc.', + schema: new OA\Schema(type: 'string', example: '+id') + ), + new OA\Parameter( + name: 'expand', + in: 'query', + required: false, + description: 'Expand relationships to include as full objects: track_groups, extra_questions, event_types, track_chair_rating_types, allowed_presentation_action_types, allowed_presentation_action_types, allowed_presentation_questions, allowed_presentation_editable_questions, summit', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'fields', + in: 'query', + required: false, + description: 'Fields to return (comma-separated)', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'relations', + in: 'query', + required: false, + description: 'Relations to include: track_groups, extra_questions, event_types, track_chair_rating_types, allowed_presentation_action_types, allowed_presentation_action_types, allowed_presentation_questions, allowed_presentation_editable_questions', + schema: new OA\Schema(type: 'string') + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: 'Selection plans retrieved successfully', + content: new OA\JsonContent(ref: '#/components/schemas/PaginatedSelectionPlansResponse') + ), + 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: 'Summit not found'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function getAll($summit_id) { return $this->_getAll( @@ -326,6 +812,107 @@ function () { * @param $selection_plan_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Get( + path: '/api/v1/summits/{id}/selection-plans/{selection_plan_id}/presentations', + operationId: 'getSelectionPlanPresentations', + summary: 'Get presentations for a selection plan', + description: 'Retrieves a paginated list of presentations for a specific selection plan. Only available to track chairs.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::ReadSummitData, + ]] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::TrackChairs, + IGroup::TrackChairsAdmins, + ] + ], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'selection_plan_id', + in: 'path', + required: true, + description: 'Selection Plan ID', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'page', + in: 'query', + required: false, + description: 'Page number for pagination', + schema: new OA\Schema(type: 'integer', example: 1) + ), + new OA\Parameter( + name: 'per_page', + in: 'query', + required: false, + description: 'Items per page', + schema: new OA\Schema(type: 'integer', example: 10, maximum: 100) + ), + new OA\Parameter( + name: 'filter[]', + in: 'query', + required: false, + description: 'Filter expressions. Available fields: title, abstract, social_summary, tags, level (=@, ==), summit_type_id, event_type_id, track_id, speaker_id, id, selection_plan_id (==), speaker, speaker_email (=@, ==), status, selection_status, is_chair_visible, is_voting_visible, track_chairs_status (voted, untouched, team_selected, selected, maybe, pass), viewed_status (seen, unseen, moved), actions', + style: 'form', + explode: true, + schema: new OA\Schema( + type: 'array', + items: new OA\Items(type: 'string', example: 'track_id==10') + ) + ), + new OA\Parameter( + name: 'order', + in: 'query', + required: false, + description: 'Order by field(s). Available fields: id, title, start_date, end_date, created, track, location, trackchairsel, last_edited', + schema: new OA\Schema(type: 'string', example: '+title') + ), + new OA\Parameter( + name: 'expand', + in: 'query', + required: false, + description: 'Expand relationships', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'fields', + in: 'query', + required: false, + description: 'Fields to return (comma-separated)', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'relations', + in: 'query', + required: false, + description: 'Related entities to include (comma-separated)', + schema: new OA\Schema(type: 'string') + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: 'Presentations retrieved successfully', + content: new OA\JsonContent(ref: '#/components/schemas/PaginateDataSchemaResponse') + ), + new OA\Response(response: Response::HTTP_UNAUTHORIZED, description: 'Unauthorized'), + new OA\Response(response: Response::HTTP_FORBIDDEN, description: 'Forbidden - Not a track chair'), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: 'Summit or Selection Plan not found'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function getSelectionPlanPresentations($summit_id, $selection_plan_id) { $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id); @@ -435,6 +1022,96 @@ function ($page, $per_page, $filter, $order, $applyExtraFilters) { * @param $selection_plan_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Get( + path: '/api/v1/summits/{id}/selection-plans/{selection_plan_id}/presentations/csv', + operationId: 'getSelectionPlanPresentationsCSV', + summary: 'Export presentations for a selection plan to CSV', + description: 'Exports presentations for a specific selection plan as a CSV file. Only available to track chairs.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::ReadSummitData, + ]] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::TrackChairs, + IGroup::TrackChairsAdmins, + ] + ], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'selection_plan_id', + in: 'path', + required: true, + description: 'Selection Plan ID', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'filter[]', + in: 'query', + required: false, + description: 'Filter expressions (same as getSelectionPlanPresentations)', + style: 'form', + explode: true, + schema: new OA\Schema( + type: 'array', + items: new OA\Items(type: 'string') + ) + ), + new OA\Parameter( + name: 'order', + in: 'query', + required: false, + description: 'Order by field(s)', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'expand', + in: 'query', + required: false, + description: 'Expand relationships', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'fields', + in: 'query', + required: false, + description: 'Fields to return (comma-separated)', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'relations', + in: 'query', + required: false, + description: 'Related entities to include (comma-separated)', + schema: new OA\Schema(type: 'string') + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: 'CSV file generated successfully', + 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 - Not a track chair'), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: 'Summit or Selection Plan not found'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function getSelectionPlanPresentationsCSV($summit_id, $selection_plan_id) { $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id); @@ -557,6 +1234,81 @@ function ($page, $per_page, $filter, $order, $applyExtraFilters) { * @param $presentation_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Get( + path: '/api/v1/summits/{id}/selection-plans/{selection_plan_id}/presentations/{presentation_id}', + operationId: 'getSelectionPlanPresentation', + summary: 'Get a specific presentation from a selection plan', + description: 'Retrieves a specific presentation by ID from a selection plan.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::ReadSummitData, + ]] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::TrackChairs, + IGroup::TrackChairsAdmins, + ] + ], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'selection_plan_id', + in: 'path', + required: true, + description: 'Selection Plan ID', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'presentation_id', + in: 'path', + required: true, + description: 'Presentation ID', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'expand', + in: 'query', + required: false, + description: 'Expand relationships', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'fields', + in: 'query', + required: false, + description: 'Fields to return (comma-separated)', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'relations', + in: 'query', + required: false, + description: 'Related entities to include (comma-separated)', + schema: new OA\Schema(type: 'string') + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: 'Presentation retrieved successfully', + content: new OA\JsonContent(ref: '#/components/schemas/TrackChairPresentation') + ), + 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: 'Summit, Selection Plan, or Presentation not found'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function getSelectionPlanPresentation($summit_id, $selection_plan_id, $presentation_id) { return $this->processRequest(function () use ($summit_id, $selection_plan_id, $presentation_id) { @@ -592,6 +1344,60 @@ public function getSelectionPlanPresentation($summit_id, $selection_plan_id, $pr * @param $presentation_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Put( + path: '/api/v1/summits/{id}/selection-plans/{selection_plan_id}/presentations/{presentation_id}/view', + operationId: 'markPresentationAsViewed', + summary: 'Mark a presentation as viewed', + description: 'Marks a presentation as viewed by the current track chair.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::WriteSummitData, + ]] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::TrackChairs, + IGroup::TrackChairsAdmins, + ] + ], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'selection_plan_id', + in: 'path', + required: true, + description: 'Selection Plan ID', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'presentation_id', + in: 'path', + required: true, + description: 'Presentation ID', + schema: new OA\Schema(type: 'integer') + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: 'Presentation marked as viewed successfully', + content: new OA\JsonContent(ref: '#/components/schemas/TrackChairPresentation') + ), + 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: 'Summit, Selection Plan, or Presentation not found'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function markPresentationAsViewed($summit_id, $selection_plan_id, $presentation_id) { return $this->processRequest(function () use ($summit_id, $selection_plan_id, $presentation_id) { @@ -625,6 +1431,67 @@ public function markPresentationAsViewed($summit_id, $selection_plan_id, $presen * @param $presentation_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Post( + path: '/api/v1/summits/{id}/selection-plans/{selection_plan_id}/presentations/{presentation_id}/comments', + operationId: 'addCommentToPresentation', + summary: 'Add a comment to a presentation', + description: 'Adds a new comment to a presentation within a selection plan.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::WriteSummitData, + ]] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::TrackChairs, + IGroup::TrackChairsAdmins, + ] + ], + requestBody: new OA\RequestBody( + description: 'Comment data', + required: true, + content: new OA\JsonContent(ref: '#/components/schemas/PresentationCommentPayload') + ), + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'selection_plan_id', + in: 'path', + required: true, + description: 'Selection Plan ID', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'presentation_id', + in: 'path', + required: true, + description: 'Presentation ID', + schema: new OA\Schema(type: 'integer') + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_CREATED, + description: 'Comment added successfully', + content: new OA\JsonContent(ref: '#/components/schemas/SummitPresentationComment') + ), + 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: 'Summit, Selection Plan, or Presentation not found'), + new OA\Response(response: Response::HTTP_UNPROCESSABLE_ENTITY, description: 'Validation Error'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function addCommentToPresentation($summit_id, $selection_plan_id, $presentation_id) { return $this->processRequest(function () use ($summit_id, $selection_plan_id, $presentation_id) { @@ -660,6 +1527,108 @@ public function addCommentToPresentation($summit_id, $selection_plan_id, $presen * @param $selection_plan_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Get( + path: '/api/v1/summits/{id}/selection-plans/{selection_plan_id}/presentations/all/category-change-requests', + operationId: 'getAllPresentationCategoryChangeRequest', + summary: 'Get all category change requests for a selection plan', + description: 'Retrieves a paginated list of category change requests for presentations in a selection plan. Only available to track chairs.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::ReadAllSummitData, + SummitScopes::ReadSummitData, + ]] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::TrackChairs, + IGroup::TrackChairsAdmins, + ] + ], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'selection_plan_id', + in: 'path', + required: true, + description: 'Selection Plan ID', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'page', + in: 'query', + required: false, + description: 'Page number for pagination', + schema: new OA\Schema(type: 'integer', example: 1) + ), + new OA\Parameter( + name: 'per_page', + in: 'query', + required: false, + description: 'Items per page', + schema: new OA\Schema(type: 'integer', example: 10) + ), + new OA\Parameter( + name: 'filter[]', + in: 'query', + required: false, + description: 'Filter expressions. Available fields: selection_plan_id, summit_id, new_category_id, old_category_id (==), new_category_name, old_category_name, requester_fullname, requester_email, aprover_fullname, aprover_email, presentation_title (=@, ==)', + style: 'form', + explode: true, + schema: new OA\Schema( + type: 'array', + items: new OA\Items(type: 'string') + ) + ), + new OA\Parameter( + name: 'order', + in: 'query', + required: false, + description: 'Order by field(s). Available: id, approval_date, status, presentation_title, new_category_name, old_category_name, requester_fullname', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'expand', + in: 'query', + required: false, + description: 'Expand relationships', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'fields', + in: 'query', + required: false, + description: 'Fields to return (comma-separated)', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'relations', + in: 'query', + required: false, + description: 'Related entities to include (comma-separated)', + schema: new OA\Schema(type: 'string') + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: 'Category change requests retrieved successfully', + content: new OA\JsonContent(ref: '#/components/schemas/PaginatedSummitCategoryChangesResponse') + ), + new OA\Response(response: Response::HTTP_UNAUTHORIZED, description: 'Unauthorized'), + new OA\Response(response: Response::HTTP_FORBIDDEN, description: 'Forbidden - Not a track chair'), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: 'Summit or Selection Plan not found'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function getAllPresentationCategoryChangeRequest($summit_id, $selection_plan_id) { @@ -746,6 +1715,67 @@ function ($page, $per_page, $filter, $order, $applyExtraFilters) { * @param $presentation_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Post( + path: '/api/v1/summits/{id}/selection-plans/{selection_plan_id}/presentations/{presentation_id}/category-change-requests', + operationId: 'createPresentationCategoryChangeRequest', + summary: 'Create a category change request for a presentation', + description: 'Creates a new request to change the category/track of a presentation.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::WriteSummitData, + ]] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::TrackChairs, + IGroup::TrackChairsAdmins, + ] + ], + requestBody: new OA\RequestBody( + description: 'Category change request data', + required: true, + content: new OA\JsonContent(ref: '#/components/schemas/CategoryChangeRequestPayload') + ), + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'selection_plan_id', + in: 'path', + required: true, + description: 'Selection Plan ID', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'presentation_id', + in: 'path', + required: true, + description: 'Presentation ID', + schema: new OA\Schema(type: 'integer') + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_CREATED, + description: 'Category change request created successfully', + content: new OA\JsonContent(ref: '#/components/schemas/SummitCategoryChange') + ), + 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: 'Summit, Selection Plan, or Presentation not found'), + new OA\Response(response: Response::HTTP_UNPROCESSABLE_ENTITY, description: 'Validation Error'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function createPresentationCategoryChangeRequest($summit_id, $selection_plan_id, $presentation_id) { return $this->processRequest(function () use ($summit_id, $selection_plan_id, $presentation_id) { @@ -781,6 +1811,74 @@ public function createPresentationCategoryChangeRequest($summit_id, $selection_p * @param $category_change_request_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Put( + path: '/api/v1/summits/{id}/selection-plans/{selection_plan_id}/presentations/{presentation_id}/category-change-requests/{category_change_request_id}', + operationId: 'resolvePresentationCategoryChangeRequest', + summary: 'Resolve a category change request', + description: 'Approves or rejects a category change request for a presentation.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::WriteSummitData, + ]] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::TrackChairs, + IGroup::TrackChairsAdmins, + ] + ], + requestBody: new OA\RequestBody( + description: 'Resolution data', + required: true, + content: new OA\JsonContent(ref: '#/components/schemas/ResolveCategoryChangeRequestPayload') + ), + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'selection_plan_id', + in: 'path', + required: true, + description: 'Selection Plan ID', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'presentation_id', + in: 'path', + required: true, + description: 'Presentation ID', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'category_change_request_id', + in: 'path', + required: true, + description: 'Category Change Request ID', + schema: new OA\Schema(type: 'integer') + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: 'Category change request resolved successfully', + content: new OA\JsonContent(ref: '#/components/schemas/SummitCategoryChange') + ), + 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: 'Resource not found'), + new OA\Response(response: Response::HTTP_UNPROCESSABLE_ENTITY, description: 'Validation Error'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function resolvePresentationCategoryChangeRequest($summit_id, $selection_plan_id, $presentation_id, $category_change_request_id) { return $this->processRequest(function () use ($summit_id, $selection_plan_id, $presentation_id, $category_change_request_id) { @@ -822,6 +1920,97 @@ public function resolvePresentationCategoryChangeRequest($summit_id, $selection_ * @param $selection_plan_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Get( + path: '/api/v1/summits/{id}/selection-plan-extra-questions', + operationId: 'getExtraQuestions', + summary: 'Get all extra questions for a summit', + description: 'Retrieves a paginated list of extra questions available for selection plans in a summit.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::ReadAllSummitData, + SummitScopes::ReadSummitData, + ]] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + ] + ], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'page', + in: 'query', + required: false, + description: 'Page number', + schema: new OA\Schema(type: 'integer', example: 1) + ), + new OA\Parameter( + name: 'per_page', + in: 'query', + required: false, + description: 'Items per page', + schema: new OA\Schema(type: 'integer', example: 10) + ), + new OA\Parameter( + name: 'filter[]', + in: 'query', + required: false, + description: 'Filter expressions. Available fields: name, type, label (=@, ==)', + style: 'form', + explode: true, + schema: new OA\Schema(type: 'array', items: new OA\Items(type: 'string')) + ), + new OA\Parameter( + name: 'order', + in: 'query', + required: false, + description: 'Order by field(s). Available: id, name, label, order', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'expand', + in: 'query', + required: false, + description: 'Expand relationships: values, sub_question_rules, parent_rules', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'fields', + in: 'query', + required: false, + description: 'Fields to return (comma-separated)', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'relations', + in: 'query', + required: false, + description: 'Related entities to include (comma-separated)', + schema: new OA\Schema(type: 'string') + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: 'Extra questions retrieved successfully', + content: new OA\JsonContent(ref: '#/components/schemas/PaginatedSummitSelectionPlanExtraQuestionTypesResponse') + ), + 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: 'Summit not found'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function getExtraQuestions($summit_id) { @@ -881,6 +2070,74 @@ function ($page, $per_page, $filter, $order, $applyExtraFilters) { * @param $question_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Get( + path: '/api/v1/summits/{id}/selection-plan-extra-questions/{question_id}', + operationId: 'getExtraQuestion', + summary: 'Get a specific extra question', + description: 'Retrieves a specific extra question by ID.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::ReadAllSummitData, + SummitScopes::ReadSummitData, + ]] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + ] + ], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'question_id', + in: 'path', + required: true, + description: 'Question ID', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'expand', + in: 'query', + required: false, + description: 'Expand relationships: values, sub_question_rules, parent_rules', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'fields', + in: 'query', + required: false, + description: 'Fields to return (comma-separated)', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'relations', + in: 'query', + required: false, + description: 'Related entities to include (comma-separated)', + schema: new OA\Schema(type: 'string') + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: 'Extra question retrieved successfully', + content: new OA\JsonContent(ref: '#/components/schemas/SummitSelectionPlanExtraQuestionType') + ), + 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: 'Summit or Question not found'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function getExtraQuestion($summit_id, $question_id){ return $this->processRequest(function() use($summit_id, $question_id){ $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id); @@ -901,6 +2158,97 @@ public function getExtraQuestion($summit_id, $question_id){ * @param $selection_plan_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Get( + path: '/api/v1/summits/{id}/selection-plans/{selection_plan_id}/extra-questions', + operationId: 'getExtraQuestionsBySelectionPlan', + summary: 'Get extra questions for a selection plan', + description: 'Retrieves a paginated list of extra questions assigned to a specific selection plan.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::ReadAllSummitData, + SummitScopes::ReadSummitData, + ]] + ], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'selection_plan_id', + in: 'path', + required: true, + description: 'Selection Plan ID', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'page', + in: 'query', + required: false, + description: 'Page number', + schema: new OA\Schema(type: 'integer', example: 1) + ), + new OA\Parameter( + name: 'per_page', + in: 'query', + required: false, + description: 'Items per page', + schema: new OA\Schema(type: 'integer', example: 10) + ), + new OA\Parameter( + name: 'filter[]', + in: 'query', + required: false, + description: 'Filter expressions. Available fields: name, type, label (=@, ==)', + style: 'form', + explode: true, + schema: new OA\Schema(type: 'array', items: new OA\Items(type: 'string')) + ), + new OA\Parameter( + name: 'order', + in: 'query', + required: false, + description: 'Order by field(s). Available: id, name, label, order', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'expand', + in: 'query', + required: false, + description: 'Expand relationships: values, sub_question_rules, parent_rules', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'fields', + in: 'query', + required: false, + description: 'Fields to return (comma-separated)', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'relations', + in: 'query', + required: false, + description: 'Related entities to include (comma-separated)', + schema: new OA\Schema(type: 'string') + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: 'Extra questions retrieved successfully', + content: new OA\JsonContent(ref: '#/components/schemas/PaginatedAssignedSelectionPlanExtraQuestionTypesResponse') + ), + 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: 'Summit or Selection Plan not found'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function getExtraQuestionsBySelectionPlan($summit_id, $selection_plan_id) { $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id); @@ -961,6 +2309,46 @@ function ($page, $per_page, $filter, $order, $applyExtraFilters) { * @param $selection_plan_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Get( + path: '/api/v1/summits/{id}/selection-plan-extra-questions/metadata', + operationId: 'getExtraQuestionsMetadata', + summary: 'Get extra questions metadata', + description: 'Retrieves metadata about available extra question types.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::ReadAllSummitData, + SummitScopes::ReadSummitData, + ]] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + ] + ], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: 'Metadata retrieved successfully', + content: new OA\JsonContent(ref: '#/components/schemas/ExtraQuestionTypeMetadata') + ), + 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: 'Summit not found'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function getExtraQuestionsMetadata($summit_id) { $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id); @@ -978,6 +2366,46 @@ public function getExtraQuestionsMetadata($summit_id) * @param $selection_plan_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Get( + path: '/api/v1/summits/{id}/selection-plans/{selection_plan_id}/extra-questions/metadata', + operationId: 'getExtraQuestionsMetadataBySelectionPlan', + summary: 'Get extra questions metadata for a selection plan', + description: 'Retrieves metadata about available extra question types for a specific selection plan.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::ReadAllSummitData, + SummitScopes::ReadSummitData, + ]] + ], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'selection_plan_id', + in: 'path', + required: true, + description: 'Selection Plan ID', + schema: new OA\Schema(type: 'integer') + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: 'Metadata retrieved successfully', + content: new OA\JsonContent(ref: '#/components/schemas/ExtraQuestionTypeMetadata') + ), + 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: 'Summit or Selection Plan not found'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function getExtraQuestionsMetadataBySelectionPlan($summit_id, $selection_plan_id) { $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id); @@ -995,6 +2423,47 @@ public function getExtraQuestionsMetadataBySelectionPlan($summit_id, $selection_ * @param $summit_id * @return \Illuminate\Http\JsonResponse */ + #[OA\Post( + path: '/api/v1/summits/{id}/selection-plan-extra-questions', + operationId: 'addExtraQuestion', + summary: 'Create a new extra question', + description: 'Creates a new extra question for selection plans in a summit.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::WriteSummitData, + ]] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + ] + ], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_CREATED, + description: 'Extra question created successfully', + content: new OA\JsonContent(ref: '#/components/schemas/SummitSelectionPlanExtraQuestionType') + ), + 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: 'Summit not found'), + new OA\Response(response: Response::HTTP_UNPROCESSABLE_ENTITY, description: 'Validation Error'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function addExtraQuestion($summit_id) { @@ -1019,6 +2488,54 @@ function ($payload, $summit) { * @param $question_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Put( + path: '/api/v1/summits/{id}/selection-plan-extra-questions/{question_id}', + operationId: 'updateExtraQuestion', + summary: 'Update an extra question', + description: 'Updates an existing extra question.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::WriteSummitData, + ]] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + ] + ], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'question_id', + in: 'path', + required: true, + description: 'Question ID', + schema: new OA\Schema(type: 'integer') + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: 'Extra question updated successfully', + content: new OA\JsonContent(ref: '#/components/schemas/SummitSelectionPlanExtraQuestionType') + ), + 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: 'Summit or Question not found'), + new OA\Response(response: Response::HTTP_UNPROCESSABLE_ENTITY, description: 'Validation Error'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function updateExtraQuestion($summit_id, $question_id) { $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id); @@ -1044,6 +2561,54 @@ function ($question_id, $payload, $summit) { * @param $selection_plan_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Post( + path: '/api/v1/summits/{id}/selection-plans/{selection_plan_id}/extra-questions', + operationId: 'addExtraQuestionAndAssign', + summary: 'Create and assign an extra question to a selection plan', + description: 'Creates a new extra question and assigns it to a specific selection plan.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::WriteSummitData, + ]] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + ] + ], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'selection_plan_id', + in: 'path', + required: true, + description: 'Selection Plan ID', + schema: new OA\Schema(type: 'integer') + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_CREATED, + description: 'Extra question created and assigned successfully', + content: new OA\JsonContent(ref: '#/components/schemas/AssignedSelectionPlanExtraQuestionType') + ), + 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: 'Summit or Selection Plan not found'), + new OA\Response(response: Response::HTTP_UNPROCESSABLE_ENTITY, description: 'Validation Error'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function addExtraQuestionAndAssign($summit_id, $selection_plan_id){ $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id); if (is_null($summit)) return $this->error404(); @@ -1070,6 +2635,52 @@ function ($payload, $selection_plan_id) { * @param $question_id * @return mixed */ + #[OA\Post( + path: '/api/v1/summits/{id}/selection-plans/{selection_plan_id}/extra-questions/{question_id}', + operationId: 'assignExtraQuestion', + summary: 'Assign an existing extra question to a selection plan', + description: 'Assigns an existing extra question to a specific selection plan.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::WriteSummitData, + ]] + ], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'selection_plan_id', + in: 'path', + required: true, + description: 'Selection Plan ID', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'question_id', + in: 'path', + required: true, + description: 'Question ID', + schema: new OA\Schema(type: 'integer') + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_CREATED, + description: 'Extra question assigned successfully', + content: new OA\JsonContent(ref: '#/components/schemas/AssignedSelectionPlanExtraQuestionType') + ), + 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: 'Summit, Selection Plan, or Question not found'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function assignExtraQuestion($summit_id, $selection_plan_id, $question_id){ return $this->processRequest(function() use($summit_id, $selection_plan_id, $question_id){ @@ -1098,6 +2709,74 @@ public function assignExtraQuestion($summit_id, $selection_plan_id, $question_id * @param $question_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Get( + path: '/api/v1/summits/{id}/selection-plans/{selection_plan_id}/extra-questions/{question_id}', + operationId: 'getExtraQuestionBySelectionPlan', + summary: 'Get an extra question by selection plan', + description: 'Retrieves a specific extra question assigned to a selection plan.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::ReadAllSummitData, + SummitScopes::ReadSummitData, + ]] + ], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'selection_plan_id', + in: 'path', + required: true, + description: 'Selection Plan ID', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'question_id', + in: 'path', + required: true, + description: 'Question ID', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'expand', + in: 'query', + required: false, + description: 'Expand relationships: values, sub_question_rules, parent_rules', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'fields', + in: 'query', + required: false, + description: 'Fields to return (comma-separated)', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'relations', + in: 'query', + required: false, + description: 'Related entities to include (comma-separated)', + schema: new OA\Schema(type: 'string') + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: 'Extra question retrieved successfully', + content: new OA\JsonContent(ref: '#/components/schemas/AssignedSelectionPlanExtraQuestionType') + ), + 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: 'Summit, Selection Plan, or Question not found'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function getExtraQuestionBySelectionPlan($summit_id, $selection_plan_id, $question_id) { $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id); @@ -1121,6 +2800,61 @@ public function getExtraQuestionBySelectionPlan($summit_id, $selection_plan_id, * @param $question_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Put( + path: '/api/v1/summits/{id}/selection-plans/{selection_plan_id}/extra-questions/{question_id}', + operationId: 'updateExtraQuestionBySelectionPlan', + summary: 'Update an extra question by selection plan', + description: 'Updates a specific extra question assigned to a selection plan.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::WriteSummitData, + ]] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + ] + ], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'selection_plan_id', + in: 'path', + required: true, + description: 'Selection Plan ID', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'question_id', + in: 'path', + required: true, + description: 'Question ID', + schema: new OA\Schema(type: 'integer') + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: 'Extra question updated successfully', + content: new OA\JsonContent(ref: '#/components/schemas/AssignedSelectionPlanExtraQuestionType') + ), + 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: 'Summit, Selection Plan, or Question not found'), + new OA\Response(response: Response::HTTP_UNPROCESSABLE_ENTITY, description: 'Validation Error'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function updateExtraQuestionBySelectionPlan($summit_id, $selection_plan_id, $question_id) { $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id); @@ -1151,6 +2885,48 @@ function ($question_id, $payload, $selection_plan) { * @param $question_id * @return \Illuminate\Http\JsonResponse */ + #[OA\Delete( + path: '/api/v1/summits/{id}/selection-plan-extra-questions/{question_id}', + operationId: 'deleteExtraQuestion', + summary: 'Delete an extra question', + description: 'Deletes a specific extra question from a summit.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::WriteSummitData, + ]] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + ] + ], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'question_id', + in: 'path', + required: true, + description: 'Question ID', + schema: new OA\Schema(type: 'integer') + ), + ], + responses: [ + new OA\Response(response: Response::HTTP_NO_CONTENT, description: 'Extra question 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: 'Summit or Question not found'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function deleteExtraQuestion($summit_id, $question_id) { $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id); @@ -1169,6 +2945,55 @@ public function deleteExtraQuestion($summit_id, $question_id) * @param $question_id * @return \Illuminate\Http\JsonResponse */ + #[OA\Delete( + path: '/api/v1/summits/{id}/selection-plans/{selection_plan_id}/extra-questions/{question_id}', + operationId: 'removeExtraQuestion', + summary: 'Remove an extra question from a selection plan', + description: 'Removes an extra question assignment from a specific selection plan (does not delete the question).', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::WriteSummitData, + ]] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + ] + ], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'selection_plan_id', + in: 'path', + required: true, + description: 'Selection Plan ID', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'question_id', + in: 'path', + required: true, + description: 'Question ID', + schema: new OA\Schema(type: 'integer') + ), + ], + responses: [ + new OA\Response(response: Response::HTTP_NO_CONTENT, description: 'Extra question removed 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: 'Summit, Selection Plan, or Question not found'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function removeExtraQuestion($summit_id, $selection_plan_id, $question_id) { $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id); @@ -1191,6 +3016,54 @@ public function removeExtraQuestion($summit_id, $selection_plan_id, $question_id * @param $question_id * @return \Illuminate\Http\JsonResponse */ + #[OA\Post( + path: '/api/v1/summits/{id}/selection-plan-extra-questions/{question_id}/values', + operationId: 'addExtraQuestionValue', + summary: 'Add a value to an extra question', + description: 'Adds a new value option to an extra question.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::WriteSummitData, + ]] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + ] + ], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'question_id', + in: 'path', + required: true, + description: 'Question ID', + schema: new OA\Schema(type: 'integer') + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_CREATED, + description: 'Extra question value created successfully', + content: new OA\JsonContent(ref: '#/components/schemas/ExtraQuestionTypeValue') + ), + 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: 'Summit or Question not found'), + new OA\Response(response: Response::HTTP_UNPROCESSABLE_ENTITY, description: 'Validation Error'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function addExtraQuestionValue($summit_id, $question_id) { $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id); @@ -1217,6 +3090,61 @@ function ($payload, $summit, $question_id) { * @param $question_id * @return \Illuminate\Http\JsonResponse */ + #[OA\Post( + path: '/api/v1/summits/{id}/selection-plans/{selection_plan_id}/extra-questions/{question_id}/values', + operationId: 'addExtraQuestionValueBySelectionPlan', + summary: 'Add a value to an extra question by selection plan', + description: 'Adds a new value option to an extra question via selection plan context.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::WriteSummitData, + ]] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + ] + ], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'selection_plan_id', + in: 'path', + required: true, + description: 'Selection Plan ID', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'question_id', + in: 'path', + required: true, + description: 'Question ID', + schema: new OA\Schema(type: 'integer') + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_CREATED, + description: 'Extra question value created successfully', + content: new OA\JsonContent(ref: '#/components/schemas/ExtraQuestionTypeValue') + ), + 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: 'Summit, Selection Plan, or Question not found'), + new OA\Response(response: Response::HTTP_UNPROCESSABLE_ENTITY, description: 'Validation Error'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function addExtraQuestionValueBySelectionPlan($summit_id, $selection_plan_id, $question_id) { $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id); @@ -1246,6 +3174,61 @@ function ($payload, $summit, $question_id) { * @param $value_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Put( + path: '/api/v1/summits/{id}/selection-plan-extra-questions/{question_id}/values/{value_id}', + operationId: 'updateExtraQuestionValue', + summary: 'Update an extra question value', + description: 'Updates a value option for an extra question.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::WriteSummitData, + ]] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + ] + ], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'question_id', + in: 'path', + required: true, + description: 'Question ID', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'value_id', + in: 'path', + required: true, + description: 'Value ID', + schema: new OA\Schema(type: 'integer') + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: 'Extra question value updated successfully', + content: new OA\JsonContent(ref: '#/components/schemas/ExtraQuestionTypeValue') + ), + 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: 'Summit, Question, or Value not found'), + new OA\Response(response: Response::HTTP_UNPROCESSABLE_ENTITY, description: 'Validation Error'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function updateExtraQuestionValue($summit_id, $question_id, $value_id) { $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id); @@ -1274,6 +3257,68 @@ function ($value_id, $payload, $summit, $question_id) { * @param $value_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Put( + path: '/api/v1/summits/{id}/selection-plans/{selection_plan_id}/extra-questions/{question_id}/values/{value_id}', + operationId: 'updateExtraQuestionValueBySelectionPlan', + summary: 'Update an extra question value by selection plan', + description: 'Updates a value option for an extra question via selection plan context.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::WriteSummitData, + ]] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + ] + ], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'selection_plan_id', + in: 'path', + required: true, + description: 'Selection Plan ID', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'question_id', + in: 'path', + required: true, + description: 'Question ID', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'value_id', + in: 'path', + required: true, + description: 'Value ID', + schema: new OA\Schema(type: 'integer') + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: 'Extra question value updated successfully', + content: new OA\JsonContent(ref: '#/components/schemas/ExtraQuestionTypeValue') + ), + 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: 'Summit, Selection Plan, Question, or Value not found'), + new OA\Response(response: Response::HTTP_UNPROCESSABLE_ENTITY, description: 'Validation Error'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function updateExtraQuestionValueBySelectionPlan($summit_id, $selection_plan_id, $question_id, $value_id) { $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id); @@ -1304,6 +3349,55 @@ function ($value_id, $payload, $summit, $question_id) { * @param $value_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Delete( + path: '/api/v1/summits/{id}/selection-plan-extra-questions/{question_id}/values/{value_id}', + operationId: 'deleteExtraQuestionValue', + summary: 'Delete an extra question value', + description: 'Deletes a value option from an extra question.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::WriteSummitData, + ]] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + ] + ], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'question_id', + in: 'path', + required: true, + description: 'Question ID', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'value_id', + in: 'path', + required: true, + description: 'Value ID', + schema: new OA\Schema(type: 'integer') + ), + ], + responses: [ + new OA\Response(response: Response::HTTP_NO_CONTENT, description: 'Extra question value 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: 'Summit, Question, or Value not found'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function deleteExtraQuestionValue($summit_id, $question_id, $value_id) { $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id); @@ -1324,6 +3418,62 @@ public function deleteExtraQuestionValue($summit_id, $question_id, $value_id) * @param $value_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Delete( + path: '/api/v1/summits/{id}/selection-plans/{selection_plan_id}/extra-questions/{question_id}/values/{value_id}', + operationId: 'deleteExtraQuestionValueBySelectionPlan', + summary: 'Delete an extra question value by selection plan', + description: 'Deletes a value option from an extra question via selection plan context.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::WriteSummitData, + ]] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + ] + ], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'selection_plan_id', + in: 'path', + required: true, + description: 'Selection Plan ID', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'question_id', + in: 'path', + required: true, + description: 'Question ID', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'value_id', + in: 'path', + required: true, + description: 'Value ID', + schema: new OA\Schema(type: 'integer') + ), + ], + responses: [ + new OA\Response(response: Response::HTTP_NO_CONTENT, description: 'Extra question value 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: 'Summit, Selection Plan, Question, or Value not found'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function deleteExtraQuestionValueBySelectionPlan($summit_id, $selection_plan_id, $question_id, $value_id) { $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id); @@ -1346,6 +3496,55 @@ public function deleteExtraQuestionValueBySelectionPlan($summit_id, $selection_p * @param $event_type_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Put( + path: '/api/v1/summits/{id}/selection-plans/{selection_plan_id}/event-types/{event_type_id}', + operationId: 'attachEventType', + summary: 'Attach an event type to a selection plan', + description: 'Attaches an event type to a specific selection plan.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::WriteSummitData, + ]] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + ] + ], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'selection_plan_id', + in: 'path', + required: true, + description: 'Selection Plan ID', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'event_type_id', + in: 'path', + required: true, + description: 'Event Type ID', + schema: new OA\Schema(type: 'integer') + ), + ], + responses: [ + new OA\Response(response: Response::HTTP_OK, description: 'Event type attached 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: 'Summit, Selection Plan, or Event Type not found'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function attachEventType($id, $selection_plan_id, $event_type_id) { return $this->processRequest(function () use ($id, $selection_plan_id, $event_type_id) { @@ -1363,6 +3562,55 @@ public function attachEventType($id, $selection_plan_id, $event_type_id) * @param $event_type_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Delete( + path: '/api/v1/summits/{id}/selection-plans/{selection_plan_id}/event-types/{event_type_id}', + operationId: 'detachEventType', + summary: 'Detach an event type from a selection plan', + description: 'Detaches an event type from a specific selection plan.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::WriteSummitData, + ]] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + ] + ], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'selection_plan_id', + in: 'path', + required: true, + description: 'Selection Plan ID', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'event_type_id', + in: 'path', + required: true, + description: 'Event Type ID', + schema: new OA\Schema(type: 'integer') + ), + ], + responses: [ + new OA\Response(response: Response::HTTP_NO_CONTENT, description: 'Event type detached 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: 'Summit, Selection Plan, or Event Type not found'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function detachEventType($id, $selection_plan_id, $event_type_id) { return $this->processRequest(function () use ($id, $selection_plan_id, $event_type_id) { @@ -1381,6 +3629,104 @@ public function detachEventType($id, $selection_plan_id, $event_type_id) * @param $selection_plan_id * @return \Illuminate\Http\JsonResponse */ + #[OA\Get( + path: '/api/v1/summits/{id}/selection-plans/{selection_plan_id}/allowed-presentation-action-types', + operationId: 'getAllowedPresentationActionTypes', + summary: 'Get allowed presentation action types', + description: 'Retrieves all allowed presentation action types for a selection plan.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::ReadAllSummitData, + SummitScopes::ReadSummitData, + ]] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + IGroup::TrackChairs, + IGroup::TrackChairsAdmins, + ] + ], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'selection_plan_id', + in: 'path', + required: true, + description: 'Selection Plan ID', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'filter', + in: 'query', + required: false, + description: 'Filter criteria. Supported filters: label (=@, ==), id (==)', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'order', + in: 'query', + required: false, + description: 'Sort order. Supported: order', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'page', + in: 'query', + required: false, + description: 'Page number', + schema: new OA\Schema(type: 'integer', default: 1) + ), + new OA\Parameter( + name: 'per_page', + in: 'query', + required: false, + description: 'Items per page', + schema: new OA\Schema(type: 'integer', default: 10) + ), + new OA\Parameter( + name: 'expand', + in: 'query', + required: false, + description: 'Expand relationships', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'fields', + in: 'query', + required: false, + description: 'Fields to return (comma-separated)', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'relations', + in: 'query', + required: false, + description: 'Related entities to include (comma-separated)', + schema: new OA\Schema(type: 'string') + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: 'Allowed presentation action types retrieved successfully', + content: new OA\JsonContent(ref: '#/components/schemas/PaginatedPresentationActionTypesResponse') + ), + 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: 'Summit or Selection Plan not found'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function getAllowedPresentationActionTypes($summit_id, $selection_plan_id) { $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id); @@ -1437,6 +3783,82 @@ function ($page, $per_page, $filter, $order, $applyExtraFilters) { * @param $type_id * @return \Illuminate\Http\JsonResponse */ + #[OA\Get( + path: '/api/v1/summits/{id}/selection-plans/{selection_plan_id}/allowed-presentation-action-types/{type_id}', + operationId: 'getAllowedPresentationActionType', + summary: 'Get a specific allowed presentation action type', + description: 'Retrieves a specific allowed presentation action type for a selection plan.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::ReadSummitData, + ]] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + IGroup::TrackChairs, + IGroup::TrackChairsAdmins, + ] + ], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'selection_plan_id', + in: 'path', + required: true, + description: 'Selection Plan ID', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'type_id', + in: 'path', + required: true, + description: 'Presentation Action Type ID', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'expand', + in: 'query', + required: false, + description: 'Expand relationships', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'fields', + in: 'query', + required: false, + description: 'Fields to return (comma-separated)', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'relations', + in: 'query', + required: false, + description: 'Related entities to include (comma-separated)', + schema: new OA\Schema(type: 'string') + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: 'Presentation action type retrieved successfully', + content: new OA\JsonContent(ref: '#/components/schemas/PresentationActionType') + ), + 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: 'Summit, Selection Plan, or Action Type not found'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function getAllowedPresentationActionType($summit_id, $selection_plan_id, $type_id) { return $this->processRequest(function() use($summit_id, $selection_plan_id, $type_id) { $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id); @@ -1468,6 +3890,68 @@ public function getAllowedPresentationActionType($summit_id, $selection_plan_id, * @param $type_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Post( + path: '/api/v1/summits/{id}/selection-plans/{selection_plan_id}/allowed-presentation-action-types/{type_id}', + operationId: 'addAllowedPresentationActionType', + summary: 'Add an allowed presentation action type', + description: 'Adds an allowed presentation action type to a selection plan.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::WriteSummitData, + ]] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + IGroup::TrackChairs, + IGroup::TrackChairsAdmins, + ] + ], + requestBody: new OA\RequestBody( + description: 'Allowed presentation action type data', + required: false, + content: new OA\JsonContent(ref: '#/components/schemas/AddAllowedPresentationActionTypePayload') + ), + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'selection_plan_id', + in: 'path', + required: true, + description: 'Selection Plan ID', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'type_id', + in: 'path', + required: true, + description: 'Presentation Action Type ID', + schema: new OA\Schema(type: 'integer') + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_CREATED, + description: 'Presentation action type added successfully', + content: new OA\JsonContent(ref: '#/components/schemas/PresentationActionType') + ), + 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: 'Summit, Selection Plan, or Action Type not found'), + new OA\Response(response: Response::HTTP_UNPROCESSABLE_ENTITY, description: 'Validation Error'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function addAllowedPresentationActionType($id, $selection_plan_id, $type_id) { return $this->processRequest(function () use ($id, $selection_plan_id, $type_id) { @@ -1496,6 +3980,68 @@ public function addAllowedPresentationActionType($id, $selection_plan_id, $type_ * @param $type_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Put( + path: '/api/v1/summits/{id}/selection-plans/{selection_plan_id}/allowed-presentation-action-types/{type_id}', + operationId: 'updateAllowedPresentationActionType', + summary: 'Update an allowed presentation action type', + description: 'Updates an allowed presentation action type for a selection plan.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::WriteSummitData, + ]] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + IGroup::TrackChairs, + IGroup::TrackChairsAdmins, + ] + ], + requestBody: new OA\RequestBody( + description: 'Allowed presentation action type data', + required: true, + content: new OA\JsonContent(ref: '#/components/schemas/UpdateAllowedPresentationActionTypePayload') + ), + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'selection_plan_id', + in: 'path', + required: true, + description: 'Selection Plan ID', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'type_id', + in: 'path', + required: true, + description: 'Presentation Action Type ID', + schema: new OA\Schema(type: 'integer') + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: 'Presentation action type updated successfully', + content: new OA\JsonContent(ref: '#/components/schemas/PresentationActionType') + ), + 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: 'Summit, Selection Plan, or Action Type not found'), + new OA\Response(response: Response::HTTP_UNPROCESSABLE_ENTITY, description: 'Validation Error'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function updateAllowedPresentationActionType($id, $selection_plan_id, $type_id) { return $this->processRequest(function () use ($id, $selection_plan_id, $type_id) { @@ -1524,6 +4070,57 @@ public function updateAllowedPresentationActionType($id, $selection_plan_id, $ty * @param $type_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Delete( + path: '/api/v1/summits/{id}/selection-plans/{selection_plan_id}/allowed-presentation-action-types/{type_id}', + operationId: 'removeAllowedPresentationActionType', + summary: 'Remove an allowed presentation action type', + description: 'Removes an allowed presentation action type from a selection plan.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::WriteSummitData, + ]] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + IGroup::TrackChairs, + IGroup::TrackChairsAdmins, + ] + ], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'selection_plan_id', + in: 'path', + required: true, + description: 'Selection Plan ID', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'type_id', + in: 'path', + required: true, + description: 'Presentation Action Type ID', + schema: new OA\Schema(type: 'integer') + ), + ], + responses: [ + new OA\Response(response: Response::HTTP_NO_CONTENT, description: 'Presentation action type removed 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: 'Summit, Selection Plan, or Action Type not found'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function removeAllowedPresentationActionType($id, $selection_plan_id, $type_id) { return $this->processRequest(function () use ($id, $selection_plan_id, $type_id) { @@ -1544,6 +4141,102 @@ public function removeAllowedPresentationActionType($id, $selection_plan_id, $ty * @param $selection_plan_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Get( + path: '/api/v1/summits/{id}/selection-plans/{selection_plan_id}/allowed-members', + operationId: 'getAllowedMembers', + summary: 'Get allowed members for a selection plan', + description: 'Retrieves all members allowed for a selection plan.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::ReadAllSummitData, + SummitScopes::ReadSummitData, + ]] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + ] + ], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'selection_plan_id', + in: 'path', + required: true, + description: 'Selection Plan ID', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'filter', + in: 'query', + required: false, + description: 'Filter criteria. Supported filters: email (@@, =@)', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'order', + in: 'query', + required: false, + description: 'Sort order. Supported: email', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'page', + in: 'query', + required: false, + description: 'Page number', + schema: new OA\Schema(type: 'integer', default: 1) + ), + new OA\Parameter( + name: 'per_page', + in: 'query', + required: false, + description: 'Items per page', + schema: new OA\Schema(type: 'integer', default: 10) + ), + new OA\Parameter( + name: 'expand', + in: 'query', + required: false, + description: 'Expand relationships', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'fields', + in: 'query', + required: false, + description: 'Fields to return (comma-separated)', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'relations', + in: 'query', + required: false, + description: 'Related entities to include (comma-separated)', + schema: new OA\Schema(type: 'string') + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: 'Allowed members retrieved successfully', + content: new OA\JsonContent(ref: '#/components/schemas/PaginatedSelectionPlanAllowedMembersResponse') + ), + 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: 'Summit or Selection Plan not found'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function getAllowedMembers($id, $selection_plan_id){ $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($id); @@ -1581,6 +4274,9 @@ function () { null, null, function ($page, $per_page, $filter, $order, $applyExtraFilters) { + /** + * @var ISelectionPlanRepository $this->repository + */ return $this->repository->getAllAllowedMembersByPage ( new PagingInfo($page, $per_page), @@ -1595,6 +4291,59 @@ function ($page, $per_page, $filter, $order, $applyExtraFilters) { * @param $selection_plan_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Post( + path: '/api/v1/summits/{id}/selection-plans/{selection_plan_id}/allowed-members', + operationId: 'addAllowedMember', + summary: 'Add an allowed member to a selection plan', + description: 'Adds a member to the allowed members list of a selection plan.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::WriteSummitData, + ]] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + ] + ], + requestBody: new OA\RequestBody( + description: 'Allowed member data', + required: true, + content: new OA\JsonContent(ref: '#/components/schemas/AllowedMemberPayload') + ), + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'selection_plan_id', + in: 'path', + required: true, + description: 'Selection Plan ID', + schema: new OA\Schema(type: 'integer') + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_CREATED, + description: 'Allowed member added successfully', + content: new OA\JsonContent(ref: '#/components/schemas/SelectionPlanAllowedMember') + ), + 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: 'Summit or Selection Plan not found'), + new OA\Response(response: Response::HTTP_UNPROCESSABLE_ENTITY, description: 'Validation Error'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function addAllowedMember($id, $selection_plan_id){ return $this->processRequest(function () use ($id, $selection_plan_id) { $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($id); @@ -1620,6 +4369,55 @@ public function addAllowedMember($id, $selection_plan_id){ * @param $selection_plan_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Delete( + path: '/api/v1/summits/{id}/selection-plans/{selection_plan_id}/allowed-members/{allowed_member_id}', + operationId: 'removeAllowedMember', + summary: 'Remove an allowed member from a selection plan', + description: 'Removes a member from the allowed members list of a selection plan.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::WriteSummitData, + ]] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + ] + ], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'selection_plan_id', + in: 'path', + required: true, + description: 'Selection Plan ID', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'allowed_member_id', + in: 'path', + required: true, + description: 'Allowed Member ID', + schema: new OA\Schema(type: 'integer') + ), + ], + responses: [ + new OA\Response(response: Response::HTTP_NO_CONTENT, description: 'Allowed member removed 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: 'Summit, Selection Plan, or Allowed Member not found'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function removeAllowedMember($id, $selection_plan_id, $allowed_member_id){ return $this->processRequest(function () use ($id, $selection_plan_id, $allowed_member_id) { $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($id); @@ -1636,6 +4434,50 @@ public function removeAllowedMember($id, $selection_plan_id, $allowed_member_id) * @param $selection_plan_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Post( + path: '/api/v1/summits/{id}/selection-plans/{selection_plan_id}/allowed-members/csv', + operationId: 'importAllowedMembers', + summary: 'Import allowed members from CSV', + description: 'Imports allowed members from a CSV file.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::WriteSummitData, + ]] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + ] + ], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'selection_plan_id', + in: 'path', + required: true, + description: 'Selection Plan ID', + schema: new OA\Schema(type: 'integer') + ), + ], + responses: [ + new OA\Response(response: Response::HTTP_OK, description: 'Allowed members imported successfully'), + 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: 'Summit or Selection Plan not found'), + new OA\Response(response: Response::HTTP_PRECONDITION_FAILED, description: 'File param not set'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function importAllowedMembers(LaravelRequest $request, $id, $selection_plan_id) { @@ -1663,6 +4505,60 @@ public function importAllowedMembers(LaravelRequest $request, $id, $selection_pl * @param $id * @return mixed */ + #[OA\Get( + path: '/api/v1/summits/{id}/selection-plans/me', + operationId: 'getMySelectionPlans', + summary: 'Get my selection plans', + description: 'Retrieves selection plans for the current authenticated user.', + tags: ['Selection Plans'], + security: [ + ['selection_plans_oauth2' => [ + SummitScopes::ReadAllSummitData, + SummitScopes::ReadSummitData, + ]] + ], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID or slug', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'expand', + in: 'query', + required: false, + description: 'Expand relationships: track_groups, extra_questions, event_types', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'fields', + in: 'query', + required: false, + description: 'Fields to return (comma-separated)', + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'relations', + in: 'query', + required: false, + description: 'Related entities to include (comma-separated)', + schema: new OA\Schema(type: 'string') + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: 'Selection plans retrieved successfully', + content: new OA\JsonContent(ref: '#/components/schemas/PaginatedSelectionPlansResponse') + ), + 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: 'Summit not found'), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: 'Server Error'), + ] + )] public function getMySelectionPlans($id){ return $this->processRequest(function() use($id){ @@ -1683,4 +4579,4 @@ public function getMySelectionPlans($id){ )); }); } -} \ No newline at end of file +} diff --git a/app/Swagger/Models/AdminPresentationSchema.php b/app/Swagger/Models/AdminPresentationSchema.php new file mode 100644 index 000000000..903d4c31a --- /dev/null +++ b/app/Swagger/Models/AdminPresentationSchema.php @@ -0,0 +1,50 @@ + 'Read All Summit Data', + SummitScopes::ReadSummitData => 'Read Summit Data', + SummitScopes::WriteSummitData => 'Write Summit Data', + ], + ), + ], + ) +] +class SelectionPlansAuthSchema {}