diff --git a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitAttendeeNotesApiController.php b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitAttendeeNotesApiController.php index 7e3bb2a91..8ae1d7136 100644 --- a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitAttendeeNotesApiController.php +++ b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitAttendeeNotesApiController.php @@ -13,13 +13,17 @@ **/ use App\Http\Utils\EpochCellFormatter; +use App\Models\Foundation\Main\IGroup; use App\Models\Foundation\Summit\Repositories\ISummitAttendeeNoteRepository; use App\ModelSerializers\SerializerUtils; +use App\Security\SummitScopes; use App\Services\Model\IAttendeeService; use models\oauth2\IResourceServerContext; use models\summit\ISummitAttendeeRepository; use models\summit\ISummitRepository; use ModelSerializers\SerializerRegistry; +use OpenApi\Attributes as OA; +use Symfony\Component\HttpFoundation\Response; use utils\Filter; use utils\FilterElement; @@ -74,6 +78,35 @@ public function __construct $this->attendee_service = $attendee_service; } + #[OA\Get( + path: "/api/v1/summits/{id}/attendees/all/notes", + summary: "Get all attendee notes for a summit", + description: "Returns all notes for all attendees in the summit. Admin access required.", + operationId: 'getAllAttendeeNotes', + tags: ["Attendee Notes"], + security: [['summit_attendee_notes_oauth2' => [ + SummitScopes::ReadAllSummitData, + SummitScopes::ReadAttendeeNotesData, + ]]], + parameters: [ + new OA\Parameter(name: "id", description: "Summit ID", in: "path", required: true, schema: new OA\Schema(type: "string")), + new OA\Parameter(name: "page", description: "Page number", in: "query", required: false, schema: new OA\Schema(type: "integer", default: 1)), + new OA\Parameter(name: "per_page", description: "Items per page", in: "query", required: false, schema: new OA\Schema(type: "integer", default: 10)), + new OA\Parameter(name: "filter", description: "Filter query", in: "query", required: false, schema: new OA\Schema(type: "string")), + new OA\Parameter(name: "order", description: "Order by", in: "query", required: false, schema: new OA\Schema(type: "string")), + new OA\Parameter(name: "expand", description: "Expand relations (author, owner, ticket)", in: "query", required: false, schema: new OA\Schema(type: "string")), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: "OK", + content: new OA\JsonContent(ref: "#/components/schemas/PaginatedAttendeeNotesResponse") + ), + new OA\Response(response: Response::HTTP_UNAUTHORIZED, description: "Unauthorized"), + new OA\Response(response: Response::HTTP_FORBIDDEN, description: "Forbidden"), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Not Found"), + ] + )] /** * @param $summit_id * @return mixed @@ -133,10 +166,30 @@ function () { ); } - /** - * @param $summit_id - * @return mixed - */ + #[OA\Get( + path: "/api/v1/summits/{id}/attendees/all/notes/csv", + summary: "Export all attendee notes in CSV format", + operationId: 'getAllAttendeeNotesCSV', + security: [['summit_attendee_notes_oauth2' => [ + SummitScopes::ReadAllSummitData, + SummitScopes::ReadAttendeeNotesData, + ]]], + tags: ["Attendee Notes"], + parameters: [ + new OA\Parameter(name: "id", description: "Summit ID", in: "path", required: true, schema: new OA\Schema(type: "string")), + new OA\Parameter(name: "filter", description: "Filter query", in: "query", required: false, schema: new OA\Schema(type: "string")), + new OA\Parameter(name: "order", description: "Order by", in: "query", required: false, schema: new OA\Schema(type: "string")), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: "CSV file download", + content: new OA\MediaType(mediaType: "text/csv", schema: new OA\Schema(type: "string", format: "binary")) + ), + new OA\Response(response: Response::HTTP_UNAUTHORIZED, description: "Unauthorized"), + new OA\Response(response: Response::HTTP_FORBIDDEN, description: "Forbidden"), + ] + )] public function getAllAttendeeNotesCSV($summit_id) { $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->getResourceServerContext())->find($summit_id); @@ -202,11 +255,33 @@ function () { ); } - /** - * @param $summit_id - * @param $attendee_id - * @return mixed - */ + #[OA\Get( + path: "/api/v1/summits/{id}/attendees/{attendee_id}/notes", + summary: "Get all notes for a specific attendee", + operationId: 'getAttendeeNotes', + security: [['summit_attendee_notes_oauth2' => [ + SummitScopes::ReadAllSummitData, + SummitScopes::ReadAttendeeNotesData, + ]]], + tags: ["Attendee Notes"], + parameters: [ + new OA\Parameter(name: "id", description: "Summit ID", in: "path", required: true, schema: new OA\Schema(type: "string")), + new OA\Parameter(name: "attendee_id", description: "Attendee ID", in: "path", required: true, schema: new OA\Schema(type: "integer")), + new OA\Parameter(name: "page", description: "Page number", in: "query", required: false, schema: new OA\Schema(type: "integer", default: 1)), + new OA\Parameter(name: "per_page", description: "Items per page", in: "query", required: false, schema: new OA\Schema(type: "integer", default: 10)), + new OA\Parameter(name: "expand", description: "Expand relations (author, owner, ticket)", in: "query", required: false, schema: new OA\Schema(type: "string")), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: "OK", + content: new OA\JsonContent(ref: "#/components/schemas/PaginatedAttendeeNotesResponse") + ), + new OA\Response(response: Response::HTTP_UNAUTHORIZED, description: "Unauthorized"), + new OA\Response(response: Response::HTTP_FORBIDDEN, description: "Forbidden"), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Not Found"), + ] + )] public function getAttendeeNotes($summit_id, $attendee_id) { $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->getResourceServerContext())->find($summit_id); @@ -260,11 +335,29 @@ function () { ); } - /** - * @param $summit_id - * @param $attendee_id - * @return mixed - */ + #[OA\Get( + path: "/api/v1/summits/{id}/attendees/{attendee_id}/notes/csv", + summary: "Export notes for a specific attendee in CSV format", + operationId: 'getAttendeeNotesCSV', + security: [['summit_attendee_notes_oauth2' => [ + SummitScopes::ReadAllSummitData, + SummitScopes::ReadAttendeeNotesData, + ]]], + tags: ["Attendee Notes"], + parameters: [ + new OA\Parameter(name: "id", description: "Summit ID", in: "path", required: true, schema: new OA\Schema(type: "string")), + new OA\Parameter(name: "attendee_id", description: "Attendee ID", in: "path", required: true, schema: new OA\Schema(type: "integer")), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: "CSV file download", + content: new OA\MediaType(mediaType: "text/csv", schema: new OA\Schema(type: "string", format: "binary")) + ), + new OA\Response(response: Response::HTTP_UNAUTHORIZED, description: "Unauthorized"), + new OA\Response(response: Response::HTTP_FORBIDDEN, description: "Forbidden"), + ] + )] public function getAttendeeNotesCSV($summit_id, $attendee_id) { $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->getResourceServerContext())->find($summit_id); @@ -328,12 +421,32 @@ function () { ); } - /** - * @param $summit_id - * @param $attendee_id - * @param $note_id - * @return mixed - */ + #[OA\Get( + path: "/api/v1/summits/{id}/attendees/{attendee_id}/notes/{note_id}", + summary: "Get a specific attendee note", + operationId: 'getAttendeeNote', + security: [['summit_attendee_notes_oauth2' => [ + SummitScopes::ReadAllSummitData, + SummitScopes::ReadAttendeeNotesData, + ]]], + tags: ["Attendee Notes"], + parameters: [ + new OA\Parameter(name: "id", description: "Summit ID", in: "path", required: true, schema: new OA\Schema(type: "string")), + new OA\Parameter(name: "attendee_id", description: "Attendee ID", in: "path", required: true, schema: new OA\Schema(type: "integer")), + new OA\Parameter(name: "note_id", description: "Note ID", in: "path", required: true, schema: new OA\Schema(type: "integer")), + new OA\Parameter(name: "expand", description: "Expand relations (author, owner, ticket)", in: "query", required: false, schema: new OA\Schema(type: "string")), + ], + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: "OK", + content: new OA\JsonContent(ref: "#/components/schemas/SummitAttendeeNote") + ), + new OA\Response(response: Response::HTTP_UNAUTHORIZED, description: "Unauthorized"), + new OA\Response(response: Response::HTTP_FORBIDDEN, description: "Forbidden"), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Not Found"), + ] + )] public function getAttendeeNote($summit_id, $attendee_id, $note_id) { return $this->processRequest(function () use ($summit_id, $attendee_id, $note_id) { @@ -363,11 +476,42 @@ public function getAttendeeNote($summit_id, $attendee_id, $note_id) }); } - /** - * @param $summit_id - * @param $attendee_id - * @return mixed - */ + #[OA\Post( + path: "/api/v1/summits/{id}/attendees/{attendee_id}/notes", + summary: "Add a note to an attendee", + operationId: 'addAttendeeNote', + security: [['summit_attendee_notes_oauth2' => [ + SummitScopes::WriteSummitData, + SummitScopes::WriteAttendeeNotesData, + ]]], + tags: ["Attendee Notes"], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + IGroup::SummitRegistrationAdmins, + ] + ], + parameters: [ + new OA\Parameter(name: "id", description: "Summit ID", in: "path", required: true, schema: new OA\Schema(type: "string")), + new OA\Parameter(name: "attendee_id", description: "Attendee ID", in: "path", required: true, schema: new OA\Schema(type: "integer")), + ], + requestBody: new OA\RequestBody( + required: true, + content: new OA\JsonContent(ref: "#/components/schemas/AttendeeNoteAddRequest") + ), + responses: [ + new OA\Response( + response: Response::HTTP_CREATED, + description: "Created", + content: new OA\JsonContent(ref: "#/components/schemas/SummitAttendeeNote") + ), + 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"), + ] + )] public function addAttendeeNote($summit_id, $attendee_id) { return $this->processRequest(function () use ($summit_id, $attendee_id) { @@ -389,12 +533,44 @@ public function addAttendeeNote($summit_id, $attendee_id) }); } - /** - * @param $summit_id - * @param $attendee_id - * @param $note_id - * @return mixed - */ + #[OA\Put( + path: "/api/v1/summits/{id}/attendees/{attendee_id}/notes/{note_id}", + summary: "Update an attendee note", + operationId: 'updateAttendeeNote', + security: [['summit_attendee_notes_oauth2' => [ + SummitScopes::WriteSummitData, + SummitScopes::WriteAttendeeNotesData, + ]]], + tags: ["Attendee Notes"], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + IGroup::SummitRegistrationAdmins, + ] + ], + parameters: [ + new OA\Parameter(name: "id", description: "Summit ID", in: "path", required: true, schema: new OA\Schema(type: "string")), + new OA\Parameter(name: "attendee_id", description: "Attendee ID", in: "path", required: true, schema: new OA\Schema(type: "integer")), + new OA\Parameter(name: "note_id", description: "Note ID", in: "path", required: true, schema: new OA\Schema(type: "integer")), + ], + requestBody: new OA\RequestBody( + required: true, + content: new OA\JsonContent(ref: "#/components/schemas/AttendeeNoteUpdateRequest") + ), + responses: [ + new OA\Response( + response: Response::HTTP_OK, + description: "OK - Note updated successfully", + content: new OA\JsonContent(ref: "#/components/schemas/SummitAttendeeNote") + ), + new OA\Response(response: Response::HTTP_BAD_REQUEST, description: "Bad Request"), + new OA\Response(response: Response::HTTP_UNAUTHORIZED, description: "Unauthorized"), + new OA\Response(response: Response::HTTP_FORBIDDEN, description: "Forbidden"), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Not Found"), + ] + )] public function updateAttendeeNote($summit_id, $attendee_id, $note_id) { return $this->processRequest(function () use ($summit_id, $attendee_id, $note_id) { @@ -416,12 +592,35 @@ public function updateAttendeeNote($summit_id, $attendee_id, $note_id) }); } - /** - * @param $summit_id - * @param $attendee_id - * @param $note_id - * @return mixed - */ + #[OA\Delete( + path: "/api/v1/summits/{id}/attendees/{attendee_id}/notes/{note_id}", + summary: "Delete an attendee note", + operationId: 'deleteAttendeeNote', + security: [['summit_attendee_notes_oauth2' => [ + SummitScopes::WriteSummitData, + SummitScopes::WriteAttendeeNotesData, + ]]], + tags: ["Attendee Notes"], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + IGroup::SummitRegistrationAdmins, + ] + ], + parameters: [ + new OA\Parameter(name: "id", description: "Summit ID", in: "path", required: true, schema: new OA\Schema(type: "string")), + new OA\Parameter(name: "attendee_id", description: "Attendee ID", in: "path", required: true, schema: new OA\Schema(type: "integer")), + new OA\Parameter(name: "note_id", description: "Note ID", in: "path", required: true, schema: new OA\Schema(type: "integer")), + ], + responses: [ + new OA\Response(response: Response::HTTP_NO_CONTENT, description: "No Content - Note 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: "Not Found"), + ] + )] public function deleteAttendeeNote($summit_id, $attendee_id, $note_id) { return $this->processRequest(function () use ($summit_id, $attendee_id, $note_id) { @@ -433,4 +632,4 @@ public function deleteAttendeeNote($summit_id, $attendee_id, $note_id) return $this->deleted(); }); } -} \ No newline at end of file +} diff --git a/app/Swagger/Models/SummitAttendeeNoteSchema.php b/app/Swagger/Models/SummitAttendeeNoteSchema.php new file mode 100644 index 000000000..91d224e63 --- /dev/null +++ b/app/Swagger/Models/SummitAttendeeNoteSchema.php @@ -0,0 +1,22 @@ + 'Read All Summit Data', + SummitScopes::ReadAttendeeNotesData => 'Read Attendee Notes Data', + SummitScopes::WriteSummitData => 'Write Summit Data', + SummitScopes::WriteAttendeeNotesData => 'Write Attendee Notes Data', + ], + ), + ], + ) +] +class SummitAttendeeNotesSecuritySchema +{ +} diff --git a/app/Swagger/security/SummitBookableRoomsAttributeTypeSecurity.php b/app/Swagger/Security/SummitBookableRoomsAttributeTypeSecurity.php similarity index 100% rename from app/Swagger/security/SummitBookableRoomsAttributeTypeSecurity.php rename to app/Swagger/Security/SummitBookableRoomsAttributeTypeSecurity.php diff --git a/app/Swagger/SummitAttendeeNoteSchemas.php b/app/Swagger/SummitAttendeeNoteSchemas.php new file mode 100644 index 000000000..f732d420a --- /dev/null +++ b/app/Swagger/SummitAttendeeNoteSchemas.php @@ -0,0 +1,45 @@ +