From f7003b9b20e0176d1b0a1b1cf8f3cb5d18f8fb6a Mon Sep 17 00:00:00 2001 From: Matias Perrone Date: Mon, 20 Oct 2025 12:02:31 -0300 Subject: [PATCH 1/6] feat: Extend Swagger Coverage for controller `OAuth2SummitProposedScheduleApiController` --- ...th2SummitProposedScheduleApiController.php | 359 +++++++++++++++++- app/Swagger/SummitProposedScheduleSchemas.php | 127 +++++++ 2 files changed, 485 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitProposedScheduleApiController.php b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitProposedScheduleApiController.php index c926010b9..1f242b236 100644 --- a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitProposedScheduleApiController.php +++ b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitProposedScheduleApiController.php @@ -12,6 +12,8 @@ * limitations under the License. **/ +use Illuminate\Http\Response; +use OpenApi\Attributes as OA; use App\Facades\ResourceServerContext; use App\ModelSerializers\SerializerUtils; use App\Rules\Boolean; @@ -88,6 +90,69 @@ protected function getRepository(): IBaseRepository * @param $summit_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Get( + path: "/api/v1/summits/{id}/proposed-schedules/{source}/presentations", + summary: "Get proposed schedule events for a specific source", + security: [["Bearer" => []]], + tags: ["summit-proposed-schedule"], + parameters: [ + new OA\Parameter( + name: "id", + in: "path", + required: true, + schema: new OA\Schema(type: "integer"), + description: "The summit id" + ), + new OA\Parameter( + name: "source", + in: "path", + required: true, + schema: new OA\Schema(type: "string"), + description: "The source identifier" + ), + new OA\Parameter( + name: "page", + in: "query", + required: false, + schema: new OA\Schema(type: "integer", default: 1), + description: "Page number" + ), + new OA\Parameter( + name: "per_page", + in: "query", + required: false, + schema: new OA\Schema(type: "integer", default: 10), + description: "Items per page" + ), + new OA\Parameter( + name: "filter", + in: "query", + required: false, + explode: false, + schema: new OA\Schema(type: "string"), + description: "Filter operators: start_date==//<=/>=/ [], end_date==//<=/>=/ [], duration==//<=/>=, presentation_title@@/=@, presentation_id==, location_id==, track_id==, type_show_always_on_schedule==" + ), + new OA\Parameter( + name: "order", + in: "query", + required: false, + explode: false, + schema: new OA\Schema(type: "string"), + description: "Order by fields: start_date, end_date, presentation_id, presentation_title, track_id" + ) + ], + responses: [ + new OA\Response( + response: 200, + description: "OK", + content: new OA\JsonContent(ref: "#/components/schemas/PaginatedSummitProposedScheduleSummitEventsResponse") + ), + new OA\Response(response: Response::HTTP_UNAUTHORIZED, description: "Unauthorized"), + new OA\Response(response: Response::HTTP_FORBIDDEN, description: "Forbidden"), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Not Found"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error") + ] + )] public function getProposedScheduleEvents($summit_id, $source) { @@ -146,6 +211,55 @@ function () { * @param $presentation_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Put( + path: "/api/v1/summits/{id}/proposed-schedules/{source}/presentations/{presentation_id}/propose", + summary: "Publish a presentation to the proposed schedule", + security: [["Bearer" => []]], + tags: ["summit-proposed-schedule"], + parameters: [ + new OA\Parameter( + name: "id", + in: "path", + required: true, + schema: new OA\Schema(type: "integer"), + description: "The summit id" + ), + new OA\Parameter( + name: "source", + in: "path", + required: true, + schema: new OA\Schema(type: "string"), + description: "The source identifier" + ), + new OA\Parameter( + name: "presentation_id", + in: "path", + required: true, + schema: new OA\Schema(type: "integer"), + description: "The presentation id" + ) + ], + requestBody: new OA\RequestBody( + required: true, + content: new OA\MediaType( + mediaType: "application/json", + schema: new OA\Schema(ref: "#/components/schemas/SummitProposedSchedulePublishRequest") + ) + ), + responses: [ + new OA\Response( + response: 201, + description: "Created", + content: new OA\JsonContent(ref: "#/components/schemas/SummitProposedScheduleSummitEvent") + ), + new OA\Response(response: Response::HTTP_BAD_REQUEST, description: "Bad Request"), + new OA\Response(response: Response::HTTP_UNAUTHORIZED, description: "Unauthorized"), + new OA\Response(response: Response::HTTP_FORBIDDEN, description: "Forbidden"), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Not Found"), + new OA\Response(response: Response::HTTP_PRECONDITION_FAILED, description: "Validation Error"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error") + ] + )] public function publish($summit_id, $source, $presentation_id) { @@ -173,6 +287,42 @@ public function publish($summit_id, $source, $presentation_id) * @param $presentation_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Delete( + path: "/api/v1/summits/{id}/proposed-schedules/{source}/presentations/{presentation_id}/propose", + summary: "Unpublish a presentation from the proposed schedule", + security: [["Bearer" => []]], + tags: ["summit-proposed-schedule"], + parameters: [ + new OA\Parameter( + name: "id", + in: "path", + required: true, + schema: new OA\Schema(type: "integer"), + description: "The summit id" + ), + new OA\Parameter( + name: "source", + in: "path", + required: true, + schema: new OA\Schema(type: "string"), + description: "The source identifier" + ), + new OA\Parameter( + name: "presentation_id", + in: "path", + required: true, + schema: new OA\Schema(type: "integer"), + description: "The presentation id" + ) + ], + responses: [ + new OA\Response(response: 204, description: "No Content"), + new OA\Response(response: Response::HTTP_UNAUTHORIZED, description: "Unauthorized"), + new OA\Response(response: Response::HTTP_FORBIDDEN, description: "Forbidden"), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Not Found"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error") + ] + )] public function unpublish($summit_id, $source, $presentation_id) { @@ -194,6 +344,56 @@ public function unpublish($summit_id, $source, $presentation_id) * @param $summit_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Put( + path: "/api/v1/summits/{id}/proposed-schedules/{source}/presentations/all/publish", + summary: "Publish all presentations to the proposed schedule with optional filters", + security: [["Bearer" => []]], + tags: ["summit-proposed-schedule"], + parameters: [ + new OA\Parameter( + name: "id", + in: "path", + required: true, + schema: new OA\Schema(type: "integer"), + description: "The summit id" + ), + new OA\Parameter( + name: "source", + in: "path", + required: true, + schema: new OA\Schema(type: "string"), + description: "The source identifier" + ), + new OA\Parameter( + name: "filter", + in: "query", + required: false, + explode: false, + schema: new OA\Schema(type: "string"), + description: "Filter operators: start_date==//<=/>=/ [], end_date==//<=/>=/ [], location_id==, track_id==" + ) + ], + requestBody: new OA\RequestBody( + required: true, + content: new OA\MediaType( + mediaType: "application/json", + schema: new OA\Schema(ref: "#/components/schemas/SummitProposedSchedulePublishAllRequest") + ) + ), + responses: [ + new OA\Response( + response: 200, + description: "OK", + content: new OA\JsonContent(ref: "#/components/schemas/SummitProposedSchedulePublishAllResponse") + ), + new OA\Response(response: Response::HTTP_BAD_REQUEST, description: "Bad Request"), + new OA\Response(response: Response::HTTP_UNAUTHORIZED, description: "Unauthorized"), + new OA\Response(response: Response::HTTP_FORBIDDEN, description: "Forbidden"), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Not Found"), + new OA\Response(response: Response::HTTP_PRECONDITION_FAILED, description: "Validation Error"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error") + ] + )] public function publishAll($summit_id, $source) { @@ -238,6 +438,55 @@ public function publishAll($summit_id, $source) * @param $track_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Post( + path: "/api/v1/summits/{id}/proposed-schedules/{source}/tracks/{track_id}/lock", + summary: "Send a track schedule for review (lock the track)", + security: [["Bearer" => []]], + tags: ["summit-proposed-schedule"], + parameters: [ + new OA\Parameter( + name: "id", + in: "path", + required: true, + schema: new OA\Schema(type: "integer"), + description: "The summit id" + ), + new OA\Parameter( + name: "source", + in: "path", + required: true, + schema: new OA\Schema(type: "string"), + description: "The source identifier" + ), + new OA\Parameter( + name: "track_id", + in: "path", + required: true, + schema: new OA\Schema(type: "integer"), + description: "The track id" + ) + ], + requestBody: new OA\RequestBody( + required: true, + content: new OA\MediaType( + mediaType: "application/json", + schema: new OA\Schema(ref: "#/components/schemas/SummitProposedScheduleLockRequest") + ) + ), + responses: [ + new OA\Response( + response: 201, + description: "Created", + content: new OA\JsonContent(ref: "#/components/schemas/SummitProposedScheduleLock") + ), + new OA\Response(response: Response::HTTP_BAD_REQUEST, description: "Bad Request"), + new OA\Response(response: Response::HTTP_UNAUTHORIZED, description: "Unauthorized"), + new OA\Response(response: Response::HTTP_FORBIDDEN, description: "Forbidden"), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Not Found"), + new OA\Response(response: Response::HTTP_PRECONDITION_FAILED, description: "Validation Error"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error") + ] + )] public function send2Review($summit_id, $source, $track_id) { return $this->processRequest(function () use ($summit_id, $source, $track_id) { @@ -266,6 +515,51 @@ public function send2Review($summit_id, $source, $track_id) * @param $track_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Delete( + path: "/api/v1/summits/{id}/proposed-schedules/{source}/tracks/{track_id}/lock", + summary: "Remove review lock from a track schedule (unlock the track)", + security: [["Bearer" => []]], + tags: ["summit-proposed-schedule"], + parameters: [ + new OA\Parameter( + name: "id", + in: "path", + required: true, + schema: new OA\Schema(type: "integer"), + description: "The summit id" + ), + new OA\Parameter( + name: "source", + in: "path", + required: true, + schema: new OA\Schema(type: "string"), + description: "The source identifier" + ), + new OA\Parameter( + name: "track_id", + in: "path", + required: true, + schema: new OA\Schema(type: "integer"), + description: "The track id" + ) + ], + requestBody: new OA\RequestBody( + required: true, + content: new OA\MediaType( + mediaType: "application/json", + schema: new OA\Schema(ref: "#/components/schemas/SummitProposedScheduleLockRequest") + ) + ), + responses: [ + new OA\Response(response: 204, description: "No Content"), + new OA\Response(response: Response::HTTP_BAD_REQUEST, description: "Bad Request"), + new OA\Response(response: Response::HTTP_UNAUTHORIZED, description: "Unauthorized"), + new OA\Response(response: Response::HTTP_FORBIDDEN, description: "Forbidden"), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Not Found"), + new OA\Response(response: Response::HTTP_PRECONDITION_FAILED, description: "Validation Error"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error") + ] + )] public function removeReview($summit_id, $source, $track_id) { return $this->processRequest(function () use ($summit_id, $source, $track_id) { @@ -286,6 +580,69 @@ public function removeReview($summit_id, $source, $track_id) * @param $source * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Get( + path: "/api/v1/summits/{id}/proposed-schedules/{source}/locks", + summary: "Get all proposed schedule review submissions (locks) for a source", + security: [["Bearer" => []]], + tags: ["summit-proposed-schedule"], + parameters: [ + new OA\Parameter( + name: "id", + in: "path", + required: true, + schema: new OA\Schema(type: "integer"), + description: "The summit id" + ), + new OA\Parameter( + name: "source", + in: "path", + required: true, + schema: new OA\Schema(type: "string"), + description: "The source identifier" + ), + new OA\Parameter( + name: "page", + in: "query", + required: false, + schema: new OA\Schema(type: "integer", default: 1), + description: "Page number" + ), + new OA\Parameter( + name: "per_page", + in: "query", + required: false, + schema: new OA\Schema(type: "integer", default: 10), + description: "Items per page" + ), + new OA\Parameter( + name: "filter", + in: "query", + required: false, + explode: false, + schema: new OA\Schema(type: "string"), + description: "Filter operators: track_id==" + ), + new OA\Parameter( + name: "order", + in: "query", + required: false, + explode: false, + schema: new OA\Schema(type: "string"), + description: "Order by fields: track_id" + ) + ], + responses: [ + new OA\Response( + response: 200, + description: "OK", + content: new OA\JsonContent(ref: "#/components/schemas/PaginatedSummitProposedScheduleLocksResponse") + ), + new OA\Response(response: Response::HTTP_UNAUTHORIZED, description: "Unauthorized"), + new OA\Response(response: Response::HTTP_FORBIDDEN, description: "Forbidden"), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Not Found"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error") + ] + )] public function getProposedScheduleReviewSubmissions($summit_id, $source) { $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find(intval($summit_id)); @@ -327,4 +684,4 @@ function ($page, $per_page, $filter, $order, $applyExtraFilters) use ($summit_id } ); } -} \ No newline at end of file +} diff --git a/app/Swagger/SummitProposedScheduleSchemas.php b/app/Swagger/SummitProposedScheduleSchemas.php index c401815ab..ddf5afec2 100644 --- a/app/Swagger/SummitProposedScheduleSchemas.php +++ b/app/Swagger/SummitProposedScheduleSchemas.php @@ -64,3 +64,130 @@ class SummitProposedScheduleAllowedDayAddRequest {} ] )] class SummitProposedScheduleAllowedDayUpdateRequest {} +#[OA\Schema( + schema: "SummitProposedScheduleSummitEvent", + properties: [ + new OA\Property(property: "id", type: "integer", example: 1), + new OA\Property(property: "created", type: "integer", description: "Unix timestamp", example: 1640995200), + new OA\Property(property: "last_edited", type: "integer", description: "Unix timestamp", example: 1640995200), + new OA\Property(property: "start_date", type: "integer", description: "Unix timestamp", example: 1640995200), + new OA\Property(property: "end_date", type: "integer", description: "Unix timestamp", example: 1641081600), + new OA\Property(property: "duration", type: "integer", description: "Duration in seconds", example: 3600), + ], + anyOf: [ + new OA\Property(property: "schedule_id", type: "integer", example: 1), + new OA\Property(property: "schedule", type: "SummitProposedSchedule"), + new OA\Property(property: "summit_event_id", type: "integer", example: 100), + new OA\Property(property: "summit_event", type: "SummitEvent"), + new OA\Property(property: "location_id", type: "integer", example: 10), + new OA\Property(property: "location", type: "SummitAbstractLocation"), + new OA\Property(property: "created_by_id", type: "integer", example: 5), + new OA\Property(property: "created_by", type: "Member"), + new OA\Property(property: "updated_by_id", type: "integer", example: 5, nullable: true), + new OA\Property(property: "updated_by", type: "Member"), + ] +)] +class SummitProposedScheduleSummitEvent {} + +#[OA\Schema( + schema: "SummitProposedSchedulePublishRequest", + required: ["start_date", "end_date", "location_id"], + properties: [ + new OA\Property(property: "start_date", type: "integer", description: "Unix timestamp", example: 1640995200), + new OA\Property(property: "end_date", type: "integer", description: "Unix timestamp (must be after start_date)", example: 1641081600), + new OA\Property(property: "duration", type: "integer", description: "Duration in seconds", example: 3600), + ], + anyOf: [ + new OA\Property(property: "location_id", type: "integer", example: 10), + new OA\Property(property: "location", type: "SummitAbstractLocation"), + ] +)] +class SummitProposedSchedulePublishRequest {} + +#[OA\Schema( + schema: "SummitProposedSchedulePublishAllRequest", + properties: [ + new OA\Property(property: "event_ids", type: "array", items: new OA\Items(type: "integer"), description: "Array of event IDs to publish") + ] +)] +class SummitProposedSchedulePublishAllRequest {} + +#[OA\Schema( + schema: "SummitProposedScheduleLock", + properties: [ + new OA\Property(property: "id", type: "integer", example: 1), + new OA\Property(property: "created", type: "integer", description: "Unix timestamp", example: 1640995200), + new OA\Property(property: "last_edited", type: "integer", description: "Unix timestamp", example: 1640995200), + new OA\Property(property: "reason", type: "string", example: "Review in progress"), + ], + anyOf: [ + new OA\Property(property: "created_by_id", type: "integer", example: 5), + new OA\Property(property: "created_by", type: "Member"), + new OA\Property(property: "track_id", type: "integer", example: 3), + new OA\Property(property: "track", type: "PresentationCategory") + ] +)] +class SummitProposedScheduleLock {} + +#[OA\Schema( + schema: "SummitProposedScheduleLockRequest", + properties: [ + new OA\Property(property: "message", type: "string", maxLength: 1024, example: "Sending track schedule for review") + ] +)] +class SummitProposedScheduleLockRequest {} + +#[OA\Schema( + schema: "PaginatedSummitProposedScheduleSummitEventsResponse", + allOf: [ + new OA\Schema(ref: "#/components/schemas/PaginateDataSchemaResponse"), + new OA\Schema( + type: "object", + properties: [ + new OA\Property( + property: "data", + type: "array", + items: new OA\Items(ref: "#/components/schemas/SummitProposedScheduleSummitEvent") + ) + ] + ) + ] +)] +class PaginatedSummitProposedScheduleSummitEventsResponse {} + +#[OA\Schema( + schema: "PaginatedSummitProposedScheduleLocksResponse", + allOf: [ + new OA\Schema(ref: "#/components/schemas/PaginateDataSchemaResponse"), + new OA\Schema( + type: "object", + properties: [ + new OA\Property( + property: "data", + type: "array", + items: new OA\Items(ref: "#/components/schemas/SummitProposedScheduleLock") + ) + ] + ) + ] +)] +class PaginatedSummitProposedScheduleLocksResponse {} + +#[OA\Schema( + schema: "SummitProposedSchedulePublishAllResponse", + properties: [ + new OA\Property(property: "id", type: "integer", example: 1), + new OA\Property(property: "created", type: "integer", description: "Unix timestamp", example: 1640995200), + new OA\Property(property: "last_edited", type: "integer", description: "Unix timestamp", example: 1640995200), + new OA\Property(property: "name", type: "string", example: "Review in progress"), + new OA\Property(property: "source", type: "string", example: "Google Calendar"), + new OA\Property(property: "summit_id", type: "integer", example: 3), + new OA\Property(property: "scheduled_summit_events", type: "array", items: new OA\Items(ref: "#/components/schemas/SummitProposedScheduleSummitEvent"), description: "Array of scheduled summit events, only available if it is added in expand."), + new OA\Property(property: "locks", type: "array", items: new OA\Items(ref: "#/components/schemas/SummitProposedScheduleLock")), + ], + anyOf: [ + new OA\Property(property: "created_by_id", type: "integer", example: 5), + new OA\Property(property: "created_by", type: "Member"), + ] +)] +class SummitProposedSchedulePublishAllResponse {} From 91d59b4fd863121f8dd375ab85aaf459c3e991b1 Mon Sep 17 00:00:00 2001 From: Matias Perrone Date: Wed, 26 Nov 2025 22:38:05 +0000 Subject: [PATCH 2/6] chore: Add the correct security and x attributes and create security schema, fix path routes and change schema to be defined as requested --- ...th2SummitProposedScheduleApiController.php | 107 +++++++++++++++--- .../SummitProposedScheduleSecuritySchemas.php | 26 +++++ 2 files changed, 119 insertions(+), 14 deletions(-) create mode 100644 app/Swagger/SummitProposedScheduleSecuritySchemas.php diff --git a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitProposedScheduleApiController.php b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitProposedScheduleApiController.php index 1f242b236..ac2cddbd2 100644 --- a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitProposedScheduleApiController.php +++ b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitProposedScheduleApiController.php @@ -12,6 +12,8 @@ * limitations under the License. **/ +use App\Models\Foundation\Main\IGroup; +use App\Security\SummitScopes; use Illuminate\Http\Response; use OpenApi\Attributes as OA; use App\Facades\ResourceServerContext; @@ -92,9 +94,23 @@ protected function getRepository(): IBaseRepository */ #[OA\Get( path: "/api/v1/summits/{id}/proposed-schedules/{source}/presentations", + operationId: 'getProposedScheduleEvents', + description: "required-groups " . IGroup::SuperAdmins . ", " . IGroup::Administrators . ", " . IGroup::SummitAdministrators . ", " . IGroup::TrackChairs . ", " . IGroup::TrackChairsAdmins, summary: "Get proposed schedule events for a specific source", - security: [["Bearer" => []]], - tags: ["summit-proposed-schedule"], + tags: ["Summit Proposed Schedule"], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + IGroup::TrackChairs, + IGroup::TrackChairsAdmins + ] + ], + security: [['summit_proposed_schedule_oauth2' => [ + SummitScopes::ReadAllSummitData, + SummitScopes::ReadSummitData, + ]]], parameters: [ new OA\Parameter( name: "id", @@ -213,9 +229,22 @@ function () { */ #[OA\Put( path: "/api/v1/summits/{id}/proposed-schedules/{source}/presentations/{presentation_id}/propose", + operationId: 'publishProposedSchedulePresentation', + description: "required-groups " . IGroup::SuperAdmins . ", " . IGroup::Administrators . ", " . IGroup::SummitAdministrators . ", " . IGroup::TrackChairs . ", " . IGroup::TrackChairsAdmins, summary: "Publish a presentation to the proposed schedule", - security: [["Bearer" => []]], - tags: ["summit-proposed-schedule"], + tags: ["Summit Proposed Schedule"], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + IGroup::TrackChairs, + IGroup::TrackChairsAdmins + ] + ], + security: [['summit_proposed_schedule_oauth2' => [ + SummitScopes::WriteSummitData, + ]]], parameters: [ new OA\Parameter( name: "id", @@ -289,9 +318,22 @@ public function publish($summit_id, $source, $presentation_id) */ #[OA\Delete( path: "/api/v1/summits/{id}/proposed-schedules/{source}/presentations/{presentation_id}/propose", + operationId: 'unpublishProposedSchedulePresentation', + description: "required-groups " . IGroup::SuperAdmins . ", " . IGroup::Administrators . ", " . IGroup::SummitAdministrators . ", " . IGroup::TrackChairs . ", " . IGroup::TrackChairsAdmins, summary: "Unpublish a presentation from the proposed schedule", - security: [["Bearer" => []]], - tags: ["summit-proposed-schedule"], + tags: ["Summit Proposed Schedule"], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + IGroup::TrackChairs, + IGroup::TrackChairsAdmins + ] + ], + security: [['summit_proposed_schedule_oauth2' => [ + SummitScopes::WriteSummitData, + ]]], parameters: [ new OA\Parameter( name: "id", @@ -346,9 +388,22 @@ public function unpublish($summit_id, $source, $presentation_id) */ #[OA\Put( path: "/api/v1/summits/{id}/proposed-schedules/{source}/presentations/all/publish", + operationId: 'publishAllProposedSchedulePresentations', + description: "required-groups " . IGroup::SuperAdmins . ", " . IGroup::Administrators . ", " . IGroup::SummitAdministrators . ", " . IGroup::TrackChairs . ", " . IGroup::TrackChairsAdmins, summary: "Publish all presentations to the proposed schedule with optional filters", - security: [["Bearer" => []]], - tags: ["summit-proposed-schedule"], + tags: ["Summit Proposed Schedule"], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + IGroup::TrackChairs, + IGroup::TrackChairsAdmins + ] + ], + security: [['summit_proposed_schedule_oauth2' => [ + SummitScopes::WriteSummitData, + ]]], parameters: [ new OA\Parameter( name: "id", @@ -440,9 +495,19 @@ public function publishAll($summit_id, $source) */ #[OA\Post( path: "/api/v1/summits/{id}/proposed-schedules/{source}/tracks/{track_id}/lock", + operationId: 'sendProposedScheduleTrackToReview', + description: "required-groups " . IGroup::TrackChairs . ", " . IGroup::TrackChairsAdmins, summary: "Send a track schedule for review (lock the track)", - security: [["Bearer" => []]], - tags: ["summit-proposed-schedule"], + tags: ["Summit Proposed Schedule"], + x: [ + 'required-groups' => [ + IGroup::TrackChairs, + IGroup::TrackChairsAdmins + ] + ], + security: [['summit_proposed_schedule_oauth2' => [ + SummitScopes::WriteSummitData, + ]]], parameters: [ new OA\Parameter( name: "id", @@ -517,9 +582,20 @@ public function send2Review($summit_id, $source, $track_id) */ #[OA\Delete( path: "/api/v1/summits/{id}/proposed-schedules/{source}/tracks/{track_id}/lock", + operationId: 'removeProposedScheduleTrackReview', + description: "required-groups " . IGroup::SuperAdmins . ", " . IGroup::Administrators . ", " . IGroup::SummitAdministrators, summary: "Remove review lock from a track schedule (unlock the track)", - security: [["Bearer" => []]], - tags: ["summit-proposed-schedule"], + tags: ["Summit Proposed Schedule"], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators + ] + ], + security: [['summit_proposed_schedule_oauth2' => [ + SummitScopes::WriteSummitData, + ]]], parameters: [ new OA\Parameter( name: "id", @@ -582,9 +658,12 @@ public function removeReview($summit_id, $source, $track_id) */ #[OA\Get( path: "/api/v1/summits/{id}/proposed-schedules/{source}/locks", + operationId: 'getProposedScheduleReviewSubmissions', summary: "Get all proposed schedule review submissions (locks) for a source", - security: [["Bearer" => []]], - tags: ["summit-proposed-schedule"], + tags: ["Summit Proposed Schedule"], + security: [['summit_proposed_schedule_oauth2' => [ + SummitScopes::ReadSummitData, + ]]], parameters: [ new OA\Parameter( name: "id", diff --git a/app/Swagger/SummitProposedScheduleSecuritySchemas.php b/app/Swagger/SummitProposedScheduleSecuritySchemas.php new file mode 100644 index 000000000..b61fb42e5 --- /dev/null +++ b/app/Swagger/SummitProposedScheduleSecuritySchemas.php @@ -0,0 +1,26 @@ + 'Read All Summit Data', + SummitScopes::ReadSummitData => 'Read Summit Data', + SummitScopes::WriteSummitData => 'Write Summit Data', + ], + ), + ], + ) +] +class SummitProposedScheduleSecuritySchemas{} From ecfe5c403dae9117cf47e15007f4608d77b65e23 Mon Sep 17 00:00:00 2001 From: Matias Perrone Date: Wed, 3 Dec 2025 20:59:25 +0000 Subject: [PATCH 3/6] feat: Add changes requested --- app/Swagger/SummitProposedScheduleSchemas.php | 38 +++++++------------ 1 file changed, 13 insertions(+), 25 deletions(-) diff --git a/app/Swagger/SummitProposedScheduleSchemas.php b/app/Swagger/SummitProposedScheduleSchemas.php index ddf5afec2..bf12ddc75 100644 --- a/app/Swagger/SummitProposedScheduleSchemas.php +++ b/app/Swagger/SummitProposedScheduleSchemas.php @@ -10,13 +10,11 @@ new OA\Property(property: "id", type: "integer", example: 1), new OA\Property(property: "created", type: "integer", description: "Unix timestamp", example: 1640995200), new OA\Property(property: "last_edited", type: "integer", description: "Unix timestamp", example: 1640995200), - new OA\Property(property: "allowed_timeframes", type: "array", items: new OA\Items(type: ["integer", "SummitProposedScheduleAllowedDay"]), description: "Array of allowed timeframe IDs or objects when expanded", nullable: true) - ], - anyOf: [ + new OA\Property(property: "allowed_timeframes", type: "array", items: new OA\Items(type: "integer"), description: "Array SummitProposedScheduleAllowedDay IDs or full SummitProposedScheduleAllowedDay objects when expanded", nullable: true), new OA\Property(property: "location_id", type: "integer", example: 10, description: "only when not expanded"), - new OA\Property(property: "location", type: "SummitAbstractLocation", description: "only when expanded"), + new OA\Property(property: "location", type: "SummitAbstractLocation", description: "ID of the SummitAbstractLocation, when not expanded, when ?expand=location, you get a SummitAbstractLocation schema object in a 'location' property"), new OA\Property(property: "track_id", type: "integer", example: 5, description: "only when not expanded"), - new OA\Property(property: "track", type: "PresentationCategory", description: "only when expanded"), + new OA\Property(property: "track", type: "PresentationCategory", description: "ID of the PresentationCategory, when not expanded, when ?expand=track, you get a PresentationCategory schema object in a 'track' property"), ], )] class SummitProposedScheduleAllowedLocation {} @@ -73,18 +71,14 @@ class SummitProposedScheduleAllowedDayUpdateRequest {} new OA\Property(property: "start_date", type: "integer", description: "Unix timestamp", example: 1640995200), new OA\Property(property: "end_date", type: "integer", description: "Unix timestamp", example: 1641081600), new OA\Property(property: "duration", type: "integer", description: "Duration in seconds", example: 3600), - ], - anyOf: [ - new OA\Property(property: "schedule_id", type: "integer", example: 1), - new OA\Property(property: "schedule", type: "SummitProposedSchedule"), + new OA\Property(property: "schedule_id", type: "integer", description: "ID of the SummitProposedSchedule, when not expanded, when ?expand=schedule, you get a SummitProposedSchedule schema object in a 'schedule' property"), new OA\Property(property: "summit_event_id", type: "integer", example: 100), - new OA\Property(property: "summit_event", type: "SummitEvent"), - new OA\Property(property: "location_id", type: "integer", example: 10), - new OA\Property(property: "location", type: "SummitAbstractLocation"), - new OA\Property(property: "created_by_id", type: "integer", example: 5), - new OA\Property(property: "created_by", type: "Member"), - new OA\Property(property: "updated_by_id", type: "integer", example: 5, nullable: true), - new OA\Property(property: "updated_by", type: "Member"), + new OA\Property(property: "summit_event", ref: "#/components/schemas/SummitEvent", description: "only present if ?expand=summit_event"), + new OA\Property(property: "location_id", type: "integer", description: "ID of the SummitAbstractLocation, when not expanded, when ?expand=location, you get a SummitAbstractLocation schema object in a 'location' property"), + new OA\Property(property: "created_by_id", type: "integer", example: 5, description: "not present if expanded"), + new OA\Property(property: "created_by", ref: "#/components/schemas/Member", description: "only present if ?expand=created_by"), + new OA\Property(property: "updated_by_id", type: "integer", example: 5, nullable: true, description: "not present if expanded"), + new OA\Property(property: "updated_by", ref: "#/components/schemas/Member", description: "only present if ?expand=updated_by"), ] )] class SummitProposedScheduleSummitEvent {} @@ -96,10 +90,7 @@ class SummitProposedScheduleSummitEvent {} new OA\Property(property: "start_date", type: "integer", description: "Unix timestamp", example: 1640995200), new OA\Property(property: "end_date", type: "integer", description: "Unix timestamp (must be after start_date)", example: 1641081600), new OA\Property(property: "duration", type: "integer", description: "Duration in seconds", example: 3600), - ], - anyOf: [ - new OA\Property(property: "location_id", type: "integer", example: 10), - new OA\Property(property: "location", type: "SummitAbstractLocation"), + new OA\Property(property: "location_id", type: "integer", description: "ID of the SummitAbstractLocation, when not expanded, when ?expand=location, you get a SummitAbstractLocation schema object in a 'location' property"), ] )] class SummitProposedSchedulePublishRequest {} @@ -119,12 +110,9 @@ class SummitProposedSchedulePublishAllRequest {} new OA\Property(property: "created", type: "integer", description: "Unix timestamp", example: 1640995200), new OA\Property(property: "last_edited", type: "integer", description: "Unix timestamp", example: 1640995200), new OA\Property(property: "reason", type: "string", example: "Review in progress"), - ], - anyOf: [ new OA\Property(property: "created_by_id", type: "integer", example: 5), - new OA\Property(property: "created_by", type: "Member"), - new OA\Property(property: "track_id", type: "integer", example: 3), - new OA\Property(property: "track", type: "PresentationCategory") + new OA\Property(property: "created_by", ref: "#/components/schemas/Member", description: "only present if ?expand=created_by"), + new OA\Property(property: "track_id", type: "integer", example: 3, description: "ID of the PresentationCategory, when not expanded, when ?expand=track, you get a PresentationCategory schema object in a 'track' property"), ] )] class SummitProposedScheduleLock {} From 6918094bbe0c07f6626da089f73ea55a3291948c Mon Sep 17 00:00:00 2001 From: Matias Perrone Date: Wed, 3 Dec 2025 20:59:59 +0000 Subject: [PATCH 4/6] feat: Add changes requested --- app/Swagger/SummitProposedScheduleSchemas.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/Swagger/SummitProposedScheduleSchemas.php b/app/Swagger/SummitProposedScheduleSchemas.php index bf12ddc75..09327cf3a 100644 --- a/app/Swagger/SummitProposedScheduleSchemas.php +++ b/app/Swagger/SummitProposedScheduleSchemas.php @@ -172,8 +172,6 @@ class PaginatedSummitProposedScheduleLocksResponse {} new OA\Property(property: "summit_id", type: "integer", example: 3), new OA\Property(property: "scheduled_summit_events", type: "array", items: new OA\Items(ref: "#/components/schemas/SummitProposedScheduleSummitEvent"), description: "Array of scheduled summit events, only available if it is added in expand."), new OA\Property(property: "locks", type: "array", items: new OA\Items(ref: "#/components/schemas/SummitProposedScheduleLock")), - ], - anyOf: [ new OA\Property(property: "created_by_id", type: "integer", example: 5), new OA\Property(property: "created_by", type: "Member"), ] From c54bd175ec14679f24ca6d606096ecc15d541432 Mon Sep 17 00:00:00 2001 From: Matias Perrone Date: Fri, 5 Dec 2025 15:30:33 +0000 Subject: [PATCH 5/6] chore: include PR requested changes --- app/Swagger/SummitProposedScheduleSchemas.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/Swagger/SummitProposedScheduleSchemas.php b/app/Swagger/SummitProposedScheduleSchemas.php index 09327cf3a..a03f3b362 100644 --- a/app/Swagger/SummitProposedScheduleSchemas.php +++ b/app/Swagger/SummitProposedScheduleSchemas.php @@ -12,9 +12,9 @@ new OA\Property(property: "last_edited", type: "integer", description: "Unix timestamp", example: 1640995200), new OA\Property(property: "allowed_timeframes", type: "array", items: new OA\Items(type: "integer"), description: "Array SummitProposedScheduleAllowedDay IDs or full SummitProposedScheduleAllowedDay objects when expanded", nullable: true), new OA\Property(property: "location_id", type: "integer", example: 10, description: "only when not expanded"), - new OA\Property(property: "location", type: "SummitAbstractLocation", description: "ID of the SummitAbstractLocation, when not expanded, when ?expand=location, you get a SummitAbstractLocation schema object in a 'location' property"), + new OA\Property(property: "location", type: "integer", description: "ID of the SummitAbstractLocation, when not expanded, when ?expand=location, you get a SummitAbstractLocation schema object in a 'location' property"), new OA\Property(property: "track_id", type: "integer", example: 5, description: "only when not expanded"), - new OA\Property(property: "track", type: "PresentationCategory", description: "ID of the PresentationCategory, when not expanded, when ?expand=track, you get a PresentationCategory schema object in a 'track' property"), + new OA\Property(property: "track", type: "integer", description: "ID of the PresentationCategory, when not expanded, when ?expand=track, you get a PresentationCategory schema object in a 'track' property"), ], )] class SummitProposedScheduleAllowedLocation {} @@ -173,7 +173,7 @@ class PaginatedSummitProposedScheduleLocksResponse {} new OA\Property(property: "scheduled_summit_events", type: "array", items: new OA\Items(ref: "#/components/schemas/SummitProposedScheduleSummitEvent"), description: "Array of scheduled summit events, only available if it is added in expand."), new OA\Property(property: "locks", type: "array", items: new OA\Items(ref: "#/components/schemas/SummitProposedScheduleLock")), new OA\Property(property: "created_by_id", type: "integer", example: 5), - new OA\Property(property: "created_by", type: "Member"), + new OA\Property(property: "created_by", ref: "#/components/schemas/Member"), ] )] class SummitProposedSchedulePublishAllResponse {} From 32ea909d2ed00500bfaf1acd993cfcacc7c90908 Mon Sep 17 00:00:00 2001 From: Matias Perrone Date: Wed, 17 Dec 2025 15:31:50 +0000 Subject: [PATCH 6/6] chore: include PR requested changes --- .../OAuth2SummitProposedScheduleApiController.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitProposedScheduleApiController.php b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitProposedScheduleApiController.php index ac2cddbd2..ce141b49f 100644 --- a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitProposedScheduleApiController.php +++ b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitProposedScheduleApiController.php @@ -159,7 +159,7 @@ protected function getRepository(): IBaseRepository ], responses: [ new OA\Response( - response: 200, + response: Response::HTTP_OK, description: "OK", content: new OA\JsonContent(ref: "#/components/schemas/PaginatedSummitProposedScheduleSummitEventsResponse") ), @@ -277,7 +277,7 @@ function () { ), responses: [ new OA\Response( - response: 201, + response: Response::HTTP_CREATED, description: "Created", content: new OA\JsonContent(ref: "#/components/schemas/SummitProposedScheduleSummitEvent") ), @@ -358,7 +358,7 @@ public function publish($summit_id, $source, $presentation_id) ) ], responses: [ - new OA\Response(response: 204, description: "No Content"), + new OA\Response(response: Response::HTTP_NO_CONTENT, description: "No Content"), new OA\Response(response: Response::HTTP_UNAUTHORIZED, description: "Unauthorized"), new OA\Response(response: Response::HTTP_FORBIDDEN, description: "Forbidden"), new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Not Found"), @@ -437,7 +437,7 @@ public function unpublish($summit_id, $source, $presentation_id) ), responses: [ new OA\Response( - response: 200, + response: Response::HTTP_OK, description: "OK", content: new OA\JsonContent(ref: "#/components/schemas/SummitProposedSchedulePublishAllResponse") ), @@ -540,7 +540,7 @@ public function publishAll($summit_id, $source) ), responses: [ new OA\Response( - response: 201, + response: Response::HTTP_CREATED, description: "Created", content: new OA\JsonContent(ref: "#/components/schemas/SummitProposedScheduleLock") ), @@ -627,7 +627,7 @@ public function send2Review($summit_id, $source, $track_id) ) ), responses: [ - new OA\Response(response: 204, description: "No Content"), + new OA\Response(response: Response::HTTP_NO_CONTENT, description: "No Content"), 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"), @@ -712,7 +712,7 @@ public function removeReview($summit_id, $source, $track_id) ], responses: [ new OA\Response( - response: 200, + response: Response::HTTP_OK, description: "OK", content: new OA\JsonContent(ref: "#/components/schemas/PaginatedSummitProposedScheduleLocksResponse") ),