From 16f87246f64c3528ad4d91473211e4b5c4bea9d6 Mon Sep 17 00:00:00 2001 From: Matias Perrone Date: Thu, 2 Oct 2025 15:11:38 -0300 Subject: [PATCH] feat: Extend Swagger Coverage for controller Apis/Protected/Summit/OAuth2SummitBadgesApiController.php --- .../OAuth2SummitBadgesApiController.php | 131 +++++++++++++++++- app/Swagger/schemas.php | 102 +++++++++++++- 2 files changed, 231 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitBadgesApiController.php b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitBadgesApiController.php index 55cac8eb6..3f383af2b 100644 --- a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitBadgesApiController.php +++ b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitBadgesApiController.php @@ -12,9 +12,11 @@ * limitations under the License. **/ use App\Models\Foundation\Summit\Repositories\ISummitAttendeeBadgeRepository; +use App\Security\SummitScopes; use models\oauth2\IResourceServerContext; use models\summit\ISummitRepository; use ModelSerializers\SerializerRegistry; +use OpenApi\Attributes as OA; use utils\Filter; use utils\FilterElement; @@ -52,6 +54,78 @@ protected function getSummitRepository(): ISummitRepository return $this->summit_repository; } + // OpenAPI Documentation + + #[OA\Get( + path: '/api/v1/summits/{id}/badges', + summary: 'Get all attendee badges for a summit', + description: 'Retrieves a paginated list of attendee badges for a specific summit. Badges are issued to attendees and contain ticket information, badge type, printing details, and feature assignments (ribbons, special access indicators, etc.).', + security: [['oauth2_security_scope' => [SummitScopes::ReadAllSummitData]]], + tags: ['Summit Badges'], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit 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. Format: fieldvalue. Available fields: owner_first_name, owner_last_name, owner_full_name, owner_email, ticket_number, order_number (all support =@, ==). Operators: == (equals), =@ (contains)', + style: 'form', + explode: true, + schema: new OA\Schema( + type: 'array', + items: new OA\Items(type: 'string', example: 'owner_email==john@example.com') + ) + ), + new OA\Parameter( + name: 'order', + in: 'query', + required: false, + description: 'Order by field(s). Available fields: id, ticket_number, order_number, created. Use "-" prefix for descending order.', + schema: new OA\Schema(type: 'string', example: 'created') + ), + new OA\Parameter( + name: 'expand', + in: 'query', + required: false, + description: 'Expand relationships. Available: ticket, type, features', + schema: new OA\Schema(type: 'string', example: 'ticket,type,features') + ), + ], + responses: [ + new OA\Response( + response: 200, + description: 'Attendee badges retrieved successfully', + content: new OA\JsonContent(ref: '#/components/schemas/PaginatedSummitAttendeeBadgesResponse') + ), + new OA\Response(response: 400, ref: '#/components/responses/400'), + new OA\Response(response: 401, ref: '#/components/responses/401'), + new OA\Response(response: 403, ref: '#/components/responses/403'), + new OA\Response(response: 404, ref: '#/components/responses/404'), + new OA\Response(response: 412, ref: '#/components/responses/412'), + new OA\Response(response: 500, ref: '#/components/responses/500'), + ] + )] + /** * @param $summit_id * @return mixed @@ -103,6 +177,61 @@ function(){ ); } + #[OA\Get( + path: '/api/v1/summits/{id}/badges/csv', + summary: 'Export all attendee badges for a summit to CSV', + description: 'Exports a CSV file containing all attendee badges for a specific summit. Supports the same filtering and ordering capabilities as the standard list endpoint.', + security: [['oauth2_security_scope' => [SummitScopes::ReadAllSummitData]]], + tags: ['Summit Badges'], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + description: 'Summit ID', + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'filter[]', + in: 'query', + required: false, + description: 'Filter expressions. Format: fieldvalue. Available fields: owner_first_name, owner_last_name, owner_full_name, owner_email, ticket_number, order_number (all support =@, ==)', + style: 'form', + explode: true, + schema: new OA\Schema( + type: 'array', + items: new OA\Items(type: 'string', example: 'owner_email=@example.com') + ) + ), + new OA\Parameter( + name: 'order', + in: 'query', + required: false, + description: 'Order by field(s). Available fields: id, ticket_number, order_number, created', + schema: new OA\Schema(type: 'string', example: '-created') + ), + ], + responses: [ + new OA\Response( + response: 200, + description: 'CSV file generated successfully', + content: new OA\MediaType( + mediaType: 'text/csv', + schema: new OA\Schema( + type: 'string', + format: 'binary' + ) + ) + ), + new OA\Response(response: 400, ref: '#/components/responses/400'), + new OA\Response(response: 401, ref: '#/components/responses/401'), + new OA\Response(response: 403, ref: '#/components/responses/403'), + new OA\Response(response: 404, ref: '#/components/responses/404'), + new OA\Response(response: 412, ref: '#/components/responses/412'), + new OA\Response(response: 500, ref: '#/components/responses/500'), + ] + )] + /** * @param $summit_id * @return mixed @@ -163,4 +292,4 @@ function(){ -} \ No newline at end of file +} diff --git a/app/Swagger/schemas.php b/app/Swagger/schemas.php index 9d04120a7..2659763e6 100644 --- a/app/Swagger/schemas.php +++ b/app/Swagger/schemas.php @@ -348,4 +348,104 @@ class RSVPUpdateRequestSchema_{ ] )] -class RSVPAdminAddRequestSchema {} \ No newline at end of file +class RSVPAdminAddRequestSchema {} + +// Summit Badge Feature Types + +#[OA\Schema( + schema: 'SummitBadgeFeatureType', + type: 'object', + properties: [ + new OA\Property(property: 'id', type: 'integer', example: 1), + new OA\Property(property: 'name', type: 'string', example: 'Speaker Ribbon'), + new OA\Property(property: 'description', type: 'string', nullable: true, example: 'Special ribbon indicating speaker status'), + new OA\Property(property: 'template_content', type: 'string', nullable: true, example: '
{{name}}
'), + new OA\Property(property: 'summit_id', type: 'integer', example: 42), + new OA\Property(property: 'image', type: 'string', nullable: true, example: 'https://example.com/images/speaker-ribbon.png'), + ] +)] +class SummitBadgeFeatureTypeSchema {} + +#[OA\Schema( + schema: 'PaginatedSummitBadgeFeatureTypesResponse', + 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/SummitBadgeFeatureType') + ) + ] + ) + ] +)] +class PaginatedSummitBadgeFeatureTypesResponseSchema {} + +#[OA\Schema( + schema: 'SummitBadgeFeatureTypeCreateRequest', + type: 'object', + required: ['name'], + properties: [ + new OA\Property(property: 'name', type: 'string', example: 'Speaker Ribbon'), + new OA\Property(property: 'description', type: 'string', nullable: true, example: 'Special ribbon for speakers'), + new OA\Property(property: 'template_content', type: 'string', nullable: true, example: '
{{name}}
'), + ] +)] +class SummitBadgeFeatureTypeCreateRequestSchema {} + +#[OA\Schema( + schema: 'SummitBadgeFeatureTypeUpdateRequest', + type: 'object', + properties: [ + new OA\Property(property: 'name', type: 'string', example: 'VIP Ribbon'), + new OA\Property(property: 'description', type: 'string', nullable: true, example: 'VIP attendee designation'), + new OA\Property(property: 'template_content', type: 'string', nullable: true, example: '
{{name}}
'), + ] +)] +class SummitBadgeFeatureTypeUpdateRequestSchema {} + +// Summit Attendee Badges + +#[OA\Schema( + schema: 'SummitAttendeeBadge', + type: 'object', + properties: [ + new OA\Property(property: 'id', type: 'integer', example: 1), + new OA\Property(property: 'print_date', type: 'integer', nullable: true, example: 1633024800, description: 'Unix timestamp of when the badge was printed'), + new OA\Property(property: 'qr_code', type: 'string', nullable: true, example: 'QR123456789'), + new OA\Property(property: 'is_void', type: 'boolean', example: false, description: 'Whether the badge has been voided'), + new OA\Property(property: 'ticket_id', type: 'integer', example: 123, description: 'Associated ticket ID'), + new OA\Property(property: 'type_id', type: 'integer', example: 5, description: 'Badge type ID'), + new OA\Property(property: 'printed_times', type: 'integer', example: 2, description: 'Number of times this badge has been printed'), + new OA\Property(property: 'print_excerpt', type: 'string', example: 'John Doe - Speaker', description: 'Short text excerpt for printing'), + new OA\Property( + property: 'features', + type: 'array', + description: 'Array of feature IDs assigned to this badge (use expand=features for full details)', + items: new OA\Items(type: 'integer'), + example: [1, 2, 3] + ), + ] +)] +class SummitAttendeeBadgeSchema {} + +#[OA\Schema( + schema: 'PaginatedSummitAttendeeBadgesResponse', + 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/SummitAttendeeBadge') + ) + ] + ) + ] +)] +class PaginatedSummitAttendeeBadgesResponseSchema {}