# Update Checker Shared Library Proposal

**Status:** Proposal - Under Review  
**Date:** February 27, 2026  
**Author:** AI Assistant  

---

## Executive Summary

Convert the current hardcoded update checker (with 15+ find-and-replace conflict points) into a single shared library that all plugins can use via simple configuration objects. Eliminates code duplication and conflict risks.

---

## Current Problem

- **Code Duplication**: ~900 lines of update checker code copied across plugins
- **Manual Conflict Management**: Each plugin requires 15+ identifier changes (class names, AJAX actions, transients, CSS classes, JS objects, nonces, etc.)
- **Maintenance Burden**: Bug fixes must be propagated to every plugin copy
- **Human Error Risk**: Easy to miss a rename, causing conflicts when multiple plugins run
- **Documentation Heavy**: 524-line setup guide required for each implementation

---

## Proposed Solution: Shared Library with Configuration

### Architecture

**Single Library Location:**
```
/wp-content/plugins/agency-pulse-update-library/
├── agency-pulse-update-library.php    # Main plugin file (loader)
├── includes/
│   ├── class-update-manager.php       # Core update logic (parametrized)
│   ├── class-config-validator.php     # Validates plugin configurations
│   └── class-singleton-registry.php   # Manages multiple instances safely
└── templates/
    └── modal-template.php              # Shared UI template
```

### How It Works

**Each plugin provides a simple config:**

```php
// In any plugin that needs updates (e.g., agency-pulse-products.php)
$update_config = array(
    'plugin_slug'     => 'agency-pulse-products',
    'plugin_file'     => __FILE__,
    'update_url'      => 'https://example.com/updates/products.json',
    'version_const'   => 'AGENCY_PULSE_PRODUCTS_VERSION',
    'domain_prefix'   => 'app_',
    'plugin_name'     => 'Agency Pulse Products',
);

new AgencyPulseUpdate_Manager( $update_config );
```

**Library handles everything:**
- Auto-generates all unique prefixes from `plugin_slug`
- Registers AJAX actions, nonces, transients with auto-prefixed names
- Generates CSS/JS with plugin-specific IDs
- Manages multiple plugin instances without conflicts
- Validates configuration for completeness

### Auto-Prefixing Example

For `plugin_slug = 'agency-pulse-products'` and `domain_prefix = 'app_'`:

```
Cache keys:          app_update_check, app_update_success, app_update_error
AJAX actions:        wp_ajax_app_get_update_info, wp_ajax_app_perform_update
Nonce names:         app_update_nonce, app_force_check
Modal IDs:           app-modal-overlay, app-modal-content
CSS classes:         app-modal, app-modal-btn, app-spinner
JavaScript object:   window.AgencyPulseProductsModal
File references:     agency-pulse-products.php, agency-pulse-products-backup
```

---

## Key Benefits

| Aspect | Current | Library |
|--------|---------|---------|
| **Lines of Code Per Plugin** | 900+ (duplicated) | 8 (config only) |
| **Setup Time** | 30-45 min + testing | 5 min + testing |
| **Conflict Risk** | High (manual prefixing) | Near zero (auto-generated) |
| **Bug Fixes** | Update everywhere | Fix once |
| **Testing** | Per-plugin | Once for library |
| **Documentation** | 524 lines per plugin | One core + one config guide |
| **Version Conflicts** | Possible with old/new code | Handled by version schema |

---

## Implementation Steps

### Phase 1: Create the Library
1. Extract core logic from `agency-pulse-invoice-enhancements` update checker
2. Parametrize all hardcoded identifiers
3. Build config validator
4. Build instance registry for simultaneous plugin support
5. Unit test the library

### Phase 2: Integrate First Plugin
1. Remove old update checker from plugin
2. Add 8-line config
3. Test integration
4. Document results

### Phase 3: Integrate Additional Plugins
1. Repeat Phase 2 for each plugin
2. Test multiple plugins simultaneously
3. Verify no conflicts in browser console or error logs

### Phase 4: Optional - Admin Dashboard
- Centralized update checker status page
- Manual force-check per plugin
- Last-check timestamps
- Notification preferences

---

## Detailed Structure

### Configuration Schema

```php
$update_config = array(
    // REQUIRED: Used to construct plugin identifiers
    'plugin_slug'      => 'agency-pulse-products',     // kebab-case
    'plugin_file'      => __FILE__,                     // Main plugin file path
    'update_url'       => 'https://api.example.com/products-update.json',
    'version_const'    => 'AGENCY_PULSE_PRODUCTS_VERSION',
    'domain_prefix'    => 'app_',                       // 2-4 char prefix (a-z, numbers, underscore)
    'plugin_name'      => 'Agency Pulse Products',      // Display name
    
    // OPTIONAL: Advanced configuration
    'cache_ttl'        => 12 * HOUR_IN_SECONDS,        // Transient timeout
    'timeout'          => 10,                           // HTTP request timeout (seconds)
    'db_prefix'        => 'agency_',                   // For custom database operations (if needed)
    'disable_ui'       => false,                        // Skip modal/UI if you want manual checks only
);

$manager = new AgencyPulseUpdate_Manager( $update_config );
```

### Library Class Interface

```php
class AgencyPulseUpdate_Manager {
    public function __construct( array $config ) {}
    public function check_for_updates() {}
    public function get_update_info() {}
    public function perform_update() {}
    public function force_check() {}
    public function get_last_check_time() {}
    public function clear_cache() {}
    public static function get_registry() {}  // View all active instances
}
```

---

## How Multiple Plugins Run Side-By-Side

**Plugin A Config:**
```php
'plugin_slug'   => 'agency-pulse-products',
'domain_prefix' => 'app_'
// Generates: app_update_check, app-modal-overlay, etc.
```

**Plugin B Config:**
```php
'plugin_slug'   => 'agency-pulse-invoices',
'domain_prefix' => 'api_'
// Generates: api_update_check, api-modal-overlay, etc.
```

**Registry maintains:** `['app' => Manager1, 'api' => Manager2, ...]`

Each instance:
- Has its own transient keys
- Listens to its own AJAX actions
- Displays its own modal with unique IDs and CSS classes
- No conflicts possible

---

## Risk Mitigation

| Risk | Impact | Mitigation |
|------|--------|-----------|
| Library breaks, all plugins affected | High | Comprehensive unit tests; semantic versioning; optional fallback to individual checkers |
| Plugin A needs library v1, Plugin B needs v2 | Medium | Library supports version schema detection; graceful downgrade |
| Difficult to debug issues | Medium | Better error messages than current setup; centralized logging |
| Large JSON config hard to maintain | Low | Config validation catches errors early; documented schema |

---

## Decision Points

### Before Implementation

1. **Library Activation Method:**
   - [ ] Required plugin (user manually activates)
   - [ ] Auto-activated by dependent plugin
   - [ ] Silently required via dependency check

2. **Old Method Support:**
   - [ ] Clean break (old class-copy method no longer works)
   - [ ] Backwards compatibility (support both old and new)

3. **Naming Convention:**
   - [ ] Keep `AgencyPulseUpdate_Manager` or rename?
   - [ ] Standardize prefix format? (Currently `app_`, `api_`, etc.)

4. **Admin Features:**
   - [ ] Start with core library only
   - [ ] Include admin dashboard in Phase 1

---

## Next Steps

- [ ] Review this proposal
- [ ] Provide feedback on decision points above
- [ ] Approve/reject approach
- [ ] Schedule Phase 1 implementation

---

## Appendix: Migration Checklist (Per Plugin)

Once library is ready, migrating a plugin requires:

- [ ] Remove `class-update-checker.php`
- [ ] Remove update checker instantiation from main file
- [ ] Add library require check: `if ( class_exists( 'AgencyPulseUpdate_Manager' ) )`
- [ ] Add config array (copy from template)
- [ ] Instantiate: `new AgencyPulseUpdate_Manager( $update_config )`
- [ ] Remove update checker documentation
- [ ] Test update check in admin
- [ ] Test modal UI
- [ ] Verify no JavaScript errors in console
- [ ] Test alongside other update-checking plugins

---

**Document Location:** `/wp-content/plugins/agency-pulse-products/UPDATE_CHECKER_LIBRARY_PROPOSAL.md`

