# Analytics Implementation Guide

This guide explains how the advanced analytics feature works and how to add it to subscription plans.

## Quick Start

### 1. Enable Advanced Analytics for a Plan

**Using Django Admin:**

1. Navigate to `http://localhost:8000/admin/platform_admin/subscriptionplan/`
2. Open or create a subscription plan
3. Scroll to the "Permissions" JSON field
4. Add `"advanced_analytics": true` to the JSON object
5. Save

**Example permissions JSON:**
```json
{
    "advanced_analytics": true,
    "can_accept_payments": false,
    "can_use_custom_domain": false,
    "can_white_label": false
}
```

**Using Django Shell:**
```bash
docker compose -f docker-compose.local.yml exec django python manage.py shell

# In the shell:
from platform_admin.models import SubscriptionPlan
plan = SubscriptionPlan.objects.get(name='Professional')  # Replace with plan name
perms = plan.permissions or {}
perms['advanced_analytics'] = True
plan.permissions = perms
plan.save()
print("✓ Analytics enabled for", plan.name)
```

### 2. Test the Permission Gating

```bash
# Get auth token
TOKEN=$(curl -X POST http://lvh.me:8000/auth-token/ \
  -H "Content-Type: application/json" \
  -d '{"username":"test@example.com","password":"password"}' \
  | jq -r '.token')

# Test dashboard endpoint (should work if permission is enabled)
curl -H "Authorization: Token $TOKEN" \
  http://lvh.me:8000/api/analytics/analytics/dashboard/ | jq
```

## How Permission Gating Works

### The Permission Class

Located in: `/home/poduck/Desktop/smoothschedule2/smoothschedule/core/permissions.py`

```python
def HasFeaturePermission(permission_key):
    """
    Factory function that creates a permission class for feature checking.
    """
    class FeaturePermission(BasePermission):
        def has_permission(self, request, view):
            tenant = getattr(request, 'tenant', None)
            if not tenant:
                return True  # No tenant = public schema, allow

            if not tenant.has_feature(permission_key):
                feature_name = self.FEATURE_NAMES.get(permission_key, ...)
                raise PermissionDenied(f"Your current plan does not include {feature_name}")

            return True
```

### The Tenant.has_feature() Method

Located in: `/home/poduck/Desktop/smoothschedule2/smoothschedule/core/models.py`

```python
def has_feature(self, permission_key):
    """Check if tenant has a feature permission"""
    # 1. Check direct boolean field on Tenant model
    if hasattr(self, permission_key):
        return bool(getattr(self, permission_key))

    # 2. Check subscription plan's permissions JSON
    if self.subscription_plan:
        plan_permissions = self.subscription_plan.permissions or {}
        return bool(plan_permissions.get(permission_key, False))

    # 3. Default to False
    return False
```

### The Analytics ViewSet

Located in: `/home/poduck/Desktop/smoothschedule2/smoothschedule/analytics/views.py`

```python
class AnalyticsViewSet(viewsets.ViewSet):
    permission_classes = [
        IsAuthenticated,                          # Requires login
        HasFeaturePermission('advanced_analytics')  # Requires permission
    ]

    @action(detail=False, methods=['get'])
    def dashboard(self, request):
        # Permission check happens before this method is called
        # If user doesn't have permission, they get 403 Forbidden
        ...
```

## Permission Flow Diagram

```
User Request
    ↓
    ├─ IsAuthenticated
    │  ├─ ✓ User logged in? → Continue
    │  └─ ✗ Not logged in? → 401 Unauthorized
    ↓
    ├─ HasFeaturePermission('advanced_analytics')
    │  ├─ Get request.tenant
    │  ├─ Call tenant.has_feature('advanced_analytics')
    │  │  ├─ Check Tenant model field → Found? Return value
    │  │  ├─ Check subscription_plan.permissions JSON → Found? Return value
    │  │  └─ Not found? Return False
    │  ├─ ✓ Has permission? → Continue
    │  └─ ✗ No permission? → 403 Forbidden
    ↓
    View Logic Executes
    ↓
    Return Analytics Data
```

## Adding New Analytics Endpoints

To add a new analytics endpoint with the same permission gating:

```python
# In analytics/views.py

class AnalyticsViewSet(viewsets.ViewSet):
    permission_classes = [IsAuthenticated, HasFeaturePermission('advanced_analytics')]

    @action(detail=False, methods=['get'])
    def my_new_analytics(self, request):
        """
        New analytics endpoint

        GET /api/analytics/analytics/my_new_analytics/
        """
        # Your analytics logic here
        data = {
            'metric_1': calculate_metric_1(),
            'metric_2': calculate_metric_2(),
        }
        return Response(data)
```

No additional permission configuration needed - the class-level `permission_classes` applies to all action methods.

## Testing Permission Gating

### Test 1: Without Authentication

```bash
curl http://lvh.me:8000/api/analytics/analytics/dashboard/
# Expected: 401 Unauthorized
```

### Test 2: With Authentication but No Permission

```bash
# Ensure tenant's plan doesn't have advanced_analytics permission
curl -H "Authorization: Token $TOKEN" \
  http://lvh.me:8000/api/analytics/analytics/dashboard/
# Expected: 403 Forbidden with "Advanced Analytics" in message
```

### Test 3: With Both Authentication and Permission

```bash
# Ensure tenant's plan has advanced_analytics: true
curl -H "Authorization: Token $TOKEN" \
  http://lvh.me:8000/api/analytics/analytics/dashboard/
# Expected: 200 OK with dashboard data
```

