-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(ZMS-3460): create endpoint for free appointments grouped by office #797
feat(ZMS-3460): create endpoint for free appointments grouped by office #797
Conversation
WalkthroughThis pull request introduces a new API endpoint Changes
Sequence DiagramsequenceDiagram
Client->>API: Request available appointments
API->>ValidationService: Validate request parameters
ValidationService-->>API: Validation result
API->>AvailableAppointmentsListService: Get appointments
AvailableAppointmentsListService->>ZmsApiFacadeService: Fetch appointments
ZmsApiFacadeService-->>AvailableAppointmentsListService: Appointment data
AvailableAppointmentsListService->>API: Grouped appointments
API->>Client: Return appointments by office
Possibly related PRs
Suggested reviewers
Poem
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
Documentation and Community
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 6
🔭 Outside diff range comments (2)
zmscitizenapi/src/Zmscitizenapi/Services/Core/ZmsApiFacadeService.php (2)
Line range hint
546-578
: Implement logic for $groupByOffice or remove unused parameterThe parameter
$groupByOffice
is added to theprocessFreeSlots
method signature but is not utilized within the method body. This can lead to confusion and may indicate incomplete implementation of the grouping logic.If the intention is to group appointment timestamps by office, consider implementing the necessary logic inside the method. Alternatively, if grouping is not required, remove the
$groupByOffice
parameter to avoid misleading future maintainers.
Line range hint
546-578
: Return the correct instance when grouping by officeCurrently, the method
processFreeSlots
returns an instance ofProcessFreeSlots
, even when appointments are grouped by office. Since you're grouping timestamps by scope ID (which may represent offices), you should return an instance ofProcessFreeSlotsGroupByOffice
to align with the new data structure.Modify the return statement to return the appropriate class instance:
- return new ProcessFreeSlots($appointmentTimestamps); + if ($groupByOffice) { + return new ProcessFreeSlotsGroupByOffice($appointmentTimestamps); + } else { + // Flatten the timestamps if not grouping by office + $flatTimestamps = []; + foreach ($appointmentTimestamps as $timestamps) { + $flatTimestamps = array_merge($flatTimestamps, $timestamps); + } + asort($flatTimestamps); + return new ProcessFreeSlots($flatTimestamps); + }Ensure that the
ProcessFreeSlotsGroupByOffice
class is properly utilized to handle the grouped data.
🧹 Nitpick comments (6)
zmscitizenapi/src/Zmscitizenapi/Models/ProcessFreeSlotsGroupByOffice.php (1)
16-17
: Define the property type explicitlyThe docblock for
$appointmentTimestamps
mentions that it can bearray|null
, but the property is declared aspublic array|null $appointmentTimestamps = [];
, which initializes it as an empty array. This can cause confusion about whether the property can ever benull
.Consider defining the property more explicitly:
- /** @var array|null */ - public array|null $appointmentTimestamps = []; + /** @var array */ + public array $appointmentTimestamps;Also, initialize the property in the constructor to ensure it's always an array.
zmscitizenapi/src/Zmscitizenapi/Controllers/Availability/AvailableAppointmentsListByOfficeController.php (1)
33-42
: Ensure consistent error handling and response formattingThe ternary operator used in the return statement can be hard to read and may lead to inconsistent responses if
$result
does not match expected formats. Consider separating the error handling and success response for clarity.Refactor the return statement for better readability:
$result = $this->service->getAvailableAppointmentsListByOffice($request->getQueryParams()); - return is_array($result) && isset($result['errors']) - ? $this->createJsonResponse( - $response, - $result, - ErrorMessages::getHighestStatusCode($result['errors']) - ) - : $this->createJsonResponse($response, $result->toArray(), 200); + if (is_array($result) && isset($result['errors'])) { + $statusCode = ErrorMessages::getHighestStatusCode($result['errors']); + return $this->createJsonResponse($response, $result, $statusCode); + } else { + return $this->createJsonResponse($response, $result->toArray(), 200); + }This enhances readability and maintainability.
zmscitizenapi/src/Zmscitizenapi/Services/Availability/AvailableAppointmentsListService.php (2)
50-58
: Consider adding type hints for better type safety.The method signature could benefit from explicit type hints for the parameters and return type.
- private function getAvailableAppointments(object $data, ?bool $groupByOffice = false): array|AvailableAppointments + private function getAvailableAppointments( + object $data, + ?bool $groupByOffice = false + ): array|AvailableAppointments|\BO\Zmsentities\Collection\ProcessList
61-71
: Add return type hint and PHPDoc for consistency.The new method is missing a return type hint and documentation.
- public function getAvailableAppointmentsListByOffice($queryParams) + /** + * Get available appointments grouped by office + * + * @param array $queryParams Query parameters containing date, officeIds, and serviceIds + * @return array|AvailableAppointments|\BO\Zmsentities\Collection\ProcessList + */ + public function getAvailableAppointmentsListByOffice(array $queryParams): array|AvailableAppointments|\BO\Zmsentities\Collection\ProcessListzmscitizenapi/src/Zmscitizenapi/Services/Core/ValidationService.php (1)
360-362
: Consider adding array element validation.While the method checks for non-empty arrays and numeric values, it might be good to add validation for individual office IDs (e.g., positive integers only).
private static function isValidOfficeIds(?array $officeIds): bool { - return !empty($officeIds) && self::isValidNumericArray($officeIds); + return !empty($officeIds) && + self::isValidNumericArray($officeIds) && + array_reduce($officeIds, fn($valid, $id) => $valid && $id > 0, true); }zmscitizenapi/src/Zmscitizenapi/Services/Availability/AvailableDaysListService.php (1)
21-28
: Consider validating before making the API call.While the error handling is good, consider validating the appointment days before making the API call to
getAvailableDays
to avoid unnecessary network requests for invalid data.- $result = $this->getAvailableDays($clientData); - $errors = ValidationService::validateAppointmentDaysNotFound($result->toArray()); - - if (!empty($errors)) { - return $errors; - } - - return $result; + $preValidationErrors = ValidationService::validateAppointmentDaysNotFound([]); + if (!empty($preValidationErrors)) { + return $preValidationErrors; + } + + $result = $this->getAvailableDays($clientData); + return $result;
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
zmscitizenapi/routing.php
(1 hunks)zmscitizenapi/src/Zmscitizenapi/Controllers/Availability/AvailableAppointmentsListByOfficeController.php
(1 hunks)zmscitizenapi/src/Zmscitizenapi/Models/ProcessFreeSlotsGroupByOffice.php
(1 hunks)zmscitizenapi/src/Zmscitizenapi/Services/Availability/AvailableAppointmentsListService.php
(2 hunks)zmscitizenapi/src/Zmscitizenapi/Services/Availability/AvailableDaysListService.php
(3 hunks)zmscitizenapi/src/Zmscitizenapi/Services/Core/ValidationService.php
(4 hunks)zmscitizenapi/src/Zmscitizenapi/Services/Core/ZmsApiFacadeService.php
(5 hunks)zmsentities/schema/citizenapi/processFreeSlotsGroupByOffice.json
(1 hunks)
🔇 Additional comments (8)
zmscitizenapi/src/Zmscitizenapi/Controllers/Availability/AvailableAppointmentsListByOfficeController.php (1)
25-31
: Handle potential localization of error messagesIn the error response at lines 26-30, the status code is retrieved using
ErrorMessages::get('invalidRequest', $this->language)['statusCode']
. Ensure that the error messages are correctly localized based on the client's language preferences.zmscitizenapi/src/Zmscitizenapi/Services/Availability/AvailableAppointmentsListService.php (2)
28-30
: LGTM: Proper handling of multiple office IDs.The implementation correctly splits comma-separated office IDs and trims whitespace.
44-44
: LGTM: Updated validation call.Correctly passing the array of office IDs to the validation service.
zmscitizenapi/src/Zmscitizenapi/Services/Core/ValidationService.php (2)
88-89
: LGTM: Proper validation of office and service IDs arrays.The validation logic correctly handles arrays of office and service IDs.
Also applies to: 96-100
Line range hint
146-156
: LGTM: Consistent validation in getAvailableAppointments.The method properly validates all required parameters including the arrays of office and service IDs.
zmscitizenapi/src/Zmscitizenapi/Services/Availability/AvailableDaysListService.php (3)
39-40
: Well-implemented input handling for multiple offices and services.Good use of array_map with trim for input sanitization, and proper handling of empty inputs maintains backward compatibility.
50-51
: Verify ValidationService compatibility with array inputs.Ensure that
ValidationService::validateGetBookableFreeDays
has been updated to handle arrays of office and service IDs correctly.✅ Verification successful
✓ ValidationService is already compatible with array inputs
The
validateGetBookableFreeDays
method is correctly typed to accept arrays of office and service IDs, with proper array validation in place. No changes needed.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Search for the validateGetBookableFreeDays method implementation rg -t php "function validateGetBookableFreeDays" --glob "ValidationService.php"Length of output: 203
Script:
#!/bin/bash # Get the validateGetBookableFreeDays method implementation with context ast-grep --pattern 'public static function validateGetBookableFreeDays($_) { $$$ }'Length of output: 87
Script:
#!/bin/bash # Get the validateGetBookableFreeDays method implementation with context rg -t php "function validateGetBookableFreeDays" -B 2 -A 15 --glob "ValidationService.php"Length of output: 1800
58-65
: Verify ZmsApiFacadeService compatibility with array inputs.The return type change to
AvailableDays
improves type safety. However, please verify thatZmsApiFacadeService::getBookableFreeDays
has been updated to handle arrays of office and service IDs.✅ Verification successful
✓ ZmsApiFacadeService is compatible with array inputs
The
ZmsApiFacadeService::getBookableFreeDays
method is correctly typed to accept arrays for office IDs, service IDs, and service counts, and returns anAvailableDays
object. The implementation is fully compatible with the changes.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Search for the getBookableFreeDays method implementation rg -t php "function getBookableFreeDays" --glob "ZmsApiFacadeService.php" # Search for AvailableDays usage to ensure proper return type handling rg -t php "class AvailableDays" --glob "AvailableDays.php"Length of output: 370
Script:
#!/bin/bash # Get the implementation of getBookableFreeDays method rg -t php -A 10 "function getBookableFreeDays" zmscitizenapi/src/Zmscitizenapi/Services/Core/ZmsApiFacadeService.php # Check for any array type hints or docblock rg -t php -B 5 "function getBookableFreeDays" zmscitizenapi/src/Zmscitizenapi/Services/Core/ZmsApiFacadeService.phpLength of output: 744
string $date, | ||
array $officeIds, | ||
array $serviceIds, | ||
array $serviceCounts, | ||
?bool $groupByOffice = false | ||
): AvailableAppointments|array { | ||
|
||
$requests = []; | ||
$providers = []; | ||
foreach ($serviceIds as $index => $serviceId) { | ||
$slotCount = isset($serviceCounts[$index]) ? intval($serviceCounts[$index]) : 1; | ||
for ($i = 0; $i < $slotCount; $i++) { | ||
$requests[] = [ | ||
'id' => $serviceId, | ||
'source' => \App::$source_name, | ||
'slotCount' => 1, | ||
'source' => \App::$source_name | ||
]; | ||
} | ||
} | ||
|
||
foreach ($officeIds as $officeId) { | ||
$providers[] = [ | ||
'id' => $officeId, | ||
'source' => \App::$source_name | ||
]; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Handle potential mismatch between $serviceIds and $serviceCounts
In the loop starting at line 513, you attempt to retrieve $serviceCounts[$index]
for each $serviceId
. While you provide a default value of 1
when $serviceCounts[$index]
is not set, this could mask issues where the counts are unintentionally mismatched.
Consider adding a validation check to ensure that $serviceIds
and $serviceCounts
have the same number of elements:
$requests = [];
+ if (count($serviceIds) !== count($serviceCounts)) {
+ throw new InvalidArgumentException('The number of service IDs must match the number of service counts.');
+ }
$providers = [];
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
string $date, | |
array $officeIds, | |
array $serviceIds, | |
array $serviceCounts, | |
?bool $groupByOffice = false | |
): AvailableAppointments|array { | |
$requests = []; | |
$providers = []; | |
foreach ($serviceIds as $index => $serviceId) { | |
$slotCount = isset($serviceCounts[$index]) ? intval($serviceCounts[$index]) : 1; | |
for ($i = 0; $i < $slotCount; $i++) { | |
$requests[] = [ | |
'id' => $serviceId, | |
'source' => \App::$source_name, | |
'slotCount' => 1, | |
'source' => \App::$source_name | |
]; | |
} | |
} | |
foreach ($officeIds as $officeId) { | |
$providers[] = [ | |
'id' => $officeId, | |
'source' => \App::$source_name | |
]; | |
} | |
string $date, | |
array $officeIds, | |
array $serviceIds, | |
array $serviceCounts, | |
?bool $groupByOffice = false | |
): AvailableAppointments|array { | |
$requests = []; | |
if (count($serviceIds) !== count($serviceCounts)) { | |
throw new InvalidArgumentException('The number of service IDs must match the number of service counts.'); | |
} | |
$providers = []; | |
foreach ($serviceIds as $index => $serviceId) { | |
$slotCount = isset($serviceCounts[$index]) ? intval($serviceCounts[$index]) : 1; | |
for ($i = 0; $i < $slotCount; $i++) { | |
$requests[] = [ | |
'id' => $serviceId, | |
'source' => \App::$source_name | |
]; | |
} | |
} | |
foreach ($officeIds as $officeId) { | |
$providers[] = [ | |
'id' => $officeId, | |
'source' => \App::$source_name | |
]; | |
} |
public static function getBookableFreeDays( | ||
array $officeIds, | ||
array $serviceIds, | ||
array $serviceCounts, | ||
string $startDate, | ||
string $endDate | ||
): AvailableDays { | ||
$firstDay = DateTimeFormatHelper::getInternalDateFromISO($startDate); | ||
$lastDay = DateTimeFormatHelper::getInternalDateFromISO($endDate); | ||
$services = []; | ||
$providers = []; | ||
|
||
$serviceNumber = 0; | ||
foreach ($serviceIds as $serviceId) { | ||
$services[] = [ | ||
'id' => $serviceId, | ||
'source' => \App::$source_name, | ||
'slotCount' => $serviceCounts[$serviceNumber], | ||
]; | ||
$serviceNumber++; | ||
} | ||
|
||
foreach ($officeIds as $officeId) { | ||
$providers[] = [ | ||
'id' => $officeId, | ||
'source' => \App::$source_name, | ||
]; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure matching lengths of $serviceIds and $serviceCounts to prevent undefined offsets
In the loop starting at line 441, you access $serviceCounts[$serviceNumber]
without verifying that the index exists. If $serviceCounts
does not have the same number of elements as $serviceIds
, this could lead to "Undefined offset" notices or errors.
Apply this diff to add validation before the loop:
+ if (count($serviceIds) !== count($serviceCounts)) {
+ throw new InvalidArgumentException('The number of service IDs must match the number of service counts.');
+ }
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
public static function getBookableFreeDays( | |
array $officeIds, | |
array $serviceIds, | |
array $serviceCounts, | |
string $startDate, | |
string $endDate | |
): AvailableDays { | |
$firstDay = DateTimeFormatHelper::getInternalDateFromISO($startDate); | |
$lastDay = DateTimeFormatHelper::getInternalDateFromISO($endDate); | |
$services = []; | |
$providers = []; | |
$serviceNumber = 0; | |
foreach ($serviceIds as $serviceId) { | |
$services[] = [ | |
'id' => $serviceId, | |
'source' => \App::$source_name, | |
'slotCount' => $serviceCounts[$serviceNumber], | |
]; | |
$serviceNumber++; | |
} | |
foreach ($officeIds as $officeId) { | |
$providers[] = [ | |
'id' => $officeId, | |
'source' => \App::$source_name, | |
]; | |
} | |
public static function getBookableFreeDays( | |
array $officeIds, | |
array $serviceIds, | |
array $serviceCounts, | |
string $startDate, | |
string $endDate | |
): AvailableDays { | |
$firstDay = DateTimeFormatHelper::getInternalDateFromISO($startDate); | |
$lastDay = DateTimeFormatHelper::getInternalDateFromISO($endDate); | |
$services = []; | |
$providers = []; | |
if (count($serviceIds) !== count($serviceCounts)) { | |
throw new InvalidArgumentException('The number of service IDs must match the number of service counts.'); | |
} | |
$serviceNumber = 0; | |
foreach ($serviceIds as $serviceId) { | |
$services[] = [ | |
'id' => $serviceId, | |
'source' => \App::$source_name, | |
'slotCount' => $serviceCounts[$serviceNumber], | |
]; | |
$serviceNumber++; | |
} | |
foreach ($officeIds as $officeId) { | |
$providers[] = [ | |
'id' => $officeId, | |
'source' => \App::$source_name, | |
]; | |
} |
public static $schema = 'citizenapi/processFreeSlots.json'; | ||
|
||
/** @var array|null */ | ||
public array|null $appointmentTimestamps = []; | ||
|
||
/** | ||
* @param array $appointmentTimestamps | ||
*/ | ||
public function __construct(array $appointmentTimestamps = []) | ||
{ | ||
|
||
$this->appointmentTimestamps = array_map('intval', $appointmentTimestamps); | ||
|
||
$this->ensureValid(); | ||
} | ||
|
||
private function ensureValid(): void | ||
{ | ||
if (!$this->testValid()) { | ||
throw new InvalidArgumentException('The provided data is invalid according to the schema.'); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct the schema path in the $schema
property
The $schema
property currently points to 'citizenapi/processFreeSlots.json'
, which may not correspond to the correct schema for the ProcessFreeSlotsGroupByOffice
class.
Update the schema path to reflect the appropriate JSON schema file:
- public static $schema = 'citizenapi/processFreeSlots.json';
+ public static $schema = 'citizenapi/processFreeSlotsGroupByOffice.json';
This ensures that the ensureValid()
method validates against the correct schema.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
public static $schema = 'citizenapi/processFreeSlots.json'; | |
/** @var array|null */ | |
public array|null $appointmentTimestamps = []; | |
/** | |
* @param array $appointmentTimestamps | |
*/ | |
public function __construct(array $appointmentTimestamps = []) | |
{ | |
$this->appointmentTimestamps = array_map('intval', $appointmentTimestamps); | |
$this->ensureValid(); | |
} | |
private function ensureValid(): void | |
{ | |
if (!$this->testValid()) { | |
throw new InvalidArgumentException('The provided data is invalid according to the schema.'); | |
} | |
} | |
public static $schema = 'citizenapi/processFreeSlotsGroupByOffice.json'; | |
/** @var array|null */ | |
public array|null $appointmentTimestamps = []; | |
/** | |
* @param array $appointmentTimestamps | |
*/ | |
public function __construct(array $appointmentTimestamps = []) | |
{ | |
$this->appointmentTimestamps = array_map('intval', $appointmentTimestamps); | |
$this->ensureValid(); | |
} | |
private function ensureValid(): void | |
{ | |
if (!$this->testValid()) { | |
throw new InvalidArgumentException('The provided data is invalid according to the schema.'); | |
} | |
} |
$this->appointmentTimestamps = array_map('intval', $appointmentTimestamps); | ||
|
||
$this->ensureValid(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Validate the structure of $appointmentTimestamps
Currently, the constructor maps $appointmentTimestamps
using array_map('intval', $appointmentTimestamps);
but since the data is intended to be grouped by office, which suggests a nested array structure, the mapping may not function as expected.
Adjust the logic to handle nested arrays appropriately. For example:
- $this->appointmentTimestamps = array_map('intval', $appointmentTimestamps);
+ foreach ($appointmentTimestamps as $officeId => $timestamps) {
+ $this->appointmentTimestamps[$officeId] = array_map('intval', $timestamps);
+ }
This ensures that timestamps for each office are properly converted to integers.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
$this->appointmentTimestamps = array_map('intval', $appointmentTimestamps); | |
$this->ensureValid(); | |
foreach ($appointmentTimestamps as $officeId => $timestamps) { | |
$this->appointmentTimestamps[$officeId] = array_map('intval', $timestamps); | |
} | |
$this->ensureValid(); |
zmscitizenapi/routing.php
Outdated
/** | ||
* @swagger | ||
* /available-appointments-by-office/: | ||
* get: | ||
* summary: Get available appointments for a specific day grouped by office | ||
* tags: | ||
* - appointments | ||
* parameters: | ||
* - name: date | ||
* description: Date in format YYYY-MM-DD | ||
* in: query | ||
* required: true | ||
* type: string | ||
* - name: officeId | ||
* description: Comma separated Office IDs | ||
* in: query | ||
* required: true | ||
* type: string | ||
* - name: serviceIds | ||
* description: Comma separated Service IDs | ||
* in: query | ||
* required: true | ||
* type: string | ||
* responses: | ||
* 200: | ||
* description: List of available appointments grouped by office id | ||
* schema: | ||
* type: object | ||
* properties: | ||
* meta: | ||
* $ref: "schema/metaresult.json" | ||
* data: | ||
* $ref: "schema/citizenapi/availableAppointments.json" | ||
*/ | ||
createLanguageRoutes( | ||
\App::$slim, | ||
'/available-appointments-by-office/', | ||
'\BO\Zmscitizenapi\Controllers\Availability\AvailableAppointmentsListController', | ||
"AvailableAppointmentsListController", | ||
"get" | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Verify the controller path in the route definition.
The route is using AvailableAppointmentsListController
but based on the AI summary, there should be a new AvailableAppointmentsListByOfficeController
. This might cause runtime errors.
- '\BO\Zmscitizenapi\Controllers\Availability\AvailableAppointmentsListController',
+ '\BO\Zmscitizenapi\Controllers\Availability\AvailableAppointmentsListByOfficeController',
Also, consider updating the Swagger documentation to include:
- Response format for error cases (400, 404)
- Example values for the parameters
- More detailed description of the response schema
Committable suggestion skipped: line range outside the PR's diff.
zmsentities/schema/citizenapi/processFreeSlotsGroupByOffice.json
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🔭 Outside diff range comments (1)
zmscitizenapi/src/Zmscitizenapi/Services/Core/ZmsApiFacadeService.php (1)
Line range hint
551-583
: Remove or utilize the unused groupByOffice parameter.The
groupByOffice
parameter is passed to the method but never used in the implementation.Either remove the parameter or implement the grouping functionality:
- private static function processFreeSlots(ProcessList $freeSlots, bool $groupByOffice): ProcessFreeSlots|array + private static function processFreeSlots(ProcessList $freeSlots): ProcessFreeSlots|arrayOr if grouping by office is needed:
private static function processFreeSlots(ProcessList $freeSlots, bool $groupByOffice): ProcessFreeSlots|array { // ... existing code ... $appointmentTimestamps = array_reduce( iterator_to_array($freeSlots), function ($timestamps, $slot) use ($currentTimestamp, $groupByOffice) { if (isset($slot->appointments) && is_iterable($slot->appointments)) { foreach ($slot->appointments as $appointment) { if (isset($appointment->date) && isset($appointment->scope->id)) { $timestamp = (int) $appointment->date; $scopeId = (int) $appointment->scope->id; if ($timestamp > $currentTimestamp) { - $timestamps[$scopeId][$timestamp] = true; + $key = $groupByOffice ? $appointment->scope->provider->id : $scopeId; + $timestamps[$key][$timestamp] = true; } } } } return $timestamps; }, [] );
🧹 Nitpick comments (3)
zmscitizenapi/src/Zmscitizenapi/Services/Availability/AvailableDaysListService.php (2)
32-33
: Enhance input validation for office and service IDs.While the basic parsing logic is correct, consider adding additional validation:
- Filter out empty strings after splitting
- Validate ID format before processing
- Consider adding a maximum limit for the number of IDs to prevent potential abuse
- 'officeIds' => array_map('trim', explode(',', $queryParams['officeId'] ?? '')), - 'serviceIds' => array_map('trim', explode(',', $queryParams['serviceId'] ?? '')), + 'officeIds' => array_filter(array_map('trim', explode(',', $queryParams['officeId'] ?? ''))), + 'serviceIds' => array_filter(array_map('trim', explode(',', $queryParams['serviceId'] ?? ''))),
Line range hint
1-60
: Consider caching strategy for multiple office queries.The service now handles multiple offices and services, which could increase response times and server load. Consider implementing caching for frequently requested office/service combinations.
zmscitizenapi/src/Zmscitizenapi/Services/Core/ZmsApiFacadeService.php (1)
Line range hint
428-583
: Consider implementing caching for performance optimization.The methods handle multiple offices and services, which could lead to increased response times when dealing with many combinations. Consider implementing caching for frequently accessed data patterns.
Suggestions:
- Cache the results of
getFreeDays
andgetFreeTimeslots
with a short TTL- Implement batch processing for multiple office/service combinations
- Add request rate limiting to prevent API abuse
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
zmscitizenapi/src/Zmscitizenapi/Services/Availability/AvailableDaysListService.php
(2 hunks)zmscitizenapi/src/Zmscitizenapi/Services/Core/ZmsApiFacadeService.php
(5 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (4)
- GitHub Check: Analyze (python)
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: call-unit-tests / zmsapi-test
- GitHub Check: call-unit-tests / zmsdb-test
🔇 Additional comments (5)
zmscitizenapi/src/Zmscitizenapi/Services/Availability/AvailableDaysListService.php (3)
51-51
: Breaking change: Return type modification.The return type has been restricted to
AvailableDays
instead ofAvailableDays|array
. This could be a breaking change for consumers expecting the array return type.Please ensure all consumers of this method are updated to handle the new return type.
43-44
: Verify ValidationService compatibility with array inputs.Ensure that
ValidationService::validateGetBookableFreeDays
has been updated to handle arrays of IDs correctly.✅ Verification successful
Validation service is already compatible with array inputs ✅
The
validateGetBookableFreeDays
method is properly implemented to handle arrays of office IDs and service IDs, with appropriate validation for both array formats and numeric values.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Search for ValidationService implementation ast-grep --pattern 'function validateGetBookableFreeDays($_)'Length of output: 951
Script:
#!/bin/bash # First, find the ValidationService class file fd ValidationServiceLength of output: 164
Script:
#!/bin/bash # View the ValidationService implementation cat zmscitizenapi/src/Zmscitizenapi/Services/Core/ValidationService.phpLength of output: 13211
54-55
: Verify ZmsApiFacadeService compatibility with array inputs.Ensure that
ZmsApiFacadeService::getBookableFreeDays
has been updated to handle arrays of office and service IDs.✅ Verification successful
ZmsApiFacadeService is already compatible with array inputs
The
getBookableFreeDays
method signature explicitly declares array parameters for both$officeIds
and$serviceIds
, confirming compatibility with the current usage.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Search for ZmsApiFacadeService implementation ast-grep --pattern 'function getBookableFreeDays($_)'Length of output: 943
Script:
#!/bin/bash # Search for ZmsApiFacadeService class and method implementation ast-grep --pattern 'class ZmsApiFacadeService { $$$ public function getBookableFreeDays($_) { $$$ } $$$ }' # Fallback to ripgrep echo "=== Searching with ripgrep ===" rg -l "getBookableFreeDays" --type phpLength of output: 472
Script:
#!/bin/bash # Examine ZmsApiFacadeService implementation echo "=== ZmsApiFacadeService implementation ===" rg "getBookableFreeDays" zmscitizenapi/src/Zmscitizenapi/Services/Core/ZmsApiFacadeService.php -B 2 -A 10Length of output: 620
zmscitizenapi/src/Zmscitizenapi/Services/Core/ZmsApiFacadeService.php (2)
428-448
:⚠️ Potential issueValidate array lengths to prevent undefined offset access.
The loop accessing
$serviceCounts[$serviceNumber]
could lead to undefined offset errors if$serviceIds
and$serviceCounts
have different lengths.Add validation before the loop:
$services = []; $providers = []; + if (count($serviceIds) !== count($serviceCounts)) { + throw new InvalidArgumentException('The number of service IDs must match the number of service counts.'); + } $serviceNumber = 0; foreach ($serviceIds as $serviceId) {Likely invalid or redundant comment.
508-532
: 🛠️ Refactor suggestionOptimize request array construction and add validation.
The nested loops for building requests array can be optimized, and array length validation is needed.
Consider this optimization:
$requests = []; + if (count($serviceIds) !== count($serviceCounts)) { + throw new InvalidArgumentException('The number of service IDs must match the number of service counts.'); + } $providers = []; - foreach ($serviceIds as $index => $serviceId) { - $slotCount = isset($serviceCounts[$index]) ? intval($serviceCounts[$index]) : 1; - for ($i = 0; $i < $slotCount; $i++) { - $requests[] = [ - 'id' => $serviceId, - 'source' => \App::$source_name - ]; - } - } + $requests = array_merge(...array_map( + fn($index) => array_fill( + 0, + intval($serviceCounts[$index] ?? 1), + ['id' => $serviceIds[$index], 'source' => \App::$source_name] + ), + array_keys($serviceIds) + ));Likely invalid or redundant comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (4)
zmscitizenapi/src/Zmscitizenapi/Services/Core/ValidationService.php (4)
96-100
: Update error messages for array validationThe error messages (
invalidOfficeId
andinvalidServiceId
) should be updated to reflect that we're now validating arrays of IDs. Consider using more descriptive messages likeinvalidOfficeIds
orinvalidServiceIds
.
156-156
: Consider adding array size limitsWhile the array validation is functionally correct, consider adding checks for:
- Maximum number of office IDs to prevent potential DoS
- Duplicate office IDs in the array
360-362
: Enhance array validation for office IDsThe current validation only checks for non-empty arrays with numeric values. Consider adding:
- Validation that each office ID is greater than 0 (like in
isValidOfficeId
)- Deduplication of office IDs
- Maximum array size limit
private static function isValidOfficeIds(?array $officeIds): bool { - return !empty($officeIds) && self::isValidNumericArray($officeIds); + if (empty($officeIds) || !self::isValidNumericArray($officeIds)) { + return false; + } + $maxOffices = 10; // Consider making this configurable + if (count($officeIds) > $maxOffices) { + return false; + } + $uniqueOfficeIds = array_unique($officeIds); + return count(array_filter($uniqueOfficeIds, fn($id) => $id > 0)) === count($uniqueOfficeIds); }
425-433
: Document legacy validation methodsThese single ID validation methods appear to be legacy code. Consider:
- Adding
@deprecated
tags with migration instructions- Adding
@see
tags referencing the new array validation methods+ /** + * @deprecated Use isValidOfficeIds() instead for better support of multiple offices + * @see isValidOfficeIds() + */ private static function isValidOfficeId(?int $officeId): bool { return !empty($officeId) && $officeId > 0; } + /** + * @deprecated Use isValidServiceIds() instead for better support of multiple services + * @see isValidServiceIds() + */ private static function isValidServiceId(?int $serviceId): bool { return !empty($serviceId) && $serviceId > 0; }
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
zmscitizenapi/src/Zmscitizenapi/Services/Core/ValidationService.php
(5 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (4)
- GitHub Check: Analyze (python)
- GitHub Check: call-unit-tests / zmsapi-test
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: call-unit-tests / zmsdb-test
🔇 Additional comments (2)
zmscitizenapi/src/Zmscitizenapi/Services/Core/ValidationService.php (2)
88-89
: Breaking Change: Method signature updated to accept arraysThe signature change from single IDs to arrays (
officeId
→officeIds
,serviceId
→serviceIds
) is a breaking change that could affect existing API clients. Consider:
- Adding a new method instead of modifying the existing one
- Maintaining backward compatibility by accepting both single values and arrays
Run this script to find potential usages that might be affected:
146-146
: Breaking Change: Ensure consistent handling of array parametersSimilar to
validateGetBookableFreeDays
, this is a breaking change. Ensure that:
- The handling of array parameters is consistent across all methods
- The migration strategy for existing clients is documented
Run this script to verify consistent parameter handling:
✅ Verification successful
Parameter type change is properly validated and consistent with existing patterns
The change from single officeId to array officeIds is consistent with:
- Proper validation through isValidOfficeIds helper method
- Similar array parameter handling in other validation methods
- Existing validation patterns for both single and array office IDs
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Search for all validation methods to ensure consistent parameter handling ast-grep --pattern 'public static function validate$_($_) { $$$ }'Length of output: 68
Script:
#!/bin/bash # Try both ast-grep and ripgrep to find validation methods echo "=== Using ast-grep with simpler pattern ===" ast-grep --pattern 'function validate' echo -e "\n=== Using ripgrep to find validation methods ===" rg "function validate\w+\s*\([^)]+\)" -A 1Length of output: 75751
Script:
#!/bin/bash # Search specifically in ValidationService.php for the relevant method echo "=== Searching for validateGetAvailableAppointments method ===" rg "validateGetAvailableAppointments" -A 5 zmscitizenapi/src/Zmscitizenapi/Services/Core/ValidationService.php echo -e "\n=== Searching for similar validation methods with officeId parameter ===" rg "officeId" -A 2 zmscitizenapi/src/Zmscitizenapi/Services/Core/ValidationService.phpLength of output: 2222
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🔭 Outside diff range comments (2)
zmscitizenapi/tests/Zmscitizenapi/Services/Availability/AvailableAppointmentsListServiceTest.php (2)
Line range hint
158-163
: Fix inconsistent parameter types between mock services.The
ValidationService
mock uses?array $officeIds
whileZmsApiFacadeService
mock still uses?int $officeId
. This inconsistency could lead to type mismatch errors.Update the
ZmsApiFacadeService
mock to match the new parameter type:public static function getAvailableAppointments( ?string $date, - ?int $officeId, + ?array $officeIds, ?array $serviceIds, ?array $serviceCounts ): \BO\Zmscitizenapi\Models\AvailableAppointments|array
Line range hint
29-43
: Add test coverage for multiple offices functionality.The test case only covers a single office ID scenario (
'officeId' => '123'
). Since the service now supports multiple offices, we need test coverage for this functionality.Add a new test case to verify the multi-office scenario:
public function testGetAvailableAppointmentsListWithMultipleOfficesReturnsAvailableAppointments(): void { // Arrange $queryParams = [ 'date' => '2025-01-15', 'officeId' => '123,456', // Multiple office IDs 'serviceId' => '789', 'serviceCount' => '1' ]; $expectedAppointments = new AvailableAppointments([1705317600, 1705321200]); $this->createMockValidationService([]); $this->createMockFacade($expectedAppointments); // Act $result = $this->service->getAvailableAppointmentsList($queryParams); // Assert $this->assertInstanceOf(AvailableAppointments::class, $result); $this->assertEquals($expectedAppointments, $result); }
🧹 Nitpick comments (2)
zmscitizenapi/tests/Zmscitizenapi/Services/Core/ValidationServiceTest.php (1)
Line range hint
91-144
: Consider adding test cases for array-specific scenarios.While the current test cases cover basic validation, consider adding tests for:
- Empty arrays (
[]
)- Arrays with multiple values (
[1, 2, 3]
)- Arrays with mixed valid/invalid values (
[1, 'invalid', 2]
)This would ensure robust validation for the new array-based parameters.
zmscitizenapi/tests/Zmscitizenapi/Services/Availability/AvailableAppointmentsListServiceTest.php (1)
Line range hint
96-116
: Add validation test for invalid office IDs.Since we now support multiple office IDs, we should add a test case to verify validation of invalid office IDs, similar to how we test invalid service IDs.
Add a new test case:
public function testGetAvailableAppointmentsListWithInvalidOfficeIdsReturnsValidationError(): void { // Arrange $queryParams = [ 'date' => '2025-01-15', 'officeId' => 'invalid,ids', 'serviceId' => '456', 'serviceCount' => '1' ]; $expectedError = ['errors' => ['Invalid office IDs']]; $this->createMockValidationService($expectedError); // Act $result = $this->service->getAvailableAppointmentsList($queryParams); // Assert $this->assertIsArray($result); $this->assertEquals($expectedError, $result); }
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
zmscitizenapi/tests/Zmscitizenapi/Services/Availability/AvailableAppointmentsListServiceTest.php
(1 hunks)zmscitizenapi/tests/Zmscitizenapi/Services/Availability/AvailableDaysListServiceTest.php
(1 hunks)zmscitizenapi/tests/Zmscitizenapi/Services/Core/ValidationServiceTest.php
(5 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (4)
- GitHub Check: Analyze (python)
- GitHub Check: call-unit-tests / zmsdb-test
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: call-unit-tests / zmsapi-test
🔇 Additional comments (6)
zmscitizenapi/tests/Zmscitizenapi/Services/Availability/AvailableDaysListServiceTest.php (1)
Line range hint
28-93
: Add test coverage for multiple offices and services.The test cases only cover scenarios with single office and service IDs, but the validation service now accepts arrays. Please add test cases to cover:
- Multiple office IDs
- Multiple service IDs
- Mix of valid and invalid IDs in arrays
- Empty arrays
This will help ensure the new functionality works as expected and maintains backward compatibility.
zmscitizenapi/tests/Zmscitizenapi/Services/Core/ValidationServiceTest.php (5)
93-95
: LGTM! Test case updated to support array parameters.The test case has been correctly updated to validate the new array-based parameters for office IDs, service IDs, and service counts.
102-104
: LGTM! Invalid date test case maintains array parameters.The test case correctly maintains consistency with array parameters while testing invalid date scenarios.
114-116
: LGTM! Invalid office ID test case updated.The test case properly validates array input with an invalid office ID (0).
126-128
: LGTM! Invalid service IDs test case updated.The test case correctly validates array input with an invalid service ID ('invalid').
138-140
: LGTM! Invalid service counts test case updated.The test case properly validates array input with an invalid service count ('invalid').
?array $officeIds, | ||
?array $serviceIds, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interface mismatch between ValidationService and ZmsApiFacadeService.
The ValidationService
now accepts arrays for office and service IDs, but ZmsApiFacadeService
still expects single integers. This inconsistency needs to be addressed:
- If the intention is to support multiple offices/services, update the facade interface accordingly
- If not, revert the validation service changes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (1)
zmscitizenapi/src/Zmscitizenapi/Services/Availability/AvailableAppointmentsListService.php (1)
50-58
: Add PHPDoc to document the groupByOffice parameter.The purpose and effect of the groupByOffice parameter should be documented for better code maintainability.
+/** + * Get available appointments for the given criteria + * + * @param object $data The appointment request data + * @param bool|null $groupByOffice When true, appointments are grouped by office + * @return array|AvailableAppointments Appointments or validation errors + */ private function getAvailableAppointments(object $data, ?bool $groupByOffice = false): array|AvailableAppointments
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
zmscitizenapi/src/Zmscitizenapi/Services/Availability/AvailableAppointmentsListService.php
(2 hunks)zmscitizenapi/src/Zmscitizenapi/Services/Availability/AvailableDaysListService.php
(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- zmscitizenapi/src/Zmscitizenapi/Services/Availability/AvailableDaysListService.php
⏰ Context from checks skipped due to timeout of 90000ms (4)
- GitHub Check: call-unit-tests / zmsapi-test
- GitHub Check: Analyze (python)
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: call-unit-tests / zmsdb-test
🔇 Additional comments (3)
zmscitizenapi/src/Zmscitizenapi/Services/Availability/AvailableAppointmentsListService.php (3)
43-47
: 🛠️ Refactor suggestionAdd validation for array length correspondence.
Ensure that serviceIds and serviceCounts arrays have matching lengths and correspond to each other to prevent mismatched service requests.
Consider adding this validation before the current validation call:
if (count($data->serviceIds) !== count($data->serviceCounts)) { return [ 'errors' => [ 'validation' => ['Service IDs and counts must have matching lengths'] ] ]; }
28-30
: Add validation for individual office IDs.While the conversion from comma-separated string to array is correct, consider adding validation for the format/structure of individual office IDs to prevent invalid inputs.
'officeIds' => isset($queryParams['officeId']) - ? array_map('trim', explode(',', (string) $queryParams['officeId'])) + ? array_filter(array_map(function($id) { + $id = trim($id); + return preg_match('/^\d+$/', $id) ? $id : null; + }, explode(',', (string) $queryParams['officeId']))) : [],
32-36
: Validate service counts as positive integers.The service counts should be validated to ensure they are positive integers to prevent invalid inputs.
'serviceCounts' => isset($queryParams['serviceCount']) - ? array_map('trim', explode(',', (string) $queryParams['serviceCount'])) + ? array_filter(array_map(function($count) { + $count = trim($count); + return (is_numeric($count) && $count > 0) ? (int)$count : null; + }, explode(',', (string) $queryParams['serviceCount']))) : []✅ Verification successful
The review comment is correct - service counts validation is necessary.
The test files confirm that service counts:
- Must be positive integers
- Must match the number of service IDs
- Are validated with error messages for invalid formats
The suggested validation in the review comment would prevent runtime errors and improve API reliability.
🏁 Scripts executed
The following scripts were executed for the analysis:
Error: No shell scripts found
Script:
#!/bin/bash # Search for serviceCounts usage and validation rg -l "serviceCount" --type php # Look for the class implementation ast-grep --pattern 'class AvailableAppointmentsListService { $$$ }' # Search for validation patterns rg "validate|sanitize|filter" --type php -A 2 -B 2Length of output: 66009
Script:
#!/bin/bash # Search for serviceCount usage in code rg -A 5 -B 5 "serviceCount" --type php # Look for the AvailableAppointmentsListService implementation ast-grep --pattern 'class AvailableAppointmentsListService { $$$ public function __construct($$$) { $$$ } $$$ }' # Search for validation patterns in ValidationService cat zmscitizenapi/src/Zmscitizenapi/Services/Core/ValidationService.phpLength of output: 65805
public function getAvailableAppointmentsListByOffice($queryParams) | ||
{ | ||
$clientData = $this->extractClientData($queryParams); | ||
|
||
$errors = $this->validateClientData($clientData); | ||
if (!empty($errors['errors'])) { | ||
return $errors; | ||
} | ||
|
||
return $this->getAvailableAppointments($clientData, true); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add type hints and documentation for the new method.
The new method should include proper type hints and documentation for better code quality and maintainability.
+/**
+ * Get available appointments grouped by office
+ *
+ * @param array $queryParams The query parameters containing date, officeId, serviceId, and serviceCount
+ * @return array|AvailableAppointments Appointments grouped by office or validation errors
+ */
-public function getAvailableAppointmentsListByOffice($queryParams)
+public function getAvailableAppointmentsListByOffice(array $queryParams): array|AvailableAppointments
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
public function getAvailableAppointmentsListByOffice($queryParams) | |
{ | |
$clientData = $this->extractClientData($queryParams); | |
$errors = $this->validateClientData($clientData); | |
if (!empty($errors['errors'])) { | |
return $errors; | |
} | |
return $this->getAvailableAppointments($clientData, true); | |
} | |
/** | |
* Get available appointments grouped by office | |
* | |
* @param array $queryParams The query parameters containing date, officeId, serviceId, and serviceCount | |
* @return array|AvailableAppointments Appointments grouped by office or validation errors | |
*/ | |
public function getAvailableAppointmentsListByOffice(array $queryParams): array|AvailableAppointments | |
{ | |
$clientData = $this->extractClientData($queryParams); | |
$errors = $this->validateClientData($clientData); | |
if (!empty($errors['errors'])) { | |
return $errors; | |
} | |
return $this->getAvailableAppointments($clientData, true); | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🔭 Outside diff range comments (1)
zmscitizenapi/tests/Zmscitizenapi/Services/Availability/AvailableAppointmentsListServiceTest.php (1)
Line range hint
157-164
: Replace eval-based mocking with PHPUnit's built-in mocking.While the parameter type changes correctly reflect the new array-based functionality, using
eval
for mocking is discouraged due to security risks and maintainability concerns. Consider using PHPUnit's built-in mocking capabilities instead.Example refactor:
private function createMockValidationService(array $returnValue): void { $mock = $this->getMockBuilder(ValidationService::class) ->disableOriginalConstructor() ->addMethods(['validateGetAvailableAppointments']) ->getMock(); $mock->expects($this->any()) ->method('validateGetAvailableAppointments') ->willReturn($returnValue); // Inject mock into service }Also applies to: 174-180
🧹 Nitpick comments (1)
zmscitizenapi/src/Zmscitizenapi/Services/Availability/AvailableDaysListService.php (1)
26-35
: Enhance input validation and sanitization.The current implementation could be improved to handle edge cases more robustly:
- Filter out empty values after exploding
- Remove duplicate IDs
- Validate format before processing
Consider applying this improvement:
- $queryParams['officeId'] = $queryParams['officeId'] ? (string) $queryParams['officeId'] : ''; - $queryParams['serviceId'] = $queryParams['serviceId'] ? (string) $queryParams['serviceId'] : ''; - // ... - 'officeIds' => array_map('trim', explode(',', $queryParams['officeId'])), - 'serviceIds' => array_map('trim', explode(',', $queryParams['serviceId'])), + $queryParams['officeId'] = isset($queryParams['officeId']) ? (string) $queryParams['officeId'] : ''; + $queryParams['serviceId'] = isset($queryParams['serviceId']) ? (string) $queryParams['serviceId'] : ''; + // ... + 'officeIds' => array_unique(array_filter(array_map('trim', explode(',', $queryParams['officeId'])))), + 'serviceIds' => array_unique(array_filter(array_map('trim', explode(',', $queryParams['serviceId'])))),
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
zmscitizenapi/src/Zmscitizenapi/Services/Availability/AvailableDaysListService.php
(2 hunks)zmscitizenapi/tests/Zmscitizenapi/Services/Availability/AvailableAppointmentsListServiceTest.php
(2 hunks)zmscitizenapi/tests/Zmscitizenapi/Services/Availability/AvailableDaysListServiceTest.php
(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- zmscitizenapi/tests/Zmscitizenapi/Services/Availability/AvailableDaysListServiceTest.php
⏰ Context from checks skipped due to timeout of 90000ms (4)
- GitHub Check: Analyze (python)
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: call-unit-tests / zmsdb-test
- GitHub Check: call-unit-tests / zmsapi-test
🔇 Additional comments (5)
zmscitizenapi/tests/Zmscitizenapi/Services/Availability/AvailableAppointmentsListServiceTest.php (2)
Line range hint
29-35
: Well-structured test data and error handling.The test data structure is consistent across test cases with clear error messages and proper type handling for query parameters.
Line range hint
28-43
: Add test cases for multiple office IDs.The test suite lacks coverage for the new array-based office IDs functionality. Consider adding test cases that verify:
- Multiple office IDs being processed correctly
- Empty office IDs array handling
- Invalid office IDs in the array
Example test case structure:
public function testGetAvailableAppointmentsListWithMultipleOffices(): void { // Arrange $queryParams = [ 'date' => '2025-01-15', 'officeId' => '123,456', // Multiple offices 'serviceId' => '789', 'serviceCount' => '1' ]; $expectedAppointments = new AvailableAppointments([/* timestamps */]); $this->createMockValidationService([]); $this->createMockFacade($expectedAppointments); // Act $result = $this->service->getAvailableAppointmentsList($queryParams); // Assert $this->assertInstanceOf(AvailableAppointments::class, $result); $this->assertEquals($expectedAppointments, $result); }✅ Verification successful
Test coverage gap for multiple office IDs confirmed
The service implementation explicitly supports multiple office IDs through array-based processing, but there are no test cases covering this functionality. The original review suggestion to add test cases for multiple office IDs is valid and important for ensuring proper test coverage.
Key implementation details that should be tested:
- Comma-separated office IDs parsing in
extractClientData
- Array-based office ID validation in
validateClientData
- Multiple office ID handling in
getAvailableAppointments
🏁 Scripts executed
The following scripts were executed for the analysis:
Error: No shell scripts found
Script:
#!/bin/bash # Search for test cases with multiple office IDs in the test file echo "=== Searching test file for multiple office ID tests ===" rg -A 5 "officeId.*['\"].*,.*['\"]" zmscitizenapi/tests/Zmscitizenapi/Services/Availability/AvailableAppointmentsListServiceTest.php # Find and check the service implementation echo -e "\n=== Finding service implementation ===" fd -t f "AvailableAppointmentsListService.php" --exec cat {} # Search for other related test files echo -e "\n=== Finding related test files ===" fd -t f ".*Test\.php$" | rg -l "officeId.*['\"].*,.*['\"]"Length of output: 2921
zmscitizenapi/src/Zmscitizenapi/Services/Availability/AvailableDaysListService.php (3)
53-53
: Great improvement in type safety!The return type change from
array|AvailableDays
toAvailableDays
makes the contract more explicit and type-safe.
56-57
: Verify array handling in ZmsApiFacadeService.Ensure that
ZmsApiFacadeService::getBookableFreeDays
properly handles arrays of office and service IDs.✅ Verification successful
Arrays are properly handled in ZmsApiFacadeService::getBookableFreeDays
The method signature explicitly declares array parameters for office and service IDs with proper type hints, ensuring correct array handling.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Search for the facade method implementation ast-grep --pattern 'function getBookableFreeDays($_)'Length of output: 943
Script:
#!/bin/bash # Find the ZmsApiFacadeService file rg -l "class ZmsApiFacadeService" # After finding the file, we'll examine its contentLength of output: 933
Script:
#!/bin/bash # Examine the facade service implementation echo "=== ZmsApiFacadeService Implementation ===" rg -A 10 "function getBookableFreeDays" zmscitizenapi/src/Zmscitizenapi/Services/Core/ZmsApiFacadeService.php echo -e "\n=== Test Cases ===" rg -A 5 "getBookableFreeDays" zmscitizenapi/tests/Zmscitizenapi/Services/Availability/AvailableDaysListServiceTest.phpLength of output: 1045
45-46
: Verify array validation in ValidationService.Ensure that
ValidationService::validateGetBookableFreeDays
properly handles arrays of IDs.✅ Verification successful
Array validation in ValidationService is properly implemented ✓
The
validateGetBookableFreeDays
method is designed to handle arrays of office IDs and service IDs, with comprehensive validation including:
- Array type checking
- Empty array validation
- Invalid ID detection
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Search for the validation method implementation ast-grep --pattern 'function validateGetBookableFreeDays($_)'Length of output: 951
Script:
#!/bin/bash # Try multiple approaches to find the validation implementation echo "=== Searching for ValidationService class ===" rg -l "class.*ValidationService" echo -e "\n=== Searching for validateGetBookableFreeDays method ===" rg "validateGetBookableFreeDays" echo -e "\n=== Looking for array validation patterns ===" rg "validate.*\[(.*)\]" -g "*.php"Length of output: 5834
Script:
#!/bin/bash echo "=== ValidationService::validateGetBookableFreeDays implementation ===" rg -A 10 "validateGetBookableFreeDays" zmscitizenapi/src/Zmscitizenapi/Services/Core/ValidationService.php echo -e "\n=== Array validation methods in ValidationService ===" ast-grep --pattern 'function validateServiceArrays($_)' zmscitizenapi/src/Zmscitizenapi/Services/Core/ValidationService.php echo -e "\n=== Test cases for array validation ===" rg -A 5 "validateServiceArrays|validateGetBookableFreeDays" zmscitizenapi/tests/Zmscitizenapi/Services/Core/ValidationServiceTest.phpLength of output: 1966
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 6
♻️ Duplicate comments (2)
zmscitizenapi/src/Zmscitizenapi/Services/Availability/AvailableAppointmentsListService.php (1)
64-74
: 🛠️ Refactor suggestionAdd return type hint and parameter validation.
The method is missing a type hint for the parameter and could benefit from early validation.
- public function getAvailableAppointmentsListByOffice($queryParams): AvailableAppointmentsByOffice|array + public function getAvailableAppointmentsListByOffice(array $queryParams): AvailableAppointmentsByOffice|array { + if (empty($queryParams['officeId'])) { + return ['errors' => ['Office ID is required']]; + } + $clientData = $this->extractClientData($queryParams);zmscitizenapi/src/Zmscitizenapi/Services/Core/ZmsApiFacadeService.php (1)
442-450
:⚠️ Potential issueAdd validation for service counts array length.
The loop assumes
$serviceCounts
array has the same length as$serviceIds
, which could lead to undefined offset errors.+ if (count($serviceIds) !== count($serviceCounts)) { + throw new InvalidArgumentException('The number of service IDs must match the number of service counts.'); + } + $serviceNumber = 0; foreach ($serviceIds as $serviceId) {
🧹 Nitpick comments (6)
zmsentities/schema/citizenapi/availableAppointmentsByOffice.json (1)
19-19
: Add format for timestamp integers.The schema should specify that the integers are Unix timestamps to ensure proper validation.
"items": { - "type": "integer" + "type": "integer", + "format": "unix-timestamp", + "minimum": 0 }zmscitizenapi/src/Zmscitizenapi/Services/Core/ZmsApiFacadeService.php (2)
567-572
: Consider using early returns for better readability.The nested conditionals make the code harder to follow. Consider restructuring with early returns.
- if (isset($appointment->date) && isset($appointment->scope->id)) { - $timestamp = (int) $appointment->date; - $scopeId = (int) $appointment->scope->id; - - if ($timestamp > $currentTimestamp) { - $timestamps[$scopeId][$timestamp] = true; - } - } + if (!isset($appointment->date, $appointment->scope->id)) { + continue; + } + + $timestamp = (int) $appointment->date; + $scopeId = (int) $appointment->scope->id; + + if ($timestamp <= $currentTimestamp) { + continue; + } + + $timestamps[$scopeId][$timestamp] = true;
582-585
: Consider using array_multisort for better performance.When sorting multiple arrays of timestamps,
array_multisort
might be more efficient than sorting each array individually.- foreach ($appointmentTimestamps as $scopeId => &$timestamps) { - $timestamps = array_keys($timestamps); - asort($timestamps); - } + $sortedTimestamps = []; + foreach ($appointmentTimestamps as $scopeId => $timestamps) { + $sortedTimestamps[$scopeId] = array_keys($timestamps); + } + array_walk($sortedTimestamps, 'sort'); + $appointmentTimestamps = $sortedTimestamps;zmscitizenapi/src/Zmscitizenapi/Models/AvailableAppointmentsByOffice.php (3)
18-27
: Enhance constructor documentation and validation.The constructor's parameter documentation should specify the expected array structure.
Consider this improvement:
/** + * @param array<string, array<int, array{ + * datetime: string, + * scope: int + * }>> $officeAppointments Array of appointments indexed by office ID */ public function __construct(array $officeAppointments = [])
29-34
: Improve validation error handling.The error message is too generic and doesn't help diagnose the actual validation failure.
Consider this improvement:
private function ensureValid(): void { if (!$this->testValid()) { - throw new InvalidArgumentException('The provided data is invalid according to the schema.'); + throw new InvalidArgumentException(sprintf( + 'Invalid office appointments data. Validation errors: %s', + json_encode($this->getErrors()) + )); } }
56-59
: Specify concrete return type for jsonSerialize.The method could use a more specific return type than
mixed
.Consider this improvement:
- public function jsonSerialize(): mixed + public function jsonSerialize(): array { return $this->toArray(); }
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
zmscitizenapi/src/Zmscitizenapi/Models/AvailableAppointmentsByOffice.php
(1 hunks)zmscitizenapi/src/Zmscitizenapi/Services/Availability/AvailableAppointmentsListService.php
(3 hunks)zmscitizenapi/src/Zmscitizenapi/Services/Core/ZmsApiFacadeService.php
(6 hunks)zmsentities/schema/citizenapi/availableAppointmentsByOffice.json
(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (3)
- GitHub Check: call-unit-tests / zmsdb-test
- GitHub Check: call-unit-tests / zmsapi-test
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (1)
zmscitizenapi/src/Zmscitizenapi/Models/AvailableAppointmentsByOffice.php (1)
1-9
: LGTM! File structure follows PHP best practices.The namespace declaration, strict typing, and imports are properly organized.
'officeIds' => isset($queryParams['officeId']) | ||
? array_map('trim', explode(',', (string) $queryParams['officeId'])) | ||
: [], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Improve array mapping for office IDs.
The current implementation splits and trims the office IDs but doesn't validate the values. Consider adding validation for numeric values and removing empty entries.
'officeIds' => isset($queryParams['officeId'])
- ? array_map('trim', explode(',', (string) $queryParams['officeId']))
+ ? array_filter(
+ array_map(function($id) {
+ $id = trim($id);
+ return is_numeric($id) ? (int)$id : null;
+ }, explode(',', (string) $queryParams['officeId'])),
+ function($id) { return $id !== null; }
+ )
: [],
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
'officeIds' => isset($queryParams['officeId']) | |
? array_map('trim', explode(',', (string) $queryParams['officeId'])) | |
: [], | |
'officeIds' => isset($queryParams['officeId']) | |
? array_filter( | |
array_map(function($id) { | |
$id = trim($id); | |
return is_numeric($id) ? (int)$id : null; | |
}, explode(',', (string) $queryParams['officeId'])), | |
function($id) { return $id !== null; } | |
) | |
: [], |
/** @var array|null */ | ||
public array|null $officeAppointments = []; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Improve property type declaration and documentation.
The property declaration has several issues:
- The type
array|null
with default[]
is inconsistent. If null is allowed, when would it be null? - The PHPDoc lacks comprehensive structure documentation.
Consider this improvement:
- /** @var array|null */
- public array|null $officeAppointments = [];
+ /**
+ * Array of appointments grouped by office ID.
+ *
+ * @var array<string, array<int, array{
+ * datetime: string,
+ * scope: int
+ * }>>
+ */
+ public array $officeAppointments = [];
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
/** @var array|null */ | |
public array|null $officeAppointments = []; | |
/** | |
* Array of appointments grouped by office ID. | |
* | |
* @var array<string, array<int, array{ | |
* datetime: string, | |
* scope: int | |
* }>> | |
*/ | |
public array $officeAppointments = []; |
public function toArray(): array | ||
{ | ||
return [ | ||
'offices' => array_map(function($appointments, $officeId) { | ||
return [ | ||
'officeId' => $officeId, | ||
'appointments' => $appointments | ||
]; | ||
}, $this->officeAppointments, array_keys($this->officeAppointments)) | ||
]; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Improve type safety in serialization logic.
The array transformation could be more type-safe and robust.
Consider these improvements:
public function toArray(): array
{
+ if (empty($this->officeAppointments)) {
+ return ['offices' => []];
+ }
+
return [
'offices' => array_map(
- function($appointments, $officeId) {
+ function(array $appointments, string $officeId): array {
return [
'officeId' => $officeId,
'appointments' => $appointments
];
},
$this->officeAppointments,
array_keys($this->officeAppointments)
)
];
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
public function toArray(): array | |
{ | |
return [ | |
'offices' => array_map(function($appointments, $officeId) { | |
return [ | |
'officeId' => $officeId, | |
'appointments' => $appointments | |
]; | |
}, $this->officeAppointments, array_keys($this->officeAppointments)) | |
]; | |
} | |
public function toArray(): array | |
{ | |
if (empty($this->officeAppointments)) { | |
return ['offices' => []]; | |
} | |
return [ | |
'offices' => array_map( | |
function(array $appointments, string $officeId): array { | |
return [ | |
'officeId' => $officeId, | |
'appointments' => $appointments | |
]; | |
}, | |
$this->officeAppointments, | |
array_keys($this->officeAppointments) | |
) | |
]; | |
} |
zmscitizenapi/src/Zmscitizenapi/Models/AvailableAppointmentsByOffice.php
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
zmscitizenapi/src/Zmscitizenapi/Services/Core/ZmsApiFacadeService.php (1)
430-457
:⚠️ Potential issueAdd validation for array lengths.
The method accesses
$serviceCounts[$serviceNumber]
without verifying that the arrays have matching lengths. This could lead to undefined offset errors.Apply this diff to add validation:
): AvailableDays|array { $firstDay = DateTimeFormatHelper::getInternalDateFromISO($startDate); $lastDay = DateTimeFormatHelper::getInternalDateFromISO($endDate); + + if (count($serviceIds) !== count($serviceCounts)) { + throw new InvalidArgumentException('The number of service IDs must match the number of service counts.'); + } $services = []; $providers = [];
🧹 Nitpick comments (1)
zmscitizenapi/src/Zmscitizenapi/Services/Core/ZmsApiFacadeService.php (1)
510-515
: Document return type behavior.The method can return different types based on the
$groupByOffice
parameter. Consider adding PHPDoc to clarify when each return type is used.+ /** + * Get available appointments, optionally grouped by office. + * + * @param string $date The date to check for appointments + * @param array $officeIds Array of office IDs + * @param array $serviceIds Array of service IDs + * @param array $serviceCounts Array of service counts + * @param bool|null $groupByOffice Whether to group results by office + * @return AvailableAppointments|AvailableAppointmentsByOffice|array Returns AvailableAppointmentsByOffice when $groupByOffice is true, + * AvailableAppointments otherwise, or array with errors if validation fails + */
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
zmscitizenapi/src/Zmscitizenapi/Services/Core/ZmsApiFacadeService.php
(6 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (3)
- GitHub Check: call-unit-tests / zmsapi-test
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: call-unit-tests / zmsdb-test
🔇 Additional comments (3)
zmscitizenapi/src/Zmscitizenapi/Services/Core/ZmsApiFacadeService.php (3)
8-8
: LGTM! New imports support office-based grouping functionality.Also applies to: 13-13
Line range hint
554-592
: LGTM! Efficient implementation of timestamp grouping.The method effectively:
- Groups timestamps by provider ID using array_reduce
- Validates timestamps against current time
- Uses references to optimize memory usage
517-525
:⚠️ Potential issueAdd validation for service arrays.
The method accesses
$serviceCounts[$index]
without verifying that the arrays have matching lengths.Apply this diff to add validation:
$requests = []; $providers = []; + + if (count($serviceIds) !== count($serviceCounts)) { + throw new InvalidArgumentException('The number of service IDs must match the number of service counts.'); + } + foreach ($serviceIds as $index => $serviceId) {Likely invalid or redundant comment.
* add zmsapi methods to base controller * add helper methods to base controller * refactored into services and controllers * remove duplicate function definitions * move helpers from base controller to new utility helper * add a method * Feature mpdzbs 887 zmscitizenapi post reserve appointment and refactor (#574) * endpoint working * fix unit tests * one working test for post-reserve * some clean up * feat(ZMS-2517): fix up response for the reserve post request * feat(ZMS-2517): add more unit tests for validations * feat(ZMS-2517): add more unit tests for validations * feat(ZMS-2517): Zmscitizenapi Refactor Part 1 of 3 move controllers back to root * feat(ZMS-2517): Zmscitizenapi Refactor Part 2 of 3 create ZmsApiFacadeService ZmsApiClientService ValidationService MapperService UtilityHelper and delete fragmented services * feat(ZMS-2517): Zmscitizenapi Refactor Part 3 of 3 clean up validations and unit tests --------- Co-authored-by: Thomas Fink <thomasafink@Thomass-MacBook-Air.local> * feat(MPDZBS-877): Readd zmscitizenapi to github workflow * feat(MPDZBS-877): Readd files lost in github history * feat(MPDZBS-877): Readd files lost in github history * feat(MPDZBS-877): Resolve merge conflict in zmsentities * feat(MPDZBS-877): Readd zmscitizenapi schemas to zmsentities deleted by github commit history * (feat MPDZBS-877): update local env cli * Feature mpdzbs 887 zms 2518 zmscitizenapi post update appointment (#587) * (feat MPDZBS-877) readd citizenapi to htaccess * feat(MPDZBS-877 ZMS-2517): Working Appointment update with too many emails exception * feat(MPDZBS-877 ZMS-2517): Test rendering working for update appointment test * feat(MPDZBS-877 ZMS-2517): Add 63 validation unit tests for appointment update * feat(MPDZBS-877 ZMS-2517): Refactor exception appointmentNotFound * feat(MPDZBS-877 ZMS-2517): Add two new edge case exception tests * feat(MPDZBS-877 ZMS-2517): Remove error_logs --------- Co-authored-by: Thomas Fink <thomasafink@Thomass-MacBook-Air.local> * feat(MPDZBS-877): update .gitignore * cleanup(MPDZBS-877): Improve security and cleanup code * fix(MPDZBS-877): fix bin configure * fix(MPDZBS-877): fix config.example.php * cleanup(MPDZBS-877): merge next into feature branch * docs(MPDZBS-877): update docs for zmscitizenapi * clean(MPDZBS-877): change friendly captcha default endpoint to eu * clean(MPDZBS-877): change maintenance and captcha enabled to boolean * clean(MPDZBS-877): improve internal error handling enable middleware * feat(MPDZBS-877): return 503 for maintenance * feat(MPDZBS-877): add generic captcha interface * clean(MPDZBS-877): improve validation for array ids * feat(MPDZBS-877): improve zmscitizenapi typing * clean(MPDZBS-877): typing overhaul using zmsentities * clean(MPDZBS-877): typing overhaul using zmsentities * clean(MPDZBS-877): improve telephone validation regex * clean(MPDZBS-877): improve serviceId validation regex * clean(MPDZBS-877): fix naming issue * clean(MPDZBS-877): make hardcoded source name dynamic * clean(MPDZBS-877): clean up more and change citizenapi to utf8 * clean(MPDZBS-877): improve error messaging codes and expand office api with geocoordinates and address * clean(MPDZBS-877): cleanup syntax and error handling * clean(MPDZBS-877): cleanup syntax and error handling * fix(MPDZBS-877): offices and services mapper * fix(MPDZBS-877): fix reserve appointment validation * fix(MPDZBS-877): improve some validation for empty arrays * feat(MPDZBS-877): Improve ThinnedProcess object and cleanup some stuff with naming (#739) * feat(MPDZB-877): Work on thinnedprocess typing * feat(MPDZB): Refactor part 1 * feat(MPDZB): Refactor part 1 * feat(MPDZB-877): revert to processId in parameter * feat(MPDZBS-877): refactor thinned process to object * feat(MPDZB-877): refactor thinned process and rename controllers --------- Co-authored-by: Tom Fink <thomasafink@Toms-MacBook-Air.local> Co-authored-by: DDEV User <nobody@example.com> Co-authored-by: Thomas Fink <thomasafink@Thomass-MacBook-Air.local> * feat(MPDZBS-877): zmscitizenapi cleanup (#740) * feat(MPDZB-877): Work on thinnedprocess typing * feat(MPDZB): Refactor part 1 * feat(MPDZB): Refactor part 1 * feat(MPDZB-877): revert to processId in parameter * feat(MPDZBS-877): refactor thinned process to object * feat(MPDZB-877): refactor thinned process and rename controllers * feat(MPDZBs-877): clean up more junk --------- Co-authored-by: Tom Fink <thomasafink@Toms-MacBook-Air.local> Co-authored-by: DDEV User <nobody@example.com> Co-authored-by: Thomas Fink <thomasafink@Thomass-MacBook-Air.local> * feat(MPDZBs-877): clean up more stuff validation improvement * Update zmscitizenapi/src/Zmscitizenapi/Captcha.php Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * feat(MPDZBs-877): clean up captcha add more tests * feat(ZMS-3430): create db indices * feat(MPDZBS-877): Refactor Controllers and improve move typing building models * feat(MPDZBS-877): Refactor Utilities and Helpers * Update zmscitizenapi/src/Zmscitizenapi/Services/MapperService.php Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * feat(MPDZBS-877): Fix bug * feat(MPDZBS-877): rename scope models in zmscitizenapi * feat(MPDZBS-877): cleanup service model * feat(MPDZBS-877): Improve ThinnedProcess and ThinnedScope models * fix(MPDZBS-877): swagger docs * fix(MPDZBS-877): swagger docs * zms-2871-2874-minus-deletion-by-location-delete-and-orthography-mail-and-notification-buttons * fix(MPDZBS-877): set up models for Office Service and Captcha * fix(MPDZBS-877): Improve captcha typing * Update zmscitizenapi/src/Zmscitizenapi/Models/Captcha/AltchaCaptcha.php Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * fix(MPDZBS-877): Improve captcha typing cleanup * fix(MPDZBS-877): Improve captcha typing cleanup * fix(MPDZBS-877): remove status from visual response * fix(MPDZBS-877): Improve typing for Office Service and ThinnedScope * fix(MPDZBS-877): Improve typing for Office Service Relations * fix(MPDZBS-877): Improve typing for ThinnedProvider * fix(MPDZBS-877): Refactor model lists to collections * fix(MPDZBS-877): Improve typing for Combinable * fix(MPDZBS-877): Cleanup AltchaCaptcha class * fix(MPDZBS-877): Improve parameters for getAvailableAppointments * fix(MPDZBS-877): Improve typing for AvailableDays and AvailableAppointments * fix(MPDZBS-877): Cleanup schemas * fix(MPDZBS-877): Cleanup schema mismatch * fix(MPDZBS-877): Optimize next loops and schema typing * fix(MPDZBS-877): Improve schema * fix(MPDZBS-877): Improve schema * fix(MPDZBS-877): Improve schema and error catching * fix(MPDZBS-877): Improve api fetching safety * fix(MPDZBS-877): Introduce strict typing for files with logic * fix(deps): update dependency phpoffice/phpspreadsheet to v1.29.6 (#738) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update dependency squizlabs/php_codesniffer to v3.11.2 (#751) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * fix(MPDZBS-877): Introduce schema validation into the models * fix(MPDZBS-877): Centralize validation, set default language to german, improve exception handling * fix(MPDZBS-877): authKeyMissMatch error exception * fix(MPDZBS-877): cleanup some code * fix(MPDZBS-877): cleanup collection models * Delete zmscitizenapi/templates/.keep * Revert "Delete zmscitizenapi/templates/.keep" This reverts commit 7725d44. * clean(MPDZBS-877): remove comments * fix(MPDZBS-877): errorCode fix * fix(MPDZBS-877): validation input date bug and add unittest plus authKeyMismatch typo and add unittest * clean(MPDZBS-877): remove unused vars * feat(MPDZBS-877): Improve zmsapi exception handling * feat(MPDZBS-877): Improve contact mapping and provider mapping * Improve exception handling * feat(MPDZBS-877): Refactor office model * feat(MPDZBS-877): fix ProcessFreeSlots typing * clean(MPDZBS-877): refactor and improve contoller legibility * fix(MPDZBS-877): improve post request validation dont get request body on null fix * clean(MPDZBS-877): improve OfficesByServiceList controller * clean(MPDZBS-877): correct not yet implemented controllers * chore(deps): update dependency sass to v1.83.0 (#750) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * fix(deps): update dependency phpoffice/phpspreadsheet to v1.29.7 (#752) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * clean(MPDZBS-877): Add null checks for requests to zmsapi * chore(deps): update dependency phpspec/prophecy-phpunit to v2.3.0 (#647) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * clean(MPDZBS-877): Improve and centralize regex patterns for ValidationService * feat(MPDZBS-877 ZMS-2523): Improve controller typing and add caching for fetchSourceData * fix(MPDZBS-877 ZMS-2523): fix php docker version to 8.0 from 8.0.2 * clean(MPDZBS-877 ZMS-2523): Cleanup Application * clean(MPDZBS-877 ZMS-2523): Cleanup Application * clean(MPDZBS-877 ZMS-2523): Improve cache logger and cache permissions * fix(MPDZBS-877 ZMS-2520): Implement preconfirmed appointment working * clean(MPDZBS-877 ZMS-2520): remove errorlogs * feat(MPDZBS-877 ZMS-2519 ZMS-2521): Implement appointment confirm and cancel controllers and improve request method error handling * feat(MPDZBS-877): remove unused import statements * clean(MPDZBS-877): fix typing * clean(MPDZBS-877): remove unused error message * clean(MPDZBS-877): Refactor folder structure and move logic from controllers to services * clean(MPDZBS-877): improve input validation * fix(MPDZBS-877): Time check with timezone * feat(MPDZBS-877): Implement LoggerService for logging requests and when caching is set * clean(MPDZBS-877): Remove logger redundancy * fix(MPDZBS-877): Add logger response max size 1MB * clean(MPDZBS-877): improve exceptions and handling in logger middleware * feat(MPDZBS-877): optimize logger service * feat(MPDZBS-877): optimize logger service * clean(MPDZBS-877): improve error body logging * feat(MPDZBS-877): optimize logger service caching * clean(MPDZBS-877): add unit test and clean up some stuff * clean(MPDZBS-877): add missing import * fix(ZMS-3500) Differentiate between editing and booking a new appointment when selecting the date (#757) * feat(MPDZBS-877 ZMS-1232): Implement security middleware Cors Csrf Security Headers Rate Limits Request Size Limits and Request Sanitation * feat(MPDZBS-877 ZMS-1232): Refactor contoller tests and fix cors test * feat(MPDZBS-877 ZMS-1232): improve middleware and fix race conditions in rate limiting * clean(MPDZBS-877 ZMS-1232): small improvements to middelware and test assertions * clean(MPDZBS-877 ZMS-1232): reduce excessive logging * clean(MPDZBS-877 ZMS-1232): fix race Condition LoggerService * chore(deps): update dependency seld/jsonlint to v1.11.0 (#754) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update dependency sass to v1.83.1 (#760) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * docs(MPDZBS-877): Add README.md * docs(MPDZBS-877): Add README.md * docs(MPDZBS-877): Update README.md * docs(MPDZBS-877): Update README.md * docs(MPDZBS-877): Update README.md * fix(MPDZBS-877): unit test * chore(deps): update dependency core-js to v3.40.0 (#761) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * docs(MPDZBS-877): Update README.md * docs(MPDZBS-877): Update README.md * Update README.md * clean(MPDZBS-877): Centralize environment variables * fix(MPDZBS-877): CORS unit tests * clean(MPDZBS-877): centralize zmsapi exception handling and write more tests * clean(MPDZBS-877): remove error log * feat(MPDZBS-877): add unit test * feat(MPDZBS-877): add MapperServiceTest * feat(MPDZBS-877): add LoggerServiceTest ExceptionServiceTest ValidationServiceTest * feat(MPDZBS-877): add ZmsApiFacadeServiceTest * feat(MPDZBS-877): add ZmsApiClientServiceTest * feat(MPDZBS-877): add AppointmentByIdServiceTest * feat(MPDZBS-877): add AppointmentByIdServiceTest * feat(MPDZBS-877): add AppointmentCancelServiceTest * feat(MPDZBS-877): add AppointmentConfirmServiceTest * feat(MPDZBS-877): add Appointment tests * feat(MPDZBS-877): add AppointmentUpdateServiceTest * feat(MPDZBS-877): add AvailableAppointmentsListServiceTest and AvailableDaysListServiceTest * feat(MPDZBS-877): add Service tests * feat(MPDZBS-877): add captcha service and application tests * feat(MPDZBS-877): remove unneeded test * feat(MPDZBS-877): Add LanguageMiddleware and i18n support * feat(MPDZBS-877): Add LanguageMiddlewareTest * feat(ZMS-3212) Notfall für Tresen deaktiveren * feat(MPDZBS-877): clean up language error messages * feat(MPDZBS-877): disable csrf for now * fix(MPDZBS-877): fix ip client helper * fix(MPDZBS-877): only log error messages in english * feat(MPDZBS-877): disable csrf for now * fix(MPDZBS-877): routing methods post * fix(MPDZBS-877): routing methods get * fix(MPDZBS-877): customTextfield save on appointment update * fix(MPDZBS-877): customTextfield unit test * feat(ZMS-3449): map more data * feat(ZMS-3449): fix mapping * feat(MPDZBS-877): Add showAlternativeLocations to offices endpoints * Revert "feat(MPDZBS-877): Add showAlternativeLocations to offices endpoints" This reverts commit 63fe1a0. * feat(MPDZBS-877 ZMS-1232 ZMS-2509 ZMS-2510 ZMS-2511 ZMS-2512 ZMS-2513 ZMS-2514 ZMS-2515 ZMS-2516 ZMS-2517 ZMS-2518 ZMS-2519 ZMS-2520 ZMS-2521 ZMS-2523 ZMS-2993): Zmscitizenapi into next (#769) * update readmes * refactor some functions to base controller class * add zmsapi methods to base controller * add helper methods to base controller * refactored into services and controllers * remove duplicate function definitions * move helpers from base controller to new utility helper * add a method * Feature mpdzbs 887 zmscitizenapi post reserve appointment and refactor (#574) * endpoint working * fix unit tests * one working test for post-reserve * some clean up * feat(ZMS-2517): fix up response for the reserve post request * feat(ZMS-2517): add more unit tests for validations * feat(ZMS-2517): add more unit tests for validations * feat(ZMS-2517): Zmscitizenapi Refactor Part 1 of 3 move controllers back to root * feat(ZMS-2517): Zmscitizenapi Refactor Part 2 of 3 create ZmsApiFacadeService ZmsApiClientService ValidationService MapperService UtilityHelper and delete fragmented services * feat(ZMS-2517): Zmscitizenapi Refactor Part 3 of 3 clean up validations and unit tests --------- Co-authored-by: Thomas Fink <thomasafink@Thomass-MacBook-Air.local> * feat(MPDZBS-877): Readd zmscitizenapi to github workflow * feat(MPDZBS-877): Readd files lost in github history * feat(MPDZBS-877): Readd files lost in github history * feat(MPDZBS-877): Resolve merge conflict in zmsentities * feat(MPDZBS-877): Readd zmscitizenapi schemas to zmsentities deleted by github commit history * (feat MPDZBS-877): update local env cli * Feature mpdzbs 887 zms 2518 zmscitizenapi post update appointment (#587) * (feat MPDZBS-877) readd citizenapi to htaccess * feat(MPDZBS-877 ZMS-2517): Working Appointment update with too many emails exception * feat(MPDZBS-877 ZMS-2517): Test rendering working for update appointment test * feat(MPDZBS-877 ZMS-2517): Add 63 validation unit tests for appointment update * feat(MPDZBS-877 ZMS-2517): Refactor exception appointmentNotFound * feat(MPDZBS-877 ZMS-2517): Add two new edge case exception tests * feat(MPDZBS-877 ZMS-2517): Remove error_logs --------- Co-authored-by: Thomas Fink <thomasafink@Thomass-MacBook-Air.local> * feat(MPDZBS-877): update .gitignore * cleanup(MPDZBS-877): Improve security and cleanup code * fix(MPDZBS-877): fix bin configure * fix(MPDZBS-877): fix config.example.php * cleanup(MPDZBS-877): merge next into feature branch * docs(MPDZBS-877): update docs for zmscitizenapi * clean(MPDZBS-877): change friendly captcha default endpoint to eu * clean(MPDZBS-877): change maintenance and captcha enabled to boolean * clean(MPDZBS-877): improve internal error handling enable middleware * feat(MPDZBS-877): return 503 for maintenance * feat(MPDZBS-877): add generic captcha interface * clean(MPDZBS-877): improve validation for array ids * feat(MPDZBS-877): improve zmscitizenapi typing * clean(MPDZBS-877): typing overhaul using zmsentities * clean(MPDZBS-877): typing overhaul using zmsentities * clean(MPDZBS-877): improve telephone validation regex * clean(MPDZBS-877): improve serviceId validation regex * clean(MPDZBS-877): fix naming issue * clean(MPDZBS-877): make hardcoded source name dynamic * clean(MPDZBS-877): clean up more and change citizenapi to utf8 * clean(MPDZBS-877): improve error messaging codes and expand office api with geocoordinates and address * clean(MPDZBS-877): cleanup syntax and error handling * clean(MPDZBS-877): cleanup syntax and error handling * fix(MPDZBS-877): offices and services mapper * fix(MPDZBS-877): fix reserve appointment validation * fix(MPDZBS-877): improve some validation for empty arrays * feat(MPDZBS-877): Improve ThinnedProcess object and cleanup some stuff with naming (#739) * feat(MPDZB-877): Work on thinnedprocess typing * feat(MPDZB): Refactor part 1 * feat(MPDZB): Refactor part 1 * feat(MPDZB-877): revert to processId in parameter * feat(MPDZBS-877): refactor thinned process to object * feat(MPDZB-877): refactor thinned process and rename controllers --------- Co-authored-by: Tom Fink <thomasafink@Toms-MacBook-Air.local> Co-authored-by: DDEV User <nobody@example.com> Co-authored-by: Thomas Fink <thomasafink@Thomass-MacBook-Air.local> * feat(MPDZBS-877): zmscitizenapi cleanup (#740) * feat(MPDZB-877): Work on thinnedprocess typing * feat(MPDZB): Refactor part 1 * feat(MPDZB): Refactor part 1 * feat(MPDZB-877): revert to processId in parameter * feat(MPDZBS-877): refactor thinned process to object * feat(MPDZB-877): refactor thinned process and rename controllers * feat(MPDZBs-877): clean up more junk --------- Co-authored-by: Tom Fink <thomasafink@Toms-MacBook-Air.local> Co-authored-by: DDEV User <nobody@example.com> Co-authored-by: Thomas Fink <thomasafink@Thomass-MacBook-Air.local> * feat(MPDZBs-877): clean up more stuff validation improvement * Update zmscitizenapi/src/Zmscitizenapi/Captcha.php Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * feat(MPDZBs-877): clean up captcha add more tests * feat(MPDZBS-877): Refactor Controllers and improve move typing building models * feat(MPDZBS-877): Refactor Utilities and Helpers * Update zmscitizenapi/src/Zmscitizenapi/Services/MapperService.php Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * feat(MPDZBS-877): Fix bug * feat(MPDZBS-877): rename scope models in zmscitizenapi * feat(MPDZBS-877): cleanup service model * feat(MPDZBS-877): Improve ThinnedProcess and ThinnedScope models * fix(MPDZBS-877): swagger docs * fix(MPDZBS-877): swagger docs * fix(MPDZBS-877): set up models for Office Service and Captcha * fix(MPDZBS-877): Improve captcha typing * Update zmscitizenapi/src/Zmscitizenapi/Models/Captcha/AltchaCaptcha.php Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * fix(MPDZBS-877): Improve captcha typing cleanup * fix(MPDZBS-877): Improve captcha typing cleanup * fix(MPDZBS-877): remove status from visual response * fix(MPDZBS-877): Improve typing for Office Service and ThinnedScope * fix(MPDZBS-877): Improve typing for Office Service Relations * fix(MPDZBS-877): Improve typing for ThinnedProvider * fix(MPDZBS-877): Refactor model lists to collections * fix(MPDZBS-877): Improve typing for Combinable * fix(MPDZBS-877): Cleanup AltchaCaptcha class * fix(MPDZBS-877): Improve parameters for getAvailableAppointments * fix(MPDZBS-877): Improve typing for AvailableDays and AvailableAppointments * fix(MPDZBS-877): Cleanup schemas * fix(MPDZBS-877): Cleanup schema mismatch * fix(MPDZBS-877): Optimize next loops and schema typing * fix(MPDZBS-877): Improve schema * fix(MPDZBS-877): Improve schema * fix(MPDZBS-877): Improve schema and error catching * fix(MPDZBS-877): Improve api fetching safety * fix(MPDZBS-877): Introduce strict typing for files with logic * fix(MPDZBS-877): Introduce schema validation into the models * fix(MPDZBS-877): Centralize validation, set default language to german, improve exception handling * fix(MPDZBS-877): authKeyMissMatch error exception * fix(MPDZBS-877): cleanup some code * fix(MPDZBS-877): cleanup collection models * Delete zmscitizenapi/templates/.keep * Revert "Delete zmscitizenapi/templates/.keep" This reverts commit 7725d44. * clean(MPDZBS-877): remove comments * fix(MPDZBS-877): errorCode fix * fix(MPDZBS-877): validation input date bug and add unittest plus authKeyMismatch typo and add unittest * clean(MPDZBS-877): remove unused vars * feat(MPDZBS-877): Improve zmsapi exception handling * feat(MPDZBS-877): Improve contact mapping and provider mapping * Improve exception handling * feat(MPDZBS-877): Refactor office model * feat(MPDZBS-877): fix ProcessFreeSlots typing * clean(MPDZBS-877): refactor and improve contoller legibility * fix(MPDZBS-877): improve post request validation dont get request body on null fix * clean(MPDZBS-877): improve OfficesByServiceList controller * clean(MPDZBS-877): correct not yet implemented controllers * clean(MPDZBS-877): Add null checks for requests to zmsapi * clean(MPDZBS-877): Improve and centralize regex patterns for ValidationService * feat(MPDZBS-877 ZMS-2523): Improve controller typing and add caching for fetchSourceData * fix(MPDZBS-877 ZMS-2523): fix php docker version to 8.0 from 8.0.2 * clean(MPDZBS-877 ZMS-2523): Cleanup Application * clean(MPDZBS-877 ZMS-2523): Cleanup Application * clean(MPDZBS-877 ZMS-2523): Improve cache logger and cache permissions * fix(MPDZBS-877 ZMS-2520): Implement preconfirmed appointment working * clean(MPDZBS-877 ZMS-2520): remove errorlogs * feat(MPDZBS-877 ZMS-2519 ZMS-2521): Implement appointment confirm and cancel controllers and improve request method error handling * feat(MPDZBS-877): remove unused import statements * clean(MPDZBS-877): fix typing * clean(MPDZBS-877): remove unused error message * clean(MPDZBS-877): Refactor folder structure and move logic from controllers to services * clean(MPDZBS-877): improve input validation * fix(MPDZBS-877): Time check with timezone * feat(MPDZBS-877): Implement LoggerService for logging requests and when caching is set * clean(MPDZBS-877): Remove logger redundancy * fix(MPDZBS-877): Add logger response max size 1MB * clean(MPDZBS-877): improve exceptions and handling in logger middleware * feat(MPDZBS-877): optimize logger service * feat(MPDZBS-877): optimize logger service * clean(MPDZBS-877): improve error body logging * feat(MPDZBS-877): optimize logger service caching * clean(MPDZBS-877): add unit test and clean up some stuff * clean(MPDZBS-877): add missing import * feat(MPDZBS-877 ZMS-1232): Implement security middleware Cors Csrf Security Headers Rate Limits Request Size Limits and Request Sanitation * feat(MPDZBS-877 ZMS-1232): Refactor contoller tests and fix cors test * feat(MPDZBS-877 ZMS-1232): improve middleware and fix race conditions in rate limiting * clean(MPDZBS-877 ZMS-1232): small improvements to middelware and test assertions * clean(MPDZBS-877 ZMS-1232): reduce excessive logging * clean(MPDZBS-877 ZMS-1232): fix race Condition LoggerService * docs(MPDZBS-877): Add README.md * docs(MPDZBS-877): Add README.md * docs(MPDZBS-877): Update README.md * docs(MPDZBS-877): Update README.md * docs(MPDZBS-877): Update README.md * fix(MPDZBS-877): unit test * docs(MPDZBS-877): Update README.md * docs(MPDZBS-877): Update README.md * Update README.md * clean(MPDZBS-877): Centralize environment variables * fix(MPDZBS-877): CORS unit tests * clean(MPDZBS-877): centralize zmsapi exception handling and write more tests * clean(MPDZBS-877): remove error log * feat(MPDZBS-877): add unit test * feat(MPDZBS-877): add MapperServiceTest * feat(MPDZBS-877): add LoggerServiceTest ExceptionServiceTest ValidationServiceTest * feat(MPDZBS-877): add ZmsApiFacadeServiceTest * feat(MPDZBS-877): add ZmsApiClientServiceTest * feat(MPDZBS-877): add AppointmentByIdServiceTest * feat(MPDZBS-877): add AppointmentByIdServiceTest * feat(MPDZBS-877): add AppointmentCancelServiceTest * feat(MPDZBS-877): add AppointmentConfirmServiceTest * feat(MPDZBS-877): add Appointment tests * feat(MPDZBS-877): add AppointmentUpdateServiceTest * feat(MPDZBS-877): add AvailableAppointmentsListServiceTest and AvailableDaysListServiceTest * feat(MPDZBS-877): add Service tests * feat(MPDZBS-877): add captcha service and application tests * feat(MPDZBS-877): remove unneeded test * feat(MPDZBS-877): Add LanguageMiddleware and i18n support * feat(MPDZBS-877): Add LanguageMiddlewareTest * feat(MPDZBS-877): clean up language error messages * feat(MPDZBS-877): disable csrf for now * fix(MPDZBS-877): fix ip client helper * fix(MPDZBS-877): only log error messages in english * feat(MPDZBS-877): disable csrf for now * fix(MPDZBS-877): routing methods post * fix(MPDZBS-877): routing methods get * fix(MPDZBS-877): customTextfield save on appointment update * fix(MPDZBS-877): customTextfield unit test * feat(MPDZBS-877): Add showAlternativeLocations to offices endpoints * Revert "feat(MPDZBS-877): Add showAlternativeLocations to offices endpoints" This reverts commit 63fe1a0. --------- Co-authored-by: Thomas Fink <thomasafink@Thomass-MacBook-Air.local> Co-authored-by: Tom Fink <thomasafink@Toms-MacBook-Air.local> Co-authored-by: Thomas Fink <thomasfink@Thomass-MacBook-Air.local> Co-authored-by: DDEV User <nobody@example.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Thomas Fink <thomasafink@thomass-air.speedport.ip> * docs(MPDZBS-877): Update README.md * feat(ZMS-3449): adjust schema * feat(ZMS-3449): fix object argument * feat(ZMS-3449): fix typo * Update .env.template * feat(ZMS-3449): fix mapping * feat(ZMS-3449): fix tests * feat(ZMS-3449): fix tests * feat(ZMS-3499) refresh queue even when losing focus * Update .env.template * feat(ZMS-3459): return slotTimeInMinutes * feat(ZMS-3430): add indexes * feat(ZMS-3430): remove indexes * writeCanceledSlots-time shortened to 5 minutes * Temporarily disable cors zmscitizenapi (#795) * disable cors middleware * Update CorsMiddlewareTest.php * Update CorsMiddlewareTest.php * Update bootstrap.php * Update SecurityHeadersMiddlewareTest.php * feat(ZMS-3519) sortierung für queueList * feat(ZMS-3430): fix test * feat(ZMS-3503): added logic to end emergency with checkbox * feat(ZMS-3503): removed console.log and unesscessy function * feat(ZMS-3503): removed console.log and unesscessy function * feat(ZMS-3503): removed console.log and unnecessary functions * fix(deps): update dependency phpoffice/phpspreadsheet to v1.29.8 [security] (#794) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update dependency sass to v1.83.4 (#806) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * feat(ZMS-3507): redirect without appointment (#775) * fix(deps): update dependency phpoffice/phpspreadsheet to v1.29.9 [security] (#814) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * feat(ZMS-3503): added explanation to the function * feat(ZMS-3499) Tabelle für die Warteschlange wird aktualisiert auch bei Mouse-Hovering * feat(ZMS-3460): create endpoint for free appointments grouped by office (#797) * feat(ZMS-3460): create endpoint for free appointments grouped by office * feat(ZMS-3460): fix test * feat(ZMS-3460): fix tests * feat(ZMS-3460): fix tests * feat(ZMS-3460): fix tests * feat(ZMS-3460): fix tests * feat(ZMS-3460): fix tests * feat(ZMS-3460): fix tests * feat(ZMS-3460): fix tests * feat(ZMS-3460): fix tests * feat(ZMS-3460): fix tests * feat(ZMS-3460): fix route * feat(ZMS-3460): refactoring * feat(ZMS-3460): show provider, not scope id * feat(ZMS-3460): fix provider id --------- Co-authored-by: Thomas Fink <tom@Thomass-MacBook-Air.local> * fix(ZMS): show alternative locations for offices (#820) Co-authored-by: Thomas Fink <tom@Thomass-MacBook-Air.local> * fix(zms): Update .env.template local env --------- Co-authored-by: Thomas Fink <thomasafink@Thomass-MacBook-Air.local> Co-authored-by: Tom Fink <thomasafink@Toms-MacBook-Air.local> Co-authored-by: Thomas Fink <thomasfink@Thomass-MacBook-Air.local> Co-authored-by: DDEV User <nobody@example.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Igor Manjencic <manjak.igor@gmail.com> Co-authored-by: matthias1996 <matthias.lorenz@muenchen.de> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Thomas Fink <thomasafink@thomass-air.speedport.ip> Co-authored-by: MoDaae <90261750+MoDaae@users.noreply.github.com> Co-authored-by: mohamad.daaeboul <mohamad.daaeboul@muenchen.de> Co-authored-by: Thomas Fink <tom@Thomass-MacBook-Air.local> Co-authored-by: Fabian Breitling <83815772+msfb3@users.noreply.github.com>
Pull Request Checklist (Feature Branch to
next
):next
Branch in meinen Feature-Branch gemergt.Description
Short description or comments
Reference
Issues #XXX
Summary by CodeRabbit
New Features
/available-appointments-by-office/
to retrieve available appointments for multiple offices on a specific date.Improvements
Technical Updates
AvailableAppointmentsByOffice
to support grouped appointment retrieval.AvailableAppointmentsByOffice
to define the structure of available appointments.