From e068c88676a415c33d97a92f9f324ba9bb21cf1b Mon Sep 17 00:00:00 2001 From: Matias Perrone Date: Mon, 13 Oct 2025 14:43:32 -0300 Subject: [PATCH 1/8] feat: Extend Swagger Coverage for controller `OAuth2CompaniesApiController` --- .../Main/OAuth2CompaniesApiController.php | 320 ++++++++++++++++-- app/Swagger/CompaniesSchemas.php | 144 +++++++- 2 files changed, 441 insertions(+), 23 deletions(-) diff --git a/app/Http/Controllers/Apis/Protected/Main/OAuth2CompaniesApiController.php b/app/Http/Controllers/Apis/Protected/Main/OAuth2CompaniesApiController.php index 15b33d3c1..007005bfa 100644 --- a/app/Http/Controllers/Apis/Protected/Main/OAuth2CompaniesApiController.php +++ b/app/Http/Controllers/Apis/Protected/Main/OAuth2CompaniesApiController.php @@ -15,16 +15,131 @@ use App\Rules\Boolean; use App\Services\Model\ICompanyService; use Illuminate\Http\Request as LaravelRequest; +use Illuminate\Http\Response; use models\exceptions\ValidationException; use models\main\ICompanyRepository; use models\oauth2\IResourceServerContext; use models\utils\IEntity; use ModelSerializers\SerializerRegistry; +use OpenApi\Attributes as OA; /** * Class OAuth2CompaniesApiController * @package App\Http\Controllers */ +#[OA\Get( + path: "/api/v1/companies/{id}", + summary: "Get a specific company", + description: "Returns detailed information about a specific company", + tags: ["Companies"], + parameters: [ + new OA\Parameter( + name: "id", + in: "path", + required: true, + description: "Company ID", + schema: new OA\Schema(type: "integer") + ), + new OA\Parameter( + name: "expand", + in: "query", + required: false, + description: "Expand related entities. Available expansions: sponsorships, project_sponsorships", + schema: new OA\Schema(type: "string") + ), + new OA\Parameter( + name: "relations", + in: "query", + required: false, + description: "Load relations. Available: sponsorships, project_sponsorships", + schema: new OA\Schema(type: "string") + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: "Success", + content: new OA\JsonContent(ref: "#/components/schemas/Company") + ), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Company not found"), + ] +)] +#[OA\Post( + path: "/api/v1/companies", + summary: "Create a new company", + description: "Creates a new company", + security: [["oauth2_security_scope" => ["openid", "profile", "email"]]], + tags: ["Companies"], + requestBody: new OA\RequestBody( + required: true, + content: new OA\JsonContent(ref: "#/components/schemas/CompanyCreateRequest") + ), + responses: [ + new OA\Response( + response: Response::HTTP_CREATED, + description: "Created", + content: new OA\JsonContent(ref: "#/components/schemas/Company") + ), + 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_PRECONDITION_FAILED, description: "Validation Error"), + ] +)] +#[OA\Put( + path: "/api/v1/companies/{id}", + summary: "Update a company", + description: "Updates an existing company", + security: [["oauth2_security_scope" => ["openid", "profile", "email"]]], + tags: ["Companies"], + parameters: [ + new OA\Parameter( + name: "id", + in: "path", + required: true, + description: "Company ID", + schema: new OA\Schema(type: "integer") + ), + ], + requestBody: new OA\RequestBody( + required: true, + content: new OA\JsonContent(ref: "#/components/schemas/CompanyUpdateRequest") + ), + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: "Success", + content: new OA\JsonContent(ref: "#/components/schemas/Company") + ), + 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: "Company not found"), + new OA\Response(response: Response::HTTP_PRECONDITION_FAILED, description: "Validation Error"), + ] +)] +#[OA\Delete( + path: "/api/v1/companies/{id}", + summary: "Delete a company", + description: "Deletes a company", + security: [["oauth2_security_scope" => ["openid", "profile", "email"]]], + tags: ["Companies"], + parameters: [ + new OA\Parameter( + name: "id", + in: "path", + required: true, + description: "Company ID", + schema: new OA\Schema(type: "integer") + ), + ], + responses: [ + new OA\Response(response: Response::HTTP_NO_CONTENT, description: "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: "Company not found"), + ] +)] final class OAuth2CompaniesApiController extends OAuth2ProtectedController { @@ -61,9 +176,54 @@ public function __construct $this->service = $service; } - /** - * @return mixed - */ + #[OA\Get( + path: "/api/v1/companies", + summary: "Get all companies", + description: "Returns a paginated list of companies. Allows ordering, filtering and pagination.", + security: [["oauth2_security_scope" => ["openid", "profile", "email"]]], + tags: ["Companies"], + parameters: [ + new OA\Parameter(ref: "#/components/parameters/page_number_param"), + new OA\Parameter(ref: "#/components/parameters/page_size_param"), + new OA\Parameter( + name: "filter[]", + in: "query", + required: false, + description: "Filter companies. Available filters: name (=@, ==, @@), member_level (=@, ==, @@), display_on_site (==)", + schema: new OA\Schema(type: "array", items: new OA\Items(type: "string")), + explode: true + ), + new OA\Parameter( + name: "order", + in: "query", + required: false, + description: "Order by field. Valid fields: id, name, member_level", + schema: new OA\Schema(type: "string") + ), + new OA\Parameter( + name: "expand", + in: "query", + required: false, + description: "Expand related entities. Available expansions: sponsorships, project_sponsorships", + schema: new OA\Schema(type: "string") + ), + new OA\Parameter( + name: "relations", + in: "query", + required: false, + description: "Load relations. Available: sponsorships, project_sponsorships", + schema: new OA\Schema(type: "string") + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: "Success", + content: new OA\JsonContent(ref: "#/components/schemas/PaginatedCompaniesResponse") + ), + new OA\Response(response: Response::HTTP_BAD_REQUEST, description: "Bad Request"), + ] + )] public function getAllCompanies() { @@ -168,11 +328,51 @@ protected function updateEntity($id, array $payload): IEntity // Logos - /** - * @param LaravelRequest $request - * @param $speaker_id - * @return mixed - */ + #[OA\Post( + path: "/api/v1/companies/{id}/logo", + summary: "Add company logo", + description: "Uploads a logo image for the company", + security: [["oauth2_security_scope" => ["openid", "profile", "email"]]], + tags: ["Companies"], + parameters: [ + new OA\Parameter( + name: "id", + in: "path", + required: true, + description: "Company ID", + schema: new OA\Schema(type: "integer") + ), + ], + requestBody: new OA\RequestBody( + required: true, + content: new OA\MediaType( + mediaType: "multipart/form-data", + schema: new OA\Schema( + required: ["file"], + properties: [ + new OA\Property( + property: "file", + type: "string", + format: "binary", + description: "Logo image file" + ) + ] + ) + ) + ), + responses: [ + new OA\Response( + response: Response::HTTP_CREATED, + description: "Logo uploaded successfully", + content: new OA\JsonContent(type: "object") + ), + 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: "Company not found"), + new OA\Response(response: Response::HTTP_PRECONDITION_FAILED, description: "File parameter not set"), + ] + )] public function addCompanyLogo(LaravelRequest $request, $company_id) { return $this->processRequest(function () use ($request, $company_id) { @@ -188,10 +388,28 @@ public function addCompanyLogo(LaravelRequest $request, $company_id) }); } - /** - * @param $company_id - * @return \Illuminate\Http\JsonResponse|mixed - */ + #[OA\Delete( + path: "/api/v1/companies/{id}/logo", + summary: "Delete company logo", + description: "Removes the logo image from the company", + security: [["oauth2_security_scope" => ["openid", "profile", "email"]]], + tags: ["Companies"], + parameters: [ + new OA\Parameter( + name: "id", + in: "path", + required: true, + description: "Company ID", + schema: new OA\Schema(type: "integer") + ), + ], + responses: [ + new OA\Response(response: Response::HTTP_NO_CONTENT, description: "Logo 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: "Company not found"), + ] + )] public function deleteCompanyLogo($company_id) { return $this->processRequest(function () use ($company_id) { @@ -203,11 +421,51 @@ public function deleteCompanyLogo($company_id) }); } - /** - * @param LaravelRequest $request - * @param $speaker_id - * @return mixed - */ + #[OA\Post( + path: "/api/v1/companies/{id}/logo/big", + summary: "Add company big logo", + description: "Uploads a big logo image for the company", + security: [["oauth2_security_scope" => ["openid", "profile", "email"]]], + tags: ["Companies"], + parameters: [ + new OA\Parameter( + name: "id", + in: "path", + required: true, + description: "Company ID", + schema: new OA\Schema(type: "integer") + ), + ], + requestBody: new OA\RequestBody( + required: true, + content: new OA\MediaType( + mediaType: "multipart/form-data", + schema: new OA\Schema( + required: ["file"], + properties: [ + new OA\Property( + property: "file", + type: "string", + format: "binary", + description: "Big logo image file" + ) + ] + ) + ) + ), + responses: [ + new OA\Response( + response: Response::HTTP_CREATED, + description: "Big logo uploaded successfully", + content: new OA\JsonContent(type: "object") + ), + 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: "Company not found"), + new OA\Response(response: Response::HTTP_PRECONDITION_FAILED, description: "File parameter not set"), + ] + )] public function addCompanyBigLogo(LaravelRequest $request, $company_id) { return $this->processRequest(function () use ($request, $company_id) { @@ -222,10 +480,28 @@ public function addCompanyBigLogo(LaravelRequest $request, $company_id) }); } - /** - * @param $company_id - * @return \Illuminate\Http\JsonResponse|mixed - */ + #[OA\Delete( + path: "/api/v1/companies/{id}/logo/big", + summary: "Delete company big logo", + description: "Removes the big logo image from the company", + security: [["oauth2_security_scope" => ["openid", "profile", "email"]]], + tags: ["Companies"], + parameters: [ + new OA\Parameter( + name: "id", + in: "path", + required: true, + description: "Company ID", + schema: new OA\Schema(type: "integer") + ), + ], + responses: [ + new OA\Response(response: Response::HTTP_NO_CONTENT, description: "Big logo 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: "Company not found"), + ] + )] public function deleteCompanyBigLogo($company_id) { return $this->processRequest(function () use ($company_id) { @@ -233,4 +509,4 @@ public function deleteCompanyBigLogo($company_id) return $this->deleted(); }); } -} \ No newline at end of file +} diff --git a/app/Swagger/CompaniesSchemas.php b/app/Swagger/CompaniesSchemas.php index 6b3e2f895..3c0b557e4 100644 --- a/app/Swagger/CompaniesSchemas.php +++ b/app/Swagger/CompaniesSchemas.php @@ -4,4 +4,146 @@ use OpenApi\Attributes as OA; -// +// Companies Schemas + +#[OA\Schema( + schema: "Company", + description: "Company", + properties: [ + new OA\Property(property: "id", type: "integer", example: 1), + new OA\Property(property: "created", type: "integer", format: "int64", description: "Creation timestamp (epoch)", example: 1234567890), + new OA\Property(property: "last_edited", type: "integer", format: "int64", description: "Last edit timestamp (epoch)", example: 1234567890), + new OA\Property(property: "name", type: "string", example: "Acme Corporation"), + new OA\Property(property: "url", type: "string", format: "uri", nullable: true, example: "https://www.acme.com"), + new OA\Property(property: "url_segment", type: "string", nullable: true, example: "acme-corporation"), + new OA\Property(property: "display_on_site", type: "boolean", example: true), + new OA\Property(property: "featured", type: "boolean", example: false), + new OA\Property(property: "city", type: "string", nullable: true, example: "San Francisco"), + new OA\Property(property: "state", type: "string", nullable: true, example: "California"), + new OA\Property(property: "country", type: "string", nullable: true, example: "United States"), + new OA\Property(property: "description", type: "string", nullable: true, example: "Leading technology company"), + new OA\Property(property: "industry", type: "string", nullable: true, example: "Technology"), + new OA\Property(property: "products", type: "string", nullable: true, example: "Cloud services, Software"), + new OA\Property(property: "contributions", type: "string", nullable: true, example: "OpenStack contributions"), + new OA\Property(property: "contact_email", type: "string", format: "email", nullable: true, example: "contact@acme.com"), + new OA\Property(property: "member_level", type: "string", nullable: true, example: "Platinum"), + new OA\Property(property: "admin_email", type: "string", format: "email", nullable: true, example: "admin@acme.com"), + new OA\Property(property: "color", type: "string", nullable: true, example: "#FF5733"), + new OA\Property(property: "logo", type: "string", format: "uri", nullable: true, example: "https://cdn.example.com/logo.png"), + new OA\Property(property: "big_logo", type: "string", format: "uri", nullable: true, example: "https://cdn.example.com/big_logo.png"), + new OA\Property(property: "overview", type: "string", nullable: true, example: "Company overview"), + new OA\Property(property: "commitment", type: "string", nullable: true, example: "Commitment to open source"), + new OA\Property(property: "commitment_author", type: "string", nullable: true, example: "John Doe, CEO"), + ], + anyOf: [ + new OA\Property( + property: "sponsorships", + type: "array", + items: new OA\Items(type: "integer"), + description: "Array of sponsorship IDs (only when relations=sponsorships)", + example: [1, 2, 3] + ), + new OA\Property( + property: "sponsorships", + type: "array", + items: new OA\Items(type: "SummitSponsorship"), + description: "Array of SummitSponsorship models (only when expand=sponsorships)", + ), + new OA\Property( + property: "project_sponsorships", + type: "array", + items: new OA\Items(type: "integer"), + description: "Array of project sponsorship IDs (only when relations=project_sponsorships)", + example: [4, 5, 6] + ), + new OA\Property( + property: "project_sponsorships", + type: "array", + items: new OA\Items(type: "ProjectSponsorshipType"), + description: "Array of project ProjectSponsorshipType models (only when expand=project_sponsorships)", + ), + ], + type: "object" +)] +class CompanySchema +{ +} + +#[OA\Schema( + schema: "PaginatedCompaniesResponse", + description: "Paginated response for Companies", + properties: [ + new OA\Property(property: "total", type: "integer", example: 100), + new OA\Property(property: "per_page", type: "integer", example: 15), + new OA\Property(property: "current_page", type: "integer", example: 1), + new OA\Property(property: "last_page", type: "integer", example: 7), + new OA\Property( + property: "data", + type: "array", + items: new OA\Items(ref: "#/components/schemas/Company") + ), + ], + type: "object" +)] +class PaginatedCompaniesResponseSchema +{ +} + +#[OA\Schema( + schema: "CompanyCreateRequest", + description: "Request to create a Company", + required: ["name"], + properties: [ + new OA\Property(property: "name", type: "string", example: "Acme Corporation"), + new OA\Property(property: "url", type: "string", format: "uri", nullable: true, example: "https://www.acme.com"), + new OA\Property(property: "display_on_site", type: "boolean", nullable: true, example: true), + new OA\Property(property: "featured", type: "boolean", nullable: true, example: false), + new OA\Property(property: "city", type: "string", nullable: true, example: "San Francisco"), + new OA\Property(property: "state", type: "string", nullable: true, example: "California"), + new OA\Property(property: "country", type: "string", nullable: true, example: "United States"), + new OA\Property(property: "description", type: "string", nullable: true, example: "Leading technology company"), + new OA\Property(property: "industry", type: "string", nullable: true, example: "Technology"), + new OA\Property(property: "products", type: "string", nullable: true, example: "Cloud services, Software"), + new OA\Property(property: "contributions", type: "string", nullable: true, example: "OpenStack contributions"), + new OA\Property(property: "contact_email", type: "string", format: "email", nullable: true, example: "contact@acme.com"), + new OA\Property(property: "member_level", type: "string", nullable: true, example: "Platinum"), + new OA\Property(property: "admin_email", type: "string", format: "email", nullable: true, example: "admin@acme.com"), + new OA\Property(property: "color", type: "string", description: "Hex color code", nullable: true, example: "#FF5733"), + new OA\Property(property: "overview", type: "string", nullable: true, example: "Company overview"), + new OA\Property(property: "commitment", type: "string", nullable: true, example: "Commitment to open source"), + new OA\Property(property: "commitment_author", type: "string", nullable: true, example: "John Doe, CEO"), + ], + type: "object" +)] +class CompanyCreateRequestSchema +{ +} + +#[OA\Schema( + schema: "CompanyUpdateRequest", + description: "Request to update a Company", + properties: [ + new OA\Property(property: "name", type: "string", nullable: true, example: "Acme Corporation"), + new OA\Property(property: "url", type: "string", format: "uri", nullable: true, example: "https://www.acme.com"), + new OA\Property(property: "display_on_site", type: "boolean", nullable: true, example: true), + new OA\Property(property: "featured", type: "boolean", nullable: true, example: false), + new OA\Property(property: "city", type: "string", nullable: true, example: "San Francisco"), + new OA\Property(property: "state", type: "string", nullable: true, example: "California"), + new OA\Property(property: "country", type: "string", nullable: true, example: "United States"), + new OA\Property(property: "description", type: "string", nullable: true, example: "Leading technology company"), + new OA\Property(property: "industry", type: "string", nullable: true, example: "Technology"), + new OA\Property(property: "products", type: "string", nullable: true, example: "Cloud services, Software"), + new OA\Property(property: "contributions", type: "string", nullable: true, example: "OpenStack contributions"), + new OA\Property(property: "contact_email", type: "string", format: "email", nullable: true, example: "contact@acme.com"), + new OA\Property(property: "member_level", type: "string", nullable: true, example: "Platinum"), + new OA\Property(property: "admin_email", type: "string", format: "email", nullable: true, example: "admin@acme.com"), + new OA\Property(property: "color", type: "string", description: "Hex color code", nullable: true, example: "#FF5733"), + new OA\Property(property: "overview", type: "string", nullable: true, example: "Company overview"), + new OA\Property(property: "commitment", type: "string", nullable: true, example: "Commitment to open source"), + new OA\Property(property: "commitment_author", type: "string", nullable: true, example: "John Doe, CEO"), + ], + type: "object" +)] +class CompanyUpdateRequestSchema +{ +} From d9e26da29cd9da96f7999629a88ff0cfcb2b645b Mon Sep 17 00:00:00 2001 From: Matias Perrone Date: Mon, 13 Oct 2025 18:18:33 -0300 Subject: [PATCH 2/8] fix: param definition --- .../Main/OAuth2CompaniesApiController.php | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/Apis/Protected/Main/OAuth2CompaniesApiController.php b/app/Http/Controllers/Apis/Protected/Main/OAuth2CompaniesApiController.php index 007005bfa..9337dffe5 100644 --- a/app/Http/Controllers/Apis/Protected/Main/OAuth2CompaniesApiController.php +++ b/app/Http/Controllers/Apis/Protected/Main/OAuth2CompaniesApiController.php @@ -183,8 +183,20 @@ public function __construct security: [["oauth2_security_scope" => ["openid", "profile", "email"]]], tags: ["Companies"], parameters: [ - new OA\Parameter(ref: "#/components/parameters/page_number_param"), - new OA\Parameter(ref: "#/components/parameters/page_size_param"), + new OA\Parameter( + name: 'page', + in: 'query', + required: false, + schema: new OA\Schema(type: 'integer'), + description: 'The page number' + ), + new OA\Parameter( + name: 'per_page', + in: 'query', + required: false, + schema: new OA\Schema(type: 'integer'), + description: 'The number of pages in each page', + ), new OA\Parameter( name: "filter[]", in: "query", From aa7367d6d2e5dc6620a88891a3785f18cecaac55 Mon Sep 17 00:00:00 2001 From: Matias Perrone Date: Tue, 14 Oct 2025 14:55:03 -0300 Subject: [PATCH 3/8] fix: Change "namespace" word positioning --- .../Apis/Protected/Main/OAuth2CompaniesApiController.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/Apis/Protected/Main/OAuth2CompaniesApiController.php b/app/Http/Controllers/Apis/Protected/Main/OAuth2CompaniesApiController.php index 9337dffe5..a8c69a7bc 100644 --- a/app/Http/Controllers/Apis/Protected/Main/OAuth2CompaniesApiController.php +++ b/app/Http/Controllers/Apis/Protected/Main/OAuth2CompaniesApiController.php @@ -1,4 +1,7 @@ -deleted(); }); } -} +} \ No newline at end of file From e1e0def57aa6fd4cec1cf9e43ded4b9226686207 Mon Sep 17 00:00:00 2001 From: Matias Perrone Date: Mon, 10 Nov 2025 22:41:54 +0000 Subject: [PATCH 4/8] fix: Add security schema --- .../Main/OAuth2CompaniesApiController.php | 220 ++++++++++++++++-- 1 file changed, 203 insertions(+), 17 deletions(-) diff --git a/app/Http/Controllers/Apis/Protected/Main/OAuth2CompaniesApiController.php b/app/Http/Controllers/Apis/Protected/Main/OAuth2CompaniesApiController.php index a8c69a7bc..c955001fe 100644 --- a/app/Http/Controllers/Apis/Protected/Main/OAuth2CompaniesApiController.php +++ b/app/Http/Controllers/Apis/Protected/Main/OAuth2CompaniesApiController.php @@ -16,6 +16,8 @@ **/ use App\Rules\Boolean; +use App\Security\CompanyScopes; +use App\Security\SummitScopes; use App\Services\Model\ICompanyService; use Illuminate\Http\Request as LaravelRequest; use Illuminate\Http\Response; @@ -26,6 +28,31 @@ use ModelSerializers\SerializerRegistry; use OpenApi\Attributes as OA; + +#[OA\SecurityScheme( + type: 'oauth2', + securityScheme: 'OAuth2CompaniesApiControllerAuthSchema', + flows: [ + new OA\Flow( + authorizationUrl: L5_SWAGGER_CONST_AUTH_URL, + tokenUrl: L5_SWAGGER_CONST_TOKEN_URL, + flow: 'authorizationCode', + scopes: [ + CompanyScopes::Read => 'Read Data', + CompanyScopes::Write => 'Write Data', + SummitScopes::ReadSummitData => 'Read Summit Data', + SummitScopes::ReadAllSummitData => 'Read All Summit Data', + SummitScopes::WriteSummitData => 'Write Summit Data', + ], + ), + ], +) +] +class OAuth2CompaniesApiControllerAuthSchema +{ +} + + /** * Class OAuth2CompaniesApiController * @package App\Http\Controllers @@ -34,6 +61,54 @@ path: "/api/v1/companies/{id}", summary: "Get a specific company", description: "Returns detailed information about a specific company", + security: [ + [ + "OAuth2CompaniesApiControllerAuthSchema" => [ + CompanyScopes::Read, + ] + ] + ], + tags: ["Companies"], + parameters: [ + new OA\Parameter( + name: "id", + in: "path", + required: true, + description: "Company ID", + schema: new OA\Schema(type: "integer") + ), + new OA\Parameter( + name: "expand", + in: "query", + required: false, + description: "Expand related entities. Available expansions: sponsorships, project_sponsorships", + schema: new OA\Schema(type: "string") + ), + new OA\Parameter( + name: "relations", + in: "query", + required: false, + description: "Load relations. Available: sponsorships, project_sponsorships", + schema: new OA\Schema(type: "string") + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: "Success", + content: new OA\JsonContent(ref: "#/components/schemas/Company") + ), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Company not found"), + ] +)] +/** + * Class OAuth2CompaniesApiController + * @package App\Http\Controllers + */ +#[OA\Get( + path: "/api/public/v1/companies/{id}", + summary: "Get a specific company (Public)", + description: "Returns detailed information about a specific company", tags: ["Companies"], parameters: [ new OA\Parameter( @@ -71,7 +146,13 @@ path: "/api/v1/companies", summary: "Create a new company", description: "Creates a new company", - security: [["oauth2_security_scope" => ["openid", "profile", "email"]]], + security: [ + [ + "OAuth2CompaniesApiControllerAuthSchema" => [ + CompanyScopes::Write, + ] + ] + ], tags: ["Companies"], requestBody: new OA\RequestBody( required: true, @@ -93,7 +174,13 @@ path: "/api/v1/companies/{id}", summary: "Update a company", description: "Updates an existing company", - security: [["oauth2_security_scope" => ["openid", "profile", "email"]]], + security: [ + [ + "OAuth2CompaniesApiControllerAuthSchema" => [ + CompanyScopes::Write, + ] + ] + ], tags: ["Companies"], parameters: [ new OA\Parameter( @@ -125,7 +212,13 @@ path: "/api/v1/companies/{id}", summary: "Delete a company", description: "Deletes a company", - security: [["oauth2_security_scope" => ["openid", "profile", "email"]]], + security: [ + [ + "OAuth2CompaniesApiControllerAuthSchema" => [ + CompanyScopes::Write, + ] + ] + ], tags: ["Companies"], parameters: [ new OA\Parameter( @@ -169,11 +262,10 @@ final class OAuth2CompaniesApiController extends OAuth2ProtectedController */ public function __construct ( - ICompanyRepository $company_repository, + ICompanyRepository $company_repository, IResourceServerContext $resource_server_context, - ICompanyService $service - ) - { + ICompanyService $service + ) { parent::__construct($resource_server_context); $this->repository = $company_repository; $this->service = $service; @@ -183,7 +275,75 @@ public function __construct path: "/api/v1/companies", summary: "Get all companies", description: "Returns a paginated list of companies. Allows ordering, filtering and pagination.", - security: [["oauth2_security_scope" => ["openid", "profile", "email"]]], + security: [ + [ + "OAuth2CompaniesApiControllerAuthSchema" => [ + CompanyScopes::Read, + SummitScopes::ReadSummitData, + SummitScopes::ReadAllSummitData, + ] + ] + ], + tags: ["Companies"], + parameters: [ + new OA\Parameter( + name: 'page', + in: 'query', + required: false, + schema: new OA\Schema(type: 'integer'), + description: 'The page number' + ), + new OA\Parameter( + name: 'per_page', + in: 'query', + required: false, + schema: new OA\Schema(type: 'integer'), + description: 'The number of pages in each page', + ), + new OA\Parameter( + name: "filter[]", + in: "query", + required: false, + description: "Filter companies. Available filters: name (=@, ==, @@), member_level (=@, ==, @@), display_on_site (==)", + schema: new OA\Schema(type: "array", items: new OA\Items(type: "string")), + explode: true + ), + new OA\Parameter( + name: "order", + in: "query", + required: false, + description: "Order by field. Valid fields: id, name, member_level", + schema: new OA\Schema(type: "string") + ), + new OA\Parameter( + name: "expand", + in: "query", + required: false, + description: "Expand related entities. Available expansions: sponsorships, project_sponsorships", + schema: new OA\Schema(type: "string") + ), + new OA\Parameter( + name: "relations", + in: "query", + required: false, + description: "Load relations. Available: sponsorships, project_sponsorships", + schema: new OA\Schema(type: "string") + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: "Success", + content: new OA\JsonContent(ref: "#/components/schemas/PaginatedCompaniesResponse") + ), + new OA\Response(response: Response::HTTP_BAD_REQUEST, description: "Bad Request"), + ] + )] + + #[OA\Get( + path: "/api/public/v1/companies", + summary: "Get all companies (Public)", + description: "Returns a paginated list of companies. Allows ordering, filtering and pagination.", tags: ["Companies"], parameters: [ new OA\Parameter( @@ -247,14 +407,14 @@ function () { return [ 'name' => ['=@', '==', '@@'], 'member_level' => ['=@', '==', '@@'], - 'display_on_site' => [ '=='], + 'display_on_site' => ['=='], ]; }, function () { return [ 'name' => 'sometimes|string', 'member_level' => 'sometimes|string', - 'display_on_site' => ['sometimes', new Boolean], + 'display_on_site' => ['sometimes', new Boolean], ]; }, function () { @@ -268,7 +428,7 @@ function ($filter) { return $filter; }, function () { - return $this->getEntitySerializerType(); + return $this->getEntitySerializerType(); } ); } @@ -292,7 +452,8 @@ protected function addEntity(array $payload): IEntity return $this->service->addCompany($payload); } - protected function addEntitySerializerType(){ + protected function addEntitySerializerType() + { return $this->getEntitySerializerType(); } @@ -320,7 +481,8 @@ protected function getEntitySerializerType() SerializerRegistry::SerializerType_Public; } - protected function updateEntitySerializerType(){ + protected function updateEntitySerializerType() + { return $this->getEntitySerializerType(); } /** @@ -347,7 +509,13 @@ protected function updateEntity($id, array $payload): IEntity path: "/api/v1/companies/{id}/logo", summary: "Add company logo", description: "Uploads a logo image for the company", - security: [["oauth2_security_scope" => ["openid", "profile", "email"]]], + security: [ + [ + "OAuth2CompaniesApiControllerAuthSchema" => [ + CompanyScopes::Write, + ] + ] + ], tags: ["Companies"], parameters: [ new OA\Parameter( @@ -407,7 +575,13 @@ public function addCompanyLogo(LaravelRequest $request, $company_id) path: "/api/v1/companies/{id}/logo", summary: "Delete company logo", description: "Removes the logo image from the company", - security: [["oauth2_security_scope" => ["openid", "profile", "email"]]], + security: [ + [ + "OAuth2CompaniesApiControllerAuthSchema" => [ + CompanyScopes::Write, + ] + ] + ], tags: ["Companies"], parameters: [ new OA\Parameter( @@ -440,7 +614,13 @@ public function deleteCompanyLogo($company_id) path: "/api/v1/companies/{id}/logo/big", summary: "Add company big logo", description: "Uploads a big logo image for the company", - security: [["oauth2_security_scope" => ["openid", "profile", "email"]]], + security: [ + [ + "OAuth2CompaniesApiControllerAuthSchema" => [ + CompanyScopes::Write, + ] + ] + ], tags: ["Companies"], parameters: [ new OA\Parameter( @@ -499,7 +679,13 @@ public function addCompanyBigLogo(LaravelRequest $request, $company_id) path: "/api/v1/companies/{id}/logo/big", summary: "Delete company big logo", description: "Removes the big logo image from the company", - security: [["oauth2_security_scope" => ["openid", "profile", "email"]]], + security: [ + [ + "OAuth2CompaniesApiControllerAuthSchema" => [ + CompanyScopes::Write, + ] + ] + ], tags: ["Companies"], parameters: [ new OA\Parameter( From 677cadefb690bf8e50f4ad069e239d155dfb9653 Mon Sep 17 00:00:00 2001 From: Matias Perrone Date: Thu, 13 Nov 2025 21:51:30 +0000 Subject: [PATCH 5/8] chore: Move the security schema for the controller to its own file --- .../Main/OAuth2CompaniesApiController.php | 428 +++++++++--------- .../Security/CompaniesOAuth2Schema.php | 30 ++ 2 files changed, 253 insertions(+), 205 deletions(-) create mode 100644 app/Swagger/Security/CompaniesOAuth2Schema.php diff --git a/app/Http/Controllers/Apis/Protected/Main/OAuth2CompaniesApiController.php b/app/Http/Controllers/Apis/Protected/Main/OAuth2CompaniesApiController.php index c955001fe..2ebd18a42 100644 --- a/app/Http/Controllers/Apis/Protected/Main/OAuth2CompaniesApiController.php +++ b/app/Http/Controllers/Apis/Protected/Main/OAuth2CompaniesApiController.php @@ -15,6 +15,7 @@ * limitations under the License. **/ +use App\Models\Foundation\Main\IGroup; use App\Rules\Boolean; use App\Security\CompanyScopes; use App\Security\SummitScopes; @@ -28,214 +29,10 @@ use ModelSerializers\SerializerRegistry; use OpenApi\Attributes as OA; - -#[OA\SecurityScheme( - type: 'oauth2', - securityScheme: 'OAuth2CompaniesApiControllerAuthSchema', - flows: [ - new OA\Flow( - authorizationUrl: L5_SWAGGER_CONST_AUTH_URL, - tokenUrl: L5_SWAGGER_CONST_TOKEN_URL, - flow: 'authorizationCode', - scopes: [ - CompanyScopes::Read => 'Read Data', - CompanyScopes::Write => 'Write Data', - SummitScopes::ReadSummitData => 'Read Summit Data', - SummitScopes::ReadAllSummitData => 'Read All Summit Data', - SummitScopes::WriteSummitData => 'Write Summit Data', - ], - ), - ], -) -] -class OAuth2CompaniesApiControllerAuthSchema -{ -} - - -/** - * Class OAuth2CompaniesApiController - * @package App\Http\Controllers - */ -#[OA\Get( - path: "/api/v1/companies/{id}", - summary: "Get a specific company", - description: "Returns detailed information about a specific company", - security: [ - [ - "OAuth2CompaniesApiControllerAuthSchema" => [ - CompanyScopes::Read, - ] - ] - ], - tags: ["Companies"], - parameters: [ - new OA\Parameter( - name: "id", - in: "path", - required: true, - description: "Company ID", - schema: new OA\Schema(type: "integer") - ), - new OA\Parameter( - name: "expand", - in: "query", - required: false, - description: "Expand related entities. Available expansions: sponsorships, project_sponsorships", - schema: new OA\Schema(type: "string") - ), - new OA\Parameter( - name: "relations", - in: "query", - required: false, - description: "Load relations. Available: sponsorships, project_sponsorships", - schema: new OA\Schema(type: "string") - ), - ], - responses: [ - new OA\Response( - response: Response::HTTP_OK, - description: "Success", - content: new OA\JsonContent(ref: "#/components/schemas/Company") - ), - new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Company not found"), - ] -)] /** * Class OAuth2CompaniesApiController * @package App\Http\Controllers */ -#[OA\Get( - path: "/api/public/v1/companies/{id}", - summary: "Get a specific company (Public)", - description: "Returns detailed information about a specific company", - tags: ["Companies"], - parameters: [ - new OA\Parameter( - name: "id", - in: "path", - required: true, - description: "Company ID", - schema: new OA\Schema(type: "integer") - ), - new OA\Parameter( - name: "expand", - in: "query", - required: false, - description: "Expand related entities. Available expansions: sponsorships, project_sponsorships", - schema: new OA\Schema(type: "string") - ), - new OA\Parameter( - name: "relations", - in: "query", - required: false, - description: "Load relations. Available: sponsorships, project_sponsorships", - schema: new OA\Schema(type: "string") - ), - ], - responses: [ - new OA\Response( - response: Response::HTTP_OK, - description: "Success", - content: new OA\JsonContent(ref: "#/components/schemas/Company") - ), - new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Company not found"), - ] -)] -#[OA\Post( - path: "/api/v1/companies", - summary: "Create a new company", - description: "Creates a new company", - security: [ - [ - "OAuth2CompaniesApiControllerAuthSchema" => [ - CompanyScopes::Write, - ] - ] - ], - tags: ["Companies"], - requestBody: new OA\RequestBody( - required: true, - content: new OA\JsonContent(ref: "#/components/schemas/CompanyCreateRequest") - ), - responses: [ - new OA\Response( - response: Response::HTTP_CREATED, - description: "Created", - content: new OA\JsonContent(ref: "#/components/schemas/Company") - ), - 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_PRECONDITION_FAILED, description: "Validation Error"), - ] -)] -#[OA\Put( - path: "/api/v1/companies/{id}", - summary: "Update a company", - description: "Updates an existing company", - security: [ - [ - "OAuth2CompaniesApiControllerAuthSchema" => [ - CompanyScopes::Write, - ] - ] - ], - tags: ["Companies"], - parameters: [ - new OA\Parameter( - name: "id", - in: "path", - required: true, - description: "Company ID", - schema: new OA\Schema(type: "integer") - ), - ], - requestBody: new OA\RequestBody( - required: true, - content: new OA\JsonContent(ref: "#/components/schemas/CompanyUpdateRequest") - ), - responses: [ - new OA\Response( - response: Response::HTTP_OK, - description: "Success", - content: new OA\JsonContent(ref: "#/components/schemas/Company") - ), - 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: "Company not found"), - new OA\Response(response: Response::HTTP_PRECONDITION_FAILED, description: "Validation Error"), - ] -)] -#[OA\Delete( - path: "/api/v1/companies/{id}", - summary: "Delete a company", - description: "Deletes a company", - security: [ - [ - "OAuth2CompaniesApiControllerAuthSchema" => [ - CompanyScopes::Write, - ] - ] - ], - tags: ["Companies"], - parameters: [ - new OA\Parameter( - name: "id", - in: "path", - required: true, - description: "Company ID", - schema: new OA\Schema(type: "integer") - ), - ], - responses: [ - new OA\Response(response: Response::HTTP_NO_CONTENT, description: "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: "Company not found"), - ] -)] final class OAuth2CompaniesApiController extends OAuth2ProtectedController { @@ -271,6 +68,203 @@ public function __construct $this->service = $service; } + #[OA\Get( + path: "/api/v1/companies/{id}", + summary: "Get a specific company", + description: "Returns detailed information about a specific company", + security: [ + [ + "OAuth2CompaniesApiControllerAuthSchema" => [ + CompanyScopes::Read, + ] + ] + ], + tags: ["Companies"], + parameters: [ + new OA\Parameter( + name: "id", + in: "path", + required: true, + description: "Company ID", + schema: new OA\Schema(type: "integer") + ), + new OA\Parameter( + name: "expand", + in: "query", + required: false, + description: "Expand related entities. Available expansions: sponsorships, project_sponsorships", + schema: new OA\Schema(type: "string") + ), + new OA\Parameter( + name: "relations", + in: "query", + required: false, + description: "Load relations. Available: sponsorships, project_sponsorships", + schema: new OA\Schema(type: "string") + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: "Success", + content: new OA\JsonContent(ref: "#/components/schemas/Company") + ), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Company not found"), + ] + )] + /** + * Class OAuth2CompaniesApiController + * @package App\Http\Controllers + */ + #[OA\Get( + path: "/api/public/v1/companies/{id}", + summary: "Get a specific company (Public)", + description: "Returns detailed information about a specific company", + tags: ["Companies"], + parameters: [ + new OA\Parameter( + name: "id", + in: "path", + required: true, + description: "Company ID", + schema: new OA\Schema(type: "integer") + ), + new OA\Parameter( + name: "expand", + in: "query", + required: false, + description: "Expand related entities. Available expansions: sponsorships, project_sponsorships", + schema: new OA\Schema(type: "string") + ), + new OA\Parameter( + name: "relations", + in: "query", + required: false, + description: "Load relations. Available: sponsorships, project_sponsorships", + schema: new OA\Schema(type: "string") + ), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: "Success", + content: new OA\JsonContent(ref: "#/components/schemas/Company") + ), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Company not found"), + ] + )] + #[OA\Post( + path: "/api/v1/companies", + summary: "Create a new company", + description: "Creates a new company", + security: [ + [ + "OAuth2CompaniesApiControllerAuthSchema" => [ + CompanyScopes::Write, + ] + ] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + ] + ], + tags: ["Companies"], + requestBody: new OA\RequestBody( + required: true, + content: new OA\JsonContent(ref: "#/components/schemas/CompanyCreateRequest") + ), + responses: [ + new OA\Response( + response: Response::HTTP_CREATED, + description: "Created", + content: new OA\JsonContent(ref: "#/components/schemas/Company") + ), + 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_PRECONDITION_FAILED, description: "Validation Error"), + ] + )] + #[OA\Put( + path: "/api/v1/companies/{id}", + summary: "Update a company", + description: "Updates an existing company", + security: [ + [ + "OAuth2CompaniesApiControllerAuthSchema" => [ + CompanyScopes::Write, + ] + ] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + ] + ], + tags: ["Companies"], + parameters: [ + new OA\Parameter( + name: "id", + in: "path", + required: true, + description: "Company ID", + schema: new OA\Schema(type: "integer") + ), + ], + requestBody: new OA\RequestBody( + required: true, + content: new OA\JsonContent(ref: "#/components/schemas/CompanyUpdateRequest") + ), + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: "Success", + content: new OA\JsonContent(ref: "#/components/schemas/Company") + ), + 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: "Company not found"), + new OA\Response(response: Response::HTTP_PRECONDITION_FAILED, description: "Validation Error"), + ] + )] + #[OA\Delete( + path: "/api/v1/companies/{id}", + summary: "Delete a company", + description: "Deletes a company", + security: [ + [ + "OAuth2CompaniesApiControllerAuthSchema" => [ + CompanyScopes::Write, + ] + ] + ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + ] + ], + tags: ["Companies"], + parameters: [ + new OA\Parameter( + name: "id", + in: "path", + required: true, + description: "Company ID", + schema: new OA\Schema(type: "integer") + ), + ], + responses: [ + new OA\Response(response: Response::HTTP_NO_CONTENT, description: "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: "Company not found"), + ] + )] #[OA\Get( path: "/api/v1/companies", summary: "Get all companies", @@ -516,6 +510,12 @@ protected function updateEntity($id, array $payload): IEntity ] ] ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + ] + ], tags: ["Companies"], parameters: [ new OA\Parameter( @@ -582,6 +582,12 @@ public function addCompanyLogo(LaravelRequest $request, $company_id) ] ] ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + ] + ], tags: ["Companies"], parameters: [ new OA\Parameter( @@ -621,6 +627,12 @@ public function deleteCompanyLogo($company_id) ] ] ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + ] + ], tags: ["Companies"], parameters: [ new OA\Parameter( @@ -686,6 +698,12 @@ public function addCompanyBigLogo(LaravelRequest $request, $company_id) ] ] ], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + ] + ], tags: ["Companies"], parameters: [ new OA\Parameter( @@ -710,4 +728,4 @@ public function deleteCompanyBigLogo($company_id) return $this->deleted(); }); } -} \ No newline at end of file +} diff --git a/app/Swagger/Security/CompaniesOAuth2Schema.php b/app/Swagger/Security/CompaniesOAuth2Schema.php new file mode 100644 index 000000000..3edb5a593 --- /dev/null +++ b/app/Swagger/Security/CompaniesOAuth2Schema.php @@ -0,0 +1,30 @@ + 'Read Data', + CompanyScopes::Write => 'Write Data', + SummitScopes::ReadSummitData => 'Read Summit Data', + SummitScopes::ReadAllSummitData => 'Read All Summit Data', + SummitScopes::WriteSummitData => 'Write Summit Data', + ], + ), + ], +) +] +class CompaniesOAuth2Schema +{ +} From b26dbfedded9c9281fc13cf5e345daf51478609d Mon Sep 17 00:00:00 2001 From: Matias Perrone Date: Wed, 3 Dec 2025 18:19:02 +0000 Subject: [PATCH 6/8] chore: add operationId and fix schema name --- .../Main/OAuth2CompaniesApiController.php | 35 ++++++++++++------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/app/Http/Controllers/Apis/Protected/Main/OAuth2CompaniesApiController.php b/app/Http/Controllers/Apis/Protected/Main/OAuth2CompaniesApiController.php index 2ebd18a42..9650c4a08 100644 --- a/app/Http/Controllers/Apis/Protected/Main/OAuth2CompaniesApiController.php +++ b/app/Http/Controllers/Apis/Protected/Main/OAuth2CompaniesApiController.php @@ -70,11 +70,12 @@ public function __construct #[OA\Get( path: "/api/v1/companies/{id}", + operationId: "getCompany", summary: "Get a specific company", description: "Returns detailed information about a specific company", security: [ [ - "OAuth2CompaniesApiControllerAuthSchema" => [ + "companies_oauth2" => [ CompanyScopes::Read, ] ] @@ -118,9 +119,10 @@ public function __construct */ #[OA\Get( path: "/api/public/v1/companies/{id}", + operationId: "getCompanyPublic", summary: "Get a specific company (Public)", description: "Returns detailed information about a specific company", - tags: ["Companies"], + tags: ["Companies (Public)"], parameters: [ new OA\Parameter( name: "id", @@ -155,11 +157,12 @@ public function __construct )] #[OA\Post( path: "/api/v1/companies", + operationId: "createCompany", summary: "Create a new company", description: "Creates a new company", security: [ [ - "OAuth2CompaniesApiControllerAuthSchema" => [ + "companies_oauth2" => [ CompanyScopes::Write, ] ] @@ -189,11 +192,12 @@ public function __construct )] #[OA\Put( path: "/api/v1/companies/{id}", + operationId: "updateCompany", summary: "Update a company", description: "Updates an existing company", security: [ [ - "OAuth2CompaniesApiControllerAuthSchema" => [ + "companies_oauth2" => [ CompanyScopes::Write, ] ] @@ -233,11 +237,12 @@ public function __construct )] #[OA\Delete( path: "/api/v1/companies/{id}", + operationId: "deleteCompany", summary: "Delete a company", description: "Deletes a company", security: [ [ - "OAuth2CompaniesApiControllerAuthSchema" => [ + "companies_oauth2" => [ CompanyScopes::Write, ] ] @@ -267,11 +272,12 @@ public function __construct )] #[OA\Get( path: "/api/v1/companies", + operationId: "getAllCompanies", summary: "Get all companies", description: "Returns a paginated list of companies. Allows ordering, filtering and pagination.", security: [ [ - "OAuth2CompaniesApiControllerAuthSchema" => [ + "companies_oauth2" => [ CompanyScopes::Read, SummitScopes::ReadSummitData, SummitScopes::ReadAllSummitData, @@ -336,9 +342,10 @@ public function __construct #[OA\Get( path: "/api/public/v1/companies", + operationId: "getAllCompaniesPublic", summary: "Get all companies (Public)", description: "Returns a paginated list of companies. Allows ordering, filtering and pagination.", - tags: ["Companies"], + tags: ["Companies (Public)"], parameters: [ new OA\Parameter( name: 'page', @@ -501,11 +508,12 @@ protected function updateEntity($id, array $payload): IEntity #[OA\Post( path: "/api/v1/companies/{id}/logo", + operationId: "addCompanyLogo", summary: "Add company logo", description: "Uploads a logo image for the company", security: [ [ - "OAuth2CompaniesApiControllerAuthSchema" => [ + "companies_oauth2" => [ CompanyScopes::Write, ] ] @@ -573,11 +581,12 @@ public function addCompanyLogo(LaravelRequest $request, $company_id) #[OA\Delete( path: "/api/v1/companies/{id}/logo", + operationId: "deleteCompanyLogo", summary: "Delete company logo", description: "Removes the logo image from the company", security: [ [ - "OAuth2CompaniesApiControllerAuthSchema" => [ + "companies_oauth2" => [ CompanyScopes::Write, ] ] @@ -618,11 +627,12 @@ public function deleteCompanyLogo($company_id) #[OA\Post( path: "/api/v1/companies/{id}/logo/big", + operationId: "addCompanyBigLogo", summary: "Add company big logo", description: "Uploads a big logo image for the company", security: [ [ - "OAuth2CompaniesApiControllerAuthSchema" => [ + "companies_oauth2" => [ CompanyScopes::Write, ] ] @@ -689,11 +699,12 @@ public function addCompanyBigLogo(LaravelRequest $request, $company_id) #[OA\Delete( path: "/api/v1/companies/{id}/logo/big", + operationId: "deleteCompanyBigLogo", summary: "Delete company big logo", description: "Removes the big logo image from the company", security: [ [ - "OAuth2CompaniesApiControllerAuthSchema" => [ + "companies_oauth2" => [ CompanyScopes::Write, ] ] @@ -728,4 +739,4 @@ public function deleteCompanyBigLogo($company_id) return $this->deleted(); }); } -} +} \ No newline at end of file From 05f950614f20fa50c484623f995f2d8fcb6e72b6 Mon Sep 17 00:00:00 2001 From: Matias Perrone Date: Wed, 3 Dec 2025 18:26:30 +0000 Subject: [PATCH 7/8] feat: change to ref the custom types --- app/Swagger/CompaniesSchemas.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/app/Swagger/CompaniesSchemas.php b/app/Swagger/CompaniesSchemas.php index 3c0b557e4..f5578e630 100644 --- a/app/Swagger/CompaniesSchemas.php +++ b/app/Swagger/CompaniesSchemas.php @@ -34,8 +34,6 @@ new OA\Property(property: "overview", type: "string", nullable: true, example: "Company overview"), new OA\Property(property: "commitment", type: "string", nullable: true, example: "Commitment to open source"), new OA\Property(property: "commitment_author", type: "string", nullable: true, example: "John Doe, CEO"), - ], - anyOf: [ new OA\Property( property: "sponsorships", type: "array", @@ -46,7 +44,7 @@ new OA\Property( property: "sponsorships", type: "array", - items: new OA\Items(type: "SummitSponsorship"), + items: new OA\Items(ref: "#/components/schemas/SummitSponsorship"), description: "Array of SummitSponsorship models (only when expand=sponsorships)", ), new OA\Property( @@ -59,7 +57,7 @@ new OA\Property( property: "project_sponsorships", type: "array", - items: new OA\Items(type: "ProjectSponsorshipType"), + items: new OA\Items(ref: "#/components/schemas/ProjectSponsorshipType"), description: "Array of project ProjectSponsorshipType models (only when expand=project_sponsorships)", ), ], From f0ce7ad690fa50cc1437dc45c018766227f18b3e Mon Sep 17 00:00:00 2001 From: Matias Perrone Date: Wed, 3 Dec 2025 18:54:42 +0000 Subject: [PATCH 8/8] fix: Company schema properties --- app/Swagger/CompaniesSchemas.php | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/app/Swagger/CompaniesSchemas.php b/app/Swagger/CompaniesSchemas.php index f5578e630..58f630983 100644 --- a/app/Swagger/CompaniesSchemas.php +++ b/app/Swagger/CompaniesSchemas.php @@ -37,28 +37,20 @@ new OA\Property( property: "sponsorships", type: "array", - items: new OA\Items(type: "integer"), + items: new OA\Items(oneOf: [ + new OA\Schema(type: "integer"), + new OA\Schema(ref: "#/components/schemas/SummitSponsorship"), + ]), description: "Array of sponsorship IDs (only when relations=sponsorships)", - example: [1, 2, 3] - ), - new OA\Property( - property: "sponsorships", - type: "array", - items: new OA\Items(ref: "#/components/schemas/SummitSponsorship"), - description: "Array of SummitSponsorship models (only when expand=sponsorships)", ), new OA\Property( property: "project_sponsorships", type: "array", - items: new OA\Items(type: "integer"), + items: new OA\Items(oneOf: [ + new OA\Schema(type: "integer"), + new OA\Schema(ref: "#/components/schemas/ProjectSponsorshipType"), + ]), description: "Array of project sponsorship IDs (only when relations=project_sponsorships)", - example: [4, 5, 6] - ), - new OA\Property( - property: "project_sponsorships", - type: "array", - items: new OA\Items(ref: "#/components/schemas/ProjectSponsorshipType"), - description: "Array of project ProjectSponsorshipType models (only when expand=project_sponsorships)", ), ], type: "object" @@ -144,4 +136,4 @@ class CompanyCreateRequestSchema )] class CompanyUpdateRequestSchema { -} +} \ No newline at end of file