## Debugging Permission Issues

### Check if Tenant Has Permission

```bash
docker compose -f docker-compose.local.yml exec django python manage.py shell

# In shell:
from core.models import Tenant
tenant = Tenant.objects.get(schema_name='demo')
print("Has permission:", tenant.has_feature('advanced_analytics'))
print("Subscription plan:", tenant.subscription_plan)
print("Plan permissions:", tenant.subscription_plan.permissions if tenant.subscription_plan else "No plan")
```

### Check if Field is Defined

```bash
# Check if 'advanced_analytics' field exists on Tenant model
docker compose -f docker-compose.local.yml exec django python manage.py shell

from core.models import Tenant
print("Available fields:")
print([f.name for f in Tenant._meta.get_fields() if 'analytic' in f.name.lower()])
```

### View Permission Class Details

```bash
docker compose -f docker-compose.local.yml exec django python manage.py shell

from core.permissions import HasFeaturePermission
FeaturePermission = HasFeaturePermission('advanced_analytics')
perm = FeaturePermission()
print("Feature names:", perm.FEATURE_NAMES.get('advanced_analytics'))
```

## Architecture Decisions

### Why Use HasFeaturePermission?

1. **Reusable**: Same pattern used for payments, webhooks, custom domains, etc.
2. **Flexible**: Checks both direct fields and plan JSON
3. **User-Friendly**: Returns detailed error messages
4. **Secure**: Denies by default, explicitly allows

### Why Not Use DjangoModelPermissions?

DjangoModelPermissions are designed for Django auth model permissions. Analytics is a plan feature, not a model permission, so it doesn't fit the pattern.

### Why Not Add a Tenant Field?

We could add `advanced_analytics` as a boolean field on the Tenant model, but:
- Harder to manage (direct field + JSON field)
- Less flexible (plan JSON can change without migrations)
- Current approach allows both field and plan-based permissions

## Common Patterns

### Dual Permission Check

Some features require multiple permissions. Example: Revenue analytics requires BOTH `advanced_analytics` AND `can_accept_payments`.

```python
@action(detail=False, methods=['get'])
def revenue(self, request):
    # First permission check happens at class level (advanced_analytics)
    # Additional check for can_accept_payments:
    tenant = getattr(request, 'tenant', None)
    if not tenant or not tenant.has_feature('can_accept_payments'):
        return Response(
            {'error': 'Payment analytics not available'},
            status=status.HTTP_403_FORBIDDEN
        )
```

### Filtering by Tenant

All queries should be filtered by tenant. Django-tenants handles this automatically:

```python
# This query is automatically scoped to request.tenant's schema
Event.objects.filter(status='confirmed')
```

## Files Modified/Created

### New Files Created
- `/home/poduck/Desktop/smoothschedule2/smoothschedule/analytics/` - Analytics app directory
- `/home/poduck/Desktop/smoothschedule2/smoothschedule/analytics/__init__.py` - Package init
- `/home/poduck/Desktop/smoothschedule2/smoothschedule/analytics/apps.py` - App config
- `/home/poduck/Desktop/smoothschedule2/smoothschedule/analytics/admin.py` - Admin config (empty, read-only app)
- `/home/poduck/Desktop/smoothschedule2/smoothschedule/analytics/views.py` - AnalyticsViewSet with 3 endpoints
- `/home/poduck/Desktop/smoothschedule2/smoothschedule/analytics/serializers.py` - Response serializers
- `/home/poduck/Desktop/smoothschedule2/smoothschedule/analytics/urls.py` - URL routing
- `/home/poduck/Desktop/smoothschedule2/smoothschedule/analytics/tests.py` - Pytest test suite
- `/home/poduck/Desktop/smoothschedule2/smoothschedule/analytics/migrations/` - Migrations directory
- `/home/poduck/Desktop/smoothschedule2/smoothschedule/analytics/README.md` - API documentation
- `/home/poduck/Desktop/smoothschedule2/smoothschedule/analytics/IMPLEMENTATION_GUIDE.md` - This file

### Files Modified
- `/home/poduck/Desktop/smoothschedule2/smoothschedule/core/permissions.py` - Added 'advanced_analytics' and 'advanced_reporting' to FEATURE_NAMES
- `/home/poduck/Desktop/smoothschedule2/smoothschedule/config/urls.py` - Added analytics URL include
- `/home/poduck/Desktop/smoothschedule2/smoothschedule/config/settings/base.py` - Added 'analytics' to INSTALLED_APPS

## Endpoints Summary

All endpoints require `IsAuthenticated` + `HasFeaturePermission('advanced_analytics')`:

| Endpoint | Method | Description | Requires Extra Permission |
|----------|--------|-------------|-------------------------|
| `/api/analytics/analytics/dashboard/` | GET | Dashboard summary stats | No |
| `/api/analytics/analytics/appointments/` | GET | Appointment analytics with trends | No |
| `/api/analytics/analytics/revenue/` | GET | Revenue analytics | Yes: `can_accept_payments` |

## Next Steps

1. **Deploy**: Add this to your production code
2. **Enable for Plans**: Grant `advanced_analytics` to desired subscription plans
3. **Test**: Use the test suite in `analytics/tests.py`
4. **Monitor**: Watch logs for any permission-related errors
5. **Enhance**: Add more analytics metrics or export features

## Support

For issues:
1. Check logs: `docker compose logs django`
2. Check tenant permissions: Run Django shell commands above
3. Check authentication: Ensure token is valid
4. Review permission class: See `core/permissions.py`
