Skip to content

Refactor: Upgrade api service#7731

Merged
DawoudIO merged 5 commits intomasterfrom
refactor/upgrade-api-service
Dec 6, 2025
Merged

Refactor: Upgrade api service#7731
DawoudIO merged 5 commits intomasterfrom
refactor/upgrade-api-service

Conversation

@DawoudIO
Copy link
Contributor

@DawoudIO DawoudIO commented Dec 6, 2025

What Changed

Fixes #

Type

  • ✨ Feature
  • 🐛 Bug fix
  • ♻️ Refactor
  • 🏗️ Build/Infrastructure
  • 🔒 Security

Testing

Screenshots

Security Check

  • Introduces new input validation
  • Modifies authentication/authorization
  • Affects data privacy/GDPR

Code Quality

  • Database: Propel ORM only, no raw SQL
  • No deprecated attributes (align, valign, nowrap, border, cellpadding, cellspacing, bgcolor)
  • Bootstrap CSS classes used
  • All CSS bundled via webpack

Pre-Merge

  • Tested locally
  • No new warnings
  • Build passes
  • Backward compatible (or migration documented)

…ity checks

- isReleaseCurrent() now populates releases cache if empty before comparing
- checkSystemUpdateAvailable() adds debug logging for version comparisons
- refresh-upgrade-info endpoint recalculates availability and updates session keys
- upgrade page fetches fresh release info on load and recomputes update state
…e duplication

Create new service layer for upgrade operations to enable code reuse across admin and
potential future public API endpoints:

New Service:
- src/ChurchCRM/Service/UpgradeAPIService.php
  - downloadLatestRelease() - download upgrade from GitHub
  - doUpgrade() - apply upgrade with SHA1 verification
  - refreshUpgradeInfo() - refresh from GitHub and update session state
  - Wraps ChurchCRMReleaseManager for API endpoint use

Admin API Route (refactored to use service):
- src/admin/routes/api/upgrade.php (moved from src/api/routes/system/system-upgrade.php)
  - Comprehensive endpoint documentation in comments
  - All three endpoints now delegate to UpgradeAPIService
  - Consistent error handling and response formats
  - Still protected by AdminRoleAuthMiddleware at router level

Frontend JavaScript:
- src/skin/js/CRMJSOM.js: Added window.CRM.AdminAPIRequest() wrapper
  - Automatically prefixes with /admin/api/ for admin endpoints
  - Eliminates double /api/ nesting issue
- webpack/upgrade-wizard-app.js: Updated all endpoints to use AdminAPIRequest
  - upgrade/download-latest-release
  - upgrade/do-upgrade
  - upgrade/refresh-upgrade-info

Updated Imports:
- src/admin/index.php: Added new upgrade route import
- src/api/index.php: Removed old system-upgrade import

Benefits:
- Single source of truth for upgrade API logic (UpgradeAPIService)
- Easy to expose same endpoints publicly if needed (just add new route file)
- Reduces code duplication across API routes
- Better separation of concerns (service vs HTTP handling)
- Git history preserved (file moved, not recreated)
@DawoudIO DawoudIO added this to the 6.4.0 milestone Dec 6, 2025
@DawoudIO DawoudIO requested a review from a team as a code owner December 6, 2025 03:02
@DawoudIO DawoudIO requested review from DAcodedBEAT, MrClever, Copilot, grayeul and respencer and removed request for a team December 6, 2025 03:02
@DawoudIO DawoudIO added the API label Dec 6, 2025
@DawoudIO DawoudIO requested a review from bigtigerku December 6, 2025 03:02
Move ChurchCRMReleaseManager import from inline fully-qualified class names to top-level
use statement, following PHP 8.2+ best practices for namespaced code.

Changes:
- Add 'use ChurchCRM\Utils\ChurchCRMReleaseManager' at top
- Replace inline \ChurchCRM\Utils\ChurchCRMReleaseManager:: with ChurchCRMReleaseManager::
- Improves code readability and follows codebase conventions
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors the system upgrade API endpoints by consolidating them under the new admin API infrastructure. The upgrade endpoints are moved from /api/systemupgrade to /admin/api/upgrade, following the established pattern for admin-only APIs introduced in previous refactorings.

Key Changes:

  • Introduces UpgradeAPIService to encapsulate upgrade operations following the service layer pattern
  • Migrates three upgrade endpoints to the new admin API route structure with proper documentation
  • Updates frontend JavaScript to use AdminAPIRequest instead of APIRequest for admin-specific endpoints

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
webpack/upgrade-wizard-app.js Updated API calls to use AdminAPIRequest with new /admin/api/upgrade paths
src/skin/js/CRMJSOM.js Added new AdminAPIRequest wrapper function for admin API endpoints
src/api/index.php Removed old system-upgrade.php route registration
src/admin/routes/system.php Added fresh release check when loading upgrade page
src/admin/routes/api/upgrade.php Migrated upgrade endpoints with enhanced documentation
src/admin/index.php Registered new upgrade API route file
src/ChurchCRM/dto/ChurchCRMReleaseManager.php Added debug logging for version comparison troubleshooting
src/ChurchCRM/Service/UpgradeAPIService.php New service class wrapping ChurchCRMReleaseManager for API routes
Comments suppressed due to low confidence (2)

src/admin/routes/api/upgrade.php:42

  • Missing input validation for required parameters. The $input['fullPath'] and $input['sha1'] are accessed directly without checking if they exist in the parsed body. If these fields are missing, this will generate PHP warnings/errors.

Add validation before calling the service:

$input = $request->getParsedBody();
if (!isset($input['fullPath']) || !isset($input['sha1'])) {
    return SlimUtils::renderJSON($response, [
        'message' => 'Missing required parameters: fullPath and sha1'
    ], 400);
}
UpgradeAPIService::doUpgrade($input['fullPath'], $input['sha1']);

webpack/upgrade-wizard-app.js:177

  • Inconsistent parameter name. The function uses type: 'GET' instead of method: 'GET', which is inconsistent with the other API calls in this file (lines 250, 347, 403) that use method. While jQuery's $.ajax() accepts both, the codebase should use consistent naming.

Change to:

window.CRM.AdminAPIRequest({
    method: 'GET',
    path: 'upgrade/download-latest-release',
})
 * Auto-download update when step is shown
 */
function autoDownloadUpdate() {

Comment on lines +28 to +32
if (!options.method) {
options.method = "GET";
} else {
options.dataType = "json";
}
Copy link

Copilot AI Dec 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The conditional logic is incorrect. When a method is provided, dataType should be set to "json", but the current logic only sets it when a method is NOT provided. This means GET requests won't have dataType: "json" but POST/PUT requests will.

This should be:

if (!options.method) {
    options.method = "GET";
}
options.dataType = "json";

The same bug exists in the original APIRequest function above (lines 6-10).

Copilot uses AI. Check for mistakes.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@DawoudIO DawoudIO merged commit 6af9056 into master Dec 6, 2025
7 checks passed
@DawoudIO DawoudIO deleted the refactor/upgrade-api-service branch December 6, 2025 03:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants