# Subscription Cache Management

## Overview

The subscription validation system uses **1-hour caching** to optimize performance and reduce database queries to the master subscription database. This document explains how cache management works and when cache is automatically cleared.

---

## 🔄 Automatic Cache Clearing

The subscription cache is **automatically cleared** in the following scenarios:

### 1. ✅ User Login
**When**: After successful authentication
**Where**: `application/controllers/Login.php` → `verify()` method
**Why**: Ensures users see the most up-to-date subscription status when they log in

```php
// In Login.php verify() method (line 31-33)
// Clear subscription cache on login to get fresh data
$this->load->library('subscription_validator');
$this->subscription_validator->clear_cache();
```

### 2. ✅ User Logout
**When**: Before session destruction
**Where**: `application/controllers/Logout.php` → `index()` method
**Why**: Cleans up cached data and ensures fresh check on next login

```php
// In Logout.php index() method (line 15-17)
// Clear subscription cache on logout
$this->load->library('subscription_validator');
$this->subscription_validator->clear_cache();
```

### 3. ✅ Manual Refresh
**When**: Admin clicks "Refresh Status" or "Clear Cache"
**Where**: `http://localhost/pos/subscription/clear_cache`
**Who**: Admin users only (user_id = 1)
**Why**: Allows immediate refresh after updating subscription in master database

### 4. ✅ Automatic Expiry
**When**: After 1 hour (3600 seconds)
**Where**: Automatic by file cache system
**Why**: Prevents stale data from being displayed indefinitely

---

## ⏱️ Cache Duration

**Default**: 1 hour (3600 seconds)

**Configure**: Edit `application/config/subscription.php`
```php
$config['subscription_cache_duration'] = 3600; // seconds
```

**Recommendations**:
- **Development**: 300 seconds (5 minutes) for quick testing
- **Production**: 3600 seconds (1 hour) for performance
- **High-traffic**: 7200 seconds (2 hours) or more

---

## 📁 Cache File Location

**Directory**: `application/cache/`

**File Pattern**: `subscription_[tenant_name].cache`

**Examples**:
- `application/cache/md5('subscription_default').cache`
- `application/cache/md5('subscription_restaurant').cache`
- `application/cache/md5('subscription_pharmacy').cache`

---

## 🛠️ Manual Cache Management

### Clear Cache for Current Tenant

**URL**: `http://localhost/pos/subscription/clear_cache`

**Access**: Admin only
**Result**: Redirects back to previous page with success message

### Clear Cache Programmatically

```php
// In any controller
$this->load->library('subscription_validator');

// Clear cache for current tenant
$this->subscription_validator->clear_cache();

// Clear cache for specific tenant
$this->subscription_validator->clear_cache('restaurant');
```

### Clear All Subscription Caches

```bash
# Delete all subscription cache files
rm application/cache/*.cache

# Or in PHP
$files = glob(APPPATH . 'cache/*.cache');
foreach ($files as $file) {
    if (is_file($file)) {
        unlink($file);
    }
}
```

---

## 🎯 Cache Behavior

### First Request (Cache Miss)
1. User accesses dashboard
2. Subscription validator checks cache → **NOT FOUND**
3. Queries master database for subscription details
4. Stores result in cache file with 1-hour expiry
5. Returns validation result
6. **Time**: ~50-100ms (database query)

### Subsequent Requests (Cache Hit)
1. User accesses dashboard
2. Subscription validator checks cache → **FOUND**
3. Verifies cache not expired (< 1 hour old)
4. Returns cached result
5. **Time**: ~1-5ms (file read)

### After Cache Expiry
1. User accesses dashboard
2. Subscription validator checks cache → **EXPIRED**
3. Deletes old cache file
4. Queries master database for fresh data
5. Creates new cache file
6. Returns validation result

---

## 🔍 Cache Debugging

### Check if Cache Exists

```php
$this->load->library('subscription_validator');
$cache_key = 'subscription_' . $this->subscription_validator->get_current_tenant();
$cache_file = APPPATH . 'cache/' . md5($cache_key) . '.cache';

if (file_exists($cache_file)) {
    $cache_data = unserialize(file_get_contents($cache_file));
    $expires = $cache_data['expires'];
    $is_expired = ($expires < time());

    echo "Cache exists: YES<br>";
    echo "Expires at: " . date('Y-m-d H:i:s', $expires) . "<br>";
    echo "Is expired: " . ($is_expired ? 'YES' : 'NO') . "<br>";
} else {
    echo "Cache exists: NO<br>";
}
```

### View Cache Contents

```php
$cache_file = APPPATH . 'cache/' . md5('subscription_default') . '.cache';
if (file_exists($cache_file)) {
    $cache_data = unserialize(file_get_contents($cache_file));
    print_r($cache_data['data']); // Shows cached subscription info
}
```

---

## ⚠️ Important Notes

### 1. Cache vs Real-Time Data
- **Cache**: Fast but may be up to 1 hour old
- **Real-time**: Accurate but slower (requires DB query)
- **Balance**: 1-hour cache provides good performance while maintaining reasonable freshness

### 2. When Cache Doesn't Clear Automatically
- **Direct database updates**: Cache won't know about changes
- **Solution**: Use admin "Refresh Status" button after DB updates

### 3. Production Considerations
- **File permissions**: Ensure `application/cache/` is writable (755 or 777)
- **Disk space**: Cache files are small (~2KB each), negligible storage
- **Multiple servers**: If using load balancer, each server has its own cache

---

## 🎬 Cache Lifecycle Example

```
User Journey:
├─ 09:00 AM - User logs in
│  └─ Cache cleared automatically
│  └─ Fresh DB query performed
│  └─ New cache created (expires 10:00 AM)
│
├─ 09:15 AM - User views dashboard
│  └─ Cache hit (45 minutes remaining)
│  └─ Fast response from cache
│
├─ 09:45 AM - User edits user profile
│  └─ Cache hit (15 minutes remaining)
│  └─ Fast response from cache
│
├─ 10:05 AM - User views subscription status
│  └─ Cache expired
│  └─ Fresh DB query performed
│  └─ New cache created (expires 11:05 AM)
│
└─ 10:30 AM - User logs out
   └─ Cache cleared automatically
   └─ Clean slate for next login
```

---

## 🚀 Performance Impact

### Without Caching
- Every page load: ~50-100ms DB query
- 100 page views/hour: 100 queries to master DB
- **Total DB load**: HIGH

### With 1-Hour Caching
- First page load: ~50-100ms DB query
- Next 99 page loads: ~1-5ms file read
- 100 page views/hour: 1-2 queries to master DB
- **Total DB load**: VERY LOW
- **Performance gain**: 95-99% reduction in DB queries

---

## 🔐 Security Considerations

- Cache files stored in `application/cache/` (not web-accessible)
- File names are MD5 hashed (obscured)
- Cache contains subscription data only (no sensitive credentials)
- Automatic cleanup on logout prevents data leakage
- Admin-only access to manual clear cache function

---

## 📊 Monitoring Cache Performance

### Log Cache Hits/Misses (Optional)

Add to `Subscription_validator.php` → `get_from_cache()`:

```php
private function get_from_cache($key) {
    $cache_file = APPPATH . 'cache/' . md5($key) . '.cache';

    if (file_exists($cache_file)) {
        $cache_data = unserialize(file_get_contents($cache_file));
        if ($cache_data['expires'] > time()) {
            log_message('debug', 'Subscription cache HIT for: ' . $key);
            return $cache_data['data'];
        } else {
            log_message('debug', 'Subscription cache EXPIRED for: ' . $key);
            @unlink($cache_file);
        }
    }

    log_message('debug', 'Subscription cache MISS for: ' . $key);
    return FALSE;
}
```

Then check `application/logs/` for cache performance metrics.

---

## ✅ Summary

**Automatic Cache Clearing**:
- ✅ On login
- ✅ On logout
- ✅ After 1 hour
- ✅ On manual refresh

**Benefits**:
- 🚀 95% faster page loads
- 📉 Minimal master DB load
- 🔄 Fresh data on login
- 🧹 Clean on logout

**Configuration**:
- Duration: `application/config/subscription.php`
- Enable/Disable: Same config file
- Manual clear: `/subscription/clear_cache`

---

**Version**: 1.0.0
**Last Updated**: 2025-01-20
