From fc5ff8a34de82b1d9af8baa39c2af44ae68b2edf Mon Sep 17 00:00:00 2001 From: "LDFOUR\\luisd" Date: Thu, 27 Feb 2025 16:49:34 -0300 Subject: [PATCH 1/3] WN-268, I added the endpoints to the Swagger documentation using either Basic Auth or API Key authentication. --- .../Controllers/ApplicationController.php | 130 ++++++- app/Http/Controllers/Controller.php | 14 +- app/Http/Controllers/FileUploadController.php | 37 ++ .../Controllers/OrganisationController.php | 131 +++++-- app/Http/Controllers/RegionController.php | 180 ++++++++- app/Http/Controllers/UsageLogController.php | 147 ++++++++ app/Http/Controllers/WhatNowController.php | 356 ++++++++++++++++++ config/l5-swagger.php | 13 +- 8 files changed, 964 insertions(+), 44 deletions(-) diff --git a/app/Http/Controllers/ApplicationController.php b/app/Http/Controllers/ApplicationController.php index 5dd536a..573c448 100644 --- a/app/Http/Controllers/ApplicationController.php +++ b/app/Http/Controllers/ApplicationController.php @@ -9,6 +9,12 @@ use Illuminate\Support\Facades\Log; use League\Fractal\Manager; +/** + * @OA\Tag( + * name="Aplications", + * description="Operations about Aplications" + * ) + */ class ApplicationController extends Controller { /** @@ -54,6 +60,29 @@ public function __construct( * @param Request $request * @return \Symfony\Component\HttpFoundation\Response */ + /** + * @OA\Get( + * path="/apps", + * tags={"Applications"}, + * summary="Get all applications for a user", + * operationId="getAllForUser", + * @OA\Parameter( + * name="userId", + * in="query", + * required=true, + * description="ID of the user to fetch applications for", + * @OA\Schema(type="string") + * ), + * @OA\Response( + * response=200, + * description="Successful response", + * @OA\JsonContent( + * type="object", + * @OA\Property(property="data", type="array", @OA\Items(type="object")) + * ) + * ) + * ) + */ public function getAllForUser(Request $request) { $this->validate($this->request, [ @@ -86,6 +115,29 @@ public function getAllForUser(Request $request) * @param int $id * @return \Symfony\Component\HttpFoundation\Response */ + /** + * @OA\Get( + * path="/apps/{id}", + * tags={"Applications"}, + * summary="Get an application by ID", + * operationId="getApplicationById", + * @OA\Parameter( + * name="id", + * in="path", + * required=true, + * description="ID of the application to retrieve", + * @OA\Schema(type="integer", format="int64") + * ), + * @OA\Response( + * response=200, + * description="Successful response", + * @OA\JsonContent( + * type="object", + * @OA\Property(property="data", type="array", @OA\Items(type="object")) + * ) + * ) + * ) + */ public function getById($id) { try { @@ -119,6 +171,32 @@ public function getById($id) * @param Request $request * @return \Symfony\Component\HttpFoundation\Response */ + /** + * @OA\Post( + * path="/apps", + * tags={"Applications"}, + * summary="Create a new application", + * operationId="createApplication", + * @OA\RequestBody( + * required=true, + * @OA\JsonContent( + * required={"name", "userId"}, + * @OA\Property(property="name", type="string", example="My Application", description="Name of the application"), + * @OA\Property(property="description", type="string", example="A description of the application", description="Description of the application (optional)"), + * @OA\Property(property="userId", type="string", example="user123", description="ID of the user creating the application"), + * @OA\Property(property="estimatedUsers", type="integer", example=100, description="Estimated number of users (optional)") + * ) + * ), + * @OA\Response( + * response=200, + * description="Successful response", + * @OA\JsonContent( + * type="object", + * @OA\Property(property="data", type="array", @OA\Items(type="object")) + * ) + * ) + * ) + */ public function create(Request $request) { $this->validate($this->request, [ @@ -152,6 +230,35 @@ public function create(Request $request) return response()->json($response->toArray(), 201); } + /** + * @OA\Patch( + * path="/apps/{id}", + * tags={"Applications"}, + * summary="Update an application by ID", + * operationId="updateApplication", + * @OA\Parameter( + * name="id", + * in="path", + * required=true, + * description="ID of the application to update", + * @OA\Schema(type="integer", format="int64") + * ), + * @OA\RequestBody( + * required=true, + * @OA\JsonContent( + * @OA\Property(property="estimatedUsers", type="integer", example=100, description="Estimated number of users (optional)") + * ) + * ), + * @OA\Response( + * response=200, + * description="Successful response", + * @OA\JsonContent( + * type="object", + * @OA\Property(property="data", type="array", @OA\Items(type="object")) + * ) + * ) + * ) + */ public function update(Request $request, $id) { $this->validate($this->request, [ @@ -182,8 +289,27 @@ public function update(Request $request, $id) } /** - * @param int $id - * @return \Symfony\Component\HttpFoundation\Response + * @OA\Delete( + * path="/apps/{id}", + * tags={"Applications"}, + * summary="Delete an application by ID", + * operationId="deleteApplication", + * @OA\Parameter( + * name="id", + * in="path", + * required=true, + * description="ID of the application to delete", + * @OA\Schema(type="integer", format="int64") + * ), + * @OA\Response( + * response=200, + * description="Successful response", + * @OA\JsonContent( + * type="object", + * @OA\Property(property="data", type="array", @OA\Items(type="object")) + * ) + * ) + * ) */ public function delete($id) { diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php index b888c41..087be92 100644 --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -8,10 +8,16 @@ use Illuminate\Foundation\Auth\Access\AuthorizesRequests; /** - * @OA\Info( - * title="Whatnow API", - * description="Whatnow API documentation", - * version="1.0.0", + * @OA\OpenApi( + * @OA\Info( + * title="Whatnow API", + * description="Whatnow API documentation", + * version="1.0.0", + * ), + * @OA\Server( + * url=L5_SWAGGER_CONST_HOST, + * description="API Base URL" + * ) * ) */ class Controller extends BaseController diff --git a/app/Http/Controllers/FileUploadController.php b/app/Http/Controllers/FileUploadController.php index 369939d..e778df7 100644 --- a/app/Http/Controllers/FileUploadController.php +++ b/app/Http/Controllers/FileUploadController.php @@ -5,8 +5,45 @@ use Illuminate\Http\Request; use Illuminate\Support\Facades\Storage; +/** + * @OA\Tag( + * name="Files", + * description="Operations about Regions" + * ) + */ class FileUploadController extends Controller { + /** + * @OA\Post( + * path="/upload", + * tags={"Whatnow"}, + * summary="Upload a file", + * operationId="uploadFile", + * @OA\RequestBody( + * required=true, + * @OA\MediaType( + * mediaType="multipart/form-data", + * @OA\Schema( + * required={"file"}, + * @OA\Property( + * property="file", + * type="string", + * format="binary", + * description="File to upload (allowed types: jpg, png; max size: 10MB)" + * ) + * ) + * ) + * ), + * @OA\Response( + * response=200, + * description="Successful response", + * @OA\JsonContent( + * type="object", + * @OA\Property(property="data", type="array", @OA\Items(type="object")) + * ) + * ) + * ) + */ public function upload(Request $request) { try { diff --git a/app/Http/Controllers/OrganisationController.php b/app/Http/Controllers/OrganisationController.php index e33191d..a2074d0 100644 --- a/app/Http/Controllers/OrganisationController.php +++ b/app/Http/Controllers/OrganisationController.php @@ -48,6 +48,22 @@ public function __construct( $this->manager = $manager; } + /** + * @OA\Get( + * path="/org", + * summary="Get all organisations", + * security={{"ApiKeyAuth": {}}}, + * tags={"Organisation"}, + * @OA\Response( + * response=200, + * description="Successful response", + * @OA\JsonContent( + * type="object", + * @OA\Property(property="data", type="array", @OA\Items(type="object")) + * ) + * ), + * ) + */ public function getAll(Request $request) { try { @@ -79,6 +95,29 @@ public function getAll(Request $request) * @param $code * @param Request $request * @return \Symfony\Component\HttpFoundation\Response + */ + /** + * @OA\Get( + * path="/org/{code}", + * summary="Get organisation by country code", + * tags={"Organisation"}, + * security={{"ApiKeyAuth": {}}}, + * @OA\Parameter( + * name="code", + * in="path", + * description="Country code of the organisation", + * required=true, + * @OA\Schema(type="string") + * ), + * @OA\Response( + * response=200, + * description="Successful response", + * @OA\JsonContent( + * type="object", + * @OA\Property(property="data", type="object") + * ) + * ), + * ) */ public function getById($code, Request $request) { @@ -108,42 +147,82 @@ public function getById($code, Request $request) * @param $code * @return \Symfony\Component\HttpFoundation\Response */ - /** + /** * @OA\Put( - * path="/organisation/{code}", - * summary="Update organisation by country code", + * path="/org/{code}", * tags={"Organisation"}, + * summary="Update an organisation by its country code", + * description="Updates the details of an organisation based on the provided country code.", + * operationId="OrganisationController@putById", * @OA\Parameter( * name="code", * in="path", * description="Country code of the organisation", * required=true, - * @OA\Schema(type="string") + * @OA\Schema( + * type="string" + * ) * ), * @OA\RequestBody( * required=true, + * description="Data to update the organisation", * @OA\JsonContent( * type="object", - * @OA\Property(property="countryCode", type="string", example="USA"), - * @OA\Property(property="name", type="string", example="American Red Cross"), - * @OA\Property(property="url", type="string", nullable=true, example=null), + * @OA\Property( + * property="url", + * type="string", + * maxLength=255, + * nullable=true, + * example="https://example.com" + * ), * @OA\Property( * property="translations", - * type="array", - * @OA\Items( + * type="object", + * @OA\AdditionalProperties( * type="object", - * @OA\Property(property="languageCode", type="string", example="en"), - * @OA\Property(property="name", type="string", example="Organization name"), - * @OA\Property(property="attributionMessage", type="string", example="Attribution Message"), - * @OA\Property(property="published", type="boolean", example=true), + * @OA\Property( + * property="languageCode", + * type="string", + * example="en" + * ), + * @OA\Property( + * property="name", + * type="string", + * maxLength=255, + * example="International Federation of Red Cross and Red Crescent Societies" + * ), + * @OA\Property( + * property="attributionMessage", + * type="string", + * maxLength=2048, + * example="PRUEBA 2" + * ), * @OA\Property( * property="contributors", * type="array", * @OA\Items( * type="object", - * @OA\Property(property="name", type="string", example="Contributor name"), - * @OA\Property(property="logo", type="string", example="logo.png") + * @OA\Property( + * property="id", + * type="integer", + * example=111 + * ), + * @OA\Property( + * property="name", + * type="string", + * example="This is an example string with exactly one hundred characters, including spaces and symbols" + * ), + * @OA\Property( + * property="logo", + * type="string", + * example="https://whatnowimages.blob.core.windows.net/images/LOGO" + * ) * ) + * ), + * @OA\Property( + * property="published", + * type="boolean", + * example=true * ) * ) * ) @@ -154,27 +233,7 @@ public function getById($code, Request $request) * description="Successful response", * @OA\JsonContent( * type="object", - * @OA\Property(property="data", type="object") - * ) - * ), - * @OA\Response( - * response=404, - * description="Organisation not found", - * @OA\JsonContent( - * type="object", - * @OA\Property(property="status", type="integer", example=404), - * @OA\Property(property="error_message", type="string", example="Organisation does not exist"), - * @OA\Property(property="errors", type="array", @OA\Items(type="string")) - * ) - * ), - * @OA\Response( - * response=500, - * description="Organisation could not be updated", - * @OA\JsonContent( - * type="object", - * @OA\Property(property="status", type="integer", example=500), - * @OA\Property(property="error_message", type="string", example="Organisation could not be updated"), - * @OA\Property(property="errors", type="array", @OA\Items(type="string")) + * @OA\Property(property="data", type="array", @OA\Items(type="object")) * ) * ) * ) diff --git a/app/Http/Controllers/RegionController.php b/app/Http/Controllers/RegionController.php index ec6573b..997d9f2 100644 --- a/app/Http/Controllers/RegionController.php +++ b/app/Http/Controllers/RegionController.php @@ -10,7 +10,12 @@ use Illuminate\Http\Request; use Illuminate\Support\Facades\Log; use Illuminate\Validation\ValidationException; - +/** + * @OA\Tag( + * name="Regions", + * description="Operations about Regions" + * ) + */ class RegionController extends Controller { /** @@ -32,6 +37,42 @@ public function __construct( $this->regRepo = $regRepo; } + /** + * @OA\Post( + * path="/regions", + * tags={"Regions"}, + * summary="Create a new region", + * operationId="createRegion", + * @OA\RequestBody( + * required=true, + * @OA\JsonContent( + * required={"countryCode", "title"}, + * @OA\Property(property="countryCode", type="string", example="USA", description="Country code (3 characters)"), + * @OA\Property(property="title", type="string", example="North America", description="Title of the region"), + * @OA\Property(property="slug", type="string", example="north-america", description="Slug for the region (optional)"), + * @OA\Property( + * property="translations", + * type="array", + * @OA\Items( + * type="object", + * @OA\Property(property="webUrl", type="string", format="url", example="https://example.com", description="Web URL for the translation"), + * @OA\Property(property="lang", type="string", example="en", description="Language code (2 characters)"), + * @OA\Property(property="title", type="string", example="North America", description="Title in the specified language"), + * @OA\Property(property="description", type="string", example="Description of the region", description="Description in the specified language") + * ) + * ) + * ) + * ), + * @OA\Response( + * response=200, + * description="Successful response", + * @OA\JsonContent( + * type="object", + * @OA\Property(property="data", type="array", @OA\Items(type="object")) + * ) + * ) + * ) + */ public function createRegion(Request $request) { try { @@ -85,6 +126,47 @@ public function createRegion(Request $request) return response()->json($region->fresh('translations'), 201); } + /** + * @OA\Put( + * path="/regions/region/{regionId}", + * tags={"Regions"}, + * summary="Update an existing region", + * operationId="updateRegion", + * @OA\Parameter( + * name="regionId", + * in="path", + * required=true, + * description="ID of the region to update", + * @OA\Schema(type="integer", format="int64") + * ), + * @OA\RequestBody( + * required=true, + * @OA\JsonContent( + * @OA\Property(property="title", type="string", example="Updated Region Title", description="Updated title of the region (optional)"), + * @OA\Property(property="slug", type="string", example="updated-region-slug", description="Updated slug for the region (optional)"), + * @OA\Property( + * property="translations", + * type="array", + * @OA\Items( + * type="object", + * @OA\Property(property="webUrl", type="string", format="url", example="https://example.com", description="Web URL for the translation"), + * @OA\Property(property="lang", type="string", example="en", description="Language code (2 characters)"), + * @OA\Property(property="title", type="string", example="Updated Title in Language", description="Title in the specified language"), + * @OA\Property(property="description", type="string", example="Updated description in language", description="Description in the specified language") + * ) + * ) + * ) + * ), + * @OA\Response( + * response=200, + * description="Successful response", + * @OA\JsonContent( + * type="object", + * @OA\Property(property="data", type="array", @OA\Items(type="object")) + * ) + * ) + * ) + */ public function updateRegion(Request $request, $regionId) { $region = Region::find($regionId); @@ -132,6 +214,27 @@ public function updateRegion(Request $request, $regionId) return response()->json($region->fresh('translations'), 201); } + /** + * @OA\Get( + * path="/regions/{country_code}", + * summary="Get all regions for a specific organisation by country code", + * tags={"Regions"}, + * @OA\Parameter( + * name="country_code", + * in="path", + * description="Country code of the organisation", + * required=true + * ), + * @OA\Response( + * response=200, + * description="Successful response", + * @OA\JsonContent( + * type="object", + * @OA\Property(property="data", type="array", @OA\Items(type="object")) + * ) + * ), + * ) + */ public function getAllForOrganisation($country_code) { if (empty($country_code)) { @@ -165,6 +268,35 @@ public function getAllForOrganisation($country_code) return response()->json($list, 200); } + /** + * @OA\Get( + * path="/regions/{country_code}/{code}", + * summary="Get regions for a specific organisation by country code and language code", + * tags={"Regions"}, + * @OA\Parameter( + * name="country_code", + * in="path", + * description="Country code of the organisation", + * required=true, + * @OA\Schema(type="string") + * ), + * @OA\Parameter( + * name="code", + * in="path", + * description="Language code for translations", + * required=true, + * @OA\Schema(type="string") + * ), + * @OA\Response( + * response=200, + * description="Successful response", + * @OA\JsonContent( + * type="object", + * @OA\Property(property="data", type="array", @OA\Items(type="object")) + * ) + * ), + * ) + */ public function getForCountryCode($country_code, $code) { if (empty($country_code) || empty($code)) { @@ -195,6 +327,29 @@ public function getForCountryCode($country_code, $code) return response()->json($list, 200); } + /** + * @OA\Delete( + * path="/regions/region/{regionId}", + * tags={"Regions"}, + * summary="Delete a region", + * operationId="deleteRegion", + * @OA\Parameter( + * name="regionId", + * in="path", + * required=true, + * description="ID of the region to delete", + * @OA\Schema(type="integer", format="int64") + * ), + * @OA\Response( + * response=200, + * description="Successful response", + * @OA\JsonContent( + * type="object", + * @OA\Property(property="data", type="array", @OA\Items(type="object")) + * ) + * ) + * ) + */ public function deleteRegion($regionId) { $region = Region::find($regionId); @@ -211,6 +366,29 @@ public function deleteRegion($regionId) return response()->json([ 'message' => 'Region deleted'], 202); } + /** + * @OA\Delete( + * path="/regions/region/translation/{translationId}", + * tags={"Regions"}, + * summary="Delete a region translation", + * operationId="deleteTranslation", + * @OA\Parameter( + * name="translationId", + * in="path", + * required=true, + * description="ID of the translation to delete", + * @OA\Schema(type="integer", format="int64") + * ), + * @OA\Response( + * response=200, + * description="Successful response", + * @OA\JsonContent( + * type="object", + * @OA\Property(property="data", type="array", @OA\Items(type="object")) + * ) + * ) + * ) + */ public function deleteTranslation($translationId) { $translation = RegionTranslation::find($translationId); diff --git a/app/Http/Controllers/UsageLogController.php b/app/Http/Controllers/UsageLogController.php index da06043..2c32ead 100644 --- a/app/Http/Controllers/UsageLogController.php +++ b/app/Http/Controllers/UsageLogController.php @@ -10,6 +10,12 @@ use League\Fractal\Manager; use App\Models\UsageLog; +/** + * @OA\Tag( + * name="UsageLogs", + * description="Operations about UsageLog" + * ) + */ class UsageLogController extends Controller { /** @@ -40,6 +46,36 @@ public function __construct(ApplicationRepositoryInterface $applicationRepo, Usa $this->usageLogRepo = $usageLogRepo; } + /** + * @OA\Get( + * path="/usage/applications", + * tags={"UsageLogs"}, + * summary="Get application usage logs", + * operationId="getApplicationLogs", + * @OA\Parameter( + * name="fromDate", + * in="query", + * required=false, + * description="Start date for filtering logs (format: YYYY-MM-DD)", + * @OA\Schema(type="string", format="date") + * ), + * @OA\Parameter( + * name="toDate", + * in="query", + * required=false, + * description="End date for filtering logs (format: YYYY-MM-DD)", + * @OA\Schema(type="string", format="date") + * ), + * @OA\Response( + * response=200, + * description="Successful response", + * @OA\JsonContent( + * type="object", + * @OA\Property(property="data", type="array", @OA\Items(type="object")) + * ) + * ) + * ) + */ public function getApplicationLogs(Request $request) { $this->validate($request, [ @@ -84,6 +120,36 @@ public function getApplicationLogs(Request $request) ], 200); } + /** + * @OA\Get( + * path="/usage/endpoints", + * tags={"UsageLogs"}, + * summary="Get endpoint usage logs", + * operationId="getEndpointLogs", + * @OA\Parameter( + * name="fromDate", + * in="query", + * required=false, + * description="Start date for filtering logs (format: YYYY-MM-DD)", + * @OA\Schema(type="string", format="date") + * ), + * @OA\Parameter( + * name="toDate", + * in="query", + * required=false, + * description="End date for filtering logs (format: YYYY-MM-DD)", + * @OA\Schema(type="string", format="date") + * ), + * @OA\Response( + * response=200, + * description="Successful response", + * @OA\JsonContent( + * type="object", + * @OA\Property(property="data", type="array", @OA\Items(type="object")) + * ) + * ) + * ) + */ public function getEndpointLogs(Request $request) { $this->validate($request, [ @@ -126,6 +192,36 @@ public function getEndpointLogs(Request $request) ], 200); } + /** + * @OA\Get( + * path="/usage/export", + * tags={"UsageLogs"}, + * summary="Export usage logs as CSV", + * operationId="exportUsageLogs", + * @OA\Parameter( + * name="fromDate", + * in="query", + * required=false, + * description="Start date for filtering logs (format: YYYY-MM-DD)", + * @OA\Schema(type="string", format="date") + * ), + * @OA\Parameter( + * name="toDate", + * in="query", + * required=false, + * description="End date for filtering logs (format: YYYY-MM-DD)", + * @OA\Schema(type="string", format="date") + * ), + * @OA\Response( + * response=200, + * description="Successful response", + * @OA\JsonContent( + * type="object", + * @OA\Property(property="data", type="array", @OA\Items(type="object")) + * ) + * ) + * ) + */ public function export(Request $request) { $this->validate($request, [ @@ -204,6 +300,57 @@ public function getForApplication(int $applicationId) /** * @return \Symfony\Component\HttpFoundation\Response */ + /** + * @OA\Get( + * path="/usage/totals", + * tags={"UsageLogs"}, + * summary="Get usage log totals", + * operationId="getTotals", + * @OA\Parameter( + * name="society", + * in="query", + * required=false, + * description="Filter by society", + * @OA\Schema(type="string") + * ), + * @OA\Parameter( + * name="region", + * in="query", + * required=false, + * description="Filter by region ID", + * @OA\Schema(type="integer") + * ), + * @OA\Parameter( + * name="hazard", + * in="query", + * required=false, + * description="Filter by hazard type", + * @OA\Schema(type="string") + * ), + * @OA\Parameter( + * name="date", + * in="query", + * required=false, + * description="Filter by specific date (format: YYYY-MM-DD)", + * @OA\Schema(type="string", format="date") + * ), + * @OA\Parameter( + * name="language", + * in="query", + * required=false, + * description="Filter by language", + * @OA\Schema(type="string") + * ), + * @OA\Response( + * response=200, + * description="Successful response", + * @OA\JsonContent( + * type="object", + * @OA\Property(property="data", type="array", @OA\Items(type="object")) + * ) + * ) + * ) + */ public function getTotals(Request $request) { $this->validate($request, [ diff --git a/app/Http/Controllers/WhatNowController.php b/app/Http/Controllers/WhatNowController.php index c42ad70..da24418 100644 --- a/app/Http/Controllers/WhatNowController.php +++ b/app/Http/Controllers/WhatNowController.php @@ -21,6 +21,12 @@ use League\Fractal\Resource\Collection; use League\Fractal\Resource\Item; +/** + * @OA\Tag( + * name="Whatnow", + * description="Operations about Regions" + * ) + */ class WhatNowController extends Controller { /** @@ -83,6 +89,34 @@ public function __construct( * @param $id * @return \Symfony\Component\HttpFoundation\Response */ + /** + * @OA\Get( + * path="/whatnow/{id}", + * tags={"Whatnow"}, + * summary="Obtiene un recurso publicado por ID", + * description="Retorna los detalles de un recurso publicado basado en el ID proporcionado.", + * operationId="getPublishedById", + * security={{"ApiKeyAuth": {}}}, + * @OA\Parameter( + * name="id", + * in="path", + * description="ID del recurso publicado", + * required=true, + * @OA\Schema( + * type="integer", + * format="int64" + * ) + * ), + * @OA\Response( + * response=200, + * description="Successful response", + * @OA\JsonContent( + * type="object", + * @OA\Property(property="data", type="array", @OA\Items(type="object")) + * ) + * ) + * ) + */ public function getPublishedById($id) { try { @@ -119,6 +153,29 @@ public function getPublishedById($id) * @param $id * @return \Symfony\Component\HttpFoundation\Response */ + /** + * @OA\Get( + * path="/whatnow/{id}/revisions/latest", + * tags={"Whatnow"}, + * summary="Get the latest revision of a WhatNow entity by ID", + * operationId="getLatestById", + * @OA\Parameter( + * name="id", + * in="path", + * required=true, + * description="ID of the WhatNow entity to fetch the latest revision for", + * @OA\Schema(type="integer", format="int64") + * ), + * @OA\Response( + * response=200, + * description="Successful response", + * @OA\JsonContent( + * type="object", + * @OA\Property(property="data", type="array", @OA\Items(type="object")) + * ) + * ) + * ) + */ public function getLatestById($id) { try { @@ -151,6 +208,29 @@ public function getLatestById($id) * @param $id * @return \Symfony\Component\HttpFoundation\Response */ + /** + * @OA\Delete( + * path="/whatnow/{id}", + * tags={"Whatnow"}, + * summary="Delete a WhatNow entity by ID", + * operationId="deleteById", + * @OA\Parameter( + * name="id", + * in="path", + * required=true, + * description="ID of the WhatNow entity to delete", + * @OA\Schema(type="integer", format="int64") + * ), + * @OA\Response( + * response=200, + * description="Successful response", + * @OA\JsonContent( + * type="object", + * @OA\Property(property="data", type="array", @OA\Items(type="object")) + * ) + * ) + * ) + */ public function deleteById($id) { try { @@ -176,6 +256,51 @@ public function deleteById($id) * @param $code * @return \Laravel\Lumen\Http\ResponseFactory|\Symfony\Component\HttpFoundation\Response */ + /** + * @OA\Get( + * path="/org/{code}/whatnow", + * tags={"Whatnow"}, + * summary="Get a feed of WhatNow entities for a specific organisation", + * operationId="getFeed", + * security={{"ApiKeyAuth": {}}}, + * @OA\Parameter( + * name="code", + * in="path", + * required=true, + * description="Country code of the organisation", + * @OA\Schema(type="string") + * ), + * @OA\Parameter( + * name="region", + * in="query", + * required=false, + * description="Filter by region slug", + * @OA\Schema(type="string") + * ), + * @OA\Parameter( + * name="language", + * in="query", + * required=false, + * description="Filter by language code", + * @OA\Schema(type="string") + * ), + * @OA\Parameter( + * name="eventType", + * in="query", + * required=false, + * description="Filter by event type", + * @OA\Schema(type="string") + * ), + * @OA\Response( + * response=200, + * description="Successful response", + * @OA\JsonContent( + * type="object", + * @OA\Property(property="data", type="array", @OA\Items(type="object")) + * ) + * ) + * ) + */ public function getFeed(WhatNowFeed $feed, $code) { try { @@ -233,6 +358,29 @@ protected function changeLogStatus($status){ * @param $code * @return \Laravel\Lumen\Http\ResponseFactory|\Symfony\Component\HttpFoundation\Response */ + /** + * @OA\Get( + * path="/org/{code}/whatnow/revisions/latest", + * tags={"Whatnow"}, + * summary="Get the latest revisions for a country code", + * operationId="getLatestForCountryCode", + * @OA\Parameter( + * name="code", + * in="path", + * required=true, + * description="Country code to fetch the latest revisions for", + * @OA\Schema(type="string") + * ), + * @OA\Response( + * response=200, + * description="Successful response", + * @OA\JsonContent( + * type="object", + * @OA\Property(property="data", type="array", @OA\Items(type="object")) + * ) + * ) + * ) + */ public function getLatestForCountryCode($code) { try { @@ -262,6 +410,36 @@ public function getLatestForCountryCode($code) * @param $code * @return \Laravel\Lumen\Http\ResponseFactory|\Symfony\Component\HttpFoundation\Response */ + /** + * @OA\Get( + * path="/org/{code}/{region}/whatnow/revisions/latest", + * tags={"Whatnow"}, + * summary="Get the latest revisions for a specific region", + * operationId="getLatestForRegion", + * @OA\Parameter( + * name="code", + * in="path", + * required=true, + * description="Country code to fetch the latest revisions for", + * @OA\Schema(type="string") + * ), + * @OA\Parameter( + * name="region", + * in="path", + * required=true, + * description="Region slug to fetch the latest revisions for", + * @OA\Schema(type="string") + * ), + * @OA\Response( + * response=200, + * description="Successful response", + * @OA\JsonContent( + * type="object", + * @OA\Property(property="data", type="array", @OA\Items(type="object")) + * ) + * ) + * ) + */ public function getLatestForRegion($code, $region) { try { @@ -317,6 +495,42 @@ public function getAllRevisions() /** * Creates a new WhatNow Entity */ + /** + * @OA\Post( + * path="/whatnow", + * tags={"Whatnow"}, + * summary="Create a new WhatNow entity", + * operationId="createWhatNowEntity", + * @OA\RequestBody( + * required=true, + * @OA\JsonContent( + * required={"countryCode", "eventType", "translations"}, + * @OA\Property(property="countryCode", type="string", example="USA", description="Country code (3 characters)"), + * @OA\Property(property="eventType", type="string", example="Flood", description="Type of event (max 50 characters)"), + * @OA\Property(property="regionName", type="string", example="North Region", description="Name of the region (optional)"), + * @OA\Property( + * property="translations", + * type="array", + * @OA\Items( + * type="object", + * @OA\Property(property="webUrl", type="string", format="url", example="https://example.com", description="Web URL for the translation (optional)"), + * @OA\Property(property="lang", type="string", example="en", description="Language code (2 characters)"), + * @OA\Property(property="title", type="string", example="Flood Alert", description="Title in the specified language"), + * @OA\Property(property="description", type="string", example="Description of the event", description="Description in the specified language") + * ) + * ) + * ) + * ), + * @OA\Response( + * response=200, + * description="Successful response", + * @OA\JsonContent( + * type="object", + * @OA\Property(property="data", type="array", @OA\Items(type="object")) + * ) + * ) + * ) + */ public function post() { try { @@ -409,6 +623,49 @@ public function post() return response()->json(['data' => $response->toArray()], 201); } + /** + * @OA\Put( + * path="/whatnow/{id}", + * tags={"Whatnow"}, + * summary="Update a WhatNow entity by ID", + * operationId="putById", + * @OA\Parameter( + * name="id", + * in="path", + * required=true, + * description="ID of the WhatNow entity to update", + * @OA\Schema(type="integer", format="int64") + * ), + * @OA\RequestBody( + * required=true, + * @OA\JsonContent( + * required={"countryCode", "eventType", "translations"}, + * @OA\Property(property="countryCode", type="string", example="USA", description="Country code (3 characters)"), + * @OA\Property(property="eventType", type="string", example="Flood", description="Type of event (max 50 characters)"), + * @OA\Property(property="regionName", type="string", example="North Region", description="Name of the region (optional)"), + * @OA\Property( + * property="translations", + * type="array", + * @OA\Items( + * type="object", + * @OA\Property(property="webUrl", type="string", example="https://example.com", description="Web URL for the translation (optional)"), + * @OA\Property(property="lang", type="string", example="en", description="Language code (2 characters)"), + * @OA\Property(property="title", type="string", example="Flood Alert", description="Title in the specified language"), + * @OA\Property(property="description", type="string", example="Description of the event", description="Description in the specified language") + * ) + * ) + * ) + * ), + * @OA\Response( + * response=200, + * description="Successful response", + * @OA\JsonContent( + * type="object", + * @OA\Property(property="data", type="array", @OA\Items(type="object")) + * ) + * ) + * ) + */ public function putById($id) { try { @@ -493,6 +750,40 @@ public function putById($id) return response()->json(['data' => $response->toArray()], 200); } + /** + * @OA\Post( + * path="/whatnow/{id}/revisions", + * tags={"Whatnow"}, + * summary="Create a new translation for a WhatNow entity", + * operationId="createNewTranslation", + * @OA\Parameter( + * name="id", + * in="path", + * required=true, + * description="ID of the WhatNow entity to add a translation to", + * @OA\Schema(type="integer", format="int64") + * ), + * @OA\RequestBody( + * required=true, + * @OA\JsonContent( + * required={"webUrl", "lang", "title", "stages"}, + * @OA\Property(property="webUrl", type="string", format="url", example="https://example.com", description="Web URL for the translation"), + * @OA\Property(property="lang", type="string", example="en", description="Language code (2 characters)"), + * @OA\Property(property="title", type="string", example="Flood Alert", description="Title in the specified language"), + * @OA\Property(property="description", type="string", example="Description of the event", description="Description in the specified language (optional)"), + * @OA\Property(property="stages", type="array", @OA\Items(type="object"), description="Stages associated with the translation") + * ) + * ), + * @OA\Response( + * response=200, + * description="Successful response", + * @OA\JsonContent( + * type="object", + * @OA\Property(property="data", type="array", @OA\Items(type="object")) + * ) + * ) + * ) + */ public function createNewTranslation($id) { try { @@ -548,6 +839,43 @@ public function createNewTranslation($id) * @param int $translationId * @return \Symfony\Component\HttpFoundation\Response */ + /** + * @OA\Patch( + * path="/whatnow/{id}/revisions/{translationId}", + * tags={"Whatnow"}, + * summary="Update the published status of a translation", + * operationId="patchTranslation", + * @OA\Parameter( + * name="id", + * in="path", + * required=true, + * description="ID of the WhatNow entity", + * @OA\Schema(type="integer", format="int64") + * ), + * @OA\Parameter( + * name="translationId", + * in="path", + * required=true, + * description="ID of the translation to update", + * @OA\Schema(type="integer", format="int64") + * ), + * @OA\RequestBody( + * required=true, + * @OA\JsonContent( + * required={"published"}, + * @OA\Property(property="published", type="boolean", example=true, description="Publish status of the translation") + * ) + * ), + * @OA\Response( + * response=200, + * description="Successful response", + * @OA\JsonContent( + * type="object", + * @OA\Property(property="data", type="array", @OA\Items(type="object")) + * ) + * ) + * ) + */ public function patchTranslation($id, $translationId) { $this->validate($this->request, [ @@ -594,6 +922,34 @@ public function patchTranslation($id, $translationId) return response()->json(['data' => $response->toArray()], 200); } + /** + * @OA\Post( + * path="/whatnow/publish", + * tags={"Whatnow"}, + * summary="Publish translations by IDs", + * operationId="publishTranslationsByIds", + * @OA\RequestBody( + * required=true, + * @OA\JsonContent( + * required={"translationIds"}, + * @OA\Property( + * property="translationIds", + * type="array", + * @OA\Items(type="integer", format="int64"), + * description="Array of translation IDs to publish" + * ) + * ) + * ), + * @OA\Response( + * response=200, + * description="Successful response", + * @OA\JsonContent( + * type="object", + * @OA\Property(property="data", type="array", @OA\Items(type="object")) + * ) + * ) + * ) + */ public function publishTranslationsByIds() { $this->validate($this->request, [ diff --git a/config/l5-swagger.php b/config/l5-swagger.php index a3ce546..0625e03 100644 --- a/config/l5-swagger.php +++ b/config/l5-swagger.php @@ -75,6 +75,7 @@ * Route Group options */ 'group_options' => [], + 'security' => [['BasicAuth' => []]], ], 'paths' => [ @@ -215,6 +216,15 @@ 'in' => 'header', // The location of the API key. Valid values are "query" or "header". ], */ + 'BasicAuth' => [ + 'type' => 'http', + 'scheme' => 'basic' + ], + 'ApiKeyAuth' => [ + 'type' => 'apiKey', + 'in' => 'header', + 'name' => 'x-api-key', + ], ], 'security' => [ /* @@ -229,6 +239,7 @@ 'passport' => [] */ + 'BasicAuth' => [] ], ], ], @@ -312,7 +323,7 @@ * Constants which can be used in annotations */ 'constants' => [ - 'L5_SWAGGER_CONST_HOST' => env('L5_SWAGGER_CONST_HOST', 'http://my-default-host.com'), + 'L5_SWAGGER_CONST_HOST' => env('APP_URL', 'http://localhost') . '/v1', ], ], ]; From 8db2dd932c25a75f9b21240cafe5eed3725f1fef Mon Sep 17 00:00:00 2001 From: "LDFOUR\\luisd" Date: Thu, 27 Feb 2025 16:51:09 -0300 Subject: [PATCH 2/3] changed example --- app/Http/Controllers/OrganisationController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Http/Controllers/OrganisationController.php b/app/Http/Controllers/OrganisationController.php index a2074d0..1b899ea 100644 --- a/app/Http/Controllers/OrganisationController.php +++ b/app/Http/Controllers/OrganisationController.php @@ -195,7 +195,7 @@ public function getById($code, Request $request) * property="attributionMessage", * type="string", * maxLength=2048, - * example="PRUEBA 2" + * example="attributionMessage example" * ), * @OA\Property( * property="contributors", From 559b81f44295d8eeb36755d2453f8a8f301fb8e4 Mon Sep 17 00:00:00 2001 From: "LDFOUR\\luisd" Date: Fri, 28 Feb 2025 12:30:16 -0300 Subject: [PATCH 3/3] I added api-docs.json --- .gitignore | 9 +- app/Http/Controllers/FileUploadController.php | 2 +- app/Http/Controllers/WhatNowController.php | 2 +- storage/api-docs/api-docs.json | 1788 +++++++++++++++++ 4 files changed, 1797 insertions(+), 4 deletions(-) create mode 100644 storage/api-docs/api-docs.json diff --git a/.gitignore b/.gitignore index 913b94c..06bc057 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +# Except swagger file +!storage/api-docs/api-docs.json + /node_modules /public/hot /public/storage @@ -5,7 +8,9 @@ /storage/*.key /vendor .vapor/ -storage/ +storage/**/* +!storage/api-docs/ +!storage/api-docs/api-docs.json .env .env.backup .phpunit.result.cache @@ -14,4 +19,4 @@ Homestead.yaml npm-debug.log yarn-error.log helm-chart/secrets.yml -.idea/* +.idea/* \ No newline at end of file diff --git a/app/Http/Controllers/FileUploadController.php b/app/Http/Controllers/FileUploadController.php index e778df7..0766255 100644 --- a/app/Http/Controllers/FileUploadController.php +++ b/app/Http/Controllers/FileUploadController.php @@ -8,7 +8,7 @@ /** * @OA\Tag( * name="Files", - * description="Operations about Regions" + * description="Operations about Files" * ) */ class FileUploadController extends Controller diff --git a/app/Http/Controllers/WhatNowController.php b/app/Http/Controllers/WhatNowController.php index da24418..c3931ee 100644 --- a/app/Http/Controllers/WhatNowController.php +++ b/app/Http/Controllers/WhatNowController.php @@ -24,7 +24,7 @@ /** * @OA\Tag( * name="Whatnow", - * description="Operations about Regions" + * description="Operations about Whatnow messages" * ) */ class WhatNowController extends Controller diff --git a/storage/api-docs/api-docs.json b/storage/api-docs/api-docs.json new file mode 100644 index 0000000..a008649 --- /dev/null +++ b/storage/api-docs/api-docs.json @@ -0,0 +1,1788 @@ +{ + "openapi": "3.0.0", + "info": { + "title": "Whatnow API", + "description": "Whatnow API documentation", + "version": "1.0.0" + }, + "servers": [ + { + "url": "http://localhost:8085/v1", + "description": "API Base URL" + } + ], + "paths": { + "/apps": { + "get": { + "tags": [ + "Applications" + ], + "summary": "Get all applications for a user", + "operationId": "getAllForUser", + "parameters": [ + { + "name": "userId", + "in": "query", + "description": "ID of the user to fetch applications for", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "type": "array", + "items": { + "type": "object" + } + } + }, + "type": "object" + } + } + } + } + } + }, + "post": { + "tags": [ + "Applications" + ], + "summary": "Create a new application", + "operationId": "createApplication", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "required": [ + "name", + "userId" + ], + "properties": { + "name": { + "description": "Name of the application", + "type": "string", + "example": "My Application" + }, + "description": { + "description": "Description of the application (optional)", + "type": "string", + "example": "A description of the application" + }, + "userId": { + "description": "ID of the user creating the application", + "type": "string", + "example": "user123" + }, + "estimatedUsers": { + "description": "Estimated number of users (optional)", + "type": "integer", + "example": 100 + } + }, + "type": "object" + } + } + } + }, + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "type": "array", + "items": { + "type": "object" + } + } + }, + "type": "object" + } + } + } + } + } + } + }, + "/apps/{id}": { + "get": { + "tags": [ + "Applications" + ], + "summary": "Get an application by ID", + "operationId": "getApplicationById", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "ID of the application to retrieve", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "type": "array", + "items": { + "type": "object" + } + } + }, + "type": "object" + } + } + } + } + } + }, + "delete": { + "tags": [ + "Applications" + ], + "summary": "Delete an application by ID", + "operationId": "deleteApplication", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "ID of the application to delete", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "type": "array", + "items": { + "type": "object" + } + } + }, + "type": "object" + } + } + } + } + } + }, + "patch": { + "tags": [ + "Applications" + ], + "summary": "Update an application by ID", + "operationId": "updateApplication", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "ID of the application to update", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "properties": { + "estimatedUsers": { + "description": "Estimated number of users (optional)", + "type": "integer", + "example": 100 + } + }, + "type": "object" + } + } + } + }, + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "type": "array", + "items": { + "type": "object" + } + } + }, + "type": "object" + } + } + } + } + } + } + }, + "/upload": { + "post": { + "tags": [ + "Whatnow" + ], + "summary": "Upload a file", + "operationId": "uploadFile", + "requestBody": { + "required": true, + "content": { + "multipart/form-data": { + "schema": { + "required": [ + "file" + ], + "properties": { + "file": { + "description": "File to upload (allowed types: jpg, png; max size: 10MB)", + "type": "string", + "format": "binary" + } + }, + "type": "object" + } + } + } + }, + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "type": "array", + "items": { + "type": "object" + } + } + }, + "type": "object" + } + } + } + } + } + } + }, + "/org": { + "get": { + "tags": [ + "Organisation" + ], + "summary": "Get all organisations", + "operationId": "04f86edf4b63c5b0f297e462633924b4", + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "type": "array", + "items": { + "type": "object" + } + } + }, + "type": "object" + } + } + } + } + }, + "security": [ + { + "ApiKeyAuth": [] + } + ] + } + }, + "/org/{code}": { + "get": { + "tags": [ + "Organisation" + ], + "summary": "Get organisation by country code", + "operationId": "b4a9c9d91b102ab0d0709eae9104db61", + "parameters": [ + { + "name": "code", + "in": "path", + "description": "Country code of the organisation", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "type": "object" + } + }, + "type": "object" + } + } + } + } + }, + "security": [ + { + "ApiKeyAuth": [] + } + ] + }, + "put": { + "tags": [ + "Organisation" + ], + "summary": "Update an organisation by its country code", + "description": "Updates the details of an organisation based on the provided country code.", + "operationId": "OrganisationController@putById", + "parameters": [ + { + "name": "code", + "in": "path", + "description": "Country code of the organisation", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "Data to update the organisation", + "required": true, + "content": { + "application/json": { + "schema": { + "properties": { + "url": { + "type": "string", + "maxLength": 255, + "example": "https://example.com", + "nullable": true + }, + "translations": { + "type": "object", + "additionalProperties": { + "properties": { + "languageCode": { + "type": "string", + "example": "en" + }, + "name": { + "type": "string", + "maxLength": 255, + "example": "International Federation of Red Cross and Red Crescent Societies" + }, + "attributionMessage": { + "type": "string", + "maxLength": 2048, + "example": "PRUEBA 2" + }, + "contributors": { + "type": "array", + "items": { + "properties": { + "id": { + "type": "integer", + "example": 111 + }, + "name": { + "type": "string", + "example": "This is an example string with exactly one hundred characters, including spaces and symbols" + }, + "logo": { + "type": "string", + "example": "https://whatnowimages.blob.core.windows.net/images/LOGO" + } + }, + "type": "object" + } + }, + "published": { + "type": "boolean", + "example": true + } + }, + "type": "object" + } + } + }, + "type": "object" + } + } + } + }, + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "type": "array", + "items": { + "type": "object" + } + } + }, + "type": "object" + } + } + } + } + } + } + }, + "/regions": { + "post": { + "tags": [ + "Regions" + ], + "summary": "Create a new region", + "operationId": "createRegion", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "required": [ + "countryCode", + "title" + ], + "properties": { + "countryCode": { + "description": "Country code (3 characters)", + "type": "string", + "example": "USA" + }, + "title": { + "description": "Title of the region", + "type": "string", + "example": "North America" + }, + "slug": { + "description": "Slug for the region (optional)", + "type": "string", + "example": "north-america" + }, + "translations": { + "type": "array", + "items": { + "properties": { + "webUrl": { + "description": "Web URL for the translation", + "type": "string", + "format": "url", + "example": "https://example.com" + }, + "lang": { + "description": "Language code (2 characters)", + "type": "string", + "example": "en" + }, + "title": { + "description": "Title in the specified language", + "type": "string", + "example": "North America" + }, + "description": { + "description": "Description in the specified language", + "type": "string", + "example": "Description of the region" + } + }, + "type": "object" + } + } + }, + "type": "object" + } + } + } + }, + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "type": "array", + "items": { + "type": "object" + } + } + }, + "type": "object" + } + } + } + } + } + } + }, + "/regions/region/{regionId}": { + "put": { + "tags": [ + "Regions" + ], + "summary": "Update an existing region", + "operationId": "updateRegion", + "parameters": [ + { + "name": "regionId", + "in": "path", + "description": "ID of the region to update", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "properties": { + "title": { + "description": "Updated title of the region (optional)", + "type": "string", + "example": "Updated Region Title" + }, + "slug": { + "description": "Updated slug for the region (optional)", + "type": "string", + "example": "updated-region-slug" + }, + "translations": { + "type": "array", + "items": { + "properties": { + "webUrl": { + "description": "Web URL for the translation", + "type": "string", + "format": "url", + "example": "https://example.com" + }, + "lang": { + "description": "Language code (2 characters)", + "type": "string", + "example": "en" + }, + "title": { + "description": "Title in the specified language", + "type": "string", + "example": "Updated Title in Language" + }, + "description": { + "description": "Description in the specified language", + "type": "string", + "example": "Updated description in language" + } + }, + "type": "object" + } + } + }, + "type": "object" + } + } + } + }, + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "type": "array", + "items": { + "type": "object" + } + } + }, + "type": "object" + } + } + } + } + } + }, + "delete": { + "tags": [ + "Regions" + ], + "summary": "Delete a region", + "operationId": "deleteRegion", + "parameters": [ + { + "name": "regionId", + "in": "path", + "description": "ID of the region to delete", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "type": "array", + "items": { + "type": "object" + } + } + }, + "type": "object" + } + } + } + } + } + } + }, + "/regions/{country_code}": { + "get": { + "tags": [ + "Regions" + ], + "summary": "Get all regions for a specific organisation by country code", + "operationId": "d2296fe4eb4c2d71309b7bd2370494bd", + "parameters": [ + { + "name": "country_code", + "in": "path", + "description": "Country code of the organisation", + "required": true + } + ], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "type": "array", + "items": { + "type": "object" + } + } + }, + "type": "object" + } + } + } + } + } + } + }, + "/regions/{country_code}/{code}": { + "get": { + "tags": [ + "Regions" + ], + "summary": "Get regions for a specific organisation by country code and language code", + "operationId": "e80be67aaefaf2057958c0e54908fbc9", + "parameters": [ + { + "name": "country_code", + "in": "path", + "description": "Country code of the organisation", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "code", + "in": "path", + "description": "Language code for translations", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "type": "array", + "items": { + "type": "object" + } + } + }, + "type": "object" + } + } + } + } + } + } + }, + "/regions/region/translation/{translationId}": { + "delete": { + "tags": [ + "Regions" + ], + "summary": "Delete a region translation", + "operationId": "deleteTranslation", + "parameters": [ + { + "name": "translationId", + "in": "path", + "description": "ID of the translation to delete", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "type": "array", + "items": { + "type": "object" + } + } + }, + "type": "object" + } + } + } + } + } + } + }, + "/usage/applications": { + "get": { + "tags": [ + "UsageLogs" + ], + "summary": "Get application usage logs", + "operationId": "getApplicationLogs", + "parameters": [ + { + "name": "fromDate", + "in": "query", + "description": "Start date for filtering logs (format: YYYY-MM-DD)", + "required": false, + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "toDate", + "in": "query", + "description": "End date for filtering logs (format: YYYY-MM-DD)", + "required": false, + "schema": { + "type": "string", + "format": "date" + } + } + ], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "type": "array", + "items": { + "type": "object" + } + } + }, + "type": "object" + } + } + } + } + } + } + }, + "/usage/endpoints": { + "get": { + "tags": [ + "UsageLogs" + ], + "summary": "Get endpoint usage logs", + "operationId": "getEndpointLogs", + "parameters": [ + { + "name": "fromDate", + "in": "query", + "description": "Start date for filtering logs (format: YYYY-MM-DD)", + "required": false, + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "toDate", + "in": "query", + "description": "End date for filtering logs (format: YYYY-MM-DD)", + "required": false, + "schema": { + "type": "string", + "format": "date" + } + } + ], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "type": "array", + "items": { + "type": "object" + } + } + }, + "type": "object" + } + } + } + } + } + } + }, + "/usage/export": { + "get": { + "tags": [ + "UsageLogs" + ], + "summary": "Export usage logs as CSV", + "operationId": "exportUsageLogs", + "parameters": [ + { + "name": "fromDate", + "in": "query", + "description": "Start date for filtering logs (format: YYYY-MM-DD)", + "required": false, + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "toDate", + "in": "query", + "description": "End date for filtering logs (format: YYYY-MM-DD)", + "required": false, + "schema": { + "type": "string", + "format": "date" + } + } + ], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "type": "array", + "items": { + "type": "object" + } + } + }, + "type": "object" + } + } + } + } + } + } + }, + "/usage/totals": { + "get": { + "tags": [ + "UsageLogs" + ], + "summary": "Get usage log totals", + "operationId": "getTotals", + "parameters": [ + { + "name": "society", + "in": "query", + "description": "Filter by society", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "region", + "in": "query", + "description": "Filter by region ID", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "name": "hazard", + "in": "query", + "description": "Filter by hazard type", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "date", + "in": "query", + "description": "Filter by specific date (format: YYYY-MM-DD)", + "required": false, + "schema": { + "type": "string", + "format": "date" + } + }, + { + "name": "language", + "in": "query", + "description": "Filter by language", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "type": "array", + "items": { + "type": "object" + } + } + }, + "type": "object" + } + } + } + } + } + } + }, + "/whatnow/{id}": { + "get": { + "tags": [ + "Whatnow" + ], + "summary": "Obtiene un recurso publicado por ID", + "description": "Retorna los detalles de un recurso publicado basado en el ID proporcionado.", + "operationId": "getPublishedById", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "ID del recurso publicado", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "type": "array", + "items": { + "type": "object" + } + } + }, + "type": "object" + } + } + } + } + }, + "security": [ + { + "ApiKeyAuth": [] + } + ] + }, + "put": { + "tags": [ + "Whatnow" + ], + "summary": "Update a WhatNow entity by ID", + "operationId": "putById", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "ID of the WhatNow entity to update", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "required": [ + "countryCode", + "eventType", + "translations" + ], + "properties": { + "countryCode": { + "description": "Country code (3 characters)", + "type": "string", + "example": "USA" + }, + "eventType": { + "description": "Type of event (max 50 characters)", + "type": "string", + "example": "Flood" + }, + "regionName": { + "description": "Name of the region (optional)", + "type": "string", + "example": "North Region" + }, + "translations": { + "type": "array", + "items": { + "properties": { + "webUrl": { + "description": "Web URL for the translation (optional)", + "type": "string", + "example": "https://example.com" + }, + "lang": { + "description": "Language code (2 characters)", + "type": "string", + "example": "en" + }, + "title": { + "description": "Title in the specified language", + "type": "string", + "example": "Flood Alert" + }, + "description": { + "description": "Description in the specified language", + "type": "string", + "example": "Description of the event" + } + }, + "type": "object" + } + } + }, + "type": "object" + } + } + } + }, + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "type": "array", + "items": { + "type": "object" + } + } + }, + "type": "object" + } + } + } + } + } + }, + "delete": { + "tags": [ + "Whatnow" + ], + "summary": "Delete a WhatNow entity by ID", + "operationId": "deleteById", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "ID of the WhatNow entity to delete", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "type": "array", + "items": { + "type": "object" + } + } + }, + "type": "object" + } + } + } + } + } + } + }, + "/whatnow/{id}/revisions/latest": { + "get": { + "tags": [ + "Whatnow" + ], + "summary": "Get the latest revision of a WhatNow entity by ID", + "operationId": "getLatestById", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "ID of the WhatNow entity to fetch the latest revision for", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "type": "array", + "items": { + "type": "object" + } + } + }, + "type": "object" + } + } + } + } + } + } + }, + "/org/{code}/whatnow": { + "get": { + "tags": [ + "Whatnow" + ], + "summary": "Get a feed of WhatNow entities for a specific organisation", + "operationId": "getFeed", + "parameters": [ + { + "name": "code", + "in": "path", + "description": "Country code of the organisation", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "region", + "in": "query", + "description": "Filter by region slug", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "language", + "in": "query", + "description": "Filter by language code", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "eventType", + "in": "query", + "description": "Filter by event type", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "type": "array", + "items": { + "type": "object" + } + } + }, + "type": "object" + } + } + } + } + }, + "security": [ + { + "ApiKeyAuth": [] + } + ] + } + }, + "/org/{code}/whatnow/revisions/latest": { + "get": { + "tags": [ + "Whatnow" + ], + "summary": "Get the latest revisions for a country code", + "operationId": "getLatestForCountryCode", + "parameters": [ + { + "name": "code", + "in": "path", + "description": "Country code to fetch the latest revisions for", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "type": "array", + "items": { + "type": "object" + } + } + }, + "type": "object" + } + } + } + } + } + } + }, + "/org/{code}/{region}/whatnow/revisions/latest": { + "get": { + "tags": [ + "Whatnow" + ], + "summary": "Get the latest revisions for a specific region", + "operationId": "getLatestForRegion", + "parameters": [ + { + "name": "code", + "in": "path", + "description": "Country code to fetch the latest revisions for", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "region", + "in": "path", + "description": "Region slug to fetch the latest revisions for", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "type": "array", + "items": { + "type": "object" + } + } + }, + "type": "object" + } + } + } + } + } + } + }, + "/whatnow": { + "post": { + "tags": [ + "Whatnow" + ], + "summary": "Create a new WhatNow entity", + "operationId": "createWhatNowEntity", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "required": [ + "countryCode", + "eventType", + "translations" + ], + "properties": { + "countryCode": { + "description": "Country code (3 characters)", + "type": "string", + "example": "USA" + }, + "eventType": { + "description": "Type of event (max 50 characters)", + "type": "string", + "example": "Flood" + }, + "regionName": { + "description": "Name of the region (optional)", + "type": "string", + "example": "North Region" + }, + "translations": { + "type": "array", + "items": { + "properties": { + "webUrl": { + "description": "Web URL for the translation (optional)", + "type": "string", + "format": "url", + "example": "https://example.com" + }, + "lang": { + "description": "Language code (2 characters)", + "type": "string", + "example": "en" + }, + "title": { + "description": "Title in the specified language", + "type": "string", + "example": "Flood Alert" + }, + "description": { + "description": "Description in the specified language", + "type": "string", + "example": "Description of the event" + } + }, + "type": "object" + } + } + }, + "type": "object" + } + } + } + }, + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "type": "array", + "items": { + "type": "object" + } + } + }, + "type": "object" + } + } + } + } + } + } + }, + "/whatnow/{id}/revisions": { + "post": { + "tags": [ + "Whatnow" + ], + "summary": "Create a new translation for a WhatNow entity", + "operationId": "createNewTranslation", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "ID of the WhatNow entity to add a translation to", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "required": [ + "webUrl", + "lang", + "title", + "stages" + ], + "properties": { + "webUrl": { + "description": "Web URL for the translation", + "type": "string", + "format": "url", + "example": "https://example.com" + }, + "lang": { + "description": "Language code (2 characters)", + "type": "string", + "example": "en" + }, + "title": { + "description": "Title in the specified language", + "type": "string", + "example": "Flood Alert" + }, + "description": { + "description": "Description in the specified language (optional)", + "type": "string", + "example": "Description of the event" + }, + "stages": { + "description": "Stages associated with the translation", + "type": "array", + "items": { + "type": "object" + } + } + }, + "type": "object" + } + } + } + }, + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "type": "array", + "items": { + "type": "object" + } + } + }, + "type": "object" + } + } + } + } + } + } + }, + "/whatnow/{id}/revisions/{translationId}": { + "patch": { + "tags": [ + "Whatnow" + ], + "summary": "Update the published status of a translation", + "operationId": "patchTranslation", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "ID of the WhatNow entity", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + }, + { + "name": "translationId", + "in": "path", + "description": "ID of the translation to update", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "required": [ + "published" + ], + "properties": { + "published": { + "description": "Publish status of the translation", + "type": "boolean", + "example": true + } + }, + "type": "object" + } + } + } + }, + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "type": "array", + "items": { + "type": "object" + } + } + }, + "type": "object" + } + } + } + } + } + } + }, + "/whatnow/publish": { + "post": { + "tags": [ + "Whatnow" + ], + "summary": "Publish translations by IDs", + "operationId": "publishTranslationsByIds", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "required": [ + "translationIds" + ], + "properties": { + "translationIds": { + "description": "Array of translation IDs to publish", + "type": "array", + "items": { + "type": "integer", + "format": "int64" + } + } + }, + "type": "object" + } + } + } + }, + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "type": "array", + "items": { + "type": "object" + } + } + }, + "type": "object" + } + } + } + } + } + } + } + }, + "tags": [ + { + "name": "Organisation", + "description": "Operations about Organisations" + }, + { + "name": "Regions", + "description": "Operations about Regions" + }, + { + "name": "UsageLogs", + "description": "Operations about UsageLog" + }, + { + "name": "Whatnow", + "description": "Operations about Regions" + }, + { + "name": "Applications", + "description": "Applications" + } + ], + "components": { + "securitySchemes": { + "BasicAuth": { + "type": "http", + "scheme": "basic" + }, + "ApiKeyAuth": { + "type": "apiKey", + "in": "header", + "name": "x-api-key" + } + } + }, + "security": [ + { + "BasicAuth": [] + } + ] +